diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra index 16020b31ae640e..5d41ebadf15e92 100644 --- a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra +++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra @@ -5,7 +5,7 @@ Description: It is possible to switch the cpi setting of the mouse with the press of a button. When read, this file returns the raw number of the actual cpi setting reported by the mouse. This number has to be further - processed to receive the real dpi value. + processed to receive the real dpi value: VALUE DPI 1 400 diff --git a/Documentation/ABI/stable/sysfs-driver-mlxreg-io b/Documentation/ABI/stable/sysfs-driver-mlxreg-io index 156319fc5b80a9..3544968f43cc05 100644 --- a/Documentation/ABI/stable/sysfs-driver-mlxreg-io +++ b/Documentation/ABI/stable/sysfs-driver-mlxreg-io @@ -1,5 +1,4 @@ -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - asic_health +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/asic_health Date: June 2018 KernelVersion: 4.19 @@ -9,9 +8,8 @@ Description: This file shows ASIC health status. The possible values are: The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - cpld1_version - cpld2_version +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld1_version +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld2_version Date: June 2018 KernelVersion: 4.19 Contact: Vadim Pasternak @@ -20,8 +18,7 @@ Description: These files show with which CPLD versions have been burned The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - fan_dir +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/fan_dir Date: December 2018 KernelVersion: 5.0 @@ -32,8 +29,7 @@ Description: This file shows the system fans direction: The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - jtag_enable +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/jtag_enable Date: November 2018 KernelVersion: 5.0 @@ -43,8 +39,7 @@ Description: These files show with which CPLD versions have been burned The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - jtag_enable +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/jtag_enable Date: November 2018 KernelVersion: 5.0 @@ -87,16 +82,15 @@ Description: These files allow asserting system power cycling, switching The files are write only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - reset_aux_pwr_or_ref - reset_asic_thermal - reset_hotswap_or_halt - reset_hotswap_or_wd - reset_fw_reset - reset_long_pb - reset_main_pwr_fail - reset_short_pb - reset_sw_reset +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_aux_pwr_or_ref +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_asic_thermal +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_hotswap_or_halt +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_hotswap_or_wd +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_fw_reset +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_long_pb +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_main_pwr_fail +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_short_pb +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_sw_reset Date: June 2018 KernelVersion: 4.19 Contact: Vadim Pasternak @@ -110,11 +104,10 @@ Description: These files show the system reset cause, as following: power The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ - reset_comex_pwr_fail - reset_from_comex - reset_system - reset_voltmon_upgrade_fail +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_comex_pwr_fail +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_from_comex +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_system +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_voltmon_upgrade_fail Date: November 2018 KernelVersion: 5.0 diff --git a/Documentation/ABI/testing/pstore b/Documentation/ABI/testing/pstore index 5fca9f5e10a3aa..d45209abdb1bd9 100644 --- a/Documentation/ABI/testing/pstore +++ b/Documentation/ABI/testing/pstore @@ -1,6 +1,6 @@ -Where: /sys/fs/pstore/... (or /dev/pstore/...) +What: /sys/fs/pstore/... (or /dev/pstore/...) Date: March 2011 -Kernel Version: 2.6.39 +KernelVersion: 2.6.39 Contact: tony.luck@intel.com Description: Generic interface to platform dependent persistent storage. diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-format b/Documentation/ABI/testing/sysfs-bus-event_source-devices-format index 77f47ff5ee02b9..5bb793ec926c1f 100644 --- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-format +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-format @@ -1,6 +1,6 @@ -Where: /sys/bus/event_source/devices//format +What: /sys/bus/event_source/devices//format Date: January 2012 -Kernel Version: 3.3 +KernelVersion: 3.3 Contact: Jiri Olsa Description: Attribute group to describe the magic bits that go into diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 index feb2e4a870755a..4a251b7f11e4ed 100644 --- a/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 +++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-hm6352 @@ -1,20 +1,20 @@ -Where: /sys/bus/i2c/devices/.../heading0_input +What: /sys/bus/i2c/devices/.../heading0_input Date: April 2010 -Kernel Version: 2.6.36? +KernelVersion: 2.6.36? Contact: alan.cox@intel.com Description: Reports the current heading from the compass as a floating point value in degrees. -Where: /sys/bus/i2c/devices/.../power_state +What: /sys/bus/i2c/devices/.../power_state Date: April 2010 -Kernel Version: 2.6.36? +KernelVersion: 2.6.36? Contact: alan.cox@intel.com Description: Sets the power state of the device. 0 sets the device into sleep mode, 1 wakes it up. -Where: /sys/bus/i2c/devices/.../calibration +What: /sys/bus/i2c/devices/.../calibration Date: April 2010 -Kernel Version: 2.6.36? +KernelVersion: 2.6.36? Contact: alan.cox@intel.com Description: Sets the calibration on or off (1 = on, 0 = off). See the chip data sheet. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 b/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 index 0a1ca1487fa97c..a133fd8d081ac2 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 +++ b/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 @@ -1,4 +1,4 @@ -What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity +What: /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity Date: January 2017 KernelVersion: 4.11 Contact: linux-iio@vger.kernel.org @@ -6,7 +6,7 @@ Description: Show or set the gain boost of the amp, from 0-31 range. default 31 -What /sys/bus/iio/devices/iio:deviceX/sensor_max_range +What: /sys/bus/iio/devices/iio:deviceX/sensor_max_range Date: January 2017 KernelVersion: 4.11 Contact: linux-iio@vger.kernel.org diff --git a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 index 9a17ab5036a4cb..c59d953463417b 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 +++ b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 @@ -1,4 +1,4 @@ -What /sys/bus/iio/devices/iio:deviceX/in_proximity_input +What: /sys/bus/iio/devices/iio:deviceX/in_proximity_input Date: March 2014 KernelVersion: 3.15 Contact: Matt Ranostay @@ -6,7 +6,7 @@ Description: Get the current distance in meters of storm (1km steps) 1000-40000 = distance in meters -What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity +What: /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity Date: March 2014 KernelVersion: 3.15 Contact: Matt Ranostay diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats index 4b0318c99507f4..3c9a8c4a25eb89 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats @@ -9,9 +9,9 @@ errors may be "seen" / reported by the link partner and not the problematic endpoint itself (which may report all counters as 0 as it never saw any problems). -Where: /sys/bus/pci/devices//aer_dev_correctable +What: /sys/bus/pci/devices//aer_dev_correctable Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: List of correctable errors seen and reported by this PCI device using ERR_COR. Note that since multiple errors may @@ -31,9 +31,9 @@ Header Log Overflow 0 TOTAL_ERR_COR 2 ------------------------------------------------------------------------- -Where: /sys/bus/pci/devices//aer_dev_fatal +What: /sys/bus/pci/devices//aer_dev_fatal Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: List of uncorrectable fatal errors seen and reported by this PCI device using ERR_FATAL. Note that since multiple errors may @@ -62,9 +62,9 @@ TLP Prefix Blocked Error 0 TOTAL_ERR_FATAL 0 ------------------------------------------------------------------------- -Where: /sys/bus/pci/devices//aer_dev_nonfatal +What: /sys/bus/pci/devices//aer_dev_nonfatal Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: List of uncorrectable nonfatal errors seen and reported by this PCI device using ERR_NONFATAL. Note that since multiple errors @@ -103,20 +103,20 @@ collectors) that are AER capable. These indicate the number of error messages as device, so these counters include them and are thus cumulative of all the error messages on the PCI hierarchy originating at that root port. -Where: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_cor +What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_cor Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: Total number of ERR_COR messages reported to rootport. -Where: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_fatal +What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_fatal Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: Total number of ERR_FATAL messages reported to rootport. -Where: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_nonfatal +What: /sys/bus/pci/devices//aer_stats/aer_rootport_total_err_nonfatal Date: July 2018 -Kernel Version: 4.19.0 +KernelVersion: 4.19.0 Contact: linux-pci@vger.kernel.org, rajatja@google.com Description: Total number of ERR_NONFATAL messages reported to rootport. diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss index 53d99edd1d75ac..92a94e1068c2b3 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss @@ -1,68 +1,68 @@ -Where: /sys/bus/pci/devices//ccissX/cXdY/model +What: /sys/bus/pci/devices//ccissX/cXdY/model Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 model for logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/rev +What: /sys/bus/pci/devices//ccissX/cXdY/rev Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 revision for logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/unique_id +What: /sys/bus/pci/devices//ccissX/cXdY/unique_id Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 83 serial number for logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/vendor +What: /sys/bus/pci/devices//ccissX/cXdY/vendor Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: Displays the SCSI INQUIRY page 0 vendor for logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/block:cciss!cXdY +What: /sys/bus/pci/devices//ccissX/cXdY/block:cciss!cXdY Date: March 2009 -Kernel Version: 2.6.30 +KernelVersion: 2.6.30 Contact: iss_storagedev@hp.com Description: A symbolic link to /sys/block/cciss!cXdY -Where: /sys/bus/pci/devices//ccissX/rescan +What: /sys/bus/pci/devices//ccissX/rescan Date: August 2009 -Kernel Version: 2.6.31 +KernelVersion: 2.6.31 Contact: iss_storagedev@hp.com Description: Kicks of a rescan of the controller to discover logical drive topology changes. -Where: /sys/bus/pci/devices//ccissX/cXdY/lunid +What: /sys/bus/pci/devices//ccissX/cXdY/lunid Date: August 2009 -Kernel Version: 2.6.31 +KernelVersion: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the 8-byte LUN ID used to address logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/raid_level +What: /sys/bus/pci/devices//ccissX/cXdY/raid_level Date: August 2009 -Kernel Version: 2.6.31 +KernelVersion: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the RAID level of logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/cXdY/usage_count +What: /sys/bus/pci/devices//ccissX/cXdY/usage_count Date: August 2009 -Kernel Version: 2.6.31 +KernelVersion: 2.6.31 Contact: iss_storagedev@hp.com Description: Displays the usage count (number of opens) of logical drive Y of controller X. -Where: /sys/bus/pci/devices//ccissX/resettable +What: /sys/bus/pci/devices//ccissX/resettable Date: February 2011 -Kernel Version: 2.6.38 +KernelVersion: 2.6.38 Contact: iss_storagedev@hp.com Description: Value of 1 indicates the controller can honor the reset_devices kernel parameter. Value of 0 indicates reset_devices cannot be @@ -71,9 +71,9 @@ Description: Value of 1 indicates the controller can honor the reset_devices a dump device, as kdump requires resetting the device in order to work reliably. -Where: /sys/bus/pci/devices//ccissX/transport_mode +What: /sys/bus/pci/devices//ccissX/transport_mode Date: July 2011 -Kernel Version: 3.0 +KernelVersion: 3.0 Contact: iss_storagedev@hp.com Description: Value of "simple" indicates that the controller has been placed in "simple mode". Value of "performant" indicates that the diff --git a/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg index 70d00dfa443d2f..9ade80f81f96c4 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg +++ b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg @@ -1,14 +1,14 @@ -Where: /sys/bus/usb/.../powered +What: /sys/bus/usb/.../powered Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: Controls whether the device's display will powered. A value of 0 is off and a non-zero value is on. -Where: /sys/bus/usb/.../mode_msb -Where: /sys/bus/usb/.../mode_lsb +What: /sys/bus/usb/.../mode_msb +What: /sys/bus/usb/.../mode_lsb Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: Controls the devices display mode. For a 6 character display the values are @@ -16,24 +16,24 @@ Description: Controls the devices display mode. for an 8 character display the values are MSB 0x08; LSB 0xFF. -Where: /sys/bus/usb/.../textmode +What: /sys/bus/usb/.../textmode Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: Controls the way the device interprets its text buffer. raw: each character controls its segment manually hex: each character is between 0-15 ascii: each character is between '0'-'9' and 'A'-'F'. -Where: /sys/bus/usb/.../text +What: /sys/bus/usb/.../text Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: The text (or data) for the device to display -Where: /sys/bus/usb/.../decimals +What: /sys/bus/usb/.../decimals Date: August 2008 -Kernel Version: 2.6.26 +KernelVersion: 2.6.26 Contact: Harrison Metzger Description: Controls the decimal places on the device. To set the nth decimal place, give this field diff --git a/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 b/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 index 77cf7ac949af76..c0e0a9ae7b3d9b 100644 --- a/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 +++ b/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 @@ -4,7 +4,7 @@ KernelVersion: 3.5 Contact: Johan Hovold Description: Get the ALS output channel used as input in - ALS-current-control mode (0, 1), where + ALS-current-control mode (0, 1), where: 0 - out_current0 (backlight 0) 1 - out_current1 (backlight 1) @@ -28,7 +28,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the brightness-mapping mode (0, 1), where + Set the brightness-mapping mode (0, 1), where: 0 - exponential mode 1 - linear mode @@ -38,7 +38,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the PWM-input control mask (5 bits), where + Set the PWM-input control mask (5 bits), where: bit 5 - PWM-input enabled in Zone 4 bit 4 - PWM-input enabled in Zone 3 diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index bbbabffc682a93..7970e3713e705c 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -1,6 +1,6 @@ -Note: Attributes that are shared between devices are stored in the directory -pointed to by the symlink device/. -Example: The real path of the attribute /sys/class/cxl/afu0.0s/irqs_max is +Please note that attributes that are shared between devices are stored in +the directory pointed to by the symlink device/. +For example, the real path of the attribute /sys/class/cxl/afu0.0s/irqs_max is /sys/class/cxl/afu0.0s/device/irqs_max, i.e. /sys/class/cxl/afu0.0/irqs_max. diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index ee39acacf6f851..01196e19afca3b 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -47,7 +47,7 @@ Description: What: /sys/class/devfreq/.../trans_stat Date: October 2012 Contact: MyungJoo Ham -Descrtiption: +Description: This ABI shows the statistics of devfreq behavior on a specific device. It shows the time spent in each state and the number of transitions between states. diff --git a/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 b/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 index 620ebb3b9baa39..e4c89b261546c3 100644 --- a/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 +++ b/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 @@ -4,7 +4,7 @@ KernelVersion: 3.5 Contact: Johan Hovold Description: Set the ALS output channel to use as input in - ALS-current-control mode (1, 2), where + ALS-current-control mode (1, 2), where: 1 - out_current1 2 - out_current2 @@ -22,7 +22,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the pattern generator fall and rise times (0..7), where + Set the pattern generator fall and rise times (0..7), where: 0 - 2048 us 1 - 262 ms @@ -45,7 +45,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the brightness-mapping mode (0, 1), where + Set the brightness-mapping mode (0, 1), where: 0 - exponential mode 1 - linear mode @@ -55,7 +55,7 @@ Date: April 2012 KernelVersion: 3.5 Contact: Johan Hovold Description: - Set the PWM-input control mask (5 bits), where + Set the PWM-input control mask (5 bits), where: bit 5 - PWM-input enabled in Zone 4 bit 4 - PWM-input enabled in Zone 3 diff --git a/Documentation/ABI/testing/sysfs-class-leds-gt683r b/Documentation/ABI/testing/sysfs-class-leds-gt683r index e4fae6026e793a..6adab27f646e66 100644 --- a/Documentation/ABI/testing/sysfs-class-leds-gt683r +++ b/Documentation/ABI/testing/sysfs-class-leds-gt683r @@ -5,7 +5,7 @@ Contact: Janne Kanniainen Description: Set the mode of LEDs. You should notice that changing the mode of one LED will update the mode of its two sibling devices as - well. + well. Possible values are: 0 - normal 1 - audio @@ -13,4 +13,4 @@ Description: Normal: LEDs are fully on when enabled Audio: LEDs brightness depends on sound level - Breathing: LEDs brightness varies at human breathing rate \ No newline at end of file + Breathing: LEDs brightness varies at human breathing rate diff --git a/Documentation/ABI/testing/sysfs-class-powercap b/Documentation/ABI/testing/sysfs-class-powercap index db3b3ff70d848c..f333a0ccc29b3a 100644 --- a/Documentation/ABI/testing/sysfs-class-powercap +++ b/Documentation/ABI/testing/sysfs-class-powercap @@ -147,6 +147,6 @@ What: /sys/class/powercap/...//enabled Date: September 2013 KernelVersion: 3.13 Contact: linux-pm@vger.kernel.org -Description +Description: This allows to enable/disable power capping at power zone level. This applies to current power zone and its children. diff --git a/Documentation/ABI/testing/sysfs-class-uwb_rc b/Documentation/ABI/testing/sysfs-class-uwb_rc index 85f4875d16ac0d..a0578751c1e38c 100644 --- a/Documentation/ABI/testing/sysfs-class-uwb_rc +++ b/Documentation/ABI/testing/sysfs-class-uwb_rc @@ -125,12 +125,6 @@ Description: The EUI-48 of this device in colon separated hex octets. -What: /sys/class/uwb_rc/uwbN//BPST -Date: July 2008 -KernelVersion: 2.6.27 -Contact: linux-usb@vger.kernel.org -Description: - What: /sys/class/uwb_rc/uwbN//IEs Date: July 2008 KernelVersion: 2.6.27 diff --git a/Documentation/ABI/testing/sysfs-driver-altera-cvp b/Documentation/ABI/testing/sysfs-driver-altera-cvp index 8cde64a71edba2..fbd8078fd7ada5 100644 --- a/Documentation/ABI/testing/sysfs-driver-altera-cvp +++ b/Documentation/ABI/testing/sysfs-driver-altera-cvp @@ -1,6 +1,6 @@ What: /sys/bus/pci/drivers/altera-cvp/chkcfg Date: May 2017 -Kernel Version: 4.13 +KernelVersion: 4.13 Contact: Anatolij Gustschin Description: Contains either 1 or 0 and controls if configuration diff --git a/Documentation/ABI/testing/sysfs-driver-hid b/Documentation/ABI/testing/sysfs-driver-hid index 48942cacb0bf49..a59533410871be 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid +++ b/Documentation/ABI/testing/sysfs-driver-hid @@ -1,6 +1,6 @@ -What: For USB devices : /sys/bus/usb/devices/-:./::./report_descriptor - For BT devices : /sys/class/bluetooth/hci/::./report_descriptor - Symlink : /sys/class/hidraw/hidraw/device/report_descriptor +What: /sys/bus/usb/devices/-:./::./report_descriptor +What: /sys/class/bluetooth/hci/::./report_descriptor +What: /sys/class/hidraw/hidraw/device/report_descriptor Date: Jan 2011 KernelVersion: 2.0.39 Contact: Alan Ott @@ -9,9 +9,9 @@ Description: When read, this file returns the device's raw binary HID This file cannot be written. Users: HIDAPI library (http://www.signal11.us/oss/hidapi) -What: For USB devices : /sys/bus/usb/devices/-:./::./country - For BT devices : /sys/class/bluetooth/hci/::./country - Symlink : /sys/class/hidraw/hidraw/device/country +What: /sys/bus/usb/devices/-:./::./country +What: /sys/class/bluetooth/hci/::./country +What: /sys/class/hidraw/hidraw/device/country Date: February 2015 KernelVersion: 3.19 Contact: Olivier Gay diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone index 3ca3971109bf62..8f7982c70d72cc 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone @@ -5,7 +5,7 @@ Description: It is possible to switch the dpi setting of the mouse with the press of a button. When read, this file returns the raw number of the actual dpi setting reported by the mouse. This number has to be further - processed to receive the real dpi value. + processed to receive the real dpi value: VALUE DPI 1 800 diff --git a/Documentation/ABI/testing/sysfs-driver-ppi b/Documentation/ABI/testing/sysfs-driver-ppi index 9921ef285899f0..1a56fc50768971 100644 --- a/Documentation/ABI/testing/sysfs-driver-ppi +++ b/Documentation/ABI/testing/sysfs-driver-ppi @@ -1,6 +1,6 @@ What: /sys/class/tpm/tpmX/ppi/ Date: August 2012 -Kernel Version: 3.6 +KernelVersion: 3.6 Contact: xiaoyan.zhang@intel.com Description: This folder includes the attributes related with PPI (Physical diff --git a/Documentation/ABI/testing/sysfs-driver-st b/Documentation/ABI/testing/sysfs-driver-st index ba5d77008a8551..88cab66fd77fb5 100644 --- a/Documentation/ABI/testing/sysfs-driver-st +++ b/Documentation/ABI/testing/sysfs-driver-st @@ -1,6 +1,6 @@ What: /sys/bus/scsi/drivers/st/debug_flag Date: October 2015 -Kernel Version: ?.? +KernelVersion: ?.? Contact: shane.seymour@hpe.com Description: This file allows you to turn debug output from the st driver diff --git a/Documentation/ABI/testing/sysfs-driver-wacom b/Documentation/ABI/testing/sysfs-driver-wacom index 2aa5503ee20076..afc48fc163b590 100644 --- a/Documentation/ABI/testing/sysfs-driver-wacom +++ b/Documentation/ABI/testing/sysfs-driver-wacom @@ -1,6 +1,6 @@ What: /sys/bus/hid/devices/::./speed Date: April 2010 -Kernel Version: 2.6.35 +KernelVersion: 2.6.35 Contact: linux-bluetooth@vger.kernel.org Description: The /sys/bus/hid/devices/::./speed file diff --git a/Documentation/ABI/testing/sysfs-kernel-fscaps b/Documentation/ABI/testing/sysfs-kernel-fscaps index 50a3033b5e150c..bcff3466519246 100644 --- a/Documentation/ABI/testing/sysfs-kernel-fscaps +++ b/Documentation/ABI/testing/sysfs-kernel-fscaps @@ -2,7 +2,7 @@ What: /sys/kernel/fscaps Date: February 2011 KernelVersion: 2.6.38 Contact: Ludwig Nussel -Description +Description: Shows whether file system capabilities are honored when executing a binary diff --git a/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo b/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo index 7bd81168e06337..1f1087a5f0757b 100644 --- a/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo +++ b/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo @@ -4,7 +4,7 @@ KernelVersion: 2.6.24 Contact: Ken'ichi Ohmichi Kexec Mailing List Vivek Goyal -Description +Description: Shows physical address and size of vmcoreinfo ELF note. First value contains physical address of note in hex and second value contains the size of note in hex. This ELF diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst index 4af9aae724f0bb..349f2dc33029d6 100644 --- a/Documentation/driver-api/gpio/driver.rst +++ b/Documentation/driver-api/gpio/driver.rst @@ -399,7 +399,7 @@ symbol: will pass the struct gpio_chip* for the chip to all IRQ callbacks, so the callbacks need to embed the gpio_chip in its state container and obtain a pointer to the container using container_of(). - (See Documentation/driver-model/design-patterns.txt) + (See Documentation/driver-model/design-patterns.rst) - gpiochip_irqchip_add_nested(): adds a nested cascaded irqchip to a gpiochip, as discussed above regarding different types of cascaded irqchips. The diff --git a/Documentation/driver-model/binding.txt b/Documentation/driver-model/binding.rst similarity index 92% rename from Documentation/driver-model/binding.txt rename to Documentation/driver-model/binding.rst index abfc8e290d53bb..7ea1d7a41e1d1b 100644 --- a/Documentation/driver-model/binding.txt +++ b/Documentation/driver-model/binding.rst @@ -1,5 +1,6 @@ - +============== Driver Binding +============== Driver binding is the process of associating a device with a device driver that can control it. Bus drivers have typically handled this @@ -25,7 +26,7 @@ device_register When a new device is added, the bus's list of drivers is iterated over to find one that supports it. In order to determine that, the device ID of the device must match one of the device IDs that the driver -supports. The format and semantics for comparing IDs is bus-specific. +supports. The format and semantics for comparing IDs is bus-specific. Instead of trying to derive a complex state machine and matching algorithm, it is up to the bus driver to provide a callback to compare a device against the IDs of a driver. The bus returns 1 if a match was @@ -36,14 +37,14 @@ int match(struct device * dev, struct device_driver * drv); If a match is found, the device's driver field is set to the driver and the driver's probe callback is called. This gives the driver a chance to verify that it really does support the hardware, and that -it's in a working state. +it's in a working state. Device Class ~~~~~~~~~~~~ Upon the successful completion of probe, the device is registered with the class to which it belongs. Device drivers belong to one and only one -class, and that is set in the driver's devclass field. +class, and that is set in the driver's devclass field. devclass_add_device is called to enumerate the device within the class and actually register it with the class, which happens with the class's register_dev callback. @@ -53,7 +54,7 @@ Driver ~~~~~~ When a driver is attached to a device, the device is inserted into the -driver's list of devices. +driver's list of devices. sysfs @@ -67,18 +68,18 @@ to the device's directory in the physical hierarchy. A directory for the device is created in the class's directory. A symlink is created in that directory that points to the device's -physical location in the sysfs tree. +physical location in the sysfs tree. A symlink can be created (though this isn't done yet) in the device's physical directory to either its class directory, or the class's top-level directory. One can also be created to point to its driver's -directory also. +directory also. driver_register ~~~~~~~~~~~~~~~ -The process is almost identical for when a new driver is added. +The process is almost identical for when a new driver is added. The bus's list of devices is iterated over to find a match. Devices that already have a driver are skipped. All the devices are iterated over, to bind as many devices as possible to the driver. @@ -94,5 +95,4 @@ of the driver is decremented. All symlinks between the two are removed. When a driver is removed, the list of devices that it supports is iterated over, and the driver's remove callback is called for each -one. The device is removed from that list and the symlinks removed. - +one. The device is removed from that list and the symlinks removed. diff --git a/Documentation/driver-model/bus.txt b/Documentation/driver-model/bus.rst similarity index 76% rename from Documentation/driver-model/bus.txt rename to Documentation/driver-model/bus.rst index c247b488a5673b..016b15a6e8ea97 100644 --- a/Documentation/driver-model/bus.txt +++ b/Documentation/driver-model/bus.rst @@ -1,5 +1,6 @@ - -Bus Types +========= +Bus Types +========= Definition ~~~~~~~~~~ @@ -13,12 +14,12 @@ Declaration Each bus type in the kernel (PCI, USB, etc) should declare one static object of this type. They must initialize the name field, and may -optionally initialize the match callback. +optionally initialize the match callback:: -struct bus_type pci_bus_type = { - .name = "pci", - .match = pci_bus_match, -}; + struct bus_type pci_bus_type = { + .name = "pci", + .match = pci_bus_match, + }; The structure should be exported to drivers in a header file: @@ -30,8 +31,8 @@ Registration When a bus driver is initialized, it calls bus_register. This initializes the rest of the fields in the bus object and inserts it -into a global list of bus types. Once the bus object is registered, -the fields in it are usable by the bus driver. +into a global list of bus types. Once the bus object is registered, +the fields in it are usable by the bus driver. Callbacks @@ -43,17 +44,17 @@ match(): Attaching Drivers to Devices The format of device ID structures and the semantics for comparing them are inherently bus-specific. Drivers typically declare an array of device IDs of devices they support that reside in a bus-specific -driver structure. +driver structure. The purpose of the match callback is to give the bus an opportunity to determine if a particular driver supports a particular device by comparing the device IDs the driver supports with the device ID of a particular device, without sacrificing bus-specific functionality or -type-safety. +type-safety. When a driver is registered with the bus, the bus's list of devices is iterated over, and the match callback is called for each device that -does not have a driver associated with it. +does not have a driver associated with it. @@ -64,22 +65,23 @@ The lists of devices and drivers are intended to replace the local lists that many buses keep. They are lists of struct devices and struct device_drivers, respectively. Bus drivers are free to use the lists as they please, but conversion to the bus-specific type may be -necessary. +necessary. -The LDM core provides helper functions for iterating over each list. +The LDM core provides helper functions for iterating over each list:: -int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, - int (*fn)(struct device *, void *)); + int bus_for_each_dev(struct bus_type * bus, struct device * start, + void * data, + int (*fn)(struct device *, void *)); -int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, - void * data, int (*fn)(struct device_driver *, void *)); + int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, + void * data, int (*fn)(struct device_driver *, void *)); These helpers iterate over the respective list, and call the callback for each device or driver in the list. All list accesses are synchronized by taking the bus's lock (read currently). The reference count on each object in the list is incremented before the callback is called; it is decremented after the next object has been obtained. The -lock is not held when calling the callback. +lock is not held when calling the callback. sysfs @@ -87,14 +89,14 @@ sysfs There is a top-level directory named 'bus'. Each bus gets a directory in the bus directory, along with two default -directories: +directories:: /sys/bus/pci/ |-- devices `-- drivers Drivers registered with the bus get a directory in the bus's drivers -directory: +directory:: /sys/bus/pci/ |-- devices @@ -106,7 +108,7 @@ directory: Each device that is discovered on a bus of that type gets a symlink in the bus's devices directory to the device's directory in the physical -hierarchy: +hierarchy:: /sys/bus/pci/ |-- devices @@ -118,26 +120,27 @@ hierarchy: Exporting Attributes ~~~~~~~~~~~~~~~~~~~~ -struct bus_attribute { + +:: + + struct bus_attribute { struct attribute attr; ssize_t (*show)(struct bus_type *, char * buf); ssize_t (*store)(struct bus_type *, const char * buf, size_t count); -}; + }; Bus drivers can export attributes using the BUS_ATTR_RW macro that works similarly to the DEVICE_ATTR_RW macro for devices. For example, a -definition like this: +definition like this:: -static BUS_ATTR_RW(debug); + static BUS_ATTR_RW(debug); -is equivalent to declaring: +is equivalent to declaring:: -static bus_attribute bus_attr_debug; + static bus_attribute bus_attr_debug; This can then be used to add and remove the attribute from the bus's -sysfs directory using: - -int bus_create_file(struct bus_type *, struct bus_attribute *); -void bus_remove_file(struct bus_type *, struct bus_attribute *); - +sysfs directory using:: + int bus_create_file(struct bus_type *, struct bus_attribute *); + void bus_remove_file(struct bus_type *, struct bus_attribute *); diff --git a/Documentation/driver-model/class.txt b/Documentation/driver-model/class.rst similarity index 75% rename from Documentation/driver-model/class.txt rename to Documentation/driver-model/class.rst index 1fefc480a80b56..fff55b80e86a54 100644 --- a/Documentation/driver-model/class.txt +++ b/Documentation/driver-model/class.rst @@ -1,6 +1,6 @@ - +============== Device Classes - +============== Introduction ~~~~~~~~~~~~ @@ -13,37 +13,37 @@ device. The following device classes have been identified: Each device class defines a set of semantics and a programming interface that devices of that class adhere to. Device drivers are the implementation of that programming interface for a particular device on -a particular bus. +a particular bus. Device classes are agnostic with respect to what bus a device resides -on. +on. Programming Interface ~~~~~~~~~~~~~~~~~~~~~ -The device class structure looks like: +The device class structure looks like:: -typedef int (*devclass_add)(struct device *); -typedef void (*devclass_remove)(struct device *); + typedef int (*devclass_add)(struct device *); + typedef void (*devclass_remove)(struct device *); See the kerneldoc for the struct class. -A typical device class definition would look like: +A typical device class definition would look like:: -struct device_class input_devclass = { + struct device_class input_devclass = { .name = "input", .add_device = input_add_device, .remove_device = input_remove_device, -}; + }; Each device class structure should be exported in a header file so it can be used by drivers, extensions and interfaces. -Device classes are registered and unregistered with the core using: +Device classes are registered and unregistered with the core using:: -int devclass_register(struct device_class * cls); -void devclass_unregister(struct device_class * cls); + int devclass_register(struct device_class * cls); + void devclass_unregister(struct device_class * cls); Devices @@ -52,16 +52,16 @@ As devices are bound to drivers, they are added to the device class that the driver belongs to. Before the driver model core, this would typically happen during the driver's probe() callback, once the device has been initialized. It now happens after the probe() callback -finishes from the core. +finishes from the core. The device is enumerated in the class. Each time a device is added to the class, the class's devnum field is incremented and assigned to the device. The field is never decremented, so if the device is removed from the class and re-added, it will receive a different enumerated -value. +value. The class is allowed to create a class-specific structure for the -device and store it in the device's class_data pointer. +device and store it in the device's class_data pointer. There is no list of devices in the device class. Each driver has a list of devices that it supports. The device class has a list of @@ -73,15 +73,15 @@ Device Drivers ~~~~~~~~~~~~~~ Device drivers are added to device classes when they are registered with the core. A driver specifies the class it belongs to by setting -the struct device_driver::devclass field. +the struct device_driver::devclass field. sysfs directory structure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There is a top-level sysfs directory named 'class'. +There is a top-level sysfs directory named 'class'. Each class gets a directory in the class directory, along with two -default subdirectories: +default subdirectories:: class/ `-- input @@ -89,8 +89,8 @@ default subdirectories: `-- drivers -Drivers registered with the class get a symlink in the drivers/ directory -that points to the driver's directory (under its bus directory): +Drivers registered with the class get a symlink in the drivers/ directory +that points to the driver's directory (under its bus directory):: class/ `-- input @@ -99,8 +99,8 @@ that points to the driver's directory (under its bus directory): `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/ -Each device gets a symlink in the devices/ directory that points to the -device's directory in the physical hierarchy: +Each device gets a symlink in the devices/ directory that points to the +device's directory in the physical hierarchy:: class/ `-- input @@ -111,37 +111,39 @@ device's directory in the physical hierarchy: Exporting Attributes ~~~~~~~~~~~~~~~~~~~~ -struct devclass_attribute { + +:: + + struct devclass_attribute { struct attribute attr; ssize_t (*show)(struct device_class *, char * buf, size_t count, loff_t off); ssize_t (*store)(struct device_class *, const char * buf, size_t count, loff_t off); -}; + }; Class drivers can export attributes using the DEVCLASS_ATTR macro that works -similarly to the DEVICE_ATTR macro for devices. For example, a definition -like this: +similarly to the DEVICE_ATTR macro for devices. For example, a definition +like this:: -static DEVCLASS_ATTR(debug,0644,show_debug,store_debug); + static DEVCLASS_ATTR(debug,0644,show_debug,store_debug); -is equivalent to declaring: +is equivalent to declaring:: -static devclass_attribute devclass_attr_debug; + static devclass_attribute devclass_attr_debug; The bus driver can add and remove the attribute from the class's -sysfs directory using: +sysfs directory using:: -int devclass_create_file(struct device_class *, struct devclass_attribute *); -void devclass_remove_file(struct device_class *, struct devclass_attribute *); + int devclass_create_file(struct device_class *, struct devclass_attribute *); + void devclass_remove_file(struct device_class *, struct devclass_attribute *); In the example above, the file will be named 'debug' in placed in the -class's directory in sysfs. +class's directory in sysfs. Interfaces ~~~~~~~~~~ There may exist multiple mechanisms for accessing the same device of a -particular class type. Device interfaces describe these mechanisms. +particular class type. Device interfaces describe these mechanisms. When a device is added to a device class, the core attempts to add it to every interface that is registered with the device class. - diff --git a/Documentation/driver-model/design-patterns.txt b/Documentation/driver-model/design-patterns.rst similarity index 59% rename from Documentation/driver-model/design-patterns.txt rename to Documentation/driver-model/design-patterns.rst index ba7b2df6490469..41eb8f41f7dd2d 100644 --- a/Documentation/driver-model/design-patterns.txt +++ b/Documentation/driver-model/design-patterns.rst @@ -1,6 +1,6 @@ - +============================= Device Driver Design Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +============================= This document describes a few common design patterns found in device drivers. It is likely that subsystem maintainers will ask driver developers to @@ -19,23 +19,23 @@ that the device the driver binds to will appear in several instances. This means that the probe() function and all callbacks need to be reentrant. The most common way to achieve this is to use the state container design -pattern. It usually has this form: +pattern. It usually has this form:: -struct foo { - spinlock_t lock; /* Example member */ - (...) -}; + struct foo { + spinlock_t lock; /* Example member */ + (...) + }; -static int foo_probe(...) -{ - struct foo *foo; + static int foo_probe(...) + { + struct foo *foo; - foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL); - if (!foo) - return -ENOMEM; - spin_lock_init(&foo->lock); - (...) -} + foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL); + if (!foo) + return -ENOMEM; + spin_lock_init(&foo->lock); + (...) + } This will create an instance of struct foo in memory every time probe() is called. This is our state container for this instance of the device driver. @@ -43,21 +43,21 @@ Of course it is then necessary to always pass this instance of the state around to all functions that need access to the state and its members. For example, if the driver is registering an interrupt handler, you would -pass around a pointer to struct foo like this: +pass around a pointer to struct foo like this:: -static irqreturn_t foo_handler(int irq, void *arg) -{ - struct foo *foo = arg; - (...) -} + static irqreturn_t foo_handler(int irq, void *arg) + { + struct foo *foo = arg; + (...) + } -static int foo_probe(...) -{ - struct foo *foo; + static int foo_probe(...) + { + struct foo *foo; - (...) - ret = request_irq(irq, foo_handler, 0, "foo", foo); -} + (...) + ret = request_irq(irq, foo_handler, 0, "foo", foo); + } This way you always get a pointer back to the correct instance of foo in your interrupt handler. @@ -66,38 +66,38 @@ your interrupt handler. 2. container_of() ~~~~~~~~~~~~~~~~~ -Continuing on the above example we add an offloaded work: +Continuing on the above example we add an offloaded work:: -struct foo { - spinlock_t lock; - struct workqueue_struct *wq; - struct work_struct offload; - (...) -}; + struct foo { + spinlock_t lock; + struct workqueue_struct *wq; + struct work_struct offload; + (...) + }; -static void foo_work(struct work_struct *work) -{ - struct foo *foo = container_of(work, struct foo, offload); + static void foo_work(struct work_struct *work) + { + struct foo *foo = container_of(work, struct foo, offload); - (...) -} + (...) + } -static irqreturn_t foo_handler(int irq, void *arg) -{ - struct foo *foo = arg; + static irqreturn_t foo_handler(int irq, void *arg) + { + struct foo *foo = arg; - queue_work(foo->wq, &foo->offload); - (...) -} + queue_work(foo->wq, &foo->offload); + (...) + } -static int foo_probe(...) -{ - struct foo *foo; + static int foo_probe(...) + { + struct foo *foo; - foo->wq = create_singlethread_workqueue("foo-wq"); - INIT_WORK(&foo->offload, foo_work); - (...) -} + foo->wq = create_singlethread_workqueue("foo-wq"); + INIT_WORK(&foo->offload, foo_work); + (...) + } The design pattern is the same for an hrtimer or something similar that will return a single argument which is a pointer to a struct member in the diff --git a/Documentation/driver-model/device.txt b/Documentation/driver-model/device.rst similarity index 71% rename from Documentation/driver-model/device.txt rename to Documentation/driver-model/device.rst index 2403eb85618777..2b868d49d3492d 100644 --- a/Documentation/driver-model/device.txt +++ b/Documentation/driver-model/device.rst @@ -1,6 +1,6 @@ - +========================== The Basic Device Structure -~~~~~~~~~~~~~~~~~~~~~~~~~~ +========================== See the kerneldoc for the struct device. @@ -8,9 +8,9 @@ See the kerneldoc for the struct device. Programming Interface ~~~~~~~~~~~~~~~~~~~~~ The bus driver that discovers the device uses this to register the -device with the core: +device with the core:: -int device_register(struct device * dev); + int device_register(struct device * dev); The bus should initialize the following fields: @@ -20,30 +20,33 @@ The bus should initialize the following fields: - bus A device is removed from the core when its reference count goes to -0. The reference count can be adjusted using: +0. The reference count can be adjusted using:: -struct device * get_device(struct device * dev); -void put_device(struct device * dev); + struct device * get_device(struct device * dev); + void put_device(struct device * dev); get_device() will return a pointer to the struct device passed to it if the reference is not already 0 (if it's in the process of being removed already). -A driver can access the lock in the device structure using: +A driver can access the lock in the device structure using:: -void lock_device(struct device * dev); -void unlock_device(struct device * dev); + void lock_device(struct device * dev); + void unlock_device(struct device * dev); Attributes ~~~~~~~~~~ -struct device_attribute { + +:: + + struct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -}; + }; Attributes of devices can be exported by a device driver through sysfs. @@ -54,39 +57,39 @@ As explained in Documentation/kobject.txt, device attributes must be created before the KOBJ_ADD uevent is generated. The only way to realize that is by defining an attribute group. -Attributes are declared using a macro called DEVICE_ATTR: +Attributes are declared using a macro called DEVICE_ATTR:: -#define DEVICE_ATTR(name,mode,show,store) + #define DEVICE_ATTR(name,mode,show,store) -Example: +Example::: -static DEVICE_ATTR(type, 0444, show_type, NULL); -static DEVICE_ATTR(power, 0644, show_power, store_power); + static DEVICE_ATTR(type, 0444, show_type, NULL); + static DEVICE_ATTR(power, 0644, show_power, store_power); This declares two structures of type struct device_attribute with respective names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be -organized as follows into a group: +organized as follows into a group:: -static struct attribute *dev_attrs[] = { + static struct attribute *dev_attrs[] = { &dev_attr_type.attr, &dev_attr_power.attr, NULL, -}; + }; -static struct attribute_group dev_attr_group = { + static struct attribute_group dev_attr_group = { .attrs = dev_attrs, -}; + }; -static const struct attribute_group *dev_attr_groups[] = { + static const struct attribute_group *dev_attr_groups[] = { &dev_attr_group, NULL, -}; + }; This array of groups can then be associated with a device by setting the -group pointer in struct device before device_register() is invoked: +group pointer in struct device before device_register() is invoked:: - dev->groups = dev_attr_groups; - device_register(dev); + dev->groups = dev_attr_groups; + device_register(dev); The device_register() function will use the 'groups' pointer to create the device attributes and the device_unregister() function will use this pointer diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.rst similarity index 93% rename from Documentation/driver-model/devres.txt rename to Documentation/driver-model/devres.rst index 69c7fa7f616c88..4ac99122b5f1b8 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.rst @@ -1,3 +1,4 @@ +================================ Devres - Managed Device Resource ================================ @@ -5,17 +6,18 @@ Tejun Heo First draft 10 January 2007 +.. contents -1. Intro : Huh? Devres? -2. Devres : Devres in a nutshell -3. Devres Group : Group devres'es and release them together -4. Details : Life time rules, calling context, ... -5. Overhead : How much do we have to pay for this? -6. List of managed interfaces : Currently implemented managed interfaces + 1. Intro : Huh? Devres? + 2. Devres : Devres in a nutshell + 3. Devres Group : Group devres'es and release them together + 4. Details : Life time rules, calling context, ... + 5. Overhead : How much do we have to pay for this? + 6. List of managed interfaces: Currently implemented managed interfaces - 1. Intro - -------- +1. Intro +-------- devres came up while trying to convert libata to use iomap. Each iomapped address should be kept and unmapped on driver detach. For @@ -42,8 +44,8 @@ would leak resources or even cause oops when failure occurs. iomap adds more to this mix. So do msi and msix. - 2. Devres - --------- +2. Devres +--------- devres is basically linked list of arbitrarily sized memory areas associated with a struct device. Each devres entry is associated with @@ -58,7 +60,7 @@ using dma_alloc_coherent(). The managed version is called dmam_alloc_coherent(). It is identical to dma_alloc_coherent() except for the DMA memory allocated using it is managed and will be automatically released on driver detach. Implementation looks like -the following. +the following:: struct dma_devres { size_t size; @@ -98,7 +100,7 @@ If a driver uses dmam_alloc_coherent(), the area is guaranteed to be freed whether initialization fails half-way or the device gets detached. If most resources are acquired using managed interface, a driver can have much simpler init and exit code. Init path basically -looks like the following. +looks like the following:: my_init_one() { @@ -119,7 +121,7 @@ looks like the following. return register_to_upper_layer(d); } -And exit path, +And exit path:: my_remove_one() { @@ -140,13 +142,13 @@ on you. In some cases this may mean introducing checks that were not necessary before moving to the managed devm_* calls. - 3. Devres group - --------------- +3. Devres group +--------------- Devres entries can be grouped using devres group. When a group is released, all contained normal devres entries and properly nested groups are released. One usage is to rollback series of acquired -resources on failure. For example, +resources on failure. For example:: if (!devres_open_group(dev, NULL, GFP_KERNEL)) return -ENOMEM; @@ -172,7 +174,7 @@ like above are usually useful in midlayer driver (e.g. libata core layer) where interface function shouldn't have side effect on failure. For LLDs, just returning error code suffices in most cases. -Each group is identified by void *id. It can either be explicitly +Each group is identified by `void *id`. It can either be explicitly specified by @id argument to devres_open_group() or automatically created by passing NULL as @id as in the above example. In both cases, devres_open_group() returns the group's id. The returned id @@ -180,7 +182,7 @@ can be passed to other devres functions to select the target group. If NULL is given to those functions, the latest open group is selected. -For example, you can do something like the following. +For example, you can do something like the following:: int my_midlayer_create_something() { @@ -199,8 +201,8 @@ For example, you can do something like the following. } - 4. Details - ---------- +4. Details +---------- Lifetime of a devres entry begins on devres allocation and finishes when it is released or destroyed (removed and freed) - no reference @@ -220,8 +222,8 @@ All devres interface functions can be called without context if the right gfp mask is given. - 5. Overhead - ----------- +5. Overhead +----------- Each devres bookkeeping info is allocated together with requested data area. With debug option turned off, bookkeeping info occupies 16 @@ -237,8 +239,8 @@ and 400 bytes on 32bit machine after naive conversion (we can certainly invest a bit more effort into libata core layer). - 6. List of managed interfaces - ----------------------------- +6. List of managed interfaces +----------------------------- CLOCK devm_clk_get() diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.rst similarity index 75% rename from Documentation/driver-model/driver.txt rename to Documentation/driver-model/driver.rst index d661e6f7e6a0cb..11d281506a0415 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.rst @@ -1,5 +1,6 @@ - +============== Device Drivers +============== See the kerneldoc for the struct device_driver. @@ -26,50 +27,50 @@ Declaration As stated above, struct device_driver objects are statically allocated. Below is an example declaration of the eepro100 driver. This declaration is hypothetical only; it relies on the driver -being converted completely to the new model. - -static struct device_driver eepro100_driver = { - .name = "eepro100", - .bus = &pci_bus_type, - - .probe = eepro100_probe, - .remove = eepro100_remove, - .suspend = eepro100_suspend, - .resume = eepro100_resume, -}; +being converted completely to the new model:: + + static struct device_driver eepro100_driver = { + .name = "eepro100", + .bus = &pci_bus_type, + + .probe = eepro100_probe, + .remove = eepro100_remove, + .suspend = eepro100_suspend, + .resume = eepro100_resume, + }; Most drivers will not be able to be converted completely to the new model because the bus they belong to has a bus-specific structure with -bus-specific fields that cannot be generalized. +bus-specific fields that cannot be generalized. The most common example of this are device ID structures. A driver typically defines an array of device IDs that it supports. The format of these structures and the semantics for comparing device IDs are completely bus-specific. Defining them as bus-specific entities would -sacrifice type-safety, so we keep bus-specific structures around. +sacrifice type-safety, so we keep bus-specific structures around. Bus-specific drivers should include a generic struct device_driver in -the definition of the bus-specific driver. Like this: +the definition of the bus-specific driver. Like this:: -struct pci_driver { - const struct pci_device_id *id_table; - struct device_driver driver; -}; + struct pci_driver { + const struct pci_device_id *id_table; + struct device_driver driver; + }; A definition that included bus-specific fields would look like -(using the eepro100 driver again): +(using the eepro100 driver again):: -static struct pci_driver eepro100_driver = { - .id_table = eepro100_pci_tbl, - .driver = { + static struct pci_driver eepro100_driver = { + .id_table = eepro100_pci_tbl, + .driver = { .name = "eepro100", .bus = &pci_bus_type, .probe = eepro100_probe, .remove = eepro100_remove, .suspend = eepro100_suspend, .resume = eepro100_resume, - }, -}; + }, + }; Some may find the syntax of embedded struct initialization awkward or even a bit ugly. So far, it's the best way we've found to do what we want... @@ -77,12 +78,14 @@ even a bit ugly. So far, it's the best way we've found to do what we want... Registration ~~~~~~~~~~~~ -int driver_register(struct device_driver * drv); +:: + + int driver_register(struct device_driver *drv); The driver registers the structure on startup. For drivers that have no bus-specific fields (i.e. don't have a bus-specific driver structure), they would use driver_register and pass a pointer to their -struct device_driver object. +struct device_driver object. Most drivers, however, will have a bus-specific structure and will need to register with the bus using something like pci_driver_register. @@ -101,7 +104,7 @@ By defining wrapper functions, the transition to the new model can be made easier. Drivers can ignore the generic structure altogether and let the bus wrapper fill in the fields. For the callbacks, the bus can define generic callbacks that forward the call to the bus-specific -callbacks of the drivers. +callbacks of the drivers. This solution is intended to be only temporary. In order to get class information in the driver, the drivers must be modified anyway. Since @@ -113,16 +116,16 @@ Access ~~~~~~ Once the object has been registered, it may access the common fields of -the object, like the lock and the list of devices. +the object, like the lock and the list of devices:: -int driver_for_each_dev(struct device_driver * drv, void * data, - int (*callback)(struct device * dev, void * data)); + int driver_for_each_dev(struct device_driver *drv, void *data, + int (*callback)(struct device *dev, void *data)); The devices field is a list of all the devices that have been bound to the driver. The LDM core provides a helper function to operate on all the devices a driver controls. This helper locks the driver on each node access, and does proper reference counting on each device as it -accesses it. +accesses it. sysfs @@ -142,7 +145,9 @@ supports. Callbacks ~~~~~~~~~ - int (*probe) (struct device * dev); +:: + + int (*probe) (struct device *dev); The probe() entry is called in task context, with the bus's rwsem locked and the driver partially bound to the device. Drivers commonly use @@ -162,9 +167,9 @@ the driver to that device. A driver's probe() may return a negative errno value to indicate that the driver did not bind to this device, in which case it should have -released all resources it allocated. +released all resources it allocated:: - int (*remove) (struct device * dev); + int (*remove) (struct device *dev); remove is called to unbind a driver from a device. This may be called if a device is physically removed from the system, if the @@ -173,43 +178,46 @@ in other cases. It is up to the driver to determine if the device is present or not. It should free any resources allocated specifically for the -device; i.e. anything in the device's driver_data field. +device; i.e. anything in the device's driver_data field. If the device is still present, it should quiesce the device and place -it into a supported low-power state. +it into a supported low-power state:: - int (*suspend) (struct device * dev, pm_message_t state); + int (*suspend) (struct device *dev, pm_message_t state); -suspend is called to put the device in a low power state. +suspend is called to put the device in a low power state:: - int (*resume) (struct device * dev); + int (*resume) (struct device *dev); Resume is used to bring a device back from a low power state. Attributes ~~~~~~~~~~ -struct driver_attribute { - struct attribute attr; - ssize_t (*show)(struct device_driver *driver, char *buf); - ssize_t (*store)(struct device_driver *, const char * buf, size_t count); -}; -Device drivers can export attributes via their sysfs directories. +:: + + struct driver_attribute { + struct attribute attr; + ssize_t (*show)(struct device_driver *driver, char *buf); + ssize_t (*store)(struct device_driver *, const char *buf, size_t count); + }; + +Device drivers can export attributes via their sysfs directories. Drivers can declare attributes using a DRIVER_ATTR_RW and DRIVER_ATTR_RO macro that works identically to the DEVICE_ATTR_RW and DEVICE_ATTR_RO macros. -Example: +Example:: -DRIVER_ATTR_RW(debug); + DRIVER_ATTR_RW(debug); -This is equivalent to declaring: +This is equivalent to declaring:: -struct driver_attribute driver_attr_debug; + struct driver_attribute driver_attr_debug; This can then be used to add and remove the attribute from the -driver's directory using: +driver's directory using:: -int driver_create_file(struct device_driver *, const struct driver_attribute *); -void driver_remove_file(struct device_driver *, const struct driver_attribute *); + int driver_create_file(struct device_driver *, const struct driver_attribute *); + void driver_remove_file(struct device_driver *, const struct driver_attribute *); diff --git a/Documentation/driver-model/index.rst b/Documentation/driver-model/index.rst new file mode 100644 index 00000000000000..9f85d579ce5648 --- /dev/null +++ b/Documentation/driver-model/index.rst @@ -0,0 +1,26 @@ +:orphan: + +============ +Driver Model +============ + +.. toctree:: + :maxdepth: 1 + + binding + bus + class + design-patterns + device + devres + driver + overview + platform + porting + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/driver-model/overview.txt b/Documentation/driver-model/overview.rst similarity index 90% rename from Documentation/driver-model/overview.txt rename to Documentation/driver-model/overview.rst index 6a8f9a8075d8b5..d4d1e9b40e0c7e 100644 --- a/Documentation/driver-model/overview.txt +++ b/Documentation/driver-model/overview.rst @@ -1,4 +1,6 @@ +============================= The Linux Kernel Device Model +============================= Patrick Mochel @@ -41,14 +43,14 @@ data structure. These fields must still be accessed by the bus layers, and sometimes by the device-specific drivers. Other bus layers are encouraged to do what has been done for the PCI layer. -struct pci_dev now looks like this: +struct pci_dev now looks like this:: -struct pci_dev { + struct pci_dev { ... struct device dev; /* Generic device interface */ ... -}; + }; Note first that the struct device dev within the struct pci_dev is statically allocated. This means only one allocation on device discovery. @@ -80,26 +82,26 @@ easy. This has been accomplished by implementing a special purpose virtual file system named sysfs. Almost all mainstream Linux distros mount this filesystem automatically; you -can see some variation of the following in the output of the "mount" command: +can see some variation of the following in the output of the "mount" command:: -$ mount -... -none on /sys type sysfs (rw,noexec,nosuid,nodev) -... -$ + $ mount + ... + none on /sys type sysfs (rw,noexec,nosuid,nodev) + ... + $ The auto-mounting of sysfs is typically accomplished by an entry similar to -the following in the /etc/fstab file: +the following in the /etc/fstab file:: -none /sys sysfs defaults 0 0 + none /sys sysfs defaults 0 0 -or something similar in the /lib/init/fstab file on Debian-based systems: +or something similar in the /lib/init/fstab file on Debian-based systems:: -none /sys sysfs nodev,noexec,nosuid 0 0 + none /sys sysfs nodev,noexec,nosuid 0 0 -If sysfs is not automatically mounted, you can always do it manually with: +If sysfs is not automatically mounted, you can always do it manually with:: -# mount -t sysfs sysfs /sys + # mount -t sysfs sysfs /sys Whenever a device is inserted into the tree, a directory is created for it. This directory may be populated at each layer of discovery - the global layer, @@ -108,7 +110,7 @@ the bus layer, or the device layer. The global layer currently creates two files - 'name' and 'power'. The former only reports the name of the device. The latter reports the current power state of the device. It will also be used to set the current -power state. +power state. The bus layer may also create files for the devices it finds while probing the bus. For example, the PCI layer currently creates 'irq' and 'resource' files @@ -118,6 +120,5 @@ A device-specific driver may also export files in its directory to expose device-specific data or tunable interfaces. More information about the sysfs directory layout can be found in -the other documents in this directory and in the file +the other documents in this directory and in the file Documentation/filesystems/sysfs.txt. - diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.rst similarity index 95% rename from Documentation/driver-model/platform.txt rename to Documentation/driver-model/platform.rst index 9d9e47dfc0138a..334dd4071ae469 100644 --- a/Documentation/driver-model/platform.txt +++ b/Documentation/driver-model/platform.rst @@ -1,5 +1,7 @@ +============================ Platform Devices and Drivers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +============================ + See for the driver model interface to the platform bus: platform_device, and platform_driver. This pseudo-bus is used to connect devices on busses with minimal infrastructure, @@ -19,15 +21,15 @@ be connected through a segment of some other kind of bus; but its registers will still be directly addressable. Platform devices are given a name, used in driver binding, and a -list of resources such as addresses and IRQs. +list of resources such as addresses and IRQs:: -struct platform_device { + struct platform_device { const char *name; u32 id; struct device dev; u32 num_resources; struct resource *resource; -}; + }; Platform drivers @@ -35,9 +37,9 @@ Platform drivers Platform drivers follow the standard driver model convention, where discovery/enumeration is handled outside the drivers, and drivers provide probe() and remove() methods. They support power management -and shutdown notifications using the standard conventions. +and shutdown notifications using the standard conventions:: -struct platform_driver { + struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); @@ -46,25 +48,25 @@ struct platform_driver { int (*resume_early)(struct platform_device *); int (*resume)(struct platform_device *); struct device_driver driver; -}; + }; Note that probe() should in general verify that the specified device hardware actually exists; sometimes platform setup code can't be sure. The probing can use device resources, including clocks, and device platform_data. -Platform drivers register themselves the normal way: +Platform drivers register themselves the normal way:: int platform_driver_register(struct platform_driver *drv); Or, in common situations where the device is known not to be hot-pluggable, the probe() routine can live in an init section to reduce the driver's -runtime memory footprint: +runtime memory footprint:: int platform_driver_probe(struct platform_driver *drv, int (*probe)(struct platform_device *)) Kernel modules can be composed of several platform drivers. The platform core -provides helpers to register and unregister an array of drivers: +provides helpers to register and unregister an array of drivers:: int __platform_register_drivers(struct platform_driver * const *drivers, unsigned int count, struct module *owner); @@ -73,7 +75,7 @@ provides helpers to register and unregister an array of drivers: If one of the drivers fails to register, all drivers registered up to that point will be unregistered in reverse order. Note that there is a convenience -macro that passes THIS_MODULE as owner parameter: +macro that passes THIS_MODULE as owner parameter:: #define platform_register_drivers(drivers, count) @@ -81,7 +83,7 @@ macro that passes THIS_MODULE as owner parameter: Device Enumeration ~~~~~~~~~~~~~~~~~~ As a rule, platform specific (and often board-specific) setup code will -register platform devices: +register platform devices:: int platform_device_register(struct platform_device *pdev); @@ -133,14 +135,14 @@ tend to already have "normal" modes, such as ones using device nodes that were created by PNP or by platform device setup. None the less, there are some APIs to support such legacy drivers. Avoid -using these calls except with such hotplug-deficient drivers. +using these calls except with such hotplug-deficient drivers:: struct platform_device *platform_device_alloc( const char *name, int id); You can use platform_device_alloc() to dynamically allocate a device, which you will then initialize with resources and platform_device_register(). -A better solution is usually: +A better solution is usually:: struct platform_device *platform_device_register_simple( const char *name, int id, diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.rst similarity index 62% rename from Documentation/driver-model/porting.txt rename to Documentation/driver-model/porting.rst index 453053f1661f47..ae4bf843c1d638 100644 --- a/Documentation/driver-model/porting.txt +++ b/Documentation/driver-model/porting.rst @@ -1,5 +1,6 @@ - +======================================= Porting Drivers to the New Driver Model +======================================= Patrick Mochel @@ -8,8 +9,8 @@ Patrick Mochel Overview -Please refer to Documentation/driver-model/*.txt for definitions of -various driver types and concepts. +Please refer to `Documentation/driver-model/*.rst` for definitions of +various driver types and concepts. Most of the work of porting devices drivers to the new model happens at the bus driver layer. This was intentional, to minimize the @@ -18,11 +19,11 @@ of bus drivers. In a nutshell, the driver model consists of a set of objects that can be embedded in larger, bus-specific objects. Fields in these generic -objects can replace fields in the bus-specific objects. +objects can replace fields in the bus-specific objects. The generic objects must be registered with the driver model core. By doing so, they will exported via the sysfs filesystem. sysfs can be -mounted by doing +mounted by doing:: # mount -t sysfs sysfs /sys @@ -30,108 +31,109 @@ mounted by doing The Process -Step 0: Read include/linux/device.h for object and function definitions. +Step 0: Read include/linux/device.h for object and function definitions. -Step 1: Registering the bus driver. +Step 1: Registering the bus driver. -- Define a struct bus_type for the bus driver. +- Define a struct bus_type for the bus driver:: -struct bus_type pci_bus_type = { - .name = "pci", -}; + struct bus_type pci_bus_type = { + .name = "pci", + }; - Register the bus type. + This should be done in the initialization function for the bus type, - which is usually the module_init(), or equivalent, function. + which is usually the module_init(), or equivalent, function:: -static int __init pci_driver_init(void) -{ - return bus_register(&pci_bus_type); -} + static int __init pci_driver_init(void) + { + return bus_register(&pci_bus_type); + } -subsys_initcall(pci_driver_init); + subsys_initcall(pci_driver_init); The bus type may be unregistered (if the bus driver may be compiled - as a module) by doing: + as a module) by doing:: bus_unregister(&pci_bus_type); -- Export the bus type for others to use. +- Export the bus type for others to use. - Other code may wish to reference the bus type, so declare it in a + Other code may wish to reference the bus type, so declare it in a shared header file and export the symbol. -From include/linux/pci.h: +From include/linux/pci.h:: -extern struct bus_type pci_bus_type; + extern struct bus_type pci_bus_type; -From file the above code appears in: +From file the above code appears in:: -EXPORT_SYMBOL(pci_bus_type); + EXPORT_SYMBOL(pci_bus_type); - This will cause the bus to show up in /sys/bus/pci/ with two - subdirectories: 'devices' and 'drivers'. + subdirectories: 'devices' and 'drivers':: -# tree -d /sys/bus/pci/ -/sys/bus/pci/ -|-- devices -`-- drivers + # tree -d /sys/bus/pci/ + /sys/bus/pci/ + |-- devices + `-- drivers -Step 2: Registering Devices. +Step 2: Registering Devices. struct device represents a single device. It mainly contains metadata -describing the relationship the device has to other entities. +describing the relationship the device has to other entities. -- Embed a struct device in the bus-specific device type. +- Embed a struct device in the bus-specific device type:: -struct pci_dev { - ... - struct device dev; /* Generic device interface */ - ... -}; + struct pci_dev { + ... + struct device dev; /* Generic device interface */ + ... + }; - It is recommended that the generic device not be the first item in + It is recommended that the generic device not be the first item in the struct to discourage programmers from doing mindless casts between the object types. Instead macros, or inline functions, - should be created to convert from the generic object type. + should be created to convert from the generic object type:: -#define to_pci_dev(n) container_of(n, struct pci_dev, dev) + #define to_pci_dev(n) container_of(n, struct pci_dev, dev) -or + or -static inline struct pci_dev * to_pci_dev(struct kobject * kobj) -{ + static inline struct pci_dev * to_pci_dev(struct kobject * kobj) + { return container_of(n, struct pci_dev, dev); -} + } - This allows the compiler to verify type-safety of the operations + This allows the compiler to verify type-safety of the operations that are performed (which is Good). - Initialize the device on registration. - When devices are discovered or registered with the bus type, the + When devices are discovered or registered with the bus type, the bus driver should initialize the generic device. The most important things to initialize are the bus_id, parent, and bus fields. The bus_id is an ASCII string that contains the device's address on the bus. The format of this string is bus-specific. This is - necessary for representing devices in sysfs. + necessary for representing devices in sysfs. parent is the physical parent of the device. It is important that - the bus driver sets this field correctly. + the bus driver sets this field correctly. The driver model maintains an ordered list of devices that it uses for power management. This list must be in order to guarantee that @@ -140,13 +142,13 @@ static inline struct pci_dev * to_pci_dev(struct kobject * kobj) devices. Also, the location of the device's sysfs directory depends on a - device's parent. sysfs exports a directory structure that mirrors + device's parent. sysfs exports a directory structure that mirrors the device hierarchy. Accurately setting the parent guarantees that sysfs will accurately represent the hierarchy. The device's bus field is a pointer to the bus type the device belongs to. This should be set to the bus_type that was declared - and initialized before. + and initialized before. Optionally, the bus driver may set the device's name and release fields. @@ -155,107 +157,107 @@ static inline struct pci_dev * to_pci_dev(struct kobject * kobj) "ATI Technologies Inc Radeon QD" - The release field is a callback that the driver model core calls - when the device has been removed, and all references to it have + The release field is a callback that the driver model core calls + when the device has been removed, and all references to it have been released. More on this in a moment. -- Register the device. +- Register the device. Once the generic device has been initialized, it can be registered - with the driver model core by doing: + with the driver model core by doing:: device_register(&dev->dev); - It can later be unregistered by doing: + It can later be unregistered by doing:: device_unregister(&dev->dev); - This should happen on buses that support hotpluggable devices. + This should happen on buses that support hotpluggable devices. If a bus driver unregisters a device, it should not immediately free - it. It should instead wait for the driver model core to call the - device's release method, then free the bus-specific object. + it. It should instead wait for the driver model core to call the + device's release method, then free the bus-specific object. (There may be other code that is currently referencing the device - structure, and it would be rude to free the device while that is + structure, and it would be rude to free the device while that is happening). - When the device is registered, a directory in sysfs is created. - The PCI tree in sysfs looks like: - -/sys/devices/pci0/ -|-- 00:00.0 -|-- 00:01.0 -| `-- 01:00.0 -|-- 00:02.0 -| `-- 02:1f.0 -| `-- 03:00.0 -|-- 00:1e.0 -| `-- 04:04.0 -|-- 00:1f.0 -|-- 00:1f.1 -| |-- ide0 -| | |-- 0.0 -| | `-- 0.1 -| `-- ide1 -| `-- 1.0 -|-- 00:1f.2 -|-- 00:1f.3 -`-- 00:1f.5 + When the device is registered, a directory in sysfs is created. + The PCI tree in sysfs looks like:: + + /sys/devices/pci0/ + |-- 00:00.0 + |-- 00:01.0 + | `-- 01:00.0 + |-- 00:02.0 + | `-- 02:1f.0 + | `-- 03:00.0 + |-- 00:1e.0 + | `-- 04:04.0 + |-- 00:1f.0 + |-- 00:1f.1 + | |-- ide0 + | | |-- 0.0 + | | `-- 0.1 + | `-- ide1 + | `-- 1.0 + |-- 00:1f.2 + |-- 00:1f.3 + `-- 00:1f.5 Also, symlinks are created in the bus's 'devices' directory - that point to the device's directory in the physical hierarchy. + that point to the device's directory in the physical hierarchy:: -/sys/bus/pci/devices/ -|-- 00:00.0 -> ../../../devices/pci0/00:00.0 -|-- 00:01.0 -> ../../../devices/pci0/00:01.0 -|-- 00:02.0 -> ../../../devices/pci0/00:02.0 -|-- 00:1e.0 -> ../../../devices/pci0/00:1e.0 -|-- 00:1f.0 -> ../../../devices/pci0/00:1f.0 -|-- 00:1f.1 -> ../../../devices/pci0/00:1f.1 -|-- 00:1f.2 -> ../../../devices/pci0/00:1f.2 -|-- 00:1f.3 -> ../../../devices/pci0/00:1f.3 -|-- 00:1f.5 -> ../../../devices/pci0/00:1f.5 -|-- 01:00.0 -> ../../../devices/pci0/00:01.0/01:00.0 -|-- 02:1f.0 -> ../../../devices/pci0/00:02.0/02:1f.0 -|-- 03:00.0 -> ../../../devices/pci0/00:02.0/02:1f.0/03:00.0 -`-- 04:04.0 -> ../../../devices/pci0/00:1e.0/04:04.0 + /sys/bus/pci/devices/ + |-- 00:00.0 -> ../../../devices/pci0/00:00.0 + |-- 00:01.0 -> ../../../devices/pci0/00:01.0 + |-- 00:02.0 -> ../../../devices/pci0/00:02.0 + |-- 00:1e.0 -> ../../../devices/pci0/00:1e.0 + |-- 00:1f.0 -> ../../../devices/pci0/00:1f.0 + |-- 00:1f.1 -> ../../../devices/pci0/00:1f.1 + |-- 00:1f.2 -> ../../../devices/pci0/00:1f.2 + |-- 00:1f.3 -> ../../../devices/pci0/00:1f.3 + |-- 00:1f.5 -> ../../../devices/pci0/00:1f.5 + |-- 01:00.0 -> ../../../devices/pci0/00:01.0/01:00.0 + |-- 02:1f.0 -> ../../../devices/pci0/00:02.0/02:1f.0 + |-- 03:00.0 -> ../../../devices/pci0/00:02.0/02:1f.0/03:00.0 + `-- 04:04.0 -> ../../../devices/pci0/00:1e.0/04:04.0 Step 3: Registering Drivers. struct device_driver is a simple driver structure that contains a set -of operations that the driver model core may call. +of operations that the driver model core may call. -- Embed a struct device_driver in the bus-specific driver. +- Embed a struct device_driver in the bus-specific driver. - Just like with devices, do something like: + Just like with devices, do something like:: -struct pci_driver { - ... - struct device_driver driver; -}; + struct pci_driver { + ... + struct device_driver driver; + }; -- Initialize the generic driver structure. +- Initialize the generic driver structure. When the driver registers with the bus (e.g. doing pci_register_driver()), initialize the necessary fields of the driver: the name and bus - fields. + fields. - Register the driver. - After the generic driver has been initialized, call + After the generic driver has been initialized, call:: driver_register(&drv->driver); to register the driver with the core. When the driver is unregistered from the bus, unregister it from the - core by doing: + core by doing:: driver_unregister(&drv->driver); @@ -265,15 +267,15 @@ struct pci_driver { - Sysfs representation. - Drivers are exported via sysfs in their bus's 'driver's directory. - For example: + Drivers are exported via sysfs in their bus's 'driver's directory. + For example:: -/sys/bus/pci/drivers/ -|-- 3c59x -|-- Ensoniq AudioPCI -|-- agpgart-amdk7 -|-- e100 -`-- serial + /sys/bus/pci/drivers/ + |-- 3c59x + |-- Ensoniq AudioPCI + |-- agpgart-amdk7 + |-- e100 + `-- serial Step 4: Define Generic Methods for Drivers. @@ -281,30 +283,30 @@ Step 4: Define Generic Methods for Drivers. struct device_driver defines a set of operations that the driver model core calls. Most of these operations are probably similar to operations the bus already defines for drivers, but taking different -parameters. +parameters. It would be difficult and tedious to force every driver on a bus to simultaneously convert their drivers to generic format. Instead, the bus driver should define single instances of the generic methods that -forward call to the bus-specific drivers. For instance: +forward call to the bus-specific drivers. For instance:: -static int pci_device_remove(struct device * dev) -{ - struct pci_dev * pci_dev = to_pci_dev(dev); - struct pci_driver * drv = pci_dev->driver; + static int pci_device_remove(struct device * dev) + { + struct pci_dev * pci_dev = to_pci_dev(dev); + struct pci_driver * drv = pci_dev->driver; - if (drv) { - if (drv->remove) - drv->remove(pci_dev); - pci_dev->driver = NULL; - } - return 0; -} + if (drv) { + if (drv->remove) + drv->remove(pci_dev); + pci_dev->driver = NULL; + } + return 0; + } The generic driver should be initialized with these methods before it -is registered. +is registered:: /* initialize common driver fields */ drv->driver.name = drv->name; @@ -320,23 +322,23 @@ is registered. Ideally, the bus should only initialize the fields if they are not already set. This allows the drivers to implement their own generic -methods. +methods. -Step 5: Support generic driver binding. +Step 5: Support generic driver binding. The model assumes that a device or driver can be dynamically registered with the bus at any time. When registration happens, devices must be bound to a driver, or drivers must be bound to all -devices that it supports. +devices that it supports. A driver typically contains a list of device IDs that it supports. The -bus driver compares these IDs to the IDs of devices registered with it. +bus driver compares these IDs to the IDs of devices registered with it. The format of the device IDs, and the semantics for comparing them are -bus-specific, so the generic model does attempt to generalize them. +bus-specific, so the generic model does attempt to generalize them. Instead, a bus may supply a method in struct bus_type that does the -comparison: +comparison:: int (*match)(struct device * dev, struct device_driver * drv); @@ -346,59 +348,59 @@ and zero otherwise. It may also return error code (for example not possible. When a device is registered, the bus's list of drivers is iterated -over. bus->match() is called for each one until a match is found. +over. bus->match() is called for each one until a match is found. When a driver is registered, the bus's list of devices is iterated over. bus->match() is called for each device that is not already -claimed by a driver. +claimed by a driver. When a device is successfully bound to a driver, device->driver is set, the device is added to a per-driver list of devices, and a symlink is created in the driver's sysfs directory that points to the -device's physical directory: +device's physical directory:: -/sys/bus/pci/drivers/ -|-- 3c59x -| `-- 00:0b.0 -> ../../../../devices/pci0/00:0b.0 -|-- Ensoniq AudioPCI -|-- agpgart-amdk7 -| `-- 00:00.0 -> ../../../../devices/pci0/00:00.0 -|-- e100 -| `-- 00:0c.0 -> ../../../../devices/pci0/00:0c.0 -`-- serial + /sys/bus/pci/drivers/ + |-- 3c59x + | `-- 00:0b.0 -> ../../../../devices/pci0/00:0b.0 + |-- Ensoniq AudioPCI + |-- agpgart-amdk7 + | `-- 00:00.0 -> ../../../../devices/pci0/00:00.0 + |-- e100 + | `-- 00:0c.0 -> ../../../../devices/pci0/00:0c.0 + `-- serial This driver binding should replace the existing driver binding -mechanism the bus currently uses. +mechanism the bus currently uses. Step 6: Supply a hotplug callback. Whenever a device is registered with the driver model core, the -userspace program /sbin/hotplug is called to notify userspace. +userspace program /sbin/hotplug is called to notify userspace. Users can define actions to perform when a device is inserted or -removed. +removed. The driver model core passes several arguments to userspace via environment variables, including - ACTION: set to 'add' or 'remove' -- DEVPATH: set to the device's physical path in sysfs. +- DEVPATH: set to the device's physical path in sysfs. A bus driver may also supply additional parameters for userspace to consume. To do this, a bus must implement the 'hotplug' method in -struct bus_type: +struct bus_type:: - int (*hotplug) (struct device *dev, char **envp, + int (*hotplug) (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); -This is called immediately before /sbin/hotplug is executed. +This is called immediately before /sbin/hotplug is executed. Step 7: Cleaning up the bus driver. The generic bus, device, and driver structures provide several fields -that can replace those defined privately to the bus driver. +that can replace those defined privately to the bus driver. - Device list. @@ -407,36 +409,36 @@ type. This includes all devices on all instances of that bus type. An internal list that the bus uses may be removed, in favor of using this one. -The core provides an iterator to access these devices. +The core provides an iterator to access these devices:: -int bus_for_each_dev(struct bus_type * bus, struct device * start, - void * data, int (*fn)(struct device *, void *)); + int bus_for_each_dev(struct bus_type * bus, struct device * start, + void * data, int (*fn)(struct device *, void *)); - Driver list. struct bus_type also contains a list of all drivers registered with -it. An internal list of drivers that the bus driver maintains may -be removed in favor of using the generic one. +it. An internal list of drivers that the bus driver maintains may +be removed in favor of using the generic one. -The drivers may be iterated over, like devices: +The drivers may be iterated over, like devices:: -int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, - void * data, int (*fn)(struct device_driver *, void *)); + int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, + void * data, int (*fn)(struct device_driver *, void *)); Please see drivers/base/bus.c for more information. -- rwsem +- rwsem struct bus_type contains an rwsem that protects all core accesses to the device and driver lists. This can be used by the bus driver internally, and should be used when accessing the device or driver -lists the bus maintains. +lists the bus maintains. -- Device and driver fields. +- Device and driver fields. Some of the fields in struct device and struct device_driver duplicate fields in the bus-specific representations of these objects. Feel free @@ -444,4 +446,3 @@ to remove the bus-specific ones and favor the generic ones. Note though, that this will likely mean fixing up all the drivers that reference the bus-specific fields (though those should all be 1-line changes). - diff --git a/Documentation/eisa.txt b/Documentation/eisa.txt index 2806e5544e4353..f388545a85a753 100644 --- a/Documentation/eisa.txt +++ b/Documentation/eisa.txt @@ -103,7 +103,7 @@ id_table an array of NULL terminated EISA id strings, (driver_data). driver a generic driver, such as described in - Documentation/driver-model/driver.txt. Only .name, + Documentation/driver-model/driver.rst. Only .name, .probe and .remove members are mandatory. =============== ==================================================== @@ -152,7 +152,7 @@ state set of flags indicating the state of the device. Current flags are EISA_CONFIG_ENABLED and EISA_CONFIG_FORCED. res set of four 256 bytes I/O regions allocated to this device dma_mask DMA mask set from the parent device. -dev generic device (see Documentation/driver-model/device.txt) +dev generic device (see Documentation/driver-model/device.rst) ======== ============================================================ You can get the 'struct eisa_device' from 'struct device' using the diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 4a0a9c3f4af60c..9e27c843d00ea0 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -169,7 +169,7 @@ byte offsets over a base for the register block. If you want to dump an u32 array in debugfs, you can create file with: - struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, + void debugfs_create_u32_array(const char *name, umode_t mode, struct dentry *parent, u32 *array, u32 elements); diff --git a/Documentation/hwmon/submitting-patches.rst b/Documentation/hwmon/submitting-patches.rst index f9796b9d9db638..d5b05d3e54baeb 100644 --- a/Documentation/hwmon/submitting-patches.rst +++ b/Documentation/hwmon/submitting-patches.rst @@ -89,7 +89,7 @@ increase the chances of your change being accepted. console. Excessive logging can seriously affect system performance. * Use devres functions whenever possible to allocate resources. For rationale - and supported functions, please see Documentation/driver-model/devres.txt. + and supported functions, please see Documentation/driver-model/devres.rst. If a function is not supported by devres, consider using devm_add_action(). * If the driver has a detect function, make sure it is silent. Debug messages diff --git a/arch/arm/include/asm/ptdump.h b/arch/arm/include/asm/ptdump.h index 3ebf9718288d99..0c2d3d0d4cc695 100644 --- a/arch/arm/include/asm/ptdump.h +++ b/arch/arm/include/asm/ptdump.h @@ -21,13 +21,10 @@ struct ptdump_info { void ptdump_walk_pgd(struct seq_file *s, struct ptdump_info *info); #ifdef CONFIG_ARM_PTDUMP_DEBUGFS -int ptdump_debugfs_register(struct ptdump_info *info, const char *name); +void ptdump_debugfs_register(struct ptdump_info *info, const char *name); #else -static inline int ptdump_debugfs_register(struct ptdump_info *info, - const char *name) -{ - return 0; -} +static inline void ptdump_debugfs_register(struct ptdump_info *info, + const char *name) { } #endif /* CONFIG_ARM_PTDUMP_DEBUGFS */ void ptdump_check_wx(void); diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 406fd2a9a88f40..bd5be82101f321 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -987,84 +987,44 @@ static int debug_clock_show(struct seq_file *s, void *unused) DEFINE_SHOW_ATTRIBUTE(debug_clock); -static int clk_debugfs_register_one(struct clk *c) +static void clk_debugfs_register_one(struct clk *c) { - int err; struct dentry *d; struct clk *pa = c->parent; d = debugfs_create_dir(c->name, pa ? pa->dent : clk_debugfs_root); - if (!d) - return -ENOMEM; c->dent = d; - d = debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount); - if (!d) { - err = -ENOMEM; - goto err_out; - } - d = debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate); - if (!d) { - err = -ENOMEM; - goto err_out; - } - d = debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags); - if (!d) { - err = -ENOMEM; - goto err_out; - } - return 0; - -err_out: - debugfs_remove_recursive(c->dent); - return err; + debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount); + debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate); + debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags); } -static int clk_debugfs_register(struct clk *c) +static void clk_debugfs_register(struct clk *c) { - int err; struct clk *pa = c->parent; - if (pa && !pa->dent) { - err = clk_debugfs_register(pa); - if (err) - return err; - } + if (pa && !pa->dent) + clk_debugfs_register(pa); - if (!c->dent) { - err = clk_debugfs_register_one(c); - if (err) - return err; - } - return 0; + if (!c->dent) + clk_debugfs_register_one(c); } static int __init clk_debugfs_init(void) { struct clk *c; struct dentry *d; - int err; d = debugfs_create_dir("clock", NULL); - if (!d) - return -ENOMEM; clk_debugfs_root = d; - list_for_each_entry(c, &clocks, node) { - err = clk_debugfs_register(c); - if (err) - goto err_out; - } + list_for_each_entry(c, &clocks, node) + clk_debugfs_register(c); - d = debugfs_create_file("summary", S_IRUGO, - d, NULL, &debug_clock_fops); - if (!d) - return -ENOMEM; + debugfs_create_file("summary", S_IRUGO, d, NULL, &debug_clock_fops); return 0; -err_out: - debugfs_remove_recursive(clk_debugfs_root); - return err; } late_initcall(clk_debugfs_init); diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 998075d3ef8666..d068958d6f8a44 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -539,11 +539,8 @@ static void omap_pm_init_debugfs(void) struct dentry *d; d = debugfs_create_dir("pm_debug", NULL); - if (!d) - return; - - (void) debugfs_create_file("omap_pm", S_IWUSR | S_IRUGO, - d, NULL, &omap_pm_debug_fops); + debugfs_create_file("omap_pm", S_IWUSR | S_IRUGO, d, NULL, + &omap_pm_debug_fops); } #endif /* CONFIG_DEBUG_FS */ diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index fe6ec9b580b9c0..fceb1e525d26b9 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -190,9 +190,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir) return 0; d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir); - if (d) - (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, - (void *)pwrdm, &pwrdm_suspend_fops); + debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, pwrdm, + &pwrdm_suspend_fops); return 0; } @@ -230,16 +229,14 @@ static int __init pm_dbg_init(void) return 0; d = debugfs_create_dir("pm_debug", NULL); - if (!d) - return -EINVAL; - (void) debugfs_create_file("count", 0444, d, NULL, &pm_dbg_counters_fops); - (void) debugfs_create_file("time", 0444, d, NULL, &pm_dbg_timers_fops); + debugfs_create_file("count", 0444, d, NULL, &pm_dbg_counters_fops); + debugfs_create_file("time", 0444, d, NULL, &pm_dbg_timers_fops); pwrdm_for_each(pwrdms_setup, (void *)d); - (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, - &enable_off_mode, &pm_dbg_option_fops); + debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, + &enable_off_mode, &pm_dbg_option_fops); pm_dbg_init_done = 1; return 0; diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c index 006d27ee4fc643..7d6291f23251e7 100644 --- a/arch/arm/mm/dump.c +++ b/arch/arm/mm/dump.c @@ -446,7 +446,7 @@ void ptdump_check_wx(void) static int ptdump_init(void) { ptdump_initialize(); - return ptdump_debugfs_register(&kernel_ptdump_info, - "kernel_page_tables"); + ptdump_debugfs_register(&kernel_ptdump_info, "kernel_page_tables"); + return 0; } __initcall(ptdump_init); diff --git a/arch/arm/mm/ptdump_debugfs.c b/arch/arm/mm/ptdump_debugfs.c index be8d87be4b9384..598b636615a29a 100644 --- a/arch/arm/mm/ptdump_debugfs.c +++ b/arch/arm/mm/ptdump_debugfs.c @@ -24,11 +24,7 @@ static const struct file_operations ptdump_fops = { .release = single_release, }; -int ptdump_debugfs_register(struct ptdump_info *info, const char *name) +void ptdump_debugfs_register(struct ptdump_info *info, const char *name) { - struct dentry *pe; - - pe = debugfs_create_file(name, 0400, NULL, info, &ptdump_fops); - return pe ? 0 : -ENOMEM; - + debugfs_create_file(name, 0400, NULL, info, &ptdump_fops); } diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index 84e8ec4011ba72..b91eb0929ed144 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -147,13 +147,13 @@ static const struct dma_map_ops ibmebus_dma_ops = { .unmap_page = ibmebus_unmap_page, }; -static int ibmebus_match_path(struct device *dev, void *data) +static int ibmebus_match_path(struct device *dev, const void *data) { struct device_node *dn = to_platform_device(dev)->dev.of_node; return (of_find_node_by_path(data) == dn); } -static int ibmebus_match_node(struct device *dev, void *data) +static int ibmebus_match_node(struct device *dev, const void *data) { return to_platform_device(dev)->dev.of_node == data; } diff --git a/arch/sh/kernel/kdebugfs.c b/arch/sh/kernel/kdebugfs.c index 95428e05d21244..8b505e1556a5f8 100644 --- a/arch/sh/kernel/kdebugfs.c +++ b/arch/sh/kernel/kdebugfs.c @@ -9,9 +9,6 @@ EXPORT_SYMBOL(arch_debugfs_dir); static int __init arch_kdebugfs_init(void) { arch_debugfs_dir = debugfs_create_dir("sh", NULL); - if (!arch_debugfs_dir) - return -ENOMEM; - return 0; } arch_initcall(arch_kdebugfs_init); diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c index e5539e0f8e3b11..4c1ca197e9c5f2 100644 --- a/arch/sh/mm/asids-debugfs.c +++ b/arch/sh/mm/asids-debugfs.c @@ -63,13 +63,8 @@ static const struct file_operations asids_debugfs_fops = { static int __init asids_debugfs_init(void) { - struct dentry *asids_dentry; - - asids_dentry = debugfs_create_file("asids", S_IRUSR, arch_debugfs_dir, - NULL, &asids_debugfs_fops); - if (!asids_dentry) - return -ENOMEM; - - return PTR_ERR_OR_ZERO(asids_dentry); + debugfs_create_file("asids", S_IRUSR, arch_debugfs_dir, NULL, + &asids_debugfs_fops); + return 0; } device_initcall(asids_debugfs_init); diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c index 4eb9d43578b4c3..17d78079449715 100644 --- a/arch/sh/mm/cache-debugfs.c +++ b/arch/sh/mm/cache-debugfs.c @@ -109,22 +109,10 @@ static const struct file_operations cache_debugfs_fops = { static int __init cache_debugfs_init(void) { - struct dentry *dcache_dentry, *icache_dentry; - - dcache_dentry = debugfs_create_file("dcache", S_IRUSR, arch_debugfs_dir, - (unsigned int *)CACHE_TYPE_DCACHE, - &cache_debugfs_fops); - if (!dcache_dentry) - return -ENOMEM; - - icache_dentry = debugfs_create_file("icache", S_IRUSR, arch_debugfs_dir, - (unsigned int *)CACHE_TYPE_ICACHE, - &cache_debugfs_fops); - if (!icache_dentry) { - debugfs_remove(dcache_dentry); - return -ENOMEM; - } - + debugfs_create_file("dcache", S_IRUSR, arch_debugfs_dir, + (void *)CACHE_TYPE_DCACHE, &cache_debugfs_fops); + debugfs_create_file("icache", S_IRUSR, arch_debugfs_dir, + (void *)CACHE_TYPE_ICACHE, &cache_debugfs_fops); return 0; } module_init(cache_debugfs_init); diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index a53a040d00543c..b59bad86b31e5b 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -861,13 +861,8 @@ static const struct file_operations pmb_debugfs_fops = { static int __init pmb_debugfs_init(void) { - struct dentry *dentry; - - dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO, - arch_debugfs_dir, NULL, &pmb_debugfs_fops); - if (!dentry) - return -ENOMEM; - + debugfs_create_file("pmb", S_IFREG | S_IRUGO, arch_debugfs_dir, NULL, + &pmb_debugfs_fops); return 0; } subsys_initcall(pmb_debugfs_init); diff --git a/arch/sh/mm/tlb-debugfs.c b/arch/sh/mm/tlb-debugfs.c index dea637a09246c2..11c6148283f3c7 100644 --- a/arch/sh/mm/tlb-debugfs.c +++ b/arch/sh/mm/tlb-debugfs.c @@ -149,22 +149,10 @@ static const struct file_operations tlb_debugfs_fops = { static int __init tlb_debugfs_init(void) { - struct dentry *itlb, *utlb; - - itlb = debugfs_create_file("itlb", S_IRUSR, arch_debugfs_dir, - (unsigned int *)TLB_TYPE_ITLB, - &tlb_debugfs_fops); - if (unlikely(!itlb)) - return -ENOMEM; - - utlb = debugfs_create_file("utlb", S_IRUSR, arch_debugfs_dir, - (unsigned int *)TLB_TYPE_UTLB, - &tlb_debugfs_fops); - if (unlikely(!utlb)) { - debugfs_remove(itlb); - return -ENOMEM; - } - + debugfs_create_file("itlb", S_IRUSR, arch_debugfs_dir, + (void *)TLB_TYPE_ITLB, &tlb_debugfs_fops); + debugfs_create_file("utlb", S_IRUSR, arch_debugfs_dir, + (void *)TLB_TYPE_UTLB, &tlb_debugfs_fops); return 0; } module_init(tlb_debugfs_init); diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index 7670ac2bda3ace..edaa30b208410d 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c @@ -67,33 +67,18 @@ static const struct file_operations fops_setup_data = { .llseek = default_llseek, }; -static int __init +static void __init create_setup_data_node(struct dentry *parent, int no, struct setup_data_node *node) { - struct dentry *d, *type, *data; + struct dentry *d; char buf[16]; sprintf(buf, "%d", no); d = debugfs_create_dir(buf, parent); - if (!d) - return -ENOMEM; - - type = debugfs_create_x32("type", S_IRUGO, d, &node->type); - if (!type) - goto err_dir; - - data = debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data); - if (!data) - goto err_type; - return 0; - -err_type: - debugfs_remove(type); -err_dir: - debugfs_remove(d); - return -ENOMEM; + debugfs_create_x32("type", S_IRUGO, d, &node->type); + debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data); } static int __init create_setup_data_nodes(struct dentry *parent) @@ -106,8 +91,6 @@ static int __init create_setup_data_nodes(struct dentry *parent) int no = 0; d = debugfs_create_dir("setup_data", parent); - if (!d) - return -ENOMEM; pa_data = boot_params.hdr.setup_data; @@ -128,19 +111,17 @@ static int __init create_setup_data_nodes(struct dentry *parent) node->paddr = pa_data; node->type = data->type; node->len = data->len; - error = create_setup_data_node(d, no, node); + create_setup_data_node(d, no, node); pa_data = data->next; memunmap(data); - if (error) - goto err_dir; no++; } return 0; err_dir: - debugfs_remove(d); + debugfs_remove_recursive(d); return error; } @@ -151,35 +132,18 @@ static struct debugfs_blob_wrapper boot_params_blob = { static int __init boot_params_kdebugfs_init(void) { - struct dentry *dbp, *version, *data; - int error = -ENOMEM; + struct dentry *dbp; + int error; dbp = debugfs_create_dir("boot_params", arch_debugfs_dir); - if (!dbp) - return -ENOMEM; - - version = debugfs_create_x16("version", S_IRUGO, dbp, - &boot_params.hdr.version); - if (!version) - goto err_dir; - data = debugfs_create_blob("data", S_IRUGO, dbp, - &boot_params_blob); - if (!data) - goto err_version; + debugfs_create_x16("version", S_IRUGO, dbp, &boot_params.hdr.version); + debugfs_create_blob("data", S_IRUGO, dbp, &boot_params_blob); error = create_setup_data_nodes(dbp); if (error) - goto err_data; + debugfs_remove_recursive(dbp); - return 0; - -err_data: - debugfs_remove(data); -err_version: - debugfs_remove(version); -err_dir: - debugfs_remove(dbp); return error; } #endif /* CONFIG_DEBUG_BOOT_PARAMS */ @@ -189,8 +153,6 @@ static int __init arch_kdebugfs_init(void) int error = 0; arch_debugfs_dir = debugfs_create_dir("x86", NULL); - if (!arch_debugfs_dir) - return -ENOMEM; #ifdef CONFIG_DEBUG_BOOT_PARAMS error = boot_params_kdebugfs_init(); diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c index c6f4982d540140..39001a401effb6 100644 --- a/arch/x86/mm/debug_pagetables.c +++ b/arch/x86/mm/debug_pagetables.c @@ -26,8 +26,6 @@ static int ptdump_curknl_show(struct seq_file *m, void *v) DEFINE_SHOW_ATTRIBUTE(ptdump_curknl); #ifdef CONFIG_PAGE_TABLE_ISOLATION -static struct dentry *pe_curusr; - static int ptdump_curusr_show(struct seq_file *m, void *v) { if (current->mm->pgd) { @@ -42,8 +40,6 @@ DEFINE_SHOW_ATTRIBUTE(ptdump_curusr); #endif #if defined(CONFIG_EFI) && defined(CONFIG_X86_64) -static struct dentry *pe_efi; - static int ptdump_efi_show(struct seq_file *m, void *v) { if (efi_mm.pgd) @@ -54,41 +50,24 @@ static int ptdump_efi_show(struct seq_file *m, void *v) DEFINE_SHOW_ATTRIBUTE(ptdump_efi); #endif -static struct dentry *dir, *pe_knl, *pe_curknl; +static struct dentry *dir; static int __init pt_dump_debug_init(void) { dir = debugfs_create_dir("page_tables", NULL); - if (!dir) - return -ENOMEM; - - pe_knl = debugfs_create_file("kernel", 0400, dir, NULL, - &ptdump_fops); - if (!pe_knl) - goto err; - pe_curknl = debugfs_create_file("current_kernel", 0400, - dir, NULL, &ptdump_curknl_fops); - if (!pe_curknl) - goto err; + debugfs_create_file("kernel", 0400, dir, NULL, &ptdump_fops); + debugfs_create_file("current_kernel", 0400, dir, NULL, + &ptdump_curknl_fops); #ifdef CONFIG_PAGE_TABLE_ISOLATION - pe_curusr = debugfs_create_file("current_user", 0400, - dir, NULL, &ptdump_curusr_fops); - if (!pe_curusr) - goto err; + debugfs_create_file("current_user", 0400, dir, NULL, + &ptdump_curusr_fops); #endif - #if defined(CONFIG_EFI) && defined(CONFIG_X86_64) - pe_efi = debugfs_create_file("efi", 0400, dir, NULL, &ptdump_efi_fops); - if (!pe_efi) - goto err; + debugfs_create_file("efi", 0400, dir, NULL, &ptdump_efi_fops); #endif - return 0; -err: - debugfs_remove_recursive(dir); - return -ENOMEM; } static void __exit pt_dump_debug_exit(void) diff --git a/arch/x86/platform/atom/punit_atom_debug.c b/arch/x86/platform/atom/punit_atom_debug.c index 17185d73d649b9..ee6b0780bea1c3 100644 --- a/arch/x86/platform/atom/punit_atom_debug.c +++ b/arch/x86/platform/atom/punit_atom_debug.c @@ -104,24 +104,12 @@ DEFINE_SHOW_ATTRIBUTE(punit_dev_state); static struct dentry *punit_dbg_file; -static int punit_dbgfs_register(struct punit_device *punit_device) +static void punit_dbgfs_register(struct punit_device *punit_device) { - struct dentry *dev_state; - punit_dbg_file = debugfs_create_dir("punit_atom", NULL); - if (!punit_dbg_file) - return -ENXIO; - - dev_state = debugfs_create_file("dev_power_state", 0444, - punit_dbg_file, punit_device, - &punit_dev_state_fops); - if (!dev_state) { - pr_err("punit_dev_state register failed\n"); - debugfs_remove(punit_dbg_file); - return -ENXIO; - } - return 0; + debugfs_create_file("dev_power_state", 0444, punit_dbg_file, + punit_device, &punit_dev_state_fops); } static void punit_dbgfs_unregister(void) @@ -145,15 +133,12 @@ MODULE_DEVICE_TABLE(x86cpu, intel_punit_cpu_ids); static int __init punit_atom_debug_init(void) { const struct x86_cpu_id *id; - int ret; id = x86_match_cpu(intel_punit_cpu_ids); if (!id) return -ENODEV; - ret = punit_dbgfs_register((struct punit_device *)id->driver_data); - if (ret < 0) - return ret; + punit_dbgfs_register((struct punit_device *)id->driver_data); return 0; } diff --git a/arch/x86/platform/intel-quark/imr.c b/arch/x86/platform/intel-quark/imr.c index b5420371d32d07..6dd25dc5f0279a 100644 --- a/arch/x86/platform/intel-quark/imr.c +++ b/arch/x86/platform/intel-quark/imr.c @@ -35,7 +35,6 @@ #include struct imr_device { - struct dentry *file; bool init; struct mutex lock; int max_imr; @@ -231,13 +230,11 @@ DEFINE_SHOW_ATTRIBUTE(imr_dbgfs_state); * imr_debugfs_register - register debugfs hooks. * * @idev: pointer to imr_device structure. - * @return: 0 on success - errno on failure. */ -static int imr_debugfs_register(struct imr_device *idev) +static void imr_debugfs_register(struct imr_device *idev) { - idev->file = debugfs_create_file("imr_state", 0444, NULL, idev, - &imr_dbgfs_state_fops); - return PTR_ERR_OR_ZERO(idev->file); + debugfs_create_file("imr_state", 0444, NULL, idev, + &imr_dbgfs_state_fops); } /** @@ -582,7 +579,6 @@ static const struct x86_cpu_id imr_ids[] __initconst = { static int __init imr_init(void) { struct imr_device *idev = &imr_dev; - int ret; if (!x86_match_cpu(imr_ids) || !iosf_mbi_available()) return -ENODEV; @@ -592,9 +588,7 @@ static int __init imr_init(void) idev->init = true; mutex_init(&idev->lock); - ret = imr_debugfs_register(idev); - if (ret != 0) - pr_warn("debugfs register failed!\n"); + imr_debugfs_register(idev); imr_fixup_memmap(idev); return 0; } diff --git a/arch/x86/platform/intel/iosf_mbi.c b/arch/x86/platform/intel/iosf_mbi.c index b393eaa798efd3..2e796b54cbde14 100644 --- a/arch/x86/platform/intel/iosf_mbi.c +++ b/arch/x86/platform/intel/iosf_mbi.c @@ -461,31 +461,16 @@ static struct dentry *iosf_dbg; static void iosf_sideband_debug_init(void) { - struct dentry *d; - iosf_dbg = debugfs_create_dir("iosf_sb", NULL); - if (IS_ERR_OR_NULL(iosf_dbg)) - return; /* mdr */ - d = debugfs_create_x32("mdr", 0660, iosf_dbg, &dbg_mdr); - if (!d) - goto cleanup; + debugfs_create_x32("mdr", 0660, iosf_dbg, &dbg_mdr); /* mcrx */ - d = debugfs_create_x32("mcrx", 0660, iosf_dbg, &dbg_mcrx); - if (!d) - goto cleanup; + debugfs_create_x32("mcrx", 0660, iosf_dbg, &dbg_mcrx); /* mcr - initiates mailbox tranaction */ - d = debugfs_create_file("mcr", 0660, iosf_dbg, &dbg_mcr, &iosf_mcr_fops); - if (!d) - goto cleanup; - - return; - -cleanup: - debugfs_remove_recursive(d); + debugfs_create_file("mcr", 0660, iosf_dbg, &dbg_mcr, &iosf_mcr_fops); } static void iosf_debugfs_init(void) diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 0c7dfec4acac8e..20c389a91b8033 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -66,7 +66,6 @@ static struct tunables tunables[] = { }; static struct dentry *tunables_dir; -static struct dentry *tunables_file; /* these correspond to the statistics printed by ptc_seq_show() */ static char *stat_description[] = { @@ -1700,18 +1699,8 @@ static int __init uv_ptc_init(void) } tunables_dir = debugfs_create_dir(UV_BAU_TUNABLES_DIR, NULL); - if (!tunables_dir) { - pr_err("unable to create debugfs directory %s\n", - UV_BAU_TUNABLES_DIR); - return -EINVAL; - } - tunables_file = debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, - tunables_dir, NULL, &tunables_fops); - if (!tunables_file) { - pr_err("unable to create debugfs file %s\n", - UV_BAU_TUNABLES_FILE); - return -EINVAL; - } + debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, tunables_dir, NULL, + &tunables_fops); return 0; } diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c index 13da87918b4f32..532410998684d9 100644 --- a/arch/x86/xen/debugfs.c +++ b/arch/x86/xen/debugfs.c @@ -9,13 +9,8 @@ static struct dentry *d_xen_debug; struct dentry * __init xen_init_debugfs(void) { - if (!d_xen_debug) { + if (!d_xen_debug) d_xen_debug = debugfs_create_dir("xen", NULL); - - if (!d_xen_debug) - pr_warning("Could not create 'xen' debugfs directory\n"); - } - return d_xen_debug; } diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 95ce9b5be41124..0acba2c712ab84 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -817,9 +817,6 @@ static int __init xen_p2m_debugfs(void) { struct dentry *d_xen = xen_init_debugfs(); - if (d_xen == NULL) - return -ENOMEM; - d_mmu_debug = debugfs_create_dir("mmu", d_xen); debugfs_create_file("p2m", 0600, d_mmu_debug, NULL, &p2m_dump_fops); diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 39845183917866..d696f165a50e6e 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -508,10 +508,10 @@ struct hid_uid { const char *uid; }; -static int match_hid_uid(struct device *dev, void *data) +static int match_hid_uid(struct device *dev, const void *data) { struct acpi_device *adev = ACPI_COMPANION(dev); - struct hid_uid *id = data; + const struct hid_uid *id = data; if (!adev) return 0; diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 7def63ab00c0ce..e3974a8f8fd41a 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -725,17 +725,15 @@ bool acpi_dev_found(const char *hid) EXPORT_SYMBOL(acpi_dev_found); struct acpi_dev_match_info { - const char *dev_name; - struct acpi_device *adev; struct acpi_device_id hid[2]; const char *uid; s64 hrv; }; -static int acpi_dev_match_cb(struct device *dev, void *data) +static int acpi_dev_match_cb(struct device *dev, const void *data) { struct acpi_device *adev = to_acpi_device(dev); - struct acpi_dev_match_info *match = data; + const struct acpi_dev_match_info *match = data; unsigned long long hrv; acpi_status status; @@ -746,9 +744,6 @@ static int acpi_dev_match_cb(struct device *dev, void *data) strcmp(adev->pnp.unique_id, match->uid))) return 0; - match->dev_name = acpi_dev_name(adev); - match->adev = adev; - if (match->hrv == -1) return 1; @@ -818,7 +813,7 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv) match.hrv = hrv; dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); - return dev ? match.adev : NULL; + return dev ? to_acpi_device(dev) : NULL; } EXPORT_SYMBOL(acpi_dev_get_first_match_dev); diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index 3eaa459ae0579d..aa64eece77a66a 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c @@ -134,10 +134,10 @@ static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset) } #ifdef CONFIG_TEGRA_IOMMU_SMMU -static int tegra_ahb_match_by_smmu(struct device *dev, void *data) +static int tegra_ahb_match_by_smmu(struct device *dev, const void *data) { struct tegra_ahb *ahb = dev_get_drvdata(dev); - struct device_node *dn = data; + const struct device_node *dn = data; return (ahb->dev->of_node == dn) ? 1 : 0; } diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 9b09e31ae82fdd..63c1e76739f126 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -137,7 +137,6 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu) sizeof(*raw_capacity), GFP_KERNEL); if (!raw_capacity) { - pr_err("cpu_capacity: failed to allocate memory for raw capacities\n"); cap_parsing_failed = true; return false; } @@ -217,10 +216,8 @@ static int __init register_cpufreq_notifier(void) if (!acpi_disabled || !raw_capacity) return -EINVAL; - if (!alloc_cpumask_var(&cpus_to_visit, GFP_KERNEL)) { - pr_err("cpu_capacity: failed to allocate memory for cpus_to_visit\n"); + if (!alloc_cpumask_var(&cpus_to_visit, GFP_KERNEL)) return -ENOMEM; - } cpumask_copy(cpus_to_visit, cpu_possible_mask); diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 0a58e969f8b7c2..df3cac739813fd 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -323,8 +323,8 @@ EXPORT_SYMBOL_GPL(bus_for_each_dev); * return to the caller and not iterate over any more devices. */ struct device *bus_find_device(struct bus_type *bus, - struct device *start, void *data, - int (*match)(struct device *dev, void *data)) + struct device *start, const void *data, + int (*match)(struct device *dev, const void *data)) { struct klist_iter i; struct device *dev; @@ -342,7 +342,7 @@ struct device *bus_find_device(struct bus_type *bus, } EXPORT_SYMBOL_GPL(bus_find_device); -static int match_name(struct device *dev, void *data) +static int match_name(struct device *dev, const void *data) { const char *name = data; diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 8827c60f51e25a..8d553c92cd3225 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -660,7 +660,8 @@ static int cacheinfo_cpu_pre_down(unsigned int cpu) static int __init cacheinfo_sysfs_init(void) { - return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "base/cacheinfo:online", + return cpuhp_setup_state(CPUHP_AP_BASE_CACHEINFO_ONLINE, + "base/cacheinfo:online", cacheinfo_cpu_online, cacheinfo_cpu_pre_down); } device_initcall(cacheinfo_sysfs_init); diff --git a/drivers/base/core.c b/drivers/base/core.c index b4c64528f13cca..da84a73f2ba63b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3356,3 +3356,9 @@ void device_set_of_node_from_dev(struct device *dev, const struct device *dev2) dev->of_node_reused = true; } EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); + +int device_match_of_node(struct device *dev, const void *np) +{ + return dev->of_node == np; +} +EXPORT_SYMBOL_GPL(device_match_of_node); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 0df9b4461766c7..994a9074742046 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -235,6 +235,19 @@ static int __init deferred_probe_timeout_setup(char *str) } __setup("deferred_probe_timeout=", deferred_probe_timeout_setup); +static int __driver_deferred_probe_check_state(struct device *dev) +{ + if (!initcalls_done) + return -EPROBE_DEFER; + + if (!deferred_probe_timeout) { + dev_WARN(dev, "deferred probe timeout, ignoring dependency"); + return -ETIMEDOUT; + } + + return 0; +} + /** * driver_deferred_probe_check_state() - Check deferred probe state * @dev: device to check @@ -248,14 +261,40 @@ __setup("deferred_probe_timeout=", deferred_probe_timeout_setup); */ int driver_deferred_probe_check_state(struct device *dev) { - if (initcalls_done) { - if (!deferred_probe_timeout) { - dev_WARN(dev, "deferred probe timeout, ignoring dependency"); - return -ETIMEDOUT; - } - dev_warn(dev, "ignoring dependency for device, assuming no driver"); - return -ENODEV; - } + int ret; + + ret = __driver_deferred_probe_check_state(dev); + if (ret < 0) + return ret; + + dev_warn(dev, "ignoring dependency for device, assuming no driver"); + + return -ENODEV; +} + +/** + * driver_deferred_probe_check_state_continue() - check deferred probe state + * @dev: device to check + * + * Returns -ETIMEDOUT if deferred probe debug timeout has expired, or + * -EPROBE_DEFER otherwise. + * + * Drivers or subsystems can opt-in to calling this function instead of + * directly returning -EPROBE_DEFER. + * + * This is similar to driver_deferred_probe_check_state(), but it allows the + * subsystem to keep deferring probe after built-in drivers have had a chance + * to probe. One scenario where that is useful is if built-in drivers rely on + * resources that are provided by modular drivers. + */ +int driver_deferred_probe_check_state_continue(struct device *dev) +{ + int ret; + + ret = __driver_deferred_probe_check_state(dev); + if (ret < 0) + return ret; + return -EPROBE_DEFER; } diff --git a/drivers/base/devcon.c b/drivers/base/devcon.c index f7035fc12b9280..09f28479b243ac 100644 --- a/drivers/base/devcon.c +++ b/drivers/base/devcon.c @@ -133,7 +133,7 @@ static struct bus_type *generic_match_buses[] = { NULL, }; -static int device_fwnode_match(struct device *dev, void *fwnode) +static int device_fwnode_match(struct device *dev, const void *fwnode) { return dev_fwnode(dev) == fwnode; } diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 857c8f1b876e56..4e5ca632f35e8f 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -73,8 +73,8 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); * return to the caller and not iterate over any more devices. */ struct device *driver_find_device(struct device_driver *drv, - struct device *start, void *data, - int (*match)(struct device *dev, void *data)) + struct device *start, const void *data, + int (*match)(struct device *dev, const void *data)) { struct klist_iter i; struct device *dev; diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig index 38f2da6f5c2b64..3f9e274e2ed325 100644 --- a/drivers/base/firmware_loader/Kconfig +++ b/drivers/base/firmware_loader/Kconfig @@ -26,6 +26,9 @@ config FW_LOADER if FW_LOADER +config FW_LOADER_PAGED_BUF + bool + config EXTRA_FIRMWARE string "Build named firmware blobs into the kernel binary" help @@ -67,6 +70,7 @@ config EXTRA_FIRMWARE_DIR config FW_LOADER_USER_HELPER bool "Enable the firmware sysfs fallback mechanism" + select FW_LOADER_PAGED_BUF help This option enables a sysfs loading facility to enable firmware loading to the kernel through userspace as a fallback mechanism @@ -151,5 +155,19 @@ config FW_LOADER_USER_HELPER_FALLBACK If you are unsure about this, say N here. +config FW_LOADER_COMPRESS + bool "Enable compressed firmware support" + select FW_LOADER_PAGED_BUF + select XZ_DEC + help + This option enables the support for loading compressed firmware + files. The caller of firmware API receives the decompressed file + content. The compressed file is loaded as a fallback, only after + loading the raw file failed at first. + + Currently only XZ-compressed files are supported, and they have to + be compressed with either none or crc32 integrity check type (pass + "-C crc32" option to xz command). + endif # FW_LOADER endmenu diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index f962488546b638..62ee90b4db56e9 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -219,20 +219,6 @@ static ssize_t firmware_loading_show(struct device *dev, return sprintf(buf, "%d\n", loading); } -/* one pages buffer should be mapped/unmapped only once */ -static int map_fw_priv_pages(struct fw_priv *fw_priv) -{ - if (!fw_priv->is_paged_buf) - return 0; - - vunmap(fw_priv->data); - fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, - PAGE_KERNEL_RO); - if (!fw_priv->data) - return -ENOMEM; - return 0; -} - /** * firmware_loading_store() - set value in the 'loading' control file * @dev: device pointer @@ -254,7 +240,6 @@ static ssize_t firmware_loading_store(struct device *dev, struct fw_priv *fw_priv; ssize_t written = count; int loading = simple_strtol(buf, NULL, 10); - int i; mutex_lock(&fw_lock); fw_priv = fw_sysfs->fw_priv; @@ -265,12 +250,7 @@ static ssize_t firmware_loading_store(struct device *dev, case 1: /* discarding any previous partial load */ if (!fw_sysfs_done(fw_priv)) { - for (i = 0; i < fw_priv->nr_pages; i++) - __free_page(fw_priv->pages[i]); - vfree(fw_priv->pages); - fw_priv->pages = NULL; - fw_priv->page_array_size = 0; - fw_priv->nr_pages = 0; + fw_free_paged_buf(fw_priv); fw_state_start(fw_priv); } break; @@ -284,7 +264,7 @@ static ssize_t firmware_loading_store(struct device *dev, * see the mapped 'buf->data' once the loading * is completed. * */ - rc = map_fw_priv_pages(fw_priv); + rc = fw_map_paged_buf(fw_priv); if (rc) dev_err(dev, "%s: map pages failed\n", __func__); @@ -389,40 +369,13 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) { - struct fw_priv *fw_priv= fw_sysfs->fw_priv; - int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT; - - /* If the array of pages is too small, grow it... */ - if (fw_priv->page_array_size < pages_needed) { - int new_array_size = max(pages_needed, - fw_priv->page_array_size * 2); - struct page **new_pages; + int err; - new_pages = vmalloc(array_size(new_array_size, sizeof(void *))); - if (!new_pages) { - fw_load_abort(fw_sysfs); - return -ENOMEM; - } - memcpy(new_pages, fw_priv->pages, - fw_priv->page_array_size * sizeof(void *)); - memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * - (new_array_size - fw_priv->page_array_size)); - vfree(fw_priv->pages); - fw_priv->pages = new_pages; - fw_priv->page_array_size = new_array_size; - } - - while (fw_priv->nr_pages < pages_needed) { - fw_priv->pages[fw_priv->nr_pages] = - alloc_page(GFP_KERNEL | __GFP_HIGHMEM); - - if (!fw_priv->pages[fw_priv->nr_pages]) { - fw_load_abort(fw_sysfs); - return -ENOMEM; - } - fw_priv->nr_pages++; - } - return 0; + err = fw_grow_paged_buf(fw_sysfs->fw_priv, + PAGE_ALIGN(min_size) >> PAGE_SHIFT); + if (err) + fw_load_abort(fw_sysfs); + return err; } /** @@ -659,7 +612,7 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags) /* Also permit LSMs and IMA to fail firmware sysfs fallback */ ret = security_kernel_load_data(LOADING_FIRMWARE); if (ret < 0) - return ret; + return false; return fw_force_sysfs_fallback(opt_flags); } diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index 4c1395f8e7ed25..7048a41973edab 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -64,12 +64,14 @@ struct fw_priv { void *data; size_t size; size_t allocated_size; -#ifdef CONFIG_FW_LOADER_USER_HELPER +#ifdef CONFIG_FW_LOADER_PAGED_BUF bool is_paged_buf; - bool need_uevent; struct page **pages; int nr_pages; int page_array_size; +#endif +#ifdef CONFIG_FW_LOADER_USER_HELPER + bool need_uevent; struct list_head pending_list; #endif const char *fw_name; @@ -133,4 +135,14 @@ static inline void fw_state_done(struct fw_priv *fw_priv) int assign_fw(struct firmware *fw, struct device *device, enum fw_opt opt_flags); +#ifdef CONFIG_FW_LOADER_PAGED_BUF +void fw_free_paged_buf(struct fw_priv *fw_priv); +int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed); +int fw_map_paged_buf(struct fw_priv *fw_priv); +#else +static inline void fw_free_paged_buf(struct fw_priv *fw_priv) {} +int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed) { return -ENXIO; } +int fw_map_paged_buf(struct fw_priv *fw_priv) { return -ENXIO; } +#endif + #endif /* __FIRMWARE_LOADER_H */ diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 7eaaf5ee5ba6ba..bf44c79beae92b 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -251,15 +252,7 @@ static void __free_fw_priv(struct kref *ref) list_del(&fw_priv->list); spin_unlock(&fwc->lock); -#ifdef CONFIG_FW_LOADER_USER_HELPER - if (fw_priv->is_paged_buf) { - int i; - vunmap(fw_priv->data); - for (i = 0; i < fw_priv->nr_pages; i++) - __free_page(fw_priv->pages[i]); - vfree(fw_priv->pages); - } else -#endif + fw_free_paged_buf(fw_priv); /* free leftover pages */ if (!fw_priv->allocated_size) vfree(fw_priv->data); kfree_const(fw_priv->fw_name); @@ -274,6 +267,174 @@ static void free_fw_priv(struct fw_priv *fw_priv) spin_unlock(&fwc->lock); } +#ifdef CONFIG_FW_LOADER_PAGED_BUF +void fw_free_paged_buf(struct fw_priv *fw_priv) +{ + int i; + + if (!fw_priv->pages) + return; + + for (i = 0; i < fw_priv->nr_pages; i++) + __free_page(fw_priv->pages[i]); + kvfree(fw_priv->pages); + fw_priv->pages = NULL; + fw_priv->page_array_size = 0; + fw_priv->nr_pages = 0; +} + +int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed) +{ + /* If the array of pages is too small, grow it */ + if (fw_priv->page_array_size < pages_needed) { + int new_array_size = max(pages_needed, + fw_priv->page_array_size * 2); + struct page **new_pages; + + new_pages = kvmalloc_array(new_array_size, sizeof(void *), + GFP_KERNEL); + if (!new_pages) + return -ENOMEM; + memcpy(new_pages, fw_priv->pages, + fw_priv->page_array_size * sizeof(void *)); + memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * + (new_array_size - fw_priv->page_array_size)); + kvfree(fw_priv->pages); + fw_priv->pages = new_pages; + fw_priv->page_array_size = new_array_size; + } + + while (fw_priv->nr_pages < pages_needed) { + fw_priv->pages[fw_priv->nr_pages] = + alloc_page(GFP_KERNEL | __GFP_HIGHMEM); + + if (!fw_priv->pages[fw_priv->nr_pages]) + return -ENOMEM; + fw_priv->nr_pages++; + } + + return 0; +} + +int fw_map_paged_buf(struct fw_priv *fw_priv) +{ + /* one pages buffer should be mapped/unmapped only once */ + if (!fw_priv->pages) + return 0; + + vunmap(fw_priv->data); + fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, + PAGE_KERNEL_RO); + if (!fw_priv->data) + return -ENOMEM; + + /* page table is no longer needed after mapping, let's free */ + kvfree(fw_priv->pages); + fw_priv->pages = NULL; + + return 0; +} +#endif + +/* + * XZ-compressed firmware support + */ +#ifdef CONFIG_FW_LOADER_COMPRESS +/* show an error and return the standard error code */ +static int fw_decompress_xz_error(struct device *dev, enum xz_ret xz_ret) +{ + if (xz_ret != XZ_STREAM_END) { + dev_warn(dev, "xz decompression failed (xz_ret=%d)\n", xz_ret); + return xz_ret == XZ_MEM_ERROR ? -ENOMEM : -EINVAL; + } + return 0; +} + +/* single-shot decompression onto the pre-allocated buffer */ +static int fw_decompress_xz_single(struct device *dev, struct fw_priv *fw_priv, + size_t in_size, const void *in_buffer) +{ + struct xz_dec *xz_dec; + struct xz_buf xz_buf; + enum xz_ret xz_ret; + + xz_dec = xz_dec_init(XZ_SINGLE, (u32)-1); + if (!xz_dec) + return -ENOMEM; + + xz_buf.in_size = in_size; + xz_buf.in = in_buffer; + xz_buf.in_pos = 0; + xz_buf.out_size = fw_priv->allocated_size; + xz_buf.out = fw_priv->data; + xz_buf.out_pos = 0; + + xz_ret = xz_dec_run(xz_dec, &xz_buf); + xz_dec_end(xz_dec); + + fw_priv->size = xz_buf.out_pos; + return fw_decompress_xz_error(dev, xz_ret); +} + +/* decompression on paged buffer and map it */ +static int fw_decompress_xz_pages(struct device *dev, struct fw_priv *fw_priv, + size_t in_size, const void *in_buffer) +{ + struct xz_dec *xz_dec; + struct xz_buf xz_buf; + enum xz_ret xz_ret; + struct page *page; + int err = 0; + + xz_dec = xz_dec_init(XZ_DYNALLOC, (u32)-1); + if (!xz_dec) + return -ENOMEM; + + xz_buf.in_size = in_size; + xz_buf.in = in_buffer; + xz_buf.in_pos = 0; + + fw_priv->is_paged_buf = true; + fw_priv->size = 0; + do { + if (fw_grow_paged_buf(fw_priv, fw_priv->nr_pages + 1)) { + err = -ENOMEM; + goto out; + } + + /* decompress onto the new allocated page */ + page = fw_priv->pages[fw_priv->nr_pages - 1]; + xz_buf.out = kmap(page); + xz_buf.out_pos = 0; + xz_buf.out_size = PAGE_SIZE; + xz_ret = xz_dec_run(xz_dec, &xz_buf); + kunmap(page); + fw_priv->size += xz_buf.out_pos; + /* partial decompression means either end or error */ + if (xz_buf.out_pos != PAGE_SIZE) + break; + } while (xz_ret == XZ_OK); + + err = fw_decompress_xz_error(dev, xz_ret); + if (!err) + err = fw_map_paged_buf(fw_priv); + + out: + xz_dec_end(xz_dec); + return err; +} + +static int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv, + size_t in_size, const void *in_buffer) +{ + /* if the buffer is pre-allocated, we can perform in single-shot mode */ + if (fw_priv->data) + return fw_decompress_xz_single(dev, fw_priv, in_size, in_buffer); + else + return fw_decompress_xz_pages(dev, fw_priv, in_size, in_buffer); +} +#endif /* CONFIG_FW_LOADER_COMPRESS */ + /* direct firmware loading support */ static char fw_path_para[256]; static const char * const fw_path[] = { @@ -293,7 +454,12 @@ module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); static int -fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) +fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv, + const char *suffix, + int (*decompress)(struct device *dev, + struct fw_priv *fw_priv, + size_t in_size, + const void *in_buffer)) { loff_t size; int i, len; @@ -301,9 +467,11 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) char *path; enum kernel_read_file_id id = READING_FIRMWARE; size_t msize = INT_MAX; + void *buffer = NULL; /* Already populated data member means we're loading into a buffer */ - if (fw_priv->data) { + if (!decompress && fw_priv->data) { + buffer = fw_priv->data; id = READING_FIRMWARE_PREALLOC_BUFFER; msize = fw_priv->allocated_size; } @@ -317,15 +485,15 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) if (!fw_path[i][0]) continue; - len = snprintf(path, PATH_MAX, "%s/%s", - fw_path[i], fw_priv->fw_name); + len = snprintf(path, PATH_MAX, "%s/%s%s", + fw_path[i], fw_priv->fw_name, suffix); if (len >= PATH_MAX) { rc = -ENAMETOOLONG; break; } fw_priv->size = 0; - rc = kernel_read_file_from_path(path, &fw_priv->data, &size, + rc = kernel_read_file_from_path(path, &buffer, &size, msize, id); if (rc) { if (rc != -ENOENT) @@ -336,8 +504,24 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) path); continue; } - dev_dbg(device, "direct-loading %s\n", fw_priv->fw_name); - fw_priv->size = size; + if (decompress) { + dev_dbg(device, "f/w decompressing %s\n", + fw_priv->fw_name); + rc = decompress(device, fw_priv, size, buffer); + /* discard the superfluous original content */ + vfree(buffer); + buffer = NULL; + if (rc) { + fw_free_paged_buf(fw_priv); + continue; + } + } else { + dev_dbg(device, "direct-loading %s\n", + fw_priv->fw_name); + if (!fw_priv->data) + fw_priv->data = buffer; + fw_priv->size = size; + } fw_state_done(fw_priv); break; } @@ -584,7 +768,13 @@ _request_firmware(const struct firmware **firmware_p, const char *name, if (ret <= 0) /* error or already assigned */ goto out; - ret = fw_get_filesystem_firmware(device, fw->priv); + ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL); +#ifdef CONFIG_FW_LOADER_COMPRESS + if (ret == -ENOENT) + ret = fw_get_filesystem_firmware(device, fw->priv, ".xz", + fw_decompress_xz); +#endif + if (ret) { if (!(opt_flags & FW_OPT_NO_WARN)) dev_warn(device, diff --git a/drivers/base/node.c b/drivers/base/node.c index 8598fcbd2a170a..aa878fbcf70514 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -66,6 +66,7 @@ static DEVICE_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL); * @dev: Device for this memory access class * @list_node: List element in the node's access list * @access: The access class rank + * @hmem_attrs: Heterogeneous memory performance attributes */ struct node_access_nodes { struct device dev; @@ -673,8 +674,8 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid) /** * register_memory_node_under_compute_node - link memory node to its compute * node for a given access class. - * @mem_node: Memory node number - * @cpu_node: Cpu node number + * @mem_nid: Memory node number + * @cpu_nid: Cpu node number * @access: Access class to register * * Description: diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 4d1729853d1afa..71390329038553 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -5,7 +5,7 @@ * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs * - * Please see Documentation/driver-model/platform.txt for more + * Please see Documentation/driver-model/platform.rst for more * information. */ diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 1dc10740fc0f7c..6707659cffd6ee 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2819,9 +2819,9 @@ static const struct device_type bmc_device_type = { .groups = bmc_dev_attr_groups, }; -static int __find_bmc_guid(struct device *dev, void *data) +static int __find_bmc_guid(struct device *dev, const void *data) { - guid_t *guid = data; + const guid_t *guid = data; struct bmc_device *bmc; int rv; @@ -2857,9 +2857,9 @@ struct prod_dev_id { unsigned char device_id; }; -static int __find_bmc_prod_dev_id(struct device *dev, void *data) +static int __find_bmc_prod_dev_id(struct device *dev, const void *data) { - struct prod_dev_id *cid = data; + const struct prod_dev_id *cid = data; struct bmc_device *bmc; int rv; diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c index f2a91c4d8cab60..fd94c423844944 100644 --- a/drivers/char/ipmi/ipmi_si_platform.c +++ b/drivers/char/ipmi/ipmi_si_platform.c @@ -426,7 +426,7 @@ static int ipmi_remove(struct platform_device *pdev) return ipmi_si_remove_by_dev(&pdev->dev); } -static int pdev_match_name(struct device *dev, void *data) +static int pdev_match_name(struct device *dev, const void *data) { struct platform_device *pdev = to_platform_device(dev); const char *name = data; diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 937a930ce87de6..44fd4f9404a974 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * System Control and Management Interface (SCMI) Message Protocol * driver common header file containing some definitions, structures diff --git a/drivers/firmware/efi/dev-path-parser.c b/drivers/firmware/efi/dev-path-parser.c index 85ec99f978412f..20123384271c81 100644 --- a/drivers/firmware/efi/dev-path-parser.c +++ b/drivers/firmware/efi/dev-path-parser.c @@ -17,9 +17,9 @@ struct acpi_hid_uid { char uid[11]; /* UINT_MAX + null byte */ }; -static int __init match_acpi_dev(struct device *dev, void *data) +static int __init match_acpi_dev(struct device *dev, const void *data) { - struct acpi_hid_uid hid_uid = *(struct acpi_hid_uid *)data; + struct acpi_hid_uid hid_uid = *(const struct acpi_hid_uid *)data; struct acpi_device *adev = to_acpi_device(dev); if (acpi_match_device_ids(adev, hid_uid.hid)) diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 4983827151bff4..adbeeefaca92fe 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: BSD-3-Clause +/* SPDX-License-Identifier: BSD-3-Clause */ /* * Texas Instruments System Control Interface (TISCI) Protocol * diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c index 75f64abf9c817c..e405309baadc19 100644 --- a/drivers/fpga/of-fpga-region.c +++ b/drivers/fpga/of-fpga-region.c @@ -22,11 +22,6 @@ static const struct of_device_id fpga_region_of_match[] = { }; MODULE_DEVICE_TABLE(of, fpga_region_of_match); -static int fpga_region_of_node_match(struct device *dev, const void *data) -{ - return dev->of_node == data; -} - /** * of_fpga_region_find - find FPGA region * @np: device node of FPGA Region @@ -37,7 +32,7 @@ static int fpga_region_of_node_match(struct device *dev, const void *data) */ static struct fpga_region *of_fpga_region_find(struct device_node *np) { - return fpga_region_class_find(NULL, np, fpga_region_of_node_match); + return fpga_region_class_find(NULL, np, device_match_of_node); } /** diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index 6314225dbed0a3..3611a05716673b 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c @@ -41,7 +41,7 @@ MODULE_PARM_DESC(mask, "GPIO channel mask."); /* * FIXME: convert this singleton driver to use the state container - * design pattern, see Documentation/driver-model/design-patterns.txt + * design pattern, see Documentation/driver-model/design-patterns.rst */ static struct cs5535_gpio_chip { struct gpio_chip chip; diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 80b75501f5c6a2..ad19df0686c93c 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -93,7 +93,7 @@ static struct bus_type mipi_dsi_bus_type = { .pm = &mipi_dsi_device_pm_ops, }; -static int of_device_match(struct device *dev, void *data) +static int of_device_match(struct device *dev, const void *data) { return dev->of_node == data; } diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 826b3f047c0cfa..cf25f183c4a71b 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -2372,10 +2372,10 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc) return 0; } -static int tegra_dc_match_by_pipe(struct device *dev, void *data) +static int tegra_dc_match_by_pipe(struct device *dev, const void *data) { struct tegra_dc *dc = dev_get_drvdata(dev); - unsigned int pipe = (unsigned long)data; + unsigned int pipe = (unsigned long)(void *)data; return dc->pipe == pipe; } diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index 58bfd6319f65e4..2463aa7ab4f674 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -525,23 +525,12 @@ static const struct file_operations debug_func_knob_fops = { static int debug_func_init(void) { - struct dentry *file; int ret; /* Create debugfs node */ debug_debugfs_dir = debugfs_create_dir("coresight_cpu_debug", NULL); - if (!debug_debugfs_dir) { - pr_err("%s: unable to create debugfs directory\n", __func__); - return -ENOMEM; - } - - file = debugfs_create_file("enable", 0644, debug_debugfs_dir, NULL, - &debug_func_knob_fops); - if (!file) { - pr_err("%s: unable to create enable knob file\n", __func__); - ret = -ENOMEM; - goto err; - } + debugfs_create_file("enable", 0644, debug_debugfs_dir, NULL, + &debug_func_knob_fops); /* Register function to be called for panic */ ret = atomic_notifier_chain_register(&panic_notifier_list, diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index cf580ffbc27c58..dad7d96c594361 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -37,7 +37,7 @@ static int coresight_alloc_conns(struct device *dev, return 0; } -int coresight_device_fwnode_match(struct device *dev, void *fwnode) +int coresight_device_fwnode_match(struct device *dev, const void *fwnode) { return dev_fwnode(dev) == fwnode; } diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 86d1fc2c1bd405..55db77f6410b04 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -498,9 +498,9 @@ struct coresight_device *coresight_get_sink(struct list_head *path) return csdev; } -static int coresight_enabled_sink(struct device *dev, void *data) +static int coresight_enabled_sink(struct device *dev, const void *data) { - bool *reset = data; + const bool *reset = data; struct coresight_device *csdev = to_coresight_device(dev); if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || @@ -544,7 +544,7 @@ struct coresight_device *coresight_get_enabled_sink(bool deactivate) return dev ? to_coresight_device(dev) : NULL; } -static int coresight_sink_by_id(struct device *dev, void *data) +static int coresight_sink_by_id(struct device *dev, const void *data) { struct coresight_device *csdev = to_coresight_device(dev); unsigned long hash; diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 033dce563c993a..55922896d86268 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -789,10 +789,9 @@ static int intel_th_populate(struct intel_th *th) return 0; } -static int match_devt(struct device *dev, void *data) +static int match_devt(struct device *dev, const void *data) { - dev_t devt = (dev_t)(unsigned long)data; - + dev_t devt = (dev_t)(unsigned long)(void *)data; return dev->devt == devt; } diff --git a/drivers/i2c/busses/i2c-amd-mp2-pci.c b/drivers/i2c/busses/i2c-amd-mp2-pci.c index 455e1f36a2a3de..c7fe3b44a86017 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-pci.c +++ b/drivers/i2c/busses/i2c-amd-mp2-pci.c @@ -457,7 +457,7 @@ static struct pci_driver amd_mp2_pci_driver = { }; module_pci_driver(amd_mp2_pci_driver); -static int amd_mp2_device_match(struct device *dev, void *data) +static int amd_mp2_device_match(struct device *dev, const void *data) { return 1; } diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index 1969bfdfe6a47e..428a82c3a35fb7 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -320,7 +320,7 @@ u32 i2c_acpi_find_bus_speed(struct device *dev) } EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed); -static int i2c_acpi_find_match_adapter(struct device *dev, void *data) +static int i2c_acpi_find_match_adapter(struct device *dev, const void *data) { struct i2c_adapter *adapter = i2c_verify_adapter(dev); @@ -330,7 +330,7 @@ static int i2c_acpi_find_match_adapter(struct device *dev, void *data) return ACPI_HANDLE(dev) == (acpi_handle)data; } -static int i2c_acpi_find_match_device(struct device *dev, void *data) +static int i2c_acpi_find_match_device(struct device *dev, const void *data) { return ACPI_COMPANION(dev) == data; } diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index 406e5f695a7ecb..2eb59a260ad469 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -112,12 +112,12 @@ void of_i2c_register_devices(struct i2c_adapter *adap) of_node_put(bus); } -static int of_dev_node_match(struct device *dev, void *data) +static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; } -static int of_dev_or_parent_node_match(struct device *dev, void *data) +static int of_dev_or_parent_node_match(struct device *dev, const void *data) { if (dev->of_node == data) return 1; diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 2fb2314548e913..5a8351c9a42659 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -90,7 +90,7 @@ static const struct iio_chan_spec #ifdef CONFIG_OF -static int iio_dev_node_match(struct device *dev, void *data) +static int iio_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data && dev->type == &iio_device_type; } diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index e068a02122f5e3..3afd3e9330e789 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -4498,7 +4498,7 @@ static const struct acpi_device_id hns_roce_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, hns_roce_acpi_match); -static int hns_roce_node_match(struct device *dev, void *fwnode) +static int hns_roce_node_match(struct device *dev, const void *fwnode) { return dev->fwnode == fwnode; } diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 2d96cf0023dd76..a9a9fabd396804 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2034,7 +2034,7 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) static struct platform_driver arm_smmu_driver; -static int arm_smmu_match_node(struct device *dev, void *data) +static int arm_smmu_match_node(struct device *dev, const void *data) { return dev->fwnode == data; } diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 653b6b3dcafb0f..64977c131ee62a 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1426,7 +1426,7 @@ static bool arm_smmu_capable(enum iommu_cap cap) } } -static int arm_smmu_match_node(struct device *dev, void *data) +static int arm_smmu_match_node(struct device *dev, const void *data) { return dev->fwnode == data; } diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c index a64116586b4ccc..43b336316fded7 100644 --- a/drivers/mailbox/bcm-flexrm-mailbox.c +++ b/drivers/mailbox/bcm-flexrm-mailbox.c @@ -296,8 +296,6 @@ struct flexrm_mbox { struct dma_pool *bd_pool; struct dma_pool *cmpl_pool; struct dentry *root; - struct dentry *config; - struct dentry *stats; struct mbox_controller controller; }; @@ -1603,7 +1601,6 @@ static int flexrm_mbox_probe(struct platform_device *pdev) 1 << RING_CMPL_ALIGN_ORDER, 0); if (!mbox->cmpl_pool) { ret = -ENOMEM; - goto fail_destroy_bd_pool; } /* Allocate platform MSIs for each ring */ @@ -1624,28 +1621,15 @@ static int flexrm_mbox_probe(struct platform_device *pdev) /* Create debugfs root entry */ mbox->root = debugfs_create_dir(dev_name(mbox->dev), NULL); - if (IS_ERR_OR_NULL(mbox->root)) { - ret = PTR_ERR_OR_ZERO(mbox->root); - goto fail_free_msis; - } /* Create debugfs config entry */ - mbox->config = debugfs_create_devm_seqfile(mbox->dev, - "config", mbox->root, - flexrm_debugfs_conf_show); - if (IS_ERR_OR_NULL(mbox->config)) { - ret = PTR_ERR_OR_ZERO(mbox->config); - goto fail_free_debugfs_root; - } + debugfs_create_devm_seqfile(mbox->dev, "config", mbox->root, + flexrm_debugfs_conf_show); /* Create debugfs stats entry */ - mbox->stats = debugfs_create_devm_seqfile(mbox->dev, - "stats", mbox->root, - flexrm_debugfs_stats_show); - if (IS_ERR_OR_NULL(mbox->stats)) { - ret = PTR_ERR_OR_ZERO(mbox->stats); - goto fail_free_debugfs_root; - } + debugfs_create_devm_seqfile(mbox->dev, "stats", mbox->root, + flexrm_debugfs_stats_show); + skip_debugfs: /* Initialize mailbox controller */ @@ -1676,11 +1660,9 @@ static int flexrm_mbox_probe(struct platform_device *pdev) fail_free_debugfs_root: debugfs_remove_recursive(mbox->root); -fail_free_msis: platform_msi_domain_free_irqs(dev); fail_destroy_cmpl_pool: dma_pool_destroy(mbox->cmpl_pool); -fail_destroy_bd_pool: dma_pool_destroy(mbox->bd_pool); fail: return ret; diff --git a/drivers/mailbox/bcm-pdc-mailbox.c b/drivers/mailbox/bcm-pdc-mailbox.c index 8513c42f70912e..fcb3b18a0678e2 100644 --- a/drivers/mailbox/bcm-pdc-mailbox.c +++ b/drivers/mailbox/bcm-pdc-mailbox.c @@ -395,8 +395,6 @@ struct pdc_state { */ struct scatterlist *src_sg[PDC_RING_ENTRIES]; - struct dentry *debugfs_stats; /* debug FS stats file for this PDC */ - /* counters */ u32 pdc_requests; /* number of request messages submitted */ u32 pdc_replies; /* number of reply messages received */ @@ -501,9 +499,8 @@ static void pdc_setup_debugfs(struct pdc_state *pdcs) debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); /* S_IRUSR == 0400 */ - pdcs->debugfs_stats = debugfs_create_file(spu_stats_name, 0400, - debugfs_dir, pdcs, - &pdc_debugfs_stats); + debugfs_create_file(spu_stats_name, 0400, debugfs_dir, pdcs, + &pdc_debugfs_stats); } static void pdc_free_debugfs(void) @@ -1603,7 +1600,6 @@ static int pdc_probe(struct platform_device *pdev) if (err) goto cleanup_buf_pool; - pdcs->debugfs_stats = NULL; pdc_setup_debugfs(pdcs); dev_dbg(dev, "pdc_probe() successful"); diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c index 8976f82785bb88..2ee14d8a6d318f 100644 --- a/drivers/mfd/altera-sysmgr.c +++ b/drivers/mfd/altera-sysmgr.c @@ -92,9 +92,9 @@ static struct regmap_config altr_sysmgr_regmap_cfg = { * Matching function used by driver_find_device(). * Return: True if match is found, otherwise false. */ -static int sysmgr_match_phandle(struct device *dev, void *data) +static int sysmgr_match_phandle(struct device *dev, const void *data) { - return dev->of_node == (struct device_node *)data; + return dev->of_node == (const struct device_node *)data; } /** diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 8ce1e41d632cc5..b65e585fc8c634 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -190,27 +190,6 @@ struct regmap *syscon_regmap_lookup_by_compatible(const char *s) } EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible); -static int syscon_match_pdevname(struct device *dev, void *data) -{ - return !strcmp(dev_name(dev), (const char *)data); -} - -struct regmap *syscon_regmap_lookup_by_pdevname(const char *s) -{ - struct device *dev; - struct syscon *syscon; - - dev = driver_find_device(&syscon_driver.driver, NULL, (void *)s, - syscon_match_pdevname); - if (!dev) - return ERR_PTR(-EPROBE_DEFER); - - syscon = dev_get_drvdata(dev); - - return syscon->regmap; -} -EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_pdevname); - struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np, const char *property) { diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index a73c9e669d78fe..5dc0f6093f9d92 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -908,11 +908,11 @@ void cxl_update_dedicated_ivtes_psl8(struct cxl_context *ctx); #ifdef CONFIG_DEBUG_FS -int cxl_debugfs_init(void); +void cxl_debugfs_init(void); void cxl_debugfs_exit(void); -int cxl_debugfs_adapter_add(struct cxl *adapter); +void cxl_debugfs_adapter_add(struct cxl *adapter); void cxl_debugfs_adapter_remove(struct cxl *adapter); -int cxl_debugfs_afu_add(struct cxl_afu *afu); +void cxl_debugfs_afu_add(struct cxl_afu *afu); void cxl_debugfs_afu_remove(struct cxl_afu *afu); void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir); void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir); @@ -921,27 +921,24 @@ void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir); #else /* CONFIG_DEBUG_FS */ -static inline int __init cxl_debugfs_init(void) +static inline void __init cxl_debugfs_init(void) { - return 0; } static inline void cxl_debugfs_exit(void) { } -static inline int cxl_debugfs_adapter_add(struct cxl *adapter) +static inline void cxl_debugfs_adapter_add(struct cxl *adapter) { - return 0; } static inline void cxl_debugfs_adapter_remove(struct cxl *adapter) { } -static inline int cxl_debugfs_afu_add(struct cxl_afu *afu) +static inline void cxl_debugfs_afu_add(struct cxl_afu *afu) { - return 0; } static inline void cxl_debugfs_afu_remove(struct cxl_afu *afu) diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c index 1fda22c24c93ee..7b987bf498b5d0 100644 --- a/drivers/misc/cxl/debugfs.c +++ b/drivers/misc/cxl/debugfs.c @@ -26,11 +26,11 @@ static int debugfs_io_u64_set(void *data, u64 val) DEFINE_DEBUGFS_ATTRIBUTE(fops_io_x64, debugfs_io_u64_get, debugfs_io_u64_set, "0x%016llx\n"); -static struct dentry *debugfs_create_io_x64(const char *name, umode_t mode, - struct dentry *parent, u64 __iomem *value) +static void debugfs_create_io_x64(const char *name, umode_t mode, + struct dentry *parent, u64 __iomem *value) { - return debugfs_create_file_unsafe(name, mode, parent, - (void __force *)value, &fops_io_x64); + debugfs_create_file_unsafe(name, mode, parent, (void __force *)value, + &fops_io_x64); } void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir) @@ -54,25 +54,22 @@ void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir) debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_TRACE)); } -int cxl_debugfs_adapter_add(struct cxl *adapter) +void cxl_debugfs_adapter_add(struct cxl *adapter) { struct dentry *dir; char buf[32]; if (!cxl_debugfs) - return -ENODEV; + return; snprintf(buf, 32, "card%i", adapter->adapter_num); dir = debugfs_create_dir(buf, cxl_debugfs); - if (IS_ERR(dir)) - return PTR_ERR(dir); adapter->debugfs = dir; debugfs_create_io_x64("err_ivte", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_ErrIVTE)); if (adapter->native->sl_ops->debugfs_add_adapter_regs) adapter->native->sl_ops->debugfs_add_adapter_regs(adapter, dir); - return 0; } void cxl_debugfs_adapter_remove(struct cxl *adapter) @@ -96,18 +93,16 @@ void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir) debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SLICE_TRACE)); } -int cxl_debugfs_afu_add(struct cxl_afu *afu) +void cxl_debugfs_afu_add(struct cxl_afu *afu) { struct dentry *dir; char buf[32]; if (!afu->adapter->debugfs) - return -ENODEV; + return; snprintf(buf, 32, "psl%i.%i", afu->adapter->adapter_num, afu->slice); dir = debugfs_create_dir(buf, afu->adapter->debugfs); - if (IS_ERR(dir)) - return PTR_ERR(dir); afu->debugfs = dir; debugfs_create_io_x64("sr", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SR_An)); @@ -118,8 +113,6 @@ int cxl_debugfs_afu_add(struct cxl_afu *afu) if (afu->adapter->native->sl_ops->debugfs_add_afu_regs) afu->adapter->native->sl_ops->debugfs_add_afu_regs(afu, dir); - - return 0; } void cxl_debugfs_afu_remove(struct cxl_afu *afu) @@ -127,19 +120,12 @@ void cxl_debugfs_afu_remove(struct cxl_afu *afu) debugfs_remove_recursive(afu->debugfs); } -int __init cxl_debugfs_init(void) +void __init cxl_debugfs_init(void) { - struct dentry *ent; - if (!cpu_has_feature(CPU_FTR_HVMODE)) - return 0; - - ent = debugfs_create_dir("cxl", NULL); - if (IS_ERR(ent)) - return PTR_ERR(ent); - cxl_debugfs = ent; + return; - return 0; + cxl_debugfs = debugfs_create_dir("cxl", NULL); } void cxl_debugfs_exit(void) diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index ab7f2cd21c93b3..1dc6c7c5cbce92 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -1369,10 +1369,6 @@ static int __init genwqe_init_module(void) class_genwqe->devnode = genwqe_devnode; debugfs_genwqe = debugfs_create_dir(GENWQE_DEVNAME, NULL); - if (!debugfs_genwqe) { - rc = -ENOMEM; - goto err_out; - } rc = pci_register_driver(&genwqe_driver); if (rc != 0) { @@ -1384,7 +1380,6 @@ static int __init genwqe_init_module(void) err_out0: debugfs_remove(debugfs_genwqe); - err_out: class_destroy(class_genwqe); return rc; } diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index 2f6dd2f3794243..0e902977d35fac 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -437,7 +437,7 @@ int genwqe_device_create(struct genwqe_dev *cd); int genwqe_device_remove(struct genwqe_dev *cd); /* debugfs */ -int genwqe_init_debugfs(struct genwqe_dev *cd); +void genwqe_init_debugfs(struct genwqe_dev *cd); void genqwe_exit_debugfs(struct genwqe_dev *cd); int genwqe_read_softreset(struct genwqe_dev *cd); diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c index 49c945d0c4885b..1b5b82e6526877 100644 --- a/drivers/misc/genwqe/card_debugfs.c +++ b/drivers/misc/genwqe/card_debugfs.c @@ -316,11 +316,9 @@ static int info_show(struct seq_file *s, void *unused) DEFINE_SHOW_ATTRIBUTE(info); -int genwqe_init_debugfs(struct genwqe_dev *cd) +void genwqe_init_debugfs(struct genwqe_dev *cd) { struct dentry *root; - struct dentry *file; - int ret; char card_name[64]; char name[64]; unsigned int i; @@ -328,153 +326,50 @@ int genwqe_init_debugfs(struct genwqe_dev *cd) sprintf(card_name, "%s%d_card", GENWQE_DEVNAME, cd->card_idx); root = debugfs_create_dir(card_name, cd->debugfs_genwqe); - if (!root) { - ret = -ENOMEM; - goto err0; - } /* non privileged interfaces are done here */ - file = debugfs_create_file("ddcb_info", S_IRUGO, root, cd, - &ddcb_info_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("info", S_IRUGO, root, cd, - &info_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_x64("err_inject", 0666, root, &cd->err_inject); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_u32("ddcb_software_timeout", 0666, root, - &cd->ddcb_software_timeout); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_u32("kill_timeout", 0666, root, - &cd->kill_timeout); - if (!file) { - ret = -ENOMEM; - goto err1; - } + debugfs_create_file("ddcb_info", S_IRUGO, root, cd, &ddcb_info_fops); + debugfs_create_file("info", S_IRUGO, root, cd, &info_fops); + debugfs_create_x64("err_inject", 0666, root, &cd->err_inject); + debugfs_create_u32("ddcb_software_timeout", 0666, root, + &cd->ddcb_software_timeout); + debugfs_create_u32("kill_timeout", 0666, root, &cd->kill_timeout); /* privileged interfaces follow here */ if (!genwqe_is_privileged(cd)) { cd->debugfs_root = root; - return 0; + return; } - file = debugfs_create_file("curr_regs", S_IRUGO, root, cd, - &curr_regs_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("curr_dbg_uid0", S_IRUGO, root, cd, - &curr_dbg_uid0_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("curr_dbg_uid1", S_IRUGO, root, cd, - &curr_dbg_uid1_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("curr_dbg_uid2", S_IRUGO, root, cd, - &curr_dbg_uid2_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("prev_regs", S_IRUGO, root, cd, - &prev_regs_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("prev_dbg_uid0", S_IRUGO, root, cd, - &prev_dbg_uid0_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("prev_dbg_uid1", S_IRUGO, root, cd, - &prev_dbg_uid1_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("prev_dbg_uid2", S_IRUGO, root, cd, - &prev_dbg_uid2_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } + debugfs_create_file("curr_regs", S_IRUGO, root, cd, &curr_regs_fops); + debugfs_create_file("curr_dbg_uid0", S_IRUGO, root, cd, + &curr_dbg_uid0_fops); + debugfs_create_file("curr_dbg_uid1", S_IRUGO, root, cd, + &curr_dbg_uid1_fops); + debugfs_create_file("curr_dbg_uid2", S_IRUGO, root, cd, + &curr_dbg_uid2_fops); + debugfs_create_file("prev_regs", S_IRUGO, root, cd, &prev_regs_fops); + debugfs_create_file("prev_dbg_uid0", S_IRUGO, root, cd, + &prev_dbg_uid0_fops); + debugfs_create_file("prev_dbg_uid1", S_IRUGO, root, cd, + &prev_dbg_uid1_fops); + debugfs_create_file("prev_dbg_uid2", S_IRUGO, root, cd, + &prev_dbg_uid2_fops); for (i = 0; i < GENWQE_MAX_VFS; i++) { sprintf(name, "vf%u_jobtimeout_msec", i); - - file = debugfs_create_u32(name, 0666, root, - &cd->vf_jobtimeout_msec[i]); - if (!file) { - ret = -ENOMEM; - goto err1; - } + debugfs_create_u32(name, 0666, root, + &cd->vf_jobtimeout_msec[i]); } - file = debugfs_create_file("jobtimer", S_IRUGO, root, cd, - &jtimer_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("queue_working_time", S_IRUGO, root, cd, - &queue_working_time_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_u32("skip_recovery", 0666, root, - &cd->skip_recovery); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_u32("use_platform_recovery", 0666, root, - &cd->use_platform_recovery); - if (!file) { - ret = -ENOMEM; - goto err1; - } + debugfs_create_file("jobtimer", S_IRUGO, root, cd, &jtimer_fops); + debugfs_create_file("queue_working_time", S_IRUGO, root, cd, + &queue_working_time_fops); + debugfs_create_u32("skip_recovery", 0666, root, &cd->skip_recovery); + debugfs_create_u32("use_platform_recovery", 0666, root, + &cd->use_platform_recovery); cd->debugfs_root = root; - return 0; -err1: - debugfs_remove_recursive(root); -err0: - return ret; } void genqwe_exit_debugfs(struct genwqe_dev *cd) diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 3bc51f19c73497..0e34c0568fed1a 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -1301,14 +1301,10 @@ int genwqe_device_create(struct genwqe_dev *cd) goto err_cdev; } - rc = genwqe_init_debugfs(cd); - if (rc != 0) - goto err_debugfs; + genwqe_init_debugfs(cd); return 0; - err_debugfs: - device_destroy(cd->class_genwqe, cd->devnum_genwqe); err_cdev: cdev_del(&cd->cdev_genwqe); err_add: diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index e9767bdcdb44af..66ae6b2a6950ca 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -391,7 +391,7 @@ static int __init lkdtm_module_init(void) { struct crashpoint *crashpoint = NULL; const struct crashtype *crashtype = NULL; - int ret = -EINVAL; + int ret; int i; /* Neither or both of these need to be set */ @@ -434,22 +434,13 @@ static int __init lkdtm_module_init(void) /* Register debugfs interface */ lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL); - if (!lkdtm_debugfs_root) { - pr_err("creating root dir failed\n"); - return -ENODEV; - } /* Install debugfs trigger files. */ for (i = 0; i < ARRAY_SIZE(crashpoints); i++) { struct crashpoint *cur = &crashpoints[i]; - struct dentry *de; - de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, - cur, &cur->fops); - if (de == NULL) { - pr_err("could not create crashpoint %s\n", cur->name); - goto out_err; - } + debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, cur, + &cur->fops); } /* Install crashpoint if one was selected. */ diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index 47cfd5005e1bd4..a26c716c61a121 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -154,46 +154,21 @@ void mei_dbgfs_deregister(struct mei_device *dev) * * @dev: the mei device structure * @name: the mei device name - * - * Return: 0 on success, <0 on failure. */ -int mei_dbgfs_register(struct mei_device *dev, const char *name) +void mei_dbgfs_register(struct mei_device *dev, const char *name) { - struct dentry *dir, *f; + struct dentry *dir; dir = debugfs_create_dir(name, NULL); - if (!dir) - return -ENOMEM; - dev->dbgfs_dir = dir; - f = debugfs_create_file("meclients", S_IRUSR, dir, - dev, &mei_dbgfs_meclients_fops); - if (!f) { - dev_err(dev->dev, "meclients: registration failed\n"); - goto err; - } - f = debugfs_create_file("active", S_IRUSR, dir, - dev, &mei_dbgfs_active_fops); - if (!f) { - dev_err(dev->dev, "active: registration failed\n"); - goto err; - } - f = debugfs_create_file("devstate", S_IRUSR, dir, - dev, &mei_dbgfs_devstate_fops); - if (!f) { - dev_err(dev->dev, "devstate: registration failed\n"); - goto err; - } - f = debugfs_create_file("allow_fixed_address", S_IRUSR | S_IWUSR, dir, - &dev->allow_fixed_address, - &mei_dbgfs_allow_fa_fops); - if (!f) { - dev_err(dev->dev, "allow_fixed_address: registration failed\n"); - goto err; - } - return 0; -err: - mei_dbgfs_deregister(dev); - return -ENODEV; + debugfs_create_file("meclients", S_IRUSR, dir, dev, + &mei_dbgfs_meclients_fops); + debugfs_create_file("active", S_IRUSR, dir, dev, + &mei_dbgfs_active_fops); + debugfs_create_file("devstate", S_IRUSR, dir, dev, + &mei_dbgfs_devstate_fops); + debugfs_create_file("allow_fixed_address", S_IRUSR | S_IWUSR, dir, + &dev->allow_fixed_address, + &mei_dbgfs_allow_fa_fops); } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index ad02097d7fee56..f894d1f8a53e0e 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -984,16 +984,10 @@ int mei_register(struct mei_device *dev, struct device *parent) goto err_dev_create; } - ret = mei_dbgfs_register(dev, dev_name(clsdev)); - if (ret) { - dev_err(clsdev, "cannot register debugfs ret = %d\n", ret); - goto err_dev_dbgfs; - } + mei_dbgfs_register(dev, dev_name(clsdev)); return 0; -err_dev_dbgfs: - device_destroy(mei_class, devno); err_dev_create: cdev_del(&dev->cdev); err_dev_add: diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index fca832fcac57f0..f71a023aed3c91 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -718,13 +718,10 @@ bool mei_hbuf_acquire(struct mei_device *dev); bool mei_write_is_idle(struct mei_device *dev); #if IS_ENABLED(CONFIG_DEBUG_FS) -int mei_dbgfs_register(struct mei_device *dev, const char *name); +void mei_dbgfs_register(struct mei_device *dev, const char *name); void mei_dbgfs_deregister(struct mei_device *dev); #else -static inline int mei_dbgfs_register(struct mei_device *dev, const char *name) -{ - return 0; -} +static inline void mei_dbgfs_register(struct mei_device *dev, const char *name) {} static inline void mei_dbgfs_deregister(struct mei_device *dev) {} #endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/misc/mic/card/mic_debugfs.c b/drivers/misc/mic/card/mic_debugfs.c index bf7a60ccc66cc8..3ee3d24026340b 100644 --- a/drivers/misc/mic/card/mic_debugfs.c +++ b/drivers/misc/mic/card/mic_debugfs.c @@ -51,25 +51,13 @@ DEFINE_SHOW_ATTRIBUTE(mic_intr); */ void __init mic_create_card_debug_dir(struct mic_driver *mdrv) { - struct dentry *d; - if (!mic_dbg) return; mdrv->dbg_dir = debugfs_create_dir(mdrv->name, mic_dbg); - if (!mdrv->dbg_dir) { - dev_err(mdrv->dev, "Cant create dbg_dir %s\n", mdrv->name); - return; - } - - d = debugfs_create_file("intr_test", 0444, mdrv->dbg_dir, - mdrv, &mic_intr_fops); - if (!d) { - dev_err(mdrv->dev, - "Cant create dbg intr_test %s\n", mdrv->name); - return; - } + debugfs_create_file("intr_test", 0444, mdrv->dbg_dir, mdrv, + &mic_intr_fops); } /** @@ -89,8 +77,6 @@ void mic_delete_card_debug_dir(struct mic_driver *mdrv) void __init mic_init_card_debugfs(void) { mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!mic_dbg) - pr_err("can't create debugfs dir\n"); } /** diff --git a/drivers/misc/mic/cosm/cosm_debugfs.c b/drivers/misc/mic/cosm/cosm_debugfs.c index 8e3f4589f16d47..2fc9f4bf700149 100644 --- a/drivers/misc/mic/cosm/cosm_debugfs.c +++ b/drivers/misc/mic/cosm/cosm_debugfs.c @@ -93,8 +93,6 @@ void cosm_create_debug_dir(struct cosm_device *cdev) scnprintf(name, sizeof(name), "mic%d", cdev->index); cdev->dbg_dir = debugfs_create_dir(name, cosm_dbg); - if (!cdev->dbg_dir) - return; debugfs_create_file("log_buf", 0444, cdev->dbg_dir, cdev, &log_buf_fops); @@ -113,8 +111,6 @@ void cosm_delete_debug_dir(struct cosm_device *cdev) void cosm_init_debugfs(void) { cosm_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!cosm_dbg) - pr_err("can't create debugfs dir\n"); } void cosm_exit_debugfs(void) diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c index 7ef8efe9552fc3..8a8e4167750174 100644 --- a/drivers/misc/mic/host/mic_debugfs.c +++ b/drivers/misc/mic/host/mic_debugfs.c @@ -113,8 +113,6 @@ void mic_create_debug_dir(struct mic_device *mdev) scnprintf(name, sizeof(name), "mic%d", mdev->id); mdev->dbg_dir = debugfs_create_dir(name, mic_dbg); - if (!mdev->dbg_dir) - return; debugfs_create_file("smpt", 0444, mdev->dbg_dir, mdev, &mic_smpt_fops); @@ -143,8 +141,6 @@ void mic_delete_debug_dir(struct mic_device *mdev) void __init mic_init_debugfs(void) { mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!mic_dbg) - pr_err("can't create debugfs dir\n"); } /** diff --git a/drivers/misc/mic/scif/scif_debugfs.c b/drivers/misc/mic/scif/scif_debugfs.c index a6820480105a8e..8fe38e7ca6e6d3 100644 --- a/drivers/misc/mic/scif/scif_debugfs.c +++ b/drivers/misc/mic/scif/scif_debugfs.c @@ -103,11 +103,6 @@ DEFINE_SHOW_ATTRIBUTE(scif_rma); void __init scif_init_debugfs(void) { scif_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!scif_dbg) { - dev_err(scif_info.mdev.this_device, - "can't create debugfs dir scif\n"); - return; - } debugfs_create_file("scif_dev", 0444, scif_dbg, NULL, &scif_dev_fops); debugfs_create_file("scif_rma", 0444, scif_dbg, NULL, &scif_rma_fops); diff --git a/drivers/misc/mic/vop/vop_debugfs.c b/drivers/misc/mic/vop/vop_debugfs.c index ed59cd75e182a1..9d4f175f4dd113 100644 --- a/drivers/misc/mic/vop/vop_debugfs.c +++ b/drivers/misc/mic/vop/vop_debugfs.c @@ -174,10 +174,6 @@ void vop_init_debugfs(struct vop_info *vi) snprintf(name, sizeof(name), "%s%d", KBUILD_MODNAME, vi->vpdev->dnode); vi->dbg = debugfs_create_dir(name, NULL); - if (!vi->dbg) { - pr_err("can't create debugfs dir vop\n"); - return; - } debugfs_create_file("dp", 0444, vi->dbg, vi, &vop_dp_fops); debugfs_create_file("vdev_info", 0444, vi->dbg, vi, &vop_vdev_info_fops); } diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 18ca938b86e6d7..a36ed1ff5967f0 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -748,10 +748,6 @@ static int kim_probe(struct platform_device *pdev) pr_info("sysfs entries created\n"); kim_debugfs_dir = debugfs_create_dir("ti-st", NULL); - if (!kim_debugfs_dir) { - pr_err(" debugfs entries creation failed "); - return 0; - } debugfs_create_file("version", S_IRUGO, kim_debugfs_dir, kim_gdata, &version_fops); diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 043eed845246ef..97b58e7ad901ad 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -1699,19 +1699,10 @@ static int vmballoon_debug_show(struct seq_file *f, void *offset) DEFINE_SHOW_ATTRIBUTE(vmballoon_debug); -static int __init vmballoon_debugfs_init(struct vmballoon *b) +static void __init vmballoon_debugfs_init(struct vmballoon *b) { - int error; - b->dbg_entry = debugfs_create_file("vmmemctl", S_IRUGO, NULL, b, &vmballoon_debug_fops); - if (IS_ERR(b->dbg_entry)) { - error = PTR_ERR(b->dbg_entry); - pr_err("failed to create debugfs entry, error: %d\n", error); - return error; - } - - return 0; } static void __exit vmballoon_debugfs_exit(struct vmballoon *b) @@ -1724,9 +1715,8 @@ static void __exit vmballoon_debugfs_exit(struct vmballoon *b) #else -static inline int vmballoon_debugfs_init(struct vmballoon *b) +static inline void vmballoon_debugfs_init(struct vmballoon *b) { - return 0; } static inline void vmballoon_debugfs_exit(struct vmballoon *b) @@ -1948,10 +1938,6 @@ static int __init vmballoon_init(void) if (error) goto fail; - error = vmballoon_debugfs_init(&balloon); - if (error) - goto fail; - /* * Initialization of compaction must be done after the call to * balloon_devinfo_init() . @@ -1971,6 +1957,8 @@ static int __init vmballoon_init(void) queue_delayed_work(system_freezable_wq, &balloon.dwork, 0); + vmballoon_debugfs_init(&balloon); + return 0; fail: vmballoon_unregister_shrinker(&balloon); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c index 09c16d88172e1d..bb6586d0e5af66 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c @@ -754,7 +754,7 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev) return (void *)misc_op; } -static int hns_dsaf_dev_match(struct device *dev, void *fwnode) +static int hns_dsaf_dev_match(struct device *dev, const void *fwnode) { return dev->fwnode == fwnode; } diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 28ec0d57941d4b..41c90f2ddb31d6 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -2286,7 +2286,7 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) struct ice_hw *hw; int err; - /* this driver uses devres, see Documentation/driver-model/devres.txt */ + /* this driver uses devres, see Documentation/driver-model/devres.rst */ err = pcim_enable_device(pdev); if (err) return err; diff --git a/drivers/net/ethernet/ti/cpsw-phy-sel.c b/drivers/net/ethernet/ti/cpsw-phy-sel.c index 48e0924259f541..4e184eecc8e180 100644 --- a/drivers/net/ethernet/ti/cpsw-phy-sel.c +++ b/drivers/net/ethernet/ti/cpsw-phy-sel.c @@ -151,9 +151,9 @@ static void cpsw_gmii_sel_dra7xx(struct cpsw_phy_sel_priv *priv, } static struct platform_driver cpsw_phy_sel_driver; -static int match(struct device *dev, void *data) +static int match(struct device *dev, const void *data) { - struct device_node *node = (struct device_node *)data; + const struct device_node *node = (const struct device_node *)data; return dev->of_node == node && dev->driver == &cpsw_phy_sel_driver.driver; } diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 5f4ece0d5a7335..ae27be85e3635a 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1371,7 +1371,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) return -EOPNOTSUPP; } -static int match_first_device(struct device *dev, void *data) +static int match_first_device(struct device *dev, const void *data) { if (dev->parent && dev->parent->of_node) return of_device_is_compatible(dev->parent->of_node, diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c index c50a9772f4affb..8479a440527b89 100644 --- a/drivers/net/ethernet/toshiba/tc35815.c +++ b/drivers/net/ethernet/toshiba/tc35815.c @@ -694,10 +694,10 @@ static int tc_mii_init(struct net_device *dev) * should provide a "tc35815-mac" device with a MAC address in its * platform_data. */ -static int tc35815_mac_match(struct device *dev, void *data) +static int tc35815_mac_match(struct device *dev, const void *data) { struct platform_device *plat_dev = to_platform_device(dev); - struct pci_dev *pci_dev = data; + const struct pci_dev *pci_dev = data; unsigned int id = pci_dev->irq; return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id; } diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index c7892c3da91f8f..ac5d945be88a8e 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -76,7 +76,7 @@ static struct bus_type nvmem_bus_type = { .name = "nvmem", }; -static int of_nvmem_match(struct device *dev, void *nvmem_np) +static int of_nvmem_match(struct device *dev, const void *nvmem_np) { return dev->of_node == nvmem_np; } diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 3b67896d9d7487..44f53496cab1be 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -281,7 +281,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) EXPORT_SYMBOL(of_mdiobus_register); /* Helper function for of_phy_find_device */ -static int of_phy_match(struct device *dev, void *phy_np) +static int of_phy_match(struct device *dev, const void *phy_np) { return dev->of_node == phy_np; } diff --git a/drivers/of/platform.c b/drivers/of/platform.c index efbff44581b3ee..7801e25e68954e 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -37,7 +37,7 @@ static const struct of_device_id of_skipped_node_table[] = { {} /* Empty terminated list */ }; -static int of_dev_node_match(struct device *dev, void *data) +static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 0e8e2c186f508d..f9ef7ad3f75d2e 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -64,7 +64,7 @@ static struct resource *get_pci_domain_busn_res(int domain_nr) return &r->res; } -static int find_anything(struct device *dev, void *data) +static int find_anything(struct device *dev, const void *data) { return 1; } diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 5c7922612733ec..7f4e65872b8daf 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -236,10 +236,10 @@ struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, } EXPORT_SYMBOL(pci_get_domain_bus_and_slot); -static int match_pci_dev_by_id(struct device *dev, void *data) +static int match_pci_dev_by_id(struct device *dev, const void *data) { struct pci_dev *pdev = to_pci_dev(dev); - struct pci_device_id *id = data; + const struct pci_device_id *id = data; if (pci_match_one_device(id, pdev)) return 1; diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index f7e354f8551815..88ddbb2e30de10 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -112,12 +112,11 @@ static int dt_to_map_one_config(struct pinctrl *p, np_pctldev = of_get_next_parent(np_pctldev); if (!np_pctldev || of_node_is_root(np_pctldev)) { of_node_put(np_pctldev); - ret = driver_deferred_probe_check_state(p->dev); /* keep deferring if modules are enabled unless we've timed out */ - if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret == -ENODEV) - ret = -EPROBE_DEFER; + if (IS_ENABLED(CONFIG_MODULES) && !allow_default) + return driver_deferred_probe_check_state_continue(p->dev); - return ret; + return driver_deferred_probe_check_state(p->dev); } /* If we're creating a hog we can use the passed pctldev */ if (hog_pctldev && (np_pctldev == p->dev->of_node)) { diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 4ebf6d4fc66cbe..c522e9313c502d 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -581,7 +581,7 @@ int ccwgroup_driver_register(struct ccwgroup_driver *cdriver) } EXPORT_SYMBOL(ccwgroup_driver_register); -static int __ccwgroup_match_all(struct device *dev, void *data) +static int __ccwgroup_match_all(struct device *dev, const void *data) { return 1; } @@ -608,9 +608,9 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) } EXPORT_SYMBOL(ccwgroup_driver_unregister); -static int __ccwgroupdev_check_busid(struct device *dev, void *id) +static int __ccwgroupdev_check_busid(struct device *dev, const void *id) { - char *bus_id = id; + const char *bus_id = id; return (strcmp(bus_id, dev_name(dev)) == 0); } diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 8d9f36625ba5eb..8f080d3fd38054 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -203,7 +203,7 @@ static void chsc_cleanup_sch_driver(void) static DEFINE_SPINLOCK(chsc_lock); -static int chsc_subchannel_match_next_free(struct device *dev, void *data) +static int chsc_subchannel_match_next_free(struct device *dev, const void *data) { struct subchannel *sch = to_subchannel(dev); diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index e1f2d0eed544c0..22c55816100be4 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -491,10 +491,10 @@ static int css_probe_device(struct subchannel_id schid, struct schib *schib) } static int -check_subchannel(struct device * dev, void * data) +check_subchannel(struct device *dev, const void *data) { struct subchannel *sch; - struct subchannel_id *schid = data; + struct subchannel_id *schid = (void *)data; sch = to_subchannel(dev); return schid_equal(&sch->schid, schid); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 9985b7484a6b75..c421899be20f27 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -643,10 +643,10 @@ static int ccw_device_add(struct ccw_device *cdev) return device_add(dev); } -static int match_dev_id(struct device *dev, void *data) +static int match_dev_id(struct device *dev, const void *data) { struct ccw_device *cdev = to_ccwdev(dev); - struct ccw_dev_id *dev_id = data; + struct ccw_dev_id *dev_id = (void *)data; return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); } @@ -1699,11 +1699,9 @@ EXPORT_SYMBOL_GPL(ccw_device_force_console); * get ccw_device matching the busid, but only if owned by cdrv */ static int -__ccwdev_check_busid(struct device *dev, void *id) +__ccwdev_check_busid(struct device *dev, const void *id) { - char *bus_id; - - bus_id = id; + const char *bus_id = id; return (strcmp(bus_id, dev_name(dev)) == 0); } diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index 6bca1d5455d4f6..9f26d4310bb346 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c @@ -174,10 +174,10 @@ static void scmdev_update(struct scm_device *scmdev, struct sale *sale) kobject_uevent(&scmdev->dev.kobj, KOBJ_CHANGE); } -static int check_address(struct device *dev, void *data) +static int check_address(struct device *dev, const void *data) { struct scm_device *scmdev = to_scm_dev(dev); - struct sale *sale = data; + const struct sale *sale = data; return scmdev->address == sale->sa; } diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index b9fc502c58c24a..b7902b643ec839 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1356,16 +1356,16 @@ static int ap_get_compatible_type(ap_qid_t qid, int rawtype, unsigned int func) * Helper function to be used with bus_find_dev * matches for the card device with the given id */ -static int __match_card_device_with_id(struct device *dev, void *data) +static int __match_card_device_with_id(struct device *dev, const void *data) { - return is_card_dev(dev) && to_ap_card(dev)->id == (int)(long) data; + return is_card_dev(dev) && to_ap_card(dev)->id == (int)(long)(void *) data; } /* * Helper function to be used with bus_find_dev * matches for the queue device with a given qid */ -static int __match_queue_device_with_qid(struct device *dev, void *data) +static int __match_queue_device_with_qid(struct device *dev, const void *data) { return is_queue_dev(dev) && to_ap_queue(dev)->qid == (int)(long) data; } @@ -1374,7 +1374,7 @@ static int __match_queue_device_with_qid(struct device *dev, void *data) * Helper function to be used with bus_find_dev * matches any queue device with given queue id */ -static int __match_queue_device_with_queue_id(struct device *dev, void *data) +static int __match_queue_device_with_queue_id(struct device *dev, const void *data) { return is_queue_dev(dev) && AP_QID_QUEUE(to_ap_queue(dev)->qid) == (int)(long) data; diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 2c9fb1423a3956..7e85ba7c6ef017 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -26,7 +26,7 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev); -static int match_apqn(struct device *dev, void *data) +static int match_apqn(struct device *dev, const void *data) { struct vfio_ap_queue *q = dev_get_drvdata(dev); diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index 7f0ceb65c3f39d..c074631086a4db 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -372,7 +372,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, return err; } -static int always_match(struct device *dev, void *data) +static int always_match(struct device *dev, const void *data) { return 1; } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 91673351bcf396..75ac046cae5267 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3652,7 +3652,7 @@ EXPORT_SYMBOL_GPL(spi_write_then_read); /*-------------------------------------------------------------------------*/ #if IS_ENABLED(CONFIG_OF) -static int __spi_of_device_match(struct device *dev, void *data) +static int __spi_of_device_match(struct device *dev, const void *data) { return dev->of_node == data; } @@ -3753,7 +3753,7 @@ static int spi_acpi_controller_match(struct device *dev, const void *data) return ACPI_COMPANION(dev->parent) == data; } -static int spi_acpi_device_match(struct device *dev, void *data) +static int spi_acpi_device_match(struct device *dev, const void *data) { return ACPI_COMPANION(dev) == data; } diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c index 86a8545c8d9740..b9841adb7181bf 100644 --- a/drivers/staging/most/core.c +++ b/drivers/staging/most/core.c @@ -561,13 +561,6 @@ static int split_string(char *buf, char **a, char **b, char **c, char **d) return 0; } -static int match_bus_dev(struct device *dev, void *data) -{ - char *mdev_name = data; - - return !strcmp(dev_name(dev), mdev_name); -} - /** * get_channel - get pointer to channel * @mdev: name of the device interface @@ -579,7 +572,7 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch) struct most_interface *iface; struct most_channel *c, *tmp; - dev = bus_find_device(&mc.bus, NULL, mdev, match_bus_dev); + dev = bus_find_device_by_name(&mc.bus, NULL, mdev); if (!dev) return NULL; iface = to_most_interface(dev); diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index ba39647a690c3e..3199977f1e7355 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -123,8 +123,6 @@ static void bcm2835_thermal_debugfs(struct platform_device *pdev) struct debugfs_regset32 *regset; data->debugfsdir = debugfs_create_dir("bcm2835_thermal", NULL); - if (!data->debugfsdir) - return; regset = devm_kzalloc(&pdev->dev, sizeof(*regset), GFP_KERNEL); if (!regset) diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c index 79d214b7291c78..5149a817456b77 100644 --- a/drivers/thermal/intel/intel_powerclamp.c +++ b/drivers/thermal/intel/intel_powerclamp.c @@ -698,17 +698,9 @@ DEFINE_SHOW_ATTRIBUTE(powerclamp_debug); static inline void powerclamp_create_debug_files(void) { debug_dir = debugfs_create_dir("intel_powerclamp", NULL); - if (!debug_dir) - return; - - if (!debugfs_create_file("powerclamp_calib", S_IRUGO, debug_dir, - cal_data, &powerclamp_debug_fops)) - goto file_error; - return; - -file_error: - debugfs_remove_recursive(debug_dir); + debugfs_create_file("powerclamp_calib", S_IRUGO, debug_dir, cal_data, + &powerclamp_debug_fops); } static enum cpuhp_state hp_state; diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index e85d54d1cdf398..ddb4a973c69860 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -75,29 +75,14 @@ static struct dentry *debugfs; static unsigned int pkg_interrupt_cnt; static unsigned int pkg_work_cnt; -static int pkg_temp_debugfs_init(void) +static void pkg_temp_debugfs_init(void) { - struct dentry *d; - debugfs = debugfs_create_dir("pkg_temp_thermal", NULL); - if (!debugfs) - return -ENOENT; - - d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs, - &pkg_interrupt_cnt); - if (!d) - goto err_out; - - d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs, - &pkg_work_cnt); - if (!d) - goto err_out; - return 0; - -err_out: - debugfs_remove_recursive(debugfs); - return -ENOENT; + debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs, + &pkg_interrupt_cnt); + debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs, + &pkg_work_cnt); } /* diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index fcf70a3728b604..43941eb734eb09 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -1485,23 +1485,13 @@ DEFINE_SHOW_ATTRIBUTE(regs); static void soctherm_debug_init(struct platform_device *pdev) { struct tegra_soctherm *tegra = platform_get_drvdata(pdev); - struct dentry *root, *file; + struct dentry *root; root = debugfs_create_dir("soctherm", NULL); - if (!root) { - dev_err(&pdev->dev, "failed to create debugfs directory\n"); - return; - } tegra->debugfs_dir = root; - file = debugfs_create_file("reg_contents", 0644, root, - pdev, ®s_fops); - if (!file) { - dev_err(&pdev->dev, "failed to create debugfs file\n"); - debugfs_remove_recursive(tegra->debugfs_dir); - tegra->debugfs_dir = NULL; - } + debugfs_create_file("reg_contents", 0644, root, pdev, ®s_fops); } #else static inline void soctherm_debug_init(struct platform_device *pdev) {} diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 10b56c66fec34c..5668a44e0653b2 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1967,10 +1967,10 @@ struct tb_sw_lookup { u64 route; }; -static int tb_switch_match(struct device *dev, void *data) +static int tb_switch_match(struct device *dev, const void *data) { struct tb_switch *sw = tb_to_switch(dev); - struct tb_sw_lookup *lookup = data; + const struct tb_sw_lookup *lookup = data; if (!sw) return 0; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e2f316ac8b019a..b265ab5405f9ae 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -942,9 +942,9 @@ static int parse_usbdevfs_streams(struct usb_dev_state *ps, return ret; } -static int match_devt(struct device *dev, void *data) +static int match_devt(struct device *dev, const void *data) { - return dev->devt == (dev_t) (unsigned long) data; + return dev->devt == (dev_t)(unsigned long)(void *)data; } static struct usb_device *usbdev_lookup_by_devt(dev_t devt) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 5a0df527a8ca22..0ab8738047da69 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -325,9 +325,9 @@ struct find_interface_arg { struct device_driver *drv; }; -static int __find_interface(struct device *dev, void *data) +static int __find_interface(struct device *dev, const void *data) { - struct find_interface_arg *arg = data; + const struct find_interface_arg *arg = data; struct usb_interface *intf; if (!is_usb_interface(dev)) diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index a3cb25cb74f833..d16dfc320faa89 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -118,9 +118,9 @@ static const struct of_device_id omap_control_usb_id_table[] = { MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); static struct platform_driver am335x_control_driver; -static int match(struct device *dev, void *data) +static int match(struct device *dev, const void *data) { - struct device_node *node = (struct device_node *)data; + const struct device_node *node = (const struct device_node *)data; return dev->of_node == node && dev->driver == &am335x_control_driver.driver; } diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index 93b7d6a30aad4c..6cf6fbd3923763 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c @@ -142,9 +142,9 @@ static struct i2c_driver isp1301_driver = { module_i2c_driver(isp1301_driver); -static int match(struct device *dev, void *data) +static int match(struct device *dev, const void *data) { - struct device_node *node = (struct device_node *)data; + const struct device_node *node = (const struct device_node *)data; return (dev->of_node == node) && (dev->driver == &isp1301_driver.driver); } diff --git a/drivers/visorbus/visorbus_main.c b/drivers/visorbus/visorbus_main.c index 0b2434cc4ecd4d..152fd29f04f295 100644 --- a/drivers/visorbus/visorbus_main.c +++ b/drivers/visorbus/visorbus_main.c @@ -171,10 +171,10 @@ struct visor_busdev { u32 dev_no; }; -static int match_visorbus_dev_by_id(struct device *dev, void *data) +static int match_visorbus_dev_by_id(struct device *dev, const void *data) { struct visor_device *vdev = to_visor_device(dev); - struct visor_busdev *id = data; + const struct visor_busdev *id = data; if (vdev->chipset_bus_no == id->bus_no && vdev->chipset_dev_no == id->dev_no) diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index e2ad4481635996..921291025680e3 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c @@ -143,24 +143,18 @@ static void bcm_kona_wdt_debug_init(struct platform_device *pdev) wdt->debugfs = NULL; dir = debugfs_create_dir(BCM_KONA_WDT_NAME, NULL); - if (IS_ERR_OR_NULL(dir)) - return; - if (debugfs_create_file("info", S_IFREG | S_IRUGO, dir, wdt, - &bcm_kona_fops)) - wdt->debugfs = dir; - else - debugfs_remove_recursive(dir); + debugfs_create_file("info", S_IFREG | S_IRUGO, dir, wdt, + &bcm_kona_fops); + wdt->debugfs = dir; } static void bcm_kona_wdt_debug_exit(struct platform_device *pdev) { struct bcm_kona_wdt *wdt = platform_get_drvdata(pdev); - if (wdt && wdt->debugfs) { + if (wdt) debugfs_remove_recursive(wdt->debugfs); - wdt->debugfs = NULL; - } } #else diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c index 8023cf28657abf..96a770938ff0a0 100644 --- a/drivers/watchdog/mei_wdt.c +++ b/drivers/watchdog/mei_wdt.c @@ -539,38 +539,23 @@ static void dbgfs_unregister(struct mei_wdt *wdt) wdt->dbgfs_dir = NULL; } -static int dbgfs_register(struct mei_wdt *wdt) +static void dbgfs_register(struct mei_wdt *wdt) { - struct dentry *dir, *f; + struct dentry *dir; dir = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!dir) - return -ENOMEM; - wdt->dbgfs_dir = dir; - f = debugfs_create_file("state", S_IRUSR, dir, wdt, &dbgfs_fops_state); - if (!f) - goto err; - f = debugfs_create_file("activation", S_IRUSR, - dir, wdt, &dbgfs_fops_activation); - if (!f) - goto err; + debugfs_create_file("state", S_IRUSR, dir, wdt, &dbgfs_fops_state); - return 0; -err: - dbgfs_unregister(wdt); - return -ENODEV; + debugfs_create_file("activation", S_IRUSR, dir, wdt, + &dbgfs_fops_activation); } #else static inline void dbgfs_unregister(struct mei_wdt *wdt) {} - -static inline int dbgfs_register(struct mei_wdt *wdt) -{ - return 0; -} +static inline void dbgfs_register(struct mei_wdt *wdt) {} #endif /* CONFIG_DEBUG_FS */ static int mei_wdt_probe(struct mei_cl_device *cldev, @@ -623,8 +608,7 @@ static int mei_wdt_probe(struct mei_cl_device *cldev, if (ret) goto err_disable; - if (dbgfs_register(wdt)) - dev_warn(&cldev->dev, "cannot register debugfs\n"); + dbgfs_register(wdt); return 0; diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 2f078b77fe1459..c1dfc97893ba59 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -303,11 +303,12 @@ static ssize_t raid_bytes_show(struct kobject *kobj, return snprintf(buf, PAGE_SIZE, "%llu\n", val); } -static struct attribute *raid_attributes[] = { +static struct attribute *raid_attrs[] = { BTRFS_ATTR_PTR(raid, total_bytes), BTRFS_ATTR_PTR(raid, used_bytes), NULL }; +ATTRIBUTE_GROUPS(raid); static void release_raid_kobj(struct kobject *kobj) { @@ -317,7 +318,7 @@ static void release_raid_kobj(struct kobject *kobj) struct kobj_type btrfs_raid_ktype = { .sysfs_ops = &kobj_sysfs_ops, .release = release_raid_kobj, - .default_attrs = raid_attributes, + .default_groups = raid_groups, }; #define SPACE_INFO_ATTR(field) \ @@ -364,6 +365,7 @@ static struct attribute *space_info_attrs[] = { BTRFS_ATTR_PTR(space_info, total_bytes_pinned), NULL, }; +ATTRIBUTE_GROUPS(space_info); static void space_info_release(struct kobject *kobj) { @@ -375,7 +377,7 @@ static void space_info_release(struct kobject *kobj) struct kobj_type space_info_ktype = { .sysfs_ops = &kobj_sysfs_ops, .release = space_info_release, - .default_attrs = space_info_attrs, + .default_groups = space_info_groups, }; static const struct attribute *allocation_attrs[] = { @@ -910,12 +912,10 @@ void btrfs_sysfs_feature_update(struct btrfs_fs_info *fs_info, ret = sysfs_create_group(fsid_kobj, &btrfs_feature_attr_group); } -static int btrfs_init_debugfs(void) +static void btrfs_init_debugfs(void) { #ifdef CONFIG_DEBUG_FS btrfs_debugfs_root_dentry = debugfs_create_dir("btrfs", NULL); - if (!btrfs_debugfs_root_dentry) - return -ENOMEM; /* * Example code, how to export data through debugfs. @@ -929,7 +929,6 @@ static int btrfs_init_debugfs(void) #endif #endif - return 0; } int __init btrfs_init_sysfs(void) @@ -940,9 +939,7 @@ int __init btrfs_init_sysfs(void) if (!btrfs_kset) return -ENOMEM; - ret = btrfs_init_debugfs(); - if (ret) - goto out1; + btrfs_init_debugfs(); init_feature_attrs(); ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_feature_attr_group); @@ -959,7 +956,6 @@ int __init btrfs_init_sysfs(void) sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group); out2: debugfs_remove_recursive(btrfs_debugfs_root_dentry); -out1: kset_unregister(btrfs_kset); return ret; diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index b3fc5fe26a1ab4..83cd41fa2b01ad 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -245,21 +245,17 @@ void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc) debugfs_remove(fsc->debugfs_mdsc); } -int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) +void ceph_fs_debugfs_init(struct ceph_fs_client *fsc) { char name[100]; - int err = -ENOMEM; dout("ceph_fs_debugfs_init\n"); - BUG_ON(!fsc->client->debugfs_dir); fsc->debugfs_congestion_kb = debugfs_create_file("writeback_congestion_kb", 0600, fsc->client->debugfs_dir, fsc, &congestion_kb_fops); - if (!fsc->debugfs_congestion_kb) - goto out; snprintf(name, sizeof(name), "../../bdi/%s", dev_name(fsc->sb->s_bdi->dev)); @@ -267,52 +263,36 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) debugfs_create_symlink("bdi", fsc->client->debugfs_dir, name); - if (!fsc->debugfs_bdi) - goto out; fsc->debugfs_mdsmap = debugfs_create_file("mdsmap", 0400, fsc->client->debugfs_dir, fsc, &mdsmap_show_fops); - if (!fsc->debugfs_mdsmap) - goto out; fsc->debugfs_mds_sessions = debugfs_create_file("mds_sessions", 0400, fsc->client->debugfs_dir, fsc, &mds_sessions_show_fops); - if (!fsc->debugfs_mds_sessions) - goto out; fsc->debugfs_mdsc = debugfs_create_file("mdsc", 0400, fsc->client->debugfs_dir, fsc, &mdsc_show_fops); - if (!fsc->debugfs_mdsc) - goto out; fsc->debugfs_caps = debugfs_create_file("caps", 0400, fsc->client->debugfs_dir, fsc, &caps_show_fops); - if (!fsc->debugfs_caps) - goto out; - - return 0; - -out: - ceph_fs_debugfs_cleanup(fsc); - return err; } #else /* CONFIG_DEBUG_FS */ -int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) +void ceph_fs_debugfs_init(struct ceph_fs_client *fsc) { return 0; } diff --git a/fs/ceph/super.c b/fs/ceph/super.c index d57fa60dcd4360..ed1b65a6c2c3d0 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -937,9 +937,7 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) dout("mount opening path %s\n", path); } - err = ceph_fs_debugfs_init(fsc); - if (err < 0) - goto out; + ceph_fs_debugfs_init(fsc); root = open_root_dentry(fsc, path, started); if (IS_ERR(root)) { diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 5f27e1f7f2d65a..fbe6869a3f9591 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -1102,7 +1102,7 @@ extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks, int num_fcntl_locks, int num_flock_locks); /* debugfs.c */ -extern int ceph_fs_debugfs_init(struct ceph_fs_client *client); +extern void ceph_fs_debugfs_init(struct ceph_fs_client *client); extern void ceph_fs_debugfs_cleanup(struct ceph_fs_client *client); /* quota.c */ diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index ddd708b09fa197..93e4ca6b2ad7a9 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -997,25 +997,19 @@ static const struct file_operations u32_array_fops = { * @array as data. If the @mode variable is so set it can be read from. * Writing is not supported. Seek within the file is also not supported. * Once array is created its size can not be changed. - * - * The function returns a pointer to dentry on success. If an error occurs, - * %ERR_PTR(-ERROR) or NULL will be returned. If debugfs is not enabled in - * the kernel, the value %ERR_PTR(-ENODEV) will be returned. */ -struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, - struct dentry *parent, - u32 *array, u32 elements) +void debugfs_create_u32_array(const char *name, umode_t mode, + struct dentry *parent, u32 *array, u32 elements) { struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) - return NULL; + return; data->array = array; data->elements = elements; - return debugfs_create_file_unsafe(name, mode, parent, data, - &u32_array_fops); + debugfs_create_file_unsafe(name, mode, parent, data, &u32_array_fops); } EXPORT_SYMBOL_GPL(debugfs_create_u32_array); diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 1e444fe1f778b1..042b688ed124a9 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -2,13 +2,16 @@ /* * inode.c - part of debugfs, a tiny little debug file system * - * Copyright (C) 2004 Greg Kroah-Hartman + * Copyright (C) 2004,2019 Greg Kroah-Hartman * Copyright (C) 2004 IBM Inc. + * Copyright (C) 2019 Linux Foundation * * debugfs is for people to use instead of /proc or /sys. * See ./Documentation/core-api/kernel-api.rst for more details. */ +#define pr_fmt(fmt) "debugfs: " fmt + #include #include #include @@ -285,15 +288,17 @@ static struct dentry *start_creating(const char *name, struct dentry *parent) struct dentry *dentry; int error; - pr_debug("debugfs: creating file '%s'\n",name); + pr_debug("creating file '%s'\n", name); if (IS_ERR(parent)) return parent; error = simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count); - if (error) + if (error) { + pr_err("Unable to pin filesystem for file '%s'\n", name); return ERR_PTR(error); + } /* If the parent is not specified, we create it in the root. * We need the root dentry to do this, which is in the super @@ -306,6 +311,12 @@ static struct dentry *start_creating(const char *name, struct dentry *parent) inode_lock(d_inode(parent)); dentry = lookup_one_len(name, parent, strlen(name)); if (!IS_ERR(dentry) && d_really_is_positive(dentry)) { + if (d_is_dir(dentry)) + pr_err("Directory '%s' with parent '%s' already present!\n", + name, parent->d_name.name); + else + pr_err("File '%s' in directory '%s' already present!\n", + name, parent->d_name.name); dput(dentry); dentry = ERR_PTR(-EEXIST); } @@ -349,8 +360,11 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, return dentry; inode = debugfs_get_inode(dentry->d_sb); - if (unlikely(!inode)) + if (unlikely(!inode)) { + pr_err("out of free dentries, can not create file '%s'\n", + name); return failed_creating(dentry); + } inode->i_mode = mode; inode->i_private = data; @@ -511,8 +525,11 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) return dentry; inode = debugfs_get_inode(dentry->d_sb); - if (unlikely(!inode)) + if (unlikely(!inode)) { + pr_err("out of free dentries, can not create directory '%s'\n", + name); return failed_creating(dentry); + } inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; inode->i_op = &simple_dir_inode_operations; @@ -550,8 +567,11 @@ struct dentry *debugfs_create_automount(const char *name, return dentry; inode = debugfs_get_inode(dentry->d_sb); - if (unlikely(!inode)) + if (unlikely(!inode)) { + pr_err("out of free dentries, can not create automount '%s'\n", + name); return failed_creating(dentry); + } make_empty_dir_inode(inode); inode->i_flags |= S_AUTOMOUNT; @@ -606,6 +626,8 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, inode = debugfs_get_inode(dentry->d_sb); if (unlikely(!inode)) { + pr_err("out of free dentries, can not create symlink '%s'\n", + name); kfree(link); return failed_creating(dentry); } diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 4c2c85a223acd5..afb8340918b868 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -158,6 +158,7 @@ static struct attribute *dlm_attrs[] = { &dlm_attr_recover_nodeid.attr, NULL, }; +ATTRIBUTE_GROUPS(dlm); static ssize_t dlm_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) @@ -187,7 +188,7 @@ static const struct sysfs_ops dlm_attr_ops = { }; static struct kobj_type dlm_ktype = { - .default_attrs = dlm_attrs, + .default_groups = dlm_groups, .sysfs_ops = &dlm_attr_ops, .release = lockspace_kobj_release, }; diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 729f46a3c9ee0b..5c85166677d49a 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -501,6 +501,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(current_reserved_blocks), NULL, }; +ATTRIBUTE_GROUPS(f2fs); static struct attribute *f2fs_feat_attrs[] = { #ifdef CONFIG_FS_ENCRYPTION @@ -520,6 +521,7 @@ static struct attribute *f2fs_feat_attrs[] = { ATTR_LIST(sb_checksum), NULL, }; +ATTRIBUTE_GROUPS(f2fs_feat); static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, @@ -527,7 +529,7 @@ static const struct sysfs_ops f2fs_attr_ops = { }; static struct kobj_type f2fs_sb_ktype = { - .default_attrs = f2fs_attrs, + .default_groups = f2fs_groups, .sysfs_ops = &f2fs_attr_ops, .release = f2fs_sb_release, }; @@ -541,7 +543,7 @@ static struct kset f2fs_kset = { }; static struct kobj_type f2fs_feat_ktype = { - .default_attrs = f2fs_feat_attrs, + .default_groups = f2fs_feat_groups, .sysfs_ops = &f2fs_attr_ops, }; diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 289328831e24a6..dd15b8e4af2ce8 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -296,6 +296,7 @@ static struct attribute *gfs2_attrs[] = { &gfs2_attr_demote_rq.attr, NULL, }; +ATTRIBUTE_GROUPS(gfs2); static void gfs2_sbd_release(struct kobject *kobj) { @@ -306,7 +307,7 @@ static void gfs2_sbd_release(struct kobject *kobj) static struct kobj_type gfs2_ktype = { .release = gfs2_sbd_release, - .default_attrs = gfs2_attrs, + .default_groups = gfs2_groups, .sysfs_ops = &gfs2_attr_ops, }; diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c index 84831253203dda..76bee0a0d3087f 100644 --- a/fs/nfsd/fault_inject.c +++ b/fs/nfsd/fault_inject.c @@ -127,24 +127,16 @@ static struct nfsd_fault_inject_op inject_ops[] = { }, }; -int nfsd_fault_inject_init(void) +void nfsd_fault_inject_init(void) { unsigned int i; struct nfsd_fault_inject_op *op; umode_t mode = S_IFREG | S_IRUSR | S_IWUSR; debug_dir = debugfs_create_dir("nfsd", NULL); - if (!debug_dir) - goto fail; for (i = 0; i < ARRAY_SIZE(inject_ops); i++) { op = &inject_ops[i]; - if (!debugfs_create_file(op->file, mode, debug_dir, op, &fops_nfsd)) - goto fail; + debugfs_create_file(op->file, mode, debug_dir, op, &fops_nfsd); } - return 0; - -fail: - nfsd_fault_inject_cleanup(); - return -ENOMEM; } diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 72fad54fc7e5b0..0a9a49ded54635 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1514,9 +1514,7 @@ static int __init init_nfsd(void) retval = nfsd4_init_pnfs(); if (retval) goto out_free_slabs; - retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */ - if (retval) - goto out_exit_pnfs; + nfsd_fault_inject_init(); /* nfsd fault injection controls */ nfsd_stat_init(); /* Statistics */ nfsd_lockd_init(); /* lockd->nfsd callbacks */ retval = create_proc_exports_entry(); @@ -1533,7 +1531,6 @@ static int __init init_nfsd(void) nfsd_lockd_shutdown(); nfsd_stat_shutdown(); nfsd_fault_inject_cleanup(); -out_exit_pnfs: nfsd4_exit_pnfs(); out_free_slabs: nfsd4_free_slabs(); diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 8cb20cab012b00..5dbd16946e8efa 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -672,7 +672,7 @@ extern void nfsd4_record_grace_done(struct nfsd_net *nn); /* nfs fault injection functions */ #ifdef CONFIG_NFSD_FAULT_INJECTION -int nfsd_fault_inject_init(void); +void nfsd_fault_inject_init(void); void nfsd_fault_inject_cleanup(void); u64 nfsd_inject_print_clients(void); @@ -693,7 +693,7 @@ u64 nfsd_inject_forget_delegations(u64); u64 nfsd_inject_recall_client_delegations(struct sockaddr_storage *, size_t); u64 nfsd_inject_recall_delegations(u64); #else /* CONFIG_NFSD_FAULT_INJECTION */ -static inline int nfsd_fault_inject_init(void) { return 0; } +static inline void nfsd_fault_inject_init(void) {} static inline void nfsd_fault_inject_cleanup(void) {} #endif /* CONFIG_NFSD_FAULT_INJECTION */ diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c index 87b1a6fce6281b..25543a966c4866 100644 --- a/fs/orangefs/orangefs-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -64,7 +64,7 @@ struct client_debug_mask { __u64 mask2; }; -static int orangefs_kernel_debug_init(void); +static void orangefs_kernel_debug_init(void); static int orangefs_debug_help_open(struct inode *, struct file *); static void *help_start(struct seq_file *, loff_t *); @@ -99,7 +99,6 @@ static char *debug_help_string; static char client_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; static char client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; -static struct dentry *help_file_dentry; static struct dentry *client_debug_dentry; static struct dentry *debug_dir; @@ -151,10 +150,8 @@ static DEFINE_MUTEX(orangefs_help_file_lock); * initialize kmod debug operations, create orangefs debugfs dir and * ORANGEFS_KMOD_DEBUG_HELP_FILE. */ -int orangefs_debugfs_init(int debug_mask) +void orangefs_debugfs_init(int debug_mask) { - int rc = -ENOMEM; - /* convert input debug mask to a 64-bit unsigned integer */ orangefs_gossip_debug_mask = (unsigned long long)debug_mask; @@ -183,37 +180,21 @@ int orangefs_debugfs_init(int debug_mask) (unsigned long long)orangefs_gossip_debug_mask); debug_dir = debugfs_create_dir("orangefs", NULL); - if (!debug_dir) { - pr_info("%s: debugfs_create_dir failed.\n", __func__); - goto out; - } - help_file_dentry = debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE, - 0444, - debug_dir, - debug_help_string, - &debug_help_fops); - if (!help_file_dentry) { - pr_info("%s: debugfs_create_file failed.\n", __func__); - goto out; - } + debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE, 0444, debug_dir, + debug_help_string, &debug_help_fops); orangefs_debug_disabled = 0; - rc = orangefs_kernel_debug_init(); - -out: - - return rc; + orangefs_kernel_debug_init(); } /* * initialize the kernel-debug file. */ -static int orangefs_kernel_debug_init(void) +static void orangefs_kernel_debug_init(void) { int rc = -ENOMEM; - struct dentry *ret; char *k_buffer = NULL; gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__); @@ -230,24 +211,11 @@ static int orangefs_kernel_debug_init(void) pr_info("%s: overflow 1!\n", __func__); } - ret = debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, - 0444, - debug_dir, - k_buffer, - &kernel_debug_fops); - if (!ret) { - pr_info("%s: failed to create %s.\n", - __func__, - ORANGEFS_KMOD_DEBUG_FILE); - goto out; - } - - rc = 0; + debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, 0444, debug_dir, k_buffer, + &kernel_debug_fops); out: - gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc); - return rc; } @@ -353,12 +321,6 @@ static int orangefs_client_debug_init(void) debug_dir, c_buffer, &kernel_debug_fops); - if (!client_debug_dentry) { - pr_info("%s: failed to create updated %s.\n", - __func__, - ORANGEFS_CLIENT_DEBUG_FILE); - goto out; - } rc = 0; diff --git a/fs/orangefs/orangefs-debugfs.h b/fs/orangefs/orangefs-debugfs.h index 51147f9ce3d6a1..502f6dedccde66 100644 --- a/fs/orangefs/orangefs-debugfs.h +++ b/fs/orangefs/orangefs-debugfs.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -int orangefs_debugfs_init(int); +void orangefs_debugfs_init(int); void orangefs_debugfs_cleanup(void); int orangefs_prepare_debugfs_help_string(int); int orangefs_debugfs_new_client_mask(void __user *); diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index 4f2d7ee0d2d190..c010c1fddafc13 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -129,9 +129,7 @@ static int __init orangefs_init(void) if (ret) goto cleanup_key_table; - ret = orangefs_debugfs_init(module_parm_debug_mask); - if (ret) - goto debugfs_init_failed; + orangefs_debugfs_init(module_parm_debug_mask); ret = orangefs_sysfs_init(); if (ret) @@ -161,8 +159,6 @@ static int __init orangefs_init(void) orangefs_dev_cleanup(); sysfs_init_failed: - -debugfs_init_failed: orangefs_debugfs_cleanup(); cleanup_key_table: diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 138c5b07d80373..a5f10d79e0ddf5 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -2800,115 +2800,69 @@ static const struct file_operations dfs_fops = { * dbg_debugfs_init_fs - initialize debugfs for UBIFS instance. * @c: UBIFS file-system description object * - * This function creates all debugfs files for this instance of UBIFS. Returns - * zero in case of success and a negative error code in case of failure. + * This function creates all debugfs files for this instance of UBIFS. * * Note, the only reason we have not merged this function with the * 'ubifs_debugging_init()' function is because it is better to initialize * debugfs interfaces at the very end of the mount process, and remove them at * the very beginning of the mount process. */ -int dbg_debugfs_init_fs(struct ubifs_info *c) +void dbg_debugfs_init_fs(struct ubifs_info *c) { - int err, n; + int n; const char *fname; - struct dentry *dent; struct ubifs_debug_info *d = c->dbg; - if (!IS_ENABLED(CONFIG_DEBUG_FS)) - return 0; - n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, c->vi.ubi_num, c->vi.vol_id); if (n == UBIFS_DFS_DIR_LEN) { /* The array size is too small */ fname = UBIFS_DFS_DIR_NAME; - dent = ERR_PTR(-EINVAL); - goto out; + return; } fname = d->dfs_dir_name; - dent = debugfs_create_dir(fname, dfs_rootdir); - if (IS_ERR_OR_NULL(dent)) - goto out; - d->dfs_dir = dent; + d->dfs_dir = debugfs_create_dir(fname, dfs_rootdir); fname = "dump_lprops"; - dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_dump_lprops = dent; + d->dfs_dump_lprops = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, + &dfs_fops); fname = "dump_budg"; - dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_dump_budg = dent; + d->dfs_dump_budg = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, + &dfs_fops); fname = "dump_tnc"; - dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_dump_tnc = dent; + d->dfs_dump_tnc = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, + &dfs_fops); fname = "chk_general"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_gen = dent; + d->dfs_chk_gen = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "chk_index"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_index = dent; + d->dfs_chk_index = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "chk_orphans"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_orph = dent; + d->dfs_chk_orph = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "chk_lprops"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_lprops = dent; + d->dfs_chk_lprops = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "chk_fs"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_chk_fs = dent; + d->dfs_chk_fs = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "tst_recovery"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_tst_rcvry = dent; + d->dfs_tst_rcvry = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); fname = "ro_error"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c, - &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - d->dfs_ro_error = dent; - - return 0; - -out_remove: - debugfs_remove_recursive(d->dfs_dir); -out: - err = dent ? PTR_ERR(dent) : -ENODEV; - ubifs_err(c, "cannot create \"%s\" debugfs file or directory, error %d\n", - fname, err); - return err; + d->dfs_ro_error = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + d->dfs_dir, c, &dfs_fops); } /** @@ -2917,8 +2871,7 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) */ void dbg_debugfs_exit_fs(struct ubifs_info *c) { - if (IS_ENABLED(CONFIG_DEBUG_FS)) - debugfs_remove_recursive(c->dbg->dfs_dir); + debugfs_remove_recursive(c->dbg->dfs_dir); } struct ubifs_global_debug_info ubifs_dbg; @@ -2994,75 +2947,38 @@ static const struct file_operations dfs_global_fops = { * * UBIFS uses debugfs file-system to expose various debugging knobs to * user-space. This function creates "ubifs" directory in the debugfs - * file-system. Returns zero in case of success and a negative error code in - * case of failure. + * file-system. */ -int dbg_debugfs_init(void) +void dbg_debugfs_init(void) { - int err; const char *fname; - struct dentry *dent; - - if (!IS_ENABLED(CONFIG_DEBUG_FS)) - return 0; fname = "ubifs"; - dent = debugfs_create_dir(fname, NULL); - if (IS_ERR_OR_NULL(dent)) - goto out; - dfs_rootdir = dent; + dfs_rootdir = debugfs_create_dir(fname, NULL); fname = "chk_general"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_gen = dent; + dfs_chk_gen = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, + NULL, &dfs_global_fops); fname = "chk_index"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_index = dent; + dfs_chk_index = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + dfs_rootdir, NULL, &dfs_global_fops); fname = "chk_orphans"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_orph = dent; + dfs_chk_orph = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + dfs_rootdir, NULL, &dfs_global_fops); fname = "chk_lprops"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_lprops = dent; + dfs_chk_lprops = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + dfs_rootdir, NULL, &dfs_global_fops); fname = "chk_fs"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_chk_fs = dent; + dfs_chk_fs = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, + NULL, &dfs_global_fops); fname = "tst_recovery"; - dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL, - &dfs_global_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dfs_tst_rcvry = dent; - - return 0; - -out_remove: - debugfs_remove_recursive(dfs_rootdir); -out: - err = dent ? PTR_ERR(dent) : -ENODEV; - pr_err("UBIFS error (pid %d): cannot create \"%s\" debugfs file or directory, error %d\n", - current->pid, fname, err); - return err; + dfs_tst_rcvry = debugfs_create_file(fname, S_IRUSR | S_IWUSR, + dfs_rootdir, NULL, &dfs_global_fops); } /** @@ -3070,8 +2986,7 @@ int dbg_debugfs_init(void) */ void dbg_debugfs_exit(void) { - if (IS_ENABLED(CONFIG_DEBUG_FS)) - debugfs_remove_recursive(dfs_rootdir); + debugfs_remove_recursive(dfs_rootdir); } void ubifs_assert_failed(struct ubifs_info *c, const char *expr, diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index eb26097b6f70f4..7763639a426bab 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h @@ -297,9 +297,9 @@ int dbg_leb_unmap(struct ubifs_info *c, int lnum); int dbg_leb_map(struct ubifs_info *c, int lnum); /* Debugfs-related stuff */ -int dbg_debugfs_init(void); +void dbg_debugfs_init(void); void dbg_debugfs_exit(void); -int dbg_debugfs_init_fs(struct ubifs_info *c); +void dbg_debugfs_init_fs(struct ubifs_info *c); void dbg_debugfs_exit_fs(struct ubifs_info *c); #endif /* !__UBIFS_DEBUG_H__ */ diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 6cfc494050bef2..fd1977b568f0bb 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1465,9 +1465,7 @@ static int mount_ubifs(struct ubifs_info *c) if (err) goto out_infos; - err = dbg_debugfs_init_fs(c); - if (err) - goto out_infos; + dbg_debugfs_init_fs(c); c->mounting = 0; @@ -2352,9 +2350,7 @@ static int __init ubifs_init(void) if (err) goto out_shrinker; - err = dbg_debugfs_init(); - if (err) - goto out_compr; + dbg_debugfs_init(); err = register_filesystem(&ubifs_fs_type); if (err) { @@ -2366,7 +2362,6 @@ static int __init ubifs_init(void) out_dbg: dbg_debugfs_exit(); -out_compr: ubifs_compressors_exit(); out_shrinker: unregister_shrinker(&ubifs_shrinker_info); diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h index 07e02d6df5ad9f..6a1a8a314d8532 100644 --- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h @@ -203,7 +203,6 @@ struct backing_dev_info { #ifdef CONFIG_DEBUG_FS struct dentry *debug_dir; - struct dentry *debug_stats; #endif }; diff --git a/include/linux/ceph/debugfs.h b/include/linux/ceph/debugfs.h index fa5f9b7f5dbbce..cf5e840eec71a1 100644 --- a/include/linux/ceph/debugfs.h +++ b/include/linux/ceph/debugfs.h @@ -19,9 +19,9 @@ static const struct file_operations name##_fops = { \ }; /* debugfs.c */ -extern int ceph_debugfs_init(void); +extern void ceph_debugfs_init(void); extern void ceph_debugfs_cleanup(void); -extern int ceph_debugfs_client_init(struct ceph_client *client); +extern void ceph_debugfs_client_init(struct ceph_client *client); extern void ceph_debugfs_client_cleanup(struct ceph_client *client); #endif diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 87c211adf49efa..068793a619ca87 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -176,6 +176,7 @@ enum cpuhp_state { CPUHP_AP_WATCHDOG_ONLINE, CPUHP_AP_WORKQUEUE_ONLINE, CPUHP_AP_RCUTREE_ONLINE, + CPUHP_AP_BASE_CACHEINFO_ONLINE, CPUHP_AP_ONLINE_DYN, CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30, CPUHP_AP_X86_HPET_ONLINE, diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 3b0ba54cc4d5b0..58424eb3b3291a 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -133,9 +133,8 @@ struct dentry *debugfs_create_regset32(const char *name, umode_t mode, void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix); -struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, - struct dentry *parent, - u32 *array, u32 elements); +void debugfs_create_u32_array(const char *name, umode_t mode, + struct dentry *parent, u32 *array, u32 elements); struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name, struct dentry *parent, @@ -353,11 +352,10 @@ static inline bool debugfs_initialized(void) return false; } -static inline struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, - struct dentry *parent, - u32 *array, u32 elements) +static inline void debugfs_create_u32_array(const char *name, umode_t mode, + struct dentry *parent, u32 *array, + u32 elements) { - return ERR_PTR(-ENODEV); } static inline struct dentry *debugfs_create_devm_seqfile(struct device *dev, diff --git a/include/linux/device.h b/include/linux/device.h index adfcabcba8a1e9..5eabfa0c4dee65 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -164,11 +164,13 @@ void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter); void subsys_dev_iter_exit(struct subsys_dev_iter *iter); +int device_match_of_node(struct device *dev, const void *np); + int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, int (*fn)(struct device *dev, void *data)); struct device *bus_find_device(struct bus_type *bus, struct device *start, - void *data, - int (*match)(struct device *dev, void *data)); + const void *data, + int (*match)(struct device *dev, const void *data)); struct device *bus_find_device_by_name(struct bus_type *bus, struct device *start, const char *name); @@ -337,11 +339,12 @@ extern int __must_check driver_for_each_device(struct device_driver *drv, int (*fn)(struct device *dev, void *)); struct device *driver_find_device(struct device_driver *drv, - struct device *start, void *data, - int (*match)(struct device *dev, void *data)); + struct device *start, const void *data, + int (*match)(struct device *dev, const void *data)); void driver_deferred_probe_add(struct device *dev); int driver_deferred_probe_check_state(struct device *dev); +int driver_deferred_probe_check_state_continue(struct device *dev); /** * struct subsys_interface - interfaces to device functions diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h index f0273c9e972be6..8cfda05543819a 100644 --- a/include/linux/mfd/syscon.h +++ b/include/linux/mfd/syscon.h @@ -19,7 +19,6 @@ struct device_node; #ifdef CONFIG_MFD_SYSCON extern struct regmap *syscon_node_to_regmap(struct device_node *np); extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s); -extern struct regmap *syscon_regmap_lookup_by_pdevname(const char *s); extern struct regmap *syscon_regmap_lookup_by_phandle( struct device_node *np, const char *property); @@ -34,11 +33,6 @@ static inline struct regmap *syscon_regmap_lookup_by_compatible(const char *s) return ERR_PTR(-ENOTSUPP); } -static inline struct regmap *syscon_regmap_lookup_by_pdevname(const char *s) -{ - return ERR_PTR(-ENOTSUPP); -} - static inline struct regmap *syscon_regmap_lookup_by_phandle( struct device_node *np, const char *property) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 13f0cb080a4dc9..62fa5a82a0651d 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -696,29 +696,12 @@ bool is_swiotlb_active(void) static int __init swiotlb_create_debugfs(void) { - struct dentry *d_swiotlb_usage; - struct dentry *ent; - - d_swiotlb_usage = debugfs_create_dir("swiotlb", NULL); - - if (!d_swiotlb_usage) - return -ENOMEM; - - ent = debugfs_create_ulong("io_tlb_nslabs", 0400, - d_swiotlb_usage, &io_tlb_nslabs); - if (!ent) - goto fail; - - ent = debugfs_create_ulong("io_tlb_used", 0400, - d_swiotlb_usage, &io_tlb_used); - if (!ent) - goto fail; + struct dentry *root; + root = debugfs_create_dir("swiotlb", NULL); + debugfs_create_ulong("io_tlb_nslabs", 0400, root, &io_tlb_nslabs); + debugfs_create_ulong("io_tlb_used", 0400, root, &io_tlb_used); return 0; - -fail: - debugfs_remove_recursive(d_swiotlb_usage); - return -ENOMEM; } late_initcall(swiotlb_create_debugfs); diff --git a/kernel/fail_function.c b/kernel/fail_function.c index feb80712b913cb..63b349168da725 100644 --- a/kernel/fail_function.c +++ b/kernel/fail_function.c @@ -152,20 +152,13 @@ static int fei_retval_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(fei_retval_ops, fei_retval_get, fei_retval_set, "%llx\n"); -static int fei_debugfs_add_attr(struct fei_attr *attr) +static void fei_debugfs_add_attr(struct fei_attr *attr) { struct dentry *dir; dir = debugfs_create_dir(attr->kp.symbol_name, fei_debugfs_dir); - if (!dir) - return -ENOMEM; - - if (!debugfs_create_file("retval", 0600, dir, attr, &fei_retval_ops)) { - debugfs_remove_recursive(dir); - return -ENOMEM; - } - return 0; + debugfs_create_file("retval", 0600, dir, attr, &fei_retval_ops); } static void fei_debugfs_remove_attr(struct fei_attr *attr) @@ -306,7 +299,7 @@ static ssize_t fei_write(struct file *file, const char __user *buffer, ret = register_kprobe(&attr->kp); if (!ret) - ret = fei_debugfs_add_attr(attr); + fei_debugfs_add_attr(attr); if (ret < 0) fei_attr_remove(attr); else { @@ -337,19 +330,13 @@ static int __init fei_debugfs_init(void) return PTR_ERR(dir); /* injectable attribute is just a symlink of error_inject/list */ - if (!debugfs_create_symlink("injectable", dir, - "../error_injection/list")) - goto error; + debugfs_create_symlink("injectable", dir, "../error_injection/list"); - if (!debugfs_create_file("inject", 0600, dir, NULL, &fei_ops)) - goto error; + debugfs_create_file("inject", 0600, dir, NULL, &fei_ops); fei_debugfs_dir = dir; return 0; -error: - debugfs_remove_recursive(dir); - return -ENOMEM; } late_initcall(fei_debugfs_init); diff --git a/kernel/gcov/fs.c b/kernel/gcov/fs.c index 6e40ff6be083da..e5eb5ea7ea5982 100644 --- a/kernel/gcov/fs.c +++ b/kernel/gcov/fs.c @@ -64,7 +64,6 @@ struct gcov_node { static const char objtree[] = OBJTREE; static const char srctree[] = SRCTREE; static struct gcov_node root_node; -static struct dentry *reset_dentry; static LIST_HEAD(all_head); static DEFINE_MUTEX(node_lock); @@ -387,8 +386,6 @@ static void add_links(struct gcov_node *node, struct dentry *parent) goto out_err; node->links[i] = debugfs_create_symlink(deskew(basename), parent, target); - if (!node->links[i]) - goto out_err; kfree(target); } @@ -450,11 +447,6 @@ static struct gcov_node *new_node(struct gcov_node *parent, parent->dentry, node, &gcov_data_fops); } else node->dentry = debugfs_create_dir(node->name, parent->dentry); - if (!node->dentry) { - pr_warn("could not create file\n"); - kfree(node); - return NULL; - } if (info) add_links(node, parent->dentry); list_add(&node->list, &parent->children); @@ -761,32 +753,20 @@ void gcov_event(enum gcov_action action, struct gcov_info *info) /* Create debugfs entries. */ static __init int gcov_fs_init(void) { - int rc = -EIO; - init_node(&root_node, NULL, NULL, NULL); /* * /sys/kernel/debug/gcov will be parent for the reset control file * and all profiling files. */ root_node.dentry = debugfs_create_dir("gcov", NULL); - if (!root_node.dentry) - goto err_remove; /* * Create reset file which resets all profiling counts when written * to. */ - reset_dentry = debugfs_create_file("reset", 0600, root_node.dentry, - NULL, &gcov_reset_fops); - if (!reset_dentry) - goto err_remove; + debugfs_create_file("reset", 0600, root_node.dentry, NULL, + &gcov_reset_fops); /* Replay previous events to get our fs hierarchy up-to-date. */ gcov_enable_events(); return 0; - -err_remove: - pr_err("init failed\n"); - debugfs_remove(root_node.dentry); - - return rc; } device_initcall(gcov_fs_init); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 445337c107e0fd..9f5433a52488c5 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -2570,33 +2570,20 @@ static const struct file_operations fops_kp = { static int __init debugfs_kprobe_init(void) { - struct dentry *dir, *file; + struct dentry *dir; unsigned int value = 1; dir = debugfs_create_dir("kprobes", NULL); - if (!dir) - return -ENOMEM; - file = debugfs_create_file("list", 0400, dir, NULL, - &debugfs_kprobes_operations); - if (!file) - goto error; + debugfs_create_file("list", 0400, dir, NULL, + &debugfs_kprobes_operations); - file = debugfs_create_file("enabled", 0600, dir, - &value, &fops_kp); - if (!file) - goto error; + debugfs_create_file("enabled", 0600, dir, &value, &fops_kp); - file = debugfs_create_file("blacklist", 0400, dir, NULL, - &debugfs_kprobe_blacklist_ops); - if (!file) - goto error; + debugfs_create_file("blacklist", 0400, dir, NULL, + &debugfs_kprobe_blacklist_ops); return 0; - -error: - debugfs_remove(dir); - return -ENOMEM; } late_initcall(debugfs_kprobe_init); diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index e1c6d79fb4cc9f..2d6e93ab047834 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -512,8 +512,6 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, dir = debugfs_lookup(buts->name, blk_debugfs_root); if (!dir) bt->dir = dir = debugfs_create_dir(buts->name, blk_debugfs_root); - if (!dir) - goto err; bt->dev = dev; atomic_set(&bt->dropped, 0); @@ -522,12 +520,8 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, ret = -EIO; bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt, &blk_dropped_fops); - if (!bt->dropped_file) - goto err; bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops); - if (!bt->msg_file) - goto err; bt->rchan = relay_open("trace", dir, buts->buf_size, buts->buf_nr, &blk_relay_callbacks, bt); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c3aabb576fe5bf..c90c687cf950a4 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8618,10 +8618,6 @@ struct dentry *tracing_init_dentry(void) */ tr->dir = debugfs_create_automount("tracing", NULL, trace_automount, NULL); - if (!tr->dir) { - pr_warn_once("Could not create debugfs directory 'tracing'\n"); - return ERR_PTR(-ENOMEM); - } return NULL; } diff --git a/lib/842/842_debugfs.h b/lib/842/842_debugfs.h index 277e403e8701fc..4469407c3e0d46 100644 --- a/lib/842/842_debugfs.h +++ b/lib/842/842_debugfs.h @@ -22,8 +22,6 @@ static int __init sw842_debugfs_create(void) return -ENODEV; sw842_debugfs_root = debugfs_create_dir(MODULE_NAME, NULL); - if (IS_ERR(sw842_debugfs_root)) - return PTR_ERR(sw842_debugfs_root); for (i = 0; i < ARRAY_SIZE(template_count); i++) { char name[32]; @@ -46,8 +44,7 @@ static int __init sw842_debugfs_create(void) static void __exit sw842_debugfs_remove(void) { - if (sw842_debugfs_root && !IS_ERR(sw842_debugfs_root)) - debugfs_remove_recursive(sw842_debugfs_root); + debugfs_remove_recursive(sw842_debugfs_root); } #endif diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 8a16c2d498e9d6..c60409138e1367 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -993,20 +993,14 @@ static __initdata int ddebug_init_success; static int __init dynamic_debug_init_debugfs(void) { - struct dentry *dir, *file; + struct dentry *dir; if (!ddebug_init_success) return -ENODEV; dir = debugfs_create_dir("dynamic_debug", NULL); - if (!dir) - return -ENOMEM; - file = debugfs_create_file("control", 0644, dir, NULL, - &ddebug_proc_fops); - if (!file) { - debugfs_remove(dir); - return -ENOMEM; - } + debugfs_create_file("control", 0644, dir, NULL, &ddebug_proc_fops); + return 0; } diff --git a/lib/fault-inject.c b/lib/fault-inject.c index 3cb21b2bf088d5..8186ca84910bc6 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -166,10 +166,10 @@ static int debugfs_ul_get(void *data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(fops_ul, debugfs_ul_get, debugfs_ul_set, "%llu\n"); -static struct dentry *debugfs_create_ul(const char *name, umode_t mode, - struct dentry *parent, unsigned long *value) +static void debugfs_create_ul(const char *name, umode_t mode, + struct dentry *parent, unsigned long *value) { - return debugfs_create_file(name, mode, parent, value, &fops_ul); + debugfs_create_file(name, mode, parent, value, &fops_ul); } #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER @@ -185,12 +185,11 @@ static int debugfs_stacktrace_depth_set(void *data, u64 val) DEFINE_SIMPLE_ATTRIBUTE(fops_stacktrace_depth, debugfs_ul_get, debugfs_stacktrace_depth_set, "%llu\n"); -static struct dentry *debugfs_create_stacktrace_depth( - const char *name, umode_t mode, - struct dentry *parent, unsigned long *value) +static void debugfs_create_stacktrace_depth(const char *name, umode_t mode, + struct dentry *parent, + unsigned long *value) { - return debugfs_create_file(name, mode, parent, value, - &fops_stacktrace_depth); + debugfs_create_file(name, mode, parent, value, &fops_stacktrace_depth); } #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ @@ -202,51 +201,31 @@ struct dentry *fault_create_debugfs_attr(const char *name, struct dentry *dir; dir = debugfs_create_dir(name, parent); - if (!dir) - return ERR_PTR(-ENOMEM); - - if (!debugfs_create_ul("probability", mode, dir, &attr->probability)) - goto fail; - if (!debugfs_create_ul("interval", mode, dir, &attr->interval)) - goto fail; - if (!debugfs_create_atomic_t("times", mode, dir, &attr->times)) - goto fail; - if (!debugfs_create_atomic_t("space", mode, dir, &attr->space)) - goto fail; - if (!debugfs_create_ul("verbose", mode, dir, &attr->verbose)) - goto fail; - if (!debugfs_create_u32("verbose_ratelimit_interval_ms", mode, dir, - &attr->ratelimit_state.interval)) - goto fail; - if (!debugfs_create_u32("verbose_ratelimit_burst", mode, dir, - &attr->ratelimit_state.burst)) - goto fail; - if (!debugfs_create_bool("task-filter", mode, dir, &attr->task_filter)) - goto fail; + if (IS_ERR(dir)) + return dir; + + debugfs_create_ul("probability", mode, dir, &attr->probability); + debugfs_create_ul("interval", mode, dir, &attr->interval); + debugfs_create_atomic_t("times", mode, dir, &attr->times); + debugfs_create_atomic_t("space", mode, dir, &attr->space); + debugfs_create_ul("verbose", mode, dir, &attr->verbose); + debugfs_create_u32("verbose_ratelimit_interval_ms", mode, dir, + &attr->ratelimit_state.interval); + debugfs_create_u32("verbose_ratelimit_burst", mode, dir, + &attr->ratelimit_state.burst); + debugfs_create_bool("task-filter", mode, dir, &attr->task_filter); #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER - - if (!debugfs_create_stacktrace_depth("stacktrace-depth", mode, dir, - &attr->stacktrace_depth)) - goto fail; - if (!debugfs_create_ul("require-start", mode, dir, - &attr->require_start)) - goto fail; - if (!debugfs_create_ul("require-end", mode, dir, &attr->require_end)) - goto fail; - if (!debugfs_create_ul("reject-start", mode, dir, &attr->reject_start)) - goto fail; - if (!debugfs_create_ul("reject-end", mode, dir, &attr->reject_end)) - goto fail; - + debugfs_create_stacktrace_depth("stacktrace-depth", mode, dir, + &attr->stacktrace_depth); + debugfs_create_ul("require-start", mode, dir, &attr->require_start); + debugfs_create_ul("require-end", mode, dir, &attr->require_end); + debugfs_create_ul("reject-start", mode, dir, &attr->reject_start); + debugfs_create_ul("reject-end", mode, dir, &attr->reject_end); #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ attr->dname = dget(dir); return dir; -fail: - debugfs_remove_recursive(dir); - - return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(fault_create_debugfs_attr); diff --git a/lib/kobject.c b/lib/kobject.c index f2ccdbac8ed98a..83198cb37d8d93 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -498,8 +498,10 @@ int kobject_rename(struct kobject *kobj, const char *new_name) kobj = kobject_get(kobj); if (!kobj) return -EINVAL; - if (!kobj->parent) + if (!kobj->parent) { + kobject_put(kobj); return -EINVAL; + } devpath = kobject_get_path(kobj, GFP_KERNEL); if (!devpath) { diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c index 3d2ba7cf83f458..21016b32d3131d 100644 --- a/lib/notifier-error-inject.c +++ b/lib/notifier-error-inject.c @@ -59,33 +59,22 @@ struct dentry *notifier_err_inject_init(const char *name, struct dentry *parent, err_inject->nb.priority = priority; dir = debugfs_create_dir(name, parent); - if (!dir) - return ERR_PTR(-ENOMEM); actions_dir = debugfs_create_dir("actions", dir); - if (!actions_dir) - goto fail; for (action = err_inject->actions; action->name; action++) { struct dentry *action_dir; action_dir = debugfs_create_dir(action->name, actions_dir); - if (!action_dir) - goto fail; /* * Create debugfs r/w file containing action->error. If * notifier call chain is called with action->val, it will * fail with the error code */ - if (!debugfs_create_errno("error", mode, action_dir, - &action->error)) - goto fail; + debugfs_create_errno("error", mode, action_dir, &action->error); } return dir; -fail: - debugfs_remove_recursive(dir); - return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(notifier_err_inject_init); diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 909dae445ea713..e8e89158adec6c 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -103,39 +103,25 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v) } DEFINE_SHOW_ATTRIBUTE(bdi_debug_stats); -static int bdi_debug_register(struct backing_dev_info *bdi, const char *name) +static void bdi_debug_register(struct backing_dev_info *bdi, const char *name) { - if (!bdi_debug_root) - return -ENOMEM; - bdi->debug_dir = debugfs_create_dir(name, bdi_debug_root); - if (!bdi->debug_dir) - return -ENOMEM; - - bdi->debug_stats = debugfs_create_file("stats", 0444, bdi->debug_dir, - bdi, &bdi_debug_stats_fops); - if (!bdi->debug_stats) { - debugfs_remove(bdi->debug_dir); - bdi->debug_dir = NULL; - return -ENOMEM; - } - return 0; + debugfs_create_file("stats", 0444, bdi->debug_dir, bdi, + &bdi_debug_stats_fops); } static void bdi_debug_unregister(struct backing_dev_info *bdi) { - debugfs_remove(bdi->debug_stats); - debugfs_remove(bdi->debug_dir); + debugfs_remove_recursive(bdi->debug_dir); } #else static inline void bdi_debug_init(void) { } -static inline int bdi_debug_register(struct backing_dev_info *bdi, +static inline void bdi_debug_register(struct backing_dev_info *bdi, const char *name) { - return 0; } static inline void bdi_debug_unregister(struct backing_dev_info *bdi) { diff --git a/mm/cleancache.c b/mm/cleancache.c index 2397f7c36cc723..db7eee9c08863c 100644 --- a/mm/cleancache.c +++ b/mm/cleancache.c @@ -304,8 +304,7 @@ static int __init init_cleancache(void) { #ifdef CONFIG_DEBUG_FS struct dentry *root = debugfs_create_dir("cleancache", NULL); - if (root == NULL) - return -ENXIO; + debugfs_create_u64("succ_gets", 0444, root, &cleancache_succ_gets); debugfs_create_u64("failed_gets", 0444, root, &cleancache_failed_gets); debugfs_create_u64("puts", 0444, root, &cleancache_puts); diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c index 1a7497d015b29b..5b7430bd83a653 100644 --- a/mm/hwpoison-inject.c +++ b/mm/hwpoison-inject.c @@ -77,63 +77,40 @@ static void pfn_inject_exit(void) static int pfn_inject_init(void) { - struct dentry *dentry; - hwpoison_dir = debugfs_create_dir("hwpoison", NULL); - if (hwpoison_dir == NULL) - return -ENOMEM; /* * Note that the below poison/unpoison interfaces do not involve * hardware status change, hence do not require hardware support. * They are mainly for testing hwpoison in software level. */ - dentry = debugfs_create_file("corrupt-pfn", 0200, hwpoison_dir, - NULL, &hwpoison_fops); - if (!dentry) - goto fail; - - dentry = debugfs_create_file("unpoison-pfn", 0200, hwpoison_dir, - NULL, &unpoison_fops); - if (!dentry) - goto fail; - - dentry = debugfs_create_u32("corrupt-filter-enable", 0600, - hwpoison_dir, &hwpoison_filter_enable); - if (!dentry) - goto fail; - - dentry = debugfs_create_u32("corrupt-filter-dev-major", 0600, - hwpoison_dir, &hwpoison_filter_dev_major); - if (!dentry) - goto fail; - - dentry = debugfs_create_u32("corrupt-filter-dev-minor", 0600, - hwpoison_dir, &hwpoison_filter_dev_minor); - if (!dentry) - goto fail; - - dentry = debugfs_create_u64("corrupt-filter-flags-mask", 0600, - hwpoison_dir, &hwpoison_filter_flags_mask); - if (!dentry) - goto fail; - - dentry = debugfs_create_u64("corrupt-filter-flags-value", 0600, - hwpoison_dir, &hwpoison_filter_flags_value); - if (!dentry) - goto fail; + debugfs_create_file("corrupt-pfn", 0200, hwpoison_dir, NULL, + &hwpoison_fops); + + debugfs_create_file("unpoison-pfn", 0200, hwpoison_dir, NULL, + &unpoison_fops); + + debugfs_create_u32("corrupt-filter-enable", 0600, hwpoison_dir, + &hwpoison_filter_enable); + + debugfs_create_u32("corrupt-filter-dev-major", 0600, hwpoison_dir, + &hwpoison_filter_dev_major); + + debugfs_create_u32("corrupt-filter-dev-minor", 0600, hwpoison_dir, + &hwpoison_filter_dev_minor); + + debugfs_create_u64("corrupt-filter-flags-mask", 0600, hwpoison_dir, + &hwpoison_filter_flags_mask); + + debugfs_create_u64("corrupt-filter-flags-value", 0600, hwpoison_dir, + &hwpoison_filter_flags_value); #ifdef CONFIG_MEMCG - dentry = debugfs_create_u64("corrupt-filter-memcg", 0600, - hwpoison_dir, &hwpoison_filter_memcg); - if (!dentry) - goto fail; + debugfs_create_u64("corrupt-filter-memcg", 0600, hwpoison_dir, + &hwpoison_filter_memcg); #endif return 0; -fail: - pfn_inject_exit(); - return -ENOMEM; } module_init(pfn_inject_init); diff --git a/mm/kmemleak.c b/mm/kmemleak.c index aa8f4fa93ca39e..dbbd518fb6b3e9 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -2105,14 +2105,9 @@ void __init kmemleak_init(void) */ static int __init kmemleak_late_init(void) { - struct dentry *dentry; - kmemleak_initialized = 1; - dentry = debugfs_create_file("kmemleak", 0644, NULL, NULL, - &kmemleak_fops); - if (!dentry) - pr_warn("Failed to create the debugfs kmemleak file\n"); + debugfs_create_file("kmemleak", 0644, NULL, NULL, &kmemleak_fops); if (kmemleak_error) { /* diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 0787d33b80d83f..db09eb3669c5d9 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -575,8 +575,6 @@ static void __init zs_stat_init(void) } zs_stat_root = debugfs_create_dir("zsmalloc", NULL); - if (!zs_stat_root) - pr_warn("debugfs 'zsmalloc' stat dir creation failed\n"); } static void __exit zs_stat_exit(void) @@ -647,29 +645,15 @@ DEFINE_SHOW_ATTRIBUTE(zs_stats_size); static void zs_pool_stat_create(struct zs_pool *pool, const char *name) { - struct dentry *entry; - if (!zs_stat_root) { pr_warn("no root stat dir, not creating <%s> stat dir\n", name); return; } - entry = debugfs_create_dir(name, zs_stat_root); - if (!entry) { - pr_warn("debugfs dir <%s> creation failed\n", name); - return; - } - pool->stat_dentry = entry; - - entry = debugfs_create_file("classes", S_IFREG | 0444, - pool->stat_dentry, pool, - &zs_stats_size_fops); - if (!entry) { - pr_warn("%s: debugfs file entry <%s> creation failed\n", - name, "classes"); - debugfs_remove_recursive(pool->stat_dentry); - pool->stat_dentry = NULL; - } + pool->stat_dentry = debugfs_create_dir(name, zs_stat_root); + + debugfs_create_file("classes", S_IFREG | 0444, pool->stat_dentry, pool, + &zs_stats_size_fops); } static void zs_pool_stat_destroy(struct zs_pool *pool) diff --git a/mm/zswap.c b/mm/zswap.c index 2412042f55503f..0e22744a76cb65 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -1253,8 +1253,6 @@ static int __init zswap_debugfs_init(void) return -ENODEV; zswap_debugfs_root = debugfs_create_dir("zswap", NULL); - if (!zswap_debugfs_root) - return -ENOMEM; debugfs_create_u64("pool_limit_hit", 0444, zswap_debugfs_root, &zswap_pool_limit_hit); diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 1c811c74bfc0f3..4eeea4d5c3ef4b 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -776,9 +776,7 @@ static int __init init_ceph_lib(void) { int ret = 0; - ret = ceph_debugfs_init(); - if (ret < 0) - goto out; + ceph_debugfs_init(); ret = ceph_crypto_init(); if (ret < 0) @@ -803,7 +801,6 @@ static int __init init_ceph_lib(void) ceph_crypto_shutdown(); out_debugfs: ceph_debugfs_cleanup(); -out: return ret; } diff --git a/net/ceph/debugfs.c b/net/ceph/debugfs.c index 63aef9915f759b..7cb992e55475ba 100644 --- a/net/ceph/debugfs.c +++ b/net/ceph/debugfs.c @@ -389,12 +389,9 @@ CEPH_DEFINE_SHOW_FUNC(monc_show) CEPH_DEFINE_SHOW_FUNC(osdc_show) CEPH_DEFINE_SHOW_FUNC(client_options_show) -int __init ceph_debugfs_init(void) +void __init ceph_debugfs_init(void) { ceph_debugfs_dir = debugfs_create_dir("ceph", NULL); - if (!ceph_debugfs_dir) - return -ENOMEM; - return 0; } void ceph_debugfs_cleanup(void) @@ -402,9 +399,8 @@ void ceph_debugfs_cleanup(void) debugfs_remove(ceph_debugfs_dir); } -int ceph_debugfs_client_init(struct ceph_client *client) +void ceph_debugfs_client_init(struct ceph_client *client) { - int ret = -ENOMEM; char name[80]; snprintf(name, sizeof(name), "%pU.client%lld", &client->fsid, @@ -412,56 +408,37 @@ int ceph_debugfs_client_init(struct ceph_client *client) dout("ceph_debugfs_client_init %p %s\n", client, name); - BUG_ON(client->debugfs_dir); client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir); - if (!client->debugfs_dir) - goto out; client->monc.debugfs_file = debugfs_create_file("monc", 0400, client->debugfs_dir, client, &monc_show_fops); - if (!client->monc.debugfs_file) - goto out; client->osdc.debugfs_file = debugfs_create_file("osdc", 0400, client->debugfs_dir, client, &osdc_show_fops); - if (!client->osdc.debugfs_file) - goto out; client->debugfs_monmap = debugfs_create_file("monmap", 0400, client->debugfs_dir, client, &monmap_show_fops); - if (!client->debugfs_monmap) - goto out; client->debugfs_osdmap = debugfs_create_file("osdmap", 0400, client->debugfs_dir, client, &osdmap_show_fops); - if (!client->debugfs_osdmap) - goto out; client->debugfs_options = debugfs_create_file("client_options", 0400, client->debugfs_dir, client, &client_options_show_fops); - if (!client->debugfs_options) - goto out; - - return 0; - -out: - ceph_debugfs_client_cleanup(client); - return ret; } void ceph_debugfs_client_cleanup(struct ceph_client *client) @@ -477,18 +454,16 @@ void ceph_debugfs_client_cleanup(struct ceph_client *client) #else /* CONFIG_DEBUG_FS */ -int __init ceph_debugfs_init(void) +void __init ceph_debugfs_init(void) { - return 0; } void ceph_debugfs_cleanup(void) { } -int ceph_debugfs_client_init(struct ceph_client *client) +void ceph_debugfs_client_init(struct ceph_client *client) { - return 0; } void ceph_debugfs_client_cleanup(struct ceph_client *client) diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c index 95ebd76b132d35..707d7aab15466a 100644 --- a/net/sunrpc/debugfs.c +++ b/net/sunrpc/debugfs.c @@ -11,7 +11,6 @@ #include "netns.h" static struct dentry *topdir; -static struct dentry *rpc_fault_dir; static struct dentry *rpc_clnt_dir; static struct dentry *rpc_xprt_dir; @@ -125,23 +124,16 @@ rpc_clnt_debugfs_register(struct rpc_clnt *clnt) char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ struct rpc_xprt *xprt; - /* Already registered? */ - if (clnt->cl_debugfs || !rpc_clnt_dir) - return; - len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); if (len >= sizeof(name)) return; /* make the per-client dir */ clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); - if (!clnt->cl_debugfs) - return; /* make tasks file */ - if (!debugfs_create_file("tasks", S_IFREG | 0400, clnt->cl_debugfs, - clnt, &tasks_fops)) - goto out_err; + debugfs_create_file("tasks", S_IFREG | 0400, clnt->cl_debugfs, clnt, + &tasks_fops); rcu_read_lock(); xprt = rcu_dereference(clnt->cl_xprt); @@ -157,8 +149,7 @@ rpc_clnt_debugfs_register(struct rpc_clnt *clnt) if (len >= sizeof(name)) goto out_err; - if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) - goto out_err; + debugfs_create_symlink("xprt", clnt->cl_debugfs, name); return; out_err: @@ -226,9 +217,6 @@ rpc_xprt_debugfs_register(struct rpc_xprt *xprt) static atomic_t cur_id; char name[9]; /* 8 hex digits + NULL term */ - if (!rpc_xprt_dir) - return; - id = (unsigned int)atomic_inc_return(&cur_id); len = snprintf(name, sizeof(name), "%x", id); @@ -237,15 +225,10 @@ rpc_xprt_debugfs_register(struct rpc_xprt *xprt) /* make the per-client dir */ xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); - if (!xprt->debugfs) - return; /* make tasks file */ - if (!debugfs_create_file("info", S_IFREG | 0400, xprt->debugfs, - xprt, &xprt_info_fops)) { - debugfs_remove_recursive(xprt->debugfs); - xprt->debugfs = NULL; - } + debugfs_create_file("info", S_IFREG | 0400, xprt->debugfs, xprt, + &xprt_info_fops); atomic_set(&xprt->inject_disconnect, rpc_inject_disconnect); } @@ -308,28 +291,11 @@ static const struct file_operations fault_disconnect_fops = { .release = fault_release, }; -static struct dentry * -inject_fault_dir(struct dentry *topdir) -{ - struct dentry *faultdir; - - faultdir = debugfs_create_dir("inject_fault", topdir); - if (!faultdir) - return NULL; - - if (!debugfs_create_file("disconnect", S_IFREG | 0400, faultdir, - NULL, &fault_disconnect_fops)) - return NULL; - - return faultdir; -} - void __exit sunrpc_debugfs_exit(void) { debugfs_remove_recursive(topdir); topdir = NULL; - rpc_fault_dir = NULL; rpc_clnt_dir = NULL; rpc_xprt_dir = NULL; } @@ -337,26 +303,16 @@ sunrpc_debugfs_exit(void) void __init sunrpc_debugfs_init(void) { - topdir = debugfs_create_dir("sunrpc", NULL); - if (!topdir) - return; + struct dentry *rpc_fault_dir; - rpc_fault_dir = inject_fault_dir(topdir); - if (!rpc_fault_dir) - goto out_remove; + topdir = debugfs_create_dir("sunrpc", NULL); rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); - if (!rpc_clnt_dir) - goto out_remove; rpc_xprt_dir = debugfs_create_dir("rpc_xprt", topdir); - if (!rpc_xprt_dir) - goto out_remove; - return; -out_remove: - debugfs_remove_recursive(topdir); - topdir = NULL; - rpc_fault_dir = NULL; - rpc_clnt_dir = NULL; + rpc_fault_dir = debugfs_create_dir("inject_fault", topdir); + + debugfs_create_file("disconnect", S_IFREG | 0400, rpc_fault_dir, NULL, + &fault_disconnect_fops); } diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci index a5af9e3351904a..fefd0331a2ded9 100644 --- a/scripts/coccinelle/free/devm_free.cocci +++ b/scripts/coccinelle/free/devm_free.cocci @@ -3,7 +3,7 @@ /// functions. Values allocated using the devm_functions are freed when /// the device is detached, and thus the use of the standard freeing /// function would cause a double free. -/// See Documentation/driver-model/devres.txt for more information. +/// See Documentation/driver-model/devres.rst for more information. /// /// A difficulty of detecting this problem is that the standard freeing /// function might be called from a different function than the one diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl new file mode 100755 index 00000000000000..c738cb79551411 --- /dev/null +++ b/scripts/get_abi.pl @@ -0,0 +1,468 @@ +#!/usr/bin/perl +# SPDX-License-Identifier: GPL-2.0 + +use strict; +use Pod::Usage; +use Getopt::Long; +use File::Find; +use Fcntl ':mode'; + +my $help; +my $man; +my $debug; +my $prefix="Documentation/ABI"; + +GetOptions( + "debug|d+" => \$debug, + "dir=s" => \$prefix, + 'help|?' => \$help, + man => \$man +) or pod2usage(2); + +pod2usage(1) if $help; +pod2usage(-exitstatus => 0, -verbose => 2) if $man; + +pod2usage(2) if (scalar @ARGV < 1 || @ARGV > 2); + +my ($cmd, $arg) = @ARGV; + +pod2usage(2) if ($cmd ne "search" && $cmd ne "rest" && $cmd ne "validate"); +pod2usage(2) if ($cmd eq "search" && !$arg); + +require Data::Dumper if ($debug); + +my %data; + +# +# Displays an error message, printing file name and line +# +sub parse_error($$$$) { + my ($file, $ln, $msg, $data) = @_; + + print STDERR "file $file#$ln: $msg at\n\t$data"; +} + +# +# Parse an ABI file, storing its contents at %data +# +sub parse_abi { + my $file = $File::Find::name; + + my $mode = (stat($file))[2]; + return if ($mode & S_IFDIR); + return if ($file =~ m,/README,); + + my $name = $file; + $name =~ s,.*/,,; + + my $nametag = "File $name"; + $data{$nametag}->{what} = "File $name"; + $data{$nametag}->{type} = "File"; + $data{$nametag}->{file} = $name; + $data{$nametag}->{filepath} = $file; + $data{$nametag}->{is_file} = 1; + + my $type = $file; + $type =~ s,.*/(.*)/.*,$1,; + + my $what; + my $new_what; + my $tag; + my $ln; + my $xrefs; + my $space; + my @labels; + my $label; + + print STDERR "Opening $file\n" if ($debug > 1); + open IN, $file; + while() { + $ln++; + if (m/^(\S+)(:\s*)(.*)/i) { + my $new_tag = lc($1); + my $sep = $2; + my $content = $3; + + if (!($new_tag =~ m/(what|where|date|kernelversion|contact|description|users)/)) { + if ($tag eq "description") { + # New "tag" is actually part of + # description. Don't consider it a tag + $new_tag = ""; + } elsif ($tag ne "") { + parse_error($file, $ln, "tag '$tag' is invalid", $_); + } + } + + # Invalid, but it is a common mistake + if ($new_tag eq "where") { + parse_error($file, $ln, "tag 'Where' is invalid. Should be 'What:' instead", $_); + $new_tag = "what"; + } + + if ($new_tag =~ m/what/) { + $space = ""; + if ($tag =~ m/what/) { + $what .= ", " . $content; + } else { + parse_error($file, $ln, "What '$what' doesn't have a description", "") if ($what && !$data{$what}->{description}); + + $what = $content; + $label = $content; + $new_what = 1; + } + push @labels, [($content, $label)]; + $tag = $new_tag; + + push @{$data{$nametag}->{xrefs}}, [($content, $label)] if ($data{$nametag}->{what}); + next; + } + + if ($tag ne "" && $new_tag) { + $tag = $new_tag; + + if ($new_what) { + @{$data{$what}->{label}} = @labels if ($data{$nametag}->{what}); + @labels = (); + $label = ""; + $new_what = 0; + + $data{$what}->{type} = $type; + $data{$what}->{file} = $name; + $data{$what}->{filepath} = $file; + print STDERR "\twhat: $what\n" if ($debug > 1); + } + + if (!$what) { + parse_error($file, $ln, "'What:' should come first:", $_); + next; + } + if ($tag eq "description") { + next if ($content =~ m/^\s*$/); + if ($content =~ m/^(\s*)(.*)/) { + my $new_content = $2; + $space = $new_tag . $sep . $1; + while ($space =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {} + $space =~ s/./ /g; + $data{$what}->{$tag} .= "$new_content\n"; + } + } else { + $data{$what}->{$tag} = $content; + } + next; + } + } + + # Store any contents before tags at the database + if (!$tag && $data{$nametag}->{what}) { + $data{$nametag}->{description} .= $_; + next; + } + + if ($tag eq "description") { + if (!$data{$what}->{description}) { + next if (m/^\s*\n/); + if (m/^(\s*)(.*)/) { + $space = $1; + while ($space =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {} + $data{$what}->{$tag} .= "$2\n"; + } + } else { + my $content = $_; + if (m/^\s*\n/) { + $data{$what}->{$tag} .= $content; + next; + } + + while ($content =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {} + $space = "" if (!($content =~ s/^($space)//)); + + # Compress spaces with tabs + $content =~ s<^ {8}> <\t>; + $content =~ s<^ {1,7}\t> <\t>; + $content =~ s< {1,7}\t> <\t>; + $data{$what}->{$tag} .= $content; + } + next; + } + if (m/^\s*(.*)/) { + $data{$what}->{$tag} .= "\n$1"; + $data{$what}->{$tag} =~ s/\n+$//; + next; + } + + # Everything else is error + parse_error($file, $ln, "Unexpected line:", $_); + } + $data{$nametag}->{description} =~ s/^\n+//; + close IN; +} + +# +# Outputs the book on ReST format +# + +my %labels; + +sub output_rest { + foreach my $what (sort { + ($data{$a}->{type} eq "File") cmp ($data{$b}->{type} eq "File") || + $a cmp $b + } keys %data) { + my $type = $data{$what}->{type}; + my $file = $data{$what}->{file}; + my $filepath = $data{$what}->{filepath}; + + my $w = $what; + $w =~ s/([\(\)\_\-\*\=\^\~\\])/\\$1/g; + + + foreach my $p (@{$data{$what}->{label}}) { + my ($content, $label) = @{$p}; + $label = "abi_" . $label . " "; + $label =~ tr/A-Z/a-z/; + + # Convert special chars to "_" + $label =~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g; + $label =~ s,_+,_,g; + $label =~ s,_$,,; + + # Avoid duplicated labels + while (defined($labels{$label})) { + my @chars = ("A".."Z", "a".."z"); + $label .= $chars[rand @chars]; + } + $labels{$label} = 1; + + $data{$what}->{label} .= $label; + + printf ".. _%s:\n\n", $label; + + # only one label is enough + last; + } + + + $filepath =~ s,.*/(.*/.*),\1,;; + $filepath =~ s,[/\-],_,g;; + my $fileref = "abi_file_".$filepath; + + if ($type eq "File") { + my $bar = $w; + $bar =~ s/./-/g; + + print ".. _$fileref:\n\n"; + print "$w\n$bar\n\n"; + } else { + my @names = split /\s*,\s*/,$w; + + my $len = 0; + + foreach my $name (@names) { + $len = length($name) if (length($name) > $len); + } + + print "What:\n\n"; + + print "+-" . "-" x $len . "-+\n"; + foreach my $name (@names) { + printf "| %s", $name . " " x ($len - length($name)) . " |\n"; + print "+-" . "-" x $len . "-+\n"; + } + print "\n"; + } + + print "Defined on file :ref:`$file <$fileref>`\n\n" if ($type ne "File"); + + my $desc = $data{$what}->{description}; + $desc =~ s/^\s+//; + + # Remove title markups from the description, as they won't work + $desc =~ s/\n[\-\*\=\^\~]+\n/\n/g; + + if (!($desc =~ /^\s*$/)) { + if ($desc =~ m/\:\n/ || $desc =~ m/\n[\t ]+/ || $desc =~ m/[\x00-\x08\x0b-\x1f\x7b-\xff]/) { + # put everything inside a code block + $desc =~ s/\n/\n /g; + + print "::\n\n"; + print " $desc\n\n"; + } else { + # Escape any special chars from description + $desc =~s/([\x00-\x08\x0b-\x1f\x21-\x2a\x2d\x2f\x3c-\x40\x5c\x5e-\x60\x7b-\xff])/\\$1/g; + + print "$desc\n\n"; + } + } else { + print "DESCRIPTION MISSING for $what\n\n" if (!$data{$what}->{is_file}); + } + + if ($data{$what}->{xrefs}) { + printf "Has the following ABI:\n\n"; + + foreach my $p(@{$data{$what}->{xrefs}}) { + my ($content, $label) = @{$p}; + $label = "abi_" . $label . " "; + $label =~ tr/A-Z/a-z/; + + # Convert special chars to "_" + $label =~s/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff])/_/g; + $label =~ s,_+,_,g; + $label =~ s,_$,,; + + # Escape special chars from content + $content =~s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g; + + print "- :ref:`$content <$label>`\n\n"; + } + } + } +} + +# +# Searches for ABI symbols +# +sub search_symbols { + foreach my $what (sort keys %data) { + next if (!($what =~ m/($arg)/)); + + my $type = $data{$what}->{type}; + next if ($type eq "File"); + + my $file = $data{$what}->{filepath}; + + my $bar = $what; + $bar =~ s/./-/g; + + print "\n$what\n$bar\n\n"; + + my $kernelversion = $data{$what}->{kernelversion}; + my $contact = $data{$what}->{contact}; + my $users = $data{$what}->{users}; + my $date = $data{$what}->{date}; + my $desc = $data{$what}->{description}; + $kernelversion =~ s/^\s+//; + $contact =~ s/^\s+//; + $users =~ s/^\s+//; + $users =~ s/\n//g; + $date =~ s/^\s+//; + $desc =~ s/^\s+//; + + printf "Kernel version:\t\t%s\n", $kernelversion if ($kernelversion); + printf "Date:\t\t\t%s\n", $date if ($date); + printf "Contact:\t\t%s\n", $contact if ($contact); + printf "Users:\t\t\t%s\n", $users if ($users); + print "Defined on file:\t$file\n\n"; + print "Description:\n\n$desc"; + } +} + + +# +# Parses all ABI files located at $prefix dir +# +find({wanted =>\&parse_abi, no_chdir => 1}, $prefix); + +print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug); + +# +# Handles the command +# +if ($cmd eq "rest") { + output_rest; +} elsif ($cmd eq "search") { + search_symbols; +} + + +__END__ + +=head1 NAME + +abi_book.pl - parse the Linux ABI files and produce a ReST book. + +=head1 SYNOPSIS + +B [--debug] [--man] [--help] [--dir=] [] + +Where can be: + +=over 8 + +B [SEARCH_REGEX] - search for [SEARCH_REGEX] inside ABI + +B - output the ABI in ReST markup language + +B - validate the ABI contents + +=back + +=head1 OPTIONS + +=over 8 + +=item B<--dir> + +Changes the location of the ABI search. By default, it uses +the Documentation/ABI directory. + +=item B<--debug> + +Put the script in verbose mode, useful for debugging. Can be called multiple +times, to increase verbosity. + +=item B<--help> + +Prints a brief help message and exits. + +=item B<--man> + +Prints the manual page and exits. + +=back + +=head1 DESCRIPTION + +Parse the Linux ABI files from ABI DIR (usually located at Documentation/ABI), +allowing to search for ABI symbols or to produce a ReST book containing +the Linux ABI documentation. + +=head1 EXAMPLES + +Search for all stable symbols with the word "usb": + +=over 8 + +$ scripts/get_abi.pl search usb --dir Documentation/ABI/stable + +=back + +Search for all symbols that match the regex expression "usb.*cap": + +=over 8 + +$ scripts/get_abi.pl search usb.*cap + +=back + +Output all obsoleted symbols in ReST format + +=over 8 + +$ scripts/get_abi.pl rest --dir Documentation/ABI/obsolete + +=back + +=head1 BUGS + +Report bugs to Mauro Carvalho Chehab + +=head1 COPYRIGHT + +Copyright (c) 2016-2019 by Mauro Carvalho Chehab . + +License GPLv2: GNU GPL version 2 . + +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +=cut diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c index 7a3e138594c175..c16b0ffe8cfc54 100644 --- a/sound/soc/rockchip/rk3399_gru_sound.c +++ b/sound/soc/rockchip/rk3399_gru_sound.c @@ -422,7 +422,7 @@ static const struct dailink_match_data dailink_match[] = { }, }; -static int of_dev_node_match(struct device *dev, void *data) +static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; } diff --git a/tools/firmware/Makefile b/tools/firmware/Makefile index d329825aa31be3..cfb297e6ef5ae4 100644 --- a/tools/firmware/Makefile +++ b/tools/firmware/Makefile @@ -10,4 +10,4 @@ all: ihex2fw clean: $(RM) ihex2fw -.PHONY: all clean \ No newline at end of file +.PHONY: all clean diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh index a4320c4b44dc9c..f901076aa2ea0c 100755 --- a/tools/testing/selftests/firmware/fw_filesystem.sh +++ b/tools/testing/selftests/firmware/fw_filesystem.sh @@ -153,13 +153,18 @@ config_set_read_fw_idx() read_firmwares() { + if [ "$1" = "xzonly" ]; then + fwfile="${FW}-orig" + else + fwfile="$FW" + fi for i in $(seq 0 3); do config_set_read_fw_idx $i # Verify the contents are what we expect. # -Z required for now -- check for yourself, md5sum # on $FW and DIR/read_firmware will yield the same. Even # cmp agrees, so something is off. - if ! diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then + if ! diff -q -Z "$fwfile" $DIR/read_firmware 2>/dev/null ; then echo "request #$i: firmware was not loaded" >&2 exit 1 fi @@ -246,17 +251,17 @@ test_request_firmware_nowait_custom_nofile() test_batched_request_firmware() { - echo -n "Batched request_firmware() try #$1: " + echo -n "Batched request_firmware() $2 try #$1: " config_reset config_trigger_sync - read_firmwares + read_firmwares $2 release_all_firmware echo "OK" } test_batched_request_firmware_direct() { - echo -n "Batched request_firmware_direct() try #$1: " + echo -n "Batched request_firmware_direct() $2 try #$1: " config_reset config_set_sync_direct config_trigger_sync @@ -266,7 +271,7 @@ test_batched_request_firmware_direct() test_request_firmware_nowait_uevent() { - echo -n "Batched request_firmware_nowait(uevent=true) try #$1: " + echo -n "Batched request_firmware_nowait(uevent=true) $2 try #$1: " config_reset config_trigger_async release_all_firmware @@ -275,11 +280,16 @@ test_request_firmware_nowait_uevent() test_request_firmware_nowait_custom() { - echo -n "Batched request_firmware_nowait(uevent=false) try #$1: " + echo -n "Batched request_firmware_nowait(uevent=false) $2 try #$1: " config_reset config_unset_uevent RANDOM_FILE_PATH=$(setup_random_file) RANDOM_FILE="$(basename $RANDOM_FILE_PATH)" + if [ "$2" = "both" ]; then + xz -9 -C crc32 -k $RANDOM_FILE_PATH + elif [ "$2" = "xzonly" ]; then + xz -9 -C crc32 $RANDOM_FILE_PATH + fi config_set_name $RANDOM_FILE config_trigger_async release_all_firmware @@ -294,19 +304,19 @@ test_config_present echo echo "Testing with the file present..." for i in $(seq 1 5); do - test_batched_request_firmware $i + test_batched_request_firmware $i normal done for i in $(seq 1 5); do - test_batched_request_firmware_direct $i + test_batched_request_firmware_direct $i normal done for i in $(seq 1 5); do - test_request_firmware_nowait_uevent $i + test_request_firmware_nowait_uevent $i normal done for i in $(seq 1 5); do - test_request_firmware_nowait_custom $i + test_request_firmware_nowait_custom $i normal done # Test for file not found, errors are expected, the failure would be @@ -329,4 +339,47 @@ for i in $(seq 1 5); do test_request_firmware_nowait_custom_nofile $i done +test "$HAS_FW_LOADER_COMPRESS" != "yes" && exit 0 + +# test with both files present +xz -9 -C crc32 -k $FW +config_set_name $NAME +echo +echo "Testing with both plain and xz files present..." +for i in $(seq 1 5); do + test_batched_request_firmware $i both +done + +for i in $(seq 1 5); do + test_batched_request_firmware_direct $i both +done + +for i in $(seq 1 5); do + test_request_firmware_nowait_uevent $i both +done + +for i in $(seq 1 5); do + test_request_firmware_nowait_custom $i both +done + +# test with only xz file present +mv "$FW" "${FW}-orig" +echo +echo "Testing with only xz file present..." +for i in $(seq 1 5); do + test_batched_request_firmware $i xzonly +done + +for i in $(seq 1 5); do + test_batched_request_firmware_direct $i xzonly +done + +for i in $(seq 1 5); do + test_request_firmware_nowait_uevent $i xzonly +done + +for i in $(seq 1 5); do + test_request_firmware_nowait_custom $i xzonly +done + exit 0 diff --git a/tools/testing/selftests/firmware/fw_lib.sh b/tools/testing/selftests/firmware/fw_lib.sh index 1cbb12e284a689..f236cc2954502b 100755 --- a/tools/testing/selftests/firmware/fw_lib.sh +++ b/tools/testing/selftests/firmware/fw_lib.sh @@ -50,6 +50,7 @@ check_setup() { HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)" HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)" + HAS_FW_LOADER_COMPRESS="$(kconfig_has CONFIG_FW_LOADER_COMPRESS=y)" PROC_FW_IGNORE_SYSFS_FALLBACK="0" PROC_FW_FORCE_SYSFS_FALLBACK="0" @@ -84,6 +85,12 @@ check_setup() fi OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)" + + if [ "$HAS_FW_LOADER_COMPRESS" = "yes" ]; then + if ! which xz 2> /dev/null > /dev/null; then + HAS_FW_LOADER_COMPRESS="" + fi + fi } verify_reqs() diff --git a/tools/testing/selftests/firmware/fw_run_tests.sh b/tools/testing/selftests/firmware/fw_run_tests.sh index cffdd4eb0a57cc..8e14d555c19784 100755 --- a/tools/testing/selftests/firmware/fw_run_tests.sh +++ b/tools/testing/selftests/firmware/fw_run_tests.sh @@ -11,6 +11,7 @@ source $TEST_DIR/fw_lib.sh export HAS_FW_LOADER_USER_HELPER="" export HAS_FW_LOADER_USER_HELPER_FALLBACK="" +export HAS_FW_LOADER_COMPRESS="" run_tests() {