diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-27 11:53:57 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-27 11:53:57 -0700 |
| commit | 556eb8b79190151506187bf0b16dda423c34d9a8 (patch) | |
| tree | 76fe79cf977e03be1b70059eef3195b89fe39948 | |
| parent | 97b2ff294381d05e59294a931c4db55276470cb5 (diff) | |
| parent | 046b6a171009e1ed9ede02194025e9ccd709beb2 (diff) | |
| download | net-556eb8b79190151506187bf0b16dda423c34d9a8.tar.gz | |
Merge tag 'driver-core-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH:
"Here is the large set of driver core changes for 6.4-rc1.
Once again, a busy development cycle, with lots of changes happening
in the driver core in the quest to be able to move "struct bus" and
"struct class" into read-only memory, a task now complete with these
changes.
This will make the future rust interactions with the driver core more
"provably correct" as well as providing more obvious lifetime rules
for all busses and classes in the kernel.
The changes required for this did touch many individual classes and
busses as many callbacks were changed to take const * parameters
instead. All of these changes have been submitted to the various
subsystem maintainers, giving them plenty of time to review, and most
of them actually did so.
Other than those changes, included in here are a small set of other
things:
- kobject logging improvements
- cacheinfo improvements and updates
- obligatory fw_devlink updates and fixes
- documentation updates
- device property cleanups and const * changes
- firwmare loader dependency fixes.
All of these have been in linux-next for a while with no reported
problems"
* tag 'driver-core-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (120 commits)
device property: make device_property functions take const device *
driver core: update comments in device_rename()
driver core: Don't require dynamic_debug for initcall_debug probe timing
firmware_loader: rework crypto dependencies
firmware_loader: Strip off \n from customized path
zram: fix up permission for the hot_add sysfs file
cacheinfo: Add use_arch[|_cache]_info field/function
arch_topology: Remove early cacheinfo error message if -ENOENT
cacheinfo: Check cache properties are present in DT
cacheinfo: Check sib_leaf in cache_leaves_are_shared()
cacheinfo: Allow early level detection when DT/ACPI info is missing/broken
cacheinfo: Add arm64 early level initializer implementation
cacheinfo: Add arch specific early level initializer
tty: make tty_class a static const structure
driver core: class: remove struct class_interface * from callbacks
driver core: class: mark the struct class in struct class_interface constant
driver core: class: make class_register() take a const *
driver core: class: mark class_release() as taking a const *
driver core: remove incorrect comment for device_create*
MIPS: vpe-cmp: remove module owner pointer from struct class usage.
...
297 files changed, 1684 insertions, 1289 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-state_synced b/Documentation/ABI/testing/sysfs-devices-state_synced index 0c922d7d02fc27..c64636ddac410a 100644 --- a/Documentation/ABI/testing/sysfs-devices-state_synced +++ b/Documentation/ABI/testing/sysfs-devices-state_synced @@ -21,4 +21,9 @@ Description: at the time the kernel starts are not affected or limited in any way by sync_state() callbacks. + Writing "1" to this file will force a call to the device's + sync_state() function if it hasn't been called already. The + sync_state() call happens independent of the state of the + consumer devices. + diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index bbecbd5797a33e..56efff519454b8 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1602,6 +1602,20 @@ dependencies. This only applies for fw_devlink=on|rpm. Format: <bool> + fw_devlink.sync_state = + [KNL] When all devices that could probe have finished + probing, this parameter controls what to do with + devices that haven't yet received their sync_state() + calls. + Format: { strict | timeout } + strict -- Default. Continue waiting on consumers to + probe successfully. + timeout -- Give up waiting on consumers and call + sync_state() on any devices that haven't yet + received their sync_state() calls after + deferred_probe_timeout has expired or by + late_initcall() if !CONFIG_MODULES. + gamecon.map[2|3]= [HW,JOY] Multisystem joystick and NES/SNES/PSX pad support via parallel port (up to 5 devices per port) @@ -6150,15 +6164,6 @@ later by a loaded module cannot be set this way. Example: sysctl.vm.swappiness=40 - sysfs.deprecated=0|1 [KNL] - Enable/disable old style sysfs layout for old udev - on older distributions. When this option is enabled - very new udev will not work anymore. When this option - is disabled (or CONFIG_SYSFS_DEPRECATED not compiled) - in older udev will not work anymore. - Default depends on CONFIG_SYSFS_DEPRECATED_V2 set in - the kernel configuration. - sysrq_always_enabled [KNL] Ignore sysrq setting - this boot parameter will diff --git a/Documentation/driver-api/driver-model/bus.rst b/Documentation/driver-api/driver-model/bus.rst index 016b15a6e8ea97..9709ab62a4682c 100644 --- a/Documentation/driver-api/driver-model/bus.rst +++ b/Documentation/driver-api/driver-model/bus.rst @@ -125,8 +125,8 @@ Exporting Attributes 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); + ssize_t (*show)(const struct bus_type *, char * buf); + ssize_t (*store)(const struct bus_type *, const char * buf, size_t count); }; Bus drivers can export attributes using the BUS_ATTR_RW macro that works diff --git a/Documentation/driver-api/firmware/fw_upload.rst b/Documentation/driver-api/firmware/fw_upload.rst index 76922591e44630..edf1d0c5e7c34d 100644 --- a/Documentation/driver-api/firmware/fw_upload.rst +++ b/Documentation/driver-api/firmware/fw_upload.rst @@ -57,7 +57,8 @@ function calls firmware_upload_unregister() such as:: len = (truncate) ? truncate - fw_name : strlen(fw_name); sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL); - fwl = firmware_upload_register(sec->dev, sec->fw_name, &m10bmc_ops, sec); + fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name, + &m10bmc_ops, sec); if (IS_ERR(fwl)) { dev_err(sec->dev, "Firmware Upload driver failed to start\n"); kfree(sec->fw_name); diff --git a/Documentation/filesystems/sysfs.rst b/Documentation/filesystems/sysfs.rst index f8187d466b97bd..c32993bc83c704 100644 --- a/Documentation/filesystems/sysfs.rst +++ b/Documentation/filesystems/sysfs.rst @@ -373,8 +373,8 @@ Structure:: 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); + ssize_t (*show)(const struct bus_type *, char * buf); + ssize_t (*store)(const struct bus_type *, const char * buf, size_t count); }; Declaring:: diff --git a/Documentation/translations/zh_CN/filesystems/sysfs.txt b/Documentation/translations/zh_CN/filesystems/sysfs.txt index 046cc1d52058de..547062759e60c0 100644 --- a/Documentation/translations/zh_CN/filesystems/sysfs.txt +++ b/Documentation/translations/zh_CN/filesystems/sysfs.txt @@ -329,8 +329,8 @@ void device_remove_file(struct device *dev, const struct device_attribute * attr 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); + ssize_t (*show)(const struct bus_type *, char * buf); + ssize_t (*store)(const struct bus_type *, const char * buf, size_t count); }; 声明: diff --git a/Documentation/translations/zh_TW/filesystems/sysfs.txt b/Documentation/translations/zh_TW/filesystems/sysfs.txt index acd677f19d4fc1..280824cc7e5ddd 100644 --- a/Documentation/translations/zh_TW/filesystems/sysfs.txt +++ b/Documentation/translations/zh_TW/filesystems/sysfs.txt @@ -332,8 +332,8 @@ void device_remove_file(struct device *dev, const struct device_attribute * attr 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); + ssize_t (*show)(const struct bus_type *, char * buf); + ssize_t (*store)(const struct bus_type *, const char * buf, size_t count); }; 聲明: diff --git a/MAINTAINERS b/MAINTAINERS index 1f83f99e7eb269..40b586033a060c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6333,7 +6333,9 @@ F: drivers/base/ F: fs/debugfs/ F: fs/sysfs/ F: include/linux/debugfs.h +F: include/linux/fwnode.h F: include/linux/kobj* +F: include/linux/property.h F: lib/kobj* DRIVERS FOR OMAP ADAPTIVE VOLTAGE SCALING (AVS) diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h index fe9ef6f79e9cfe..82ec1ccf1fee4c 100644 --- a/arch/arm/include/asm/dma-iommu.h +++ b/arch/arm/include/asm/dma-iommu.h @@ -24,7 +24,7 @@ struct dma_iommu_mapping { }; struct dma_iommu_mapping * -arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size); +arm_iommu_create_mapping(const struct bus_type *bus, dma_addr_t base, u64 size); void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping); diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 8bc01071474ab7..b4a33358d2e9c8 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1543,7 +1543,7 @@ static const struct dma_map_ops iommu_ops = { * arm_iommu_attach_device function. */ struct dma_iommu_mapping * -arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size) +arm_iommu_create_mapping(const struct bus_type *bus, dma_addr_t base, u64 size) { unsigned int bits = size >> PAGE_SHIFT; unsigned int bitmap_size = BITS_TO_LONGS(bits) * sizeof(long); diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c index c307f69e9b55dd..d9c9218fa1fddc 100644 --- a/arch/arm64/kernel/cacheinfo.c +++ b/arch/arm64/kernel/cacheinfo.c @@ -38,11 +38,9 @@ static void ci_leaf_init(struct cacheinfo *this_leaf, this_leaf->type = type; } -int init_cache_level(unsigned int cpu) +static void detect_cache_level(unsigned int *level_p, unsigned int *leaves_p) { unsigned int ctype, level, leaves; - int fw_level, ret; - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) { ctype = get_cache_type(level); @@ -54,6 +52,27 @@ int init_cache_level(unsigned int cpu) leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1; } + *level_p = level; + *leaves_p = leaves; +} + +int early_cache_level(unsigned int cpu) +{ + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + + detect_cache_level(&this_cpu_ci->num_levels, &this_cpu_ci->num_leaves); + + return 0; +} + +int init_cache_level(unsigned int cpu) +{ + unsigned int level, leaves; + int fw_level, ret; + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + + detect_cache_level(&level, &leaves); + if (acpi_disabled) { fw_level = of_find_last_cache_level(cpu); } else { diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 1bdad599e7696e..2f9911256503fc 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1497,10 +1497,18 @@ static const DEVICE_ATTR_RO(aarch32_el0); static int __init aarch32_el0_sysfs_init(void) { + struct device *dev_root; + int ret = 0; + if (!allow_mismatched_32bit_el0) return 0; - return device_create_file(cpu_subsys.dev_root, &dev_attr_aarch32_el0); + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + ret = device_create_file(dev_root, &dev_attr_aarch32_el0); + put_device(dev_root); + } + return ret; } device_initcall(aarch32_el0_sysfs_init); diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index dc023a97980356..f88b7919f11f49 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -234,7 +234,7 @@ static int __init mips_mt_init(void) { struct class *mtc; - mtc = class_create(THIS_MODULE, "mt"); + mtc = class_create("mt"); if (IS_ERR(mtc)) return PTR_ERR(mtc); diff --git a/arch/mips/kernel/vpe-cmp.c b/arch/mips/kernel/vpe-cmp.c index 92140edb3ce3ed..4ef7f49a4c6d37 100644 --- a/arch/mips/kernel/vpe-cmp.c +++ b/arch/mips/kernel/vpe-cmp.c @@ -79,7 +79,6 @@ static void vpe_device_release(struct device *cd) static struct class vpe_class = { .name = "vpe", - .owner = THIS_MODULE, .dev_release = vpe_device_release, .dev_groups = vpe_groups, }; diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c index 223d6274f2e5b2..667bc75f642031 100644 --- a/arch/mips/kernel/vpe-mt.c +++ b/arch/mips/kernel/vpe-mt.c @@ -316,7 +316,6 @@ static void vpe_device_release(struct device *cd) static struct class vpe_class = { .name = "vpe", - .owner = THIS_MODULE, .dev_release = vpe_device_release, .dev_groups = vpe_groups, }; diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c index bc47681e825a3d..ac376dfb4e7ca7 100644 --- a/arch/mips/sibyte/common/sb_tbprof.c +++ b/arch/mips/sibyte/common/sb_tbprof.c @@ -550,7 +550,7 @@ static int __init sbprof_tb_init(void) return -EIO; } - tbc = class_create(THIS_MODULE, "sb_tracebuffer"); + tbc = class_create("sb_tracebuffer"); if (IS_ERR(tbc)) { err = PTR_ERR(tbc); goto out_chrdev; diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index ef9a6171894036..0f39a6b8413286 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -217,13 +217,18 @@ static DEVICE_ATTR(dscr_default, 0600, static void __init sysfs_create_dscr_default(void) { if (cpu_has_feature(CPU_FTR_DSCR)) { + struct device *dev_root; int cpu; dscr_default = spr_default_dscr; for_each_possible_cpu(cpu) paca_ptrs[cpu]->dscr_default = dscr_default; - device_create_file(cpu_subsys.dev_root, &dev_attr_dscr_default); + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + device_create_file(dev_root, &dev_attr_dscr_default); + put_device(dev_root); + } } } #endif /* CONFIG_PPC64 */ @@ -746,7 +751,12 @@ static DEVICE_ATTR(svm, 0444, show_svm, NULL); static void __init create_svm_file(void) { - device_create_file(cpu_subsys.dev_root, &dev_attr_svm); + struct device *dev_root = bus_get_dev_root(&cpu_subsys); + + if (dev_root) { + device_create_file(dev_root, &dev_attr_svm); + put_device(dev_root); + } } #else static void __init create_svm_file(void) diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c index 36c21648d19a36..77ea9335fd049c 100644 --- a/arch/powerpc/platforms/book3s/vas-api.c +++ b/arch/powerpc/platforms/book3s/vas-api.c @@ -581,7 +581,7 @@ int vas_register_coproc_api(struct module *mod, enum vas_cop_type cop_type, pr_devel("%s device allocated, dev [%i,%i]\n", name, MAJOR(coproc_device.devt), MINOR(coproc_device.devt)); - coproc_device.class = class_create(mod, name); + coproc_device.class = class_create(name); if (IS_ERR(coproc_device.class)) { rc = PTR_ERR(coproc_device.class); pr_err("Unable to create %s class %d\n", name, rc); diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 841cb7f31f4f4d..6dfe8d611164fd 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -1464,14 +1464,19 @@ static int __init pnv_init_idle_states(void) power7_fastsleep_workaround_entry = false; power7_fastsleep_workaround_exit = false; } else { + struct device *dev_root; /* * OPAL_PM_SLEEP_ENABLED_ER1 is set. It indicates that * workaround is needed to use fastsleep. Provide sysfs * control to choose how this workaround has to be * applied. */ - device_create_file(cpu_subsys.dev_root, - &dev_attr_fastsleep_workaround_applyonce); + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + device_create_file(dev_root, + &dev_attr_fastsleep_workaround_applyonce); + put_device(dev_root); + } } update_subcore_sibling_mask(); diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c index 7e98b00ea2e843..428532a6976277 100644 --- a/arch/powerpc/platforms/powernv/subcore.c +++ b/arch/powerpc/platforms/powernv/subcore.c @@ -415,7 +415,9 @@ static DEVICE_ATTR(subcores_per_core, 0644, static int subcore_init(void) { + struct device *dev_root; unsigned pvr_ver; + int rc = 0; pvr_ver = PVR_VER(mfspr(SPRN_PVR)); @@ -435,7 +437,11 @@ static int subcore_init(void) set_subcores_per_core(1); - return device_create_file(cpu_subsys.dev_root, - &dev_attr_subcores_per_core); + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + rc = device_create_file(dev_root, &dev_attr_subcores_per_core); + put_device(dev_root); + } + return rc; } machine_device_initcall(powernv, subcore_init); diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 75ffdbcd28659e..719c97a155edfa 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -512,7 +512,7 @@ static int dlpar_parse_id_type(char **cmd, struct pseries_hp_errorlog *hp_elog) return 0; } -static ssize_t dlpar_store(struct class *class, struct class_attribute *attr, +static ssize_t dlpar_store(const struct class *class, const struct class_attribute *attr, const char *buf, size_t count) { struct pseries_hp_errorlog hp_elog; @@ -551,7 +551,7 @@ dlpar_store_out: return rc ? rc : count; } -static ssize_t dlpar_show(struct class *class, struct class_attribute *attr, +static ssize_t dlpar_show(const struct class *class, const struct class_attribute *attr, char *buf) { return sprintf(buf, "%s\n", "memory,cpu"); diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index bb9c1868278335..44703f13985bf3 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -267,7 +267,7 @@ static char *ibmebus_chomp(const char *in, size_t count) return out; } -static ssize_t probe_store(struct bus_type *bus, const char *buf, size_t count) +static ssize_t probe_store(const struct bus_type *bus, const char *buf, size_t count) { struct device_node *dn = NULL; struct device *dev; @@ -305,7 +305,7 @@ out: } static BUS_ATTR_WO(probe); -static ssize_t remove_store(struct bus_type *bus, const char *buf, size_t count) +static ssize_t remove_store(const struct bus_type *bus, const char *buf, size_t count) { struct device *dev; char *path; diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 643d309d1bd052..6b25642adfa045 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -787,8 +787,8 @@ int rtas_syscall_dispatch_ibm_suspend_me(u64 handle) return pseries_migrate_partition(handle); } -static ssize_t migration_store(struct class *class, - struct class_attribute *attr, const char *buf, +static ssize_t migration_store(const struct class *class, + const struct class_attribute *attr, const char *buf, size_t count) { u64 streamid; diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c index 09e98d301db0f3..2c661b798235ed 100644 --- a/arch/powerpc/platforms/pseries/pseries_energy.c +++ b/arch/powerpc/platforms/pseries/pseries_energy.c @@ -300,20 +300,22 @@ static struct device_attribute attr_percpu_deactivate_hint = static int __init pseries_energy_init(void) { int cpu, err; - struct device *cpu_dev; + struct device *cpu_dev, *dev_root; if (!firmware_has_feature(FW_FEATURE_BEST_ENERGY)) return 0; /* H_BEST_ENERGY hcall not supported */ /* Create the sysfs files */ - err = device_create_file(cpu_subsys.dev_root, - &attr_cpu_activate_hint_list); - if (!err) - err = device_create_file(cpu_subsys.dev_root, - &attr_cpu_deactivate_hint_list); + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + err = device_create_file(dev_root, &attr_cpu_activate_hint_list); + if (!err) + err = device_create_file(dev_root, &attr_cpu_deactivate_hint_list); + put_device(dev_root); + if (err) + return err; + } - if (err) - return err; for_each_possible_cpu(cpu) { cpu_dev = get_cpu_device(cpu); err = device_create_file(cpu_dev, @@ -337,14 +339,18 @@ static int __init pseries_energy_init(void) static void __exit pseries_energy_cleanup(void) { int cpu; - struct device *cpu_dev; + struct device *cpu_dev, *dev_root; if (!sysfs_entries) return; /* Remove the sysfs files */ - device_remove_file(cpu_subsys.dev_root, &attr_cpu_activate_hint_list); - device_remove_file(cpu_subsys.dev_root, &attr_cpu_deactivate_hint_list); + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + device_remove_file(dev_root, &attr_cpu_activate_hint_list); + device_remove_file(dev_root, &attr_cpu_deactivate_hint_list); + put_device(dev_root); + } for_each_possible_cpu(cpu) { cpu_dev = get_cpu_device(cpu); diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index 1b902cbf85c537..5c43435472cc3b 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c @@ -143,6 +143,7 @@ static const struct platform_suspend_ops pseries_suspend_ops = { **/ static int pseries_suspend_sysfs_register(struct device *dev) { + struct device *dev_root; int rc; if ((rc = subsys_system_register(&suspend_subsys, NULL))) @@ -151,8 +152,13 @@ static int pseries_suspend_sysfs_register(struct device *dev) dev->id = 0; dev->bus = &suspend_subsys; - if ((rc = device_create_file(suspend_subsys.dev_root, &dev_attr_hibernate))) - goto subsys_unregister; + dev_root = bus_get_dev_root(&suspend_subsys); + if (dev_root) { + rc = device_create_file(dev_root, &dev_attr_hibernate); + put_device(dev_root); + if (rc) + goto subsys_unregister; + } return 0; diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index 770df9351aaa98..bf7aff6390be39 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -1006,7 +1006,7 @@ ATTRIBUTE_GROUPS(vio_cmo_dev); /* sysfs bus functions and data structures for CMO */ #define viobus_cmo_rd_attr(name) \ -static ssize_t cmo_bus_##name##_show(struct bus_type *bt, char *buf) \ +static ssize_t cmo_bus_##name##_show(const struct bus_type *bt, char *buf) \ { \ return sprintf(buf, "%lu\n", vio_cmo.name); \ } \ @@ -1015,7 +1015,7 @@ static struct bus_attribute bus_attr_cmo_bus_##name = \ #define viobus_cmo_pool_rd_attr(name, var) \ static ssize_t \ -cmo_##name##_##var##_show(struct bus_type *bt, char *buf) \ +cmo_##name##_##var##_show(const struct bus_type *bt, char *buf) \ { \ return sprintf(buf, "%lu\n", vio_cmo.name.var); \ } \ @@ -1030,12 +1030,12 @@ viobus_cmo_pool_rd_attr(reserve, size); viobus_cmo_pool_rd_attr(excess, size); viobus_cmo_pool_rd_attr(excess, free); -static ssize_t cmo_high_show(struct bus_type *bt, char *buf) +static ssize_t cmo_high_show(const struct bus_type *bt, char *buf) { return sprintf(buf, "%lu\n", vio_cmo.high); } -static ssize_t cmo_high_store(struct bus_type *bt, const char *buf, +static ssize_t cmo_high_store(const struct bus_type *bt, const char *buf, size_t count) { unsigned long flags; diff --git a/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c b/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c index c2baa283e62434..ce6c739c51e510 100644 --- a/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c +++ b/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c @@ -116,7 +116,8 @@ static struct device_attribute mpic_attributes = __ATTR(timer_wakeup, 0644, static int __init fsl_wakeup_sys_init(void) { - int ret; + struct device *dev_root; + int ret = -EINVAL; fsl_wakeup = kzalloc(sizeof(struct fsl_mpic_timer_wakeup), GFP_KERNEL); if (!fsl_wakeup) @@ -124,16 +125,26 @@ static int __init fsl_wakeup_sys_init(void) INIT_WORK(&fsl_wakeup->free_work, fsl_free_resource); - ret = device_create_file(mpic_subsys.dev_root, &mpic_attributes); - if (ret) - kfree(fsl_wakeup); + dev_root = bus_get_dev_root(&mpic_subsys); + if (dev_root) { + ret = device_create_file(dev_root, &mpic_attributes); + put_device(dev_root); + if (ret) + kfree(fsl_wakeup); + } return ret; } static void __exit fsl_wakeup_sys_exit(void) { - device_remove_file(mpic_subsys.dev_root, &mpic_attributes); + struct device *dev_root; + + dev_root = bus_get_dev_root(&mpic_subsys); + if (dev_root) { + device_remove_file(dev_root, &mpic_attributes); + put_device(dev_root); + } mutex_lock(&sysfs_lock); diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index d4888453bbf8b1..4df797ab8ca273 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1227,11 +1227,17 @@ static DEVICE_ATTR_WO(rescan); static int __init s390_smp_init(void) { + struct device *dev_root; int cpu, rc = 0; - rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan); - if (rc) - return rc; + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + rc = device_create_file(dev_root, &dev_attr_rescan); + put_device(dev_root); + if (rc) + return rc; + } + for_each_present_cpu(cpu) { rc = smp_add_present_cpu(cpu); if (rc) diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index c6eecd4a5302d0..72af753d1bbacc 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -649,12 +649,21 @@ static struct ctl_table topology_dir_table[] = { static int __init topology_init(void) { + struct device *dev_root; + int rc = 0; + timer_setup(&topology_timer, topology_timer_fn, TIMER_DEFERRABLE); if (MACHINE_HAS_TOPOLOGY) set_topology_timer(); else topology_update_polarization_simple(); register_sysctl_table(topology_dir_table); - return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); + + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + rc = device_create_file(dev_root, &dev_attr_dispatching); + put_device(dev_root); + } + return rc; } device_initcall(topology_init); diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c index 8ef318150f84db..431bc18f0a4119 100644 --- a/arch/sh/drivers/dma/dma-sysfs.c +++ b/arch/sh/drivers/dma/dma-sysfs.c @@ -45,13 +45,19 @@ static DEVICE_ATTR(devices, S_IRUGO, dma_show_devices, NULL); static int __init dma_subsys_init(void) { + struct device *dev_root; int ret; ret = subsys_system_register(&dma_subsys, NULL); if (unlikely(ret)) return ret; - return device_create_file(dma_subsys.dev_root, &dev_attr_devices); + dev_root = bus_get_dev_root(&dma_subsys); + if (dev_root) { + ret = device_create_file(dev_root, &dev_attr_devices); + put_device(dev_root); + } + return ret; } postcore_initcall(dma_subsys_init); diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 7a329e5613544b..3afcf3de0dd494 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -632,6 +632,7 @@ static const struct attribute_group cpu_root_microcode_group = { static int __init microcode_init(void) { + struct device *dev_root; struct cpuinfo_x86 *c = &boot_cpu_data; int error; @@ -652,10 +653,14 @@ static int __init microcode_init(void) if (IS_ERR(microcode_pdev)) return PTR_ERR(microcode_pdev); - error = sysfs_create_group(&cpu_subsys.dev_root->kobj, &cpu_root_microcode_group); - if (error) { - pr_err("Error creating microcode group!\n"); - goto out_pdev; + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + error = sysfs_create_group(&dev_root->kobj, &cpu_root_microcode_group); + put_device(dev_root); + if (error) { + pr_err("Error creating microcode group!\n"); + goto out_pdev; + } } /* Do per-CPU setup */ diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c index 524f8ff3e69c78..458cb74195022e 100644 --- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c +++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c @@ -1580,7 +1580,7 @@ int rdt_pseudo_lock_init(void) pseudo_lock_major = ret; - pseudo_lock_class = class_create(THIS_MODULE, "pseudo_lock"); + pseudo_lock_class = class_create("pseudo_lock"); if (IS_ERR(pseudo_lock_class)) { ret = PTR_ERR(pseudo_lock_class); unregister_chrdev(pseudo_lock_major, "pseudo_lock"); diff --git a/arch/x86/kernel/cpu/umwait.c b/arch/x86/kernel/cpu/umwait.c index ec8064c0ae035d..2293efd6ffa696 100644 --- a/arch/x86/kernel/cpu/umwait.c +++ b/arch/x86/kernel/cpu/umwait.c @@ -232,7 +232,11 @@ static int __init umwait_init(void) * Add umwait control interface. Ignore failure, so at least the * default values are set up in case the machine manages to boot. */ - dev = cpu_subsys.dev_root; - return sysfs_create_group(&dev->kobj, &umwait_attr_group); + dev = bus_get_dev_root(&cpu_subsys); + if (dev) { + ret = sysfs_create_group(&dev->kobj, &umwait_attr_group); + put_device(dev); + } + return ret; } device_initcall(umwait_init); diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 621ba9c0f17a9d..bdc0d5539b5706 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -154,7 +154,7 @@ static int __init cpuid_init(void) CPUID_MAJOR); return -EBUSY; } - cpuid_class = class_create(THIS_MODULE, "cpuid"); + cpuid_class = class_create("cpuid"); if (IS_ERR(cpuid_class)) { err = PTR_ERR(cpuid_class); goto out_chrdev; diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 7087513117861e..7bb17d37db0117 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -263,7 +263,7 @@ static int __init msr_init(void) pr_err("unable to get major %d for msr\n", MSR_MAJOR); return -EBUSY; } - msr_class = class_create(THIS_MODULE, "msr"); + msr_class = class_create("msr"); if (IS_ERR(msr_class)) { err = PTR_ERR(msr_class); goto out_chrdev; diff --git a/block/bsg.c b/block/bsg.c index 30fcc865ef4f0a..7eca43f33d7ff8 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -245,7 +245,7 @@ static int __init bsg_init(void) dev_t devid; int ret; - bsg_class = class_create(THIS_MODULE, "bsg"); + bsg_class = class_create("bsg"); if (IS_ERR(bsg_class)) return PTR_ERR(bsg_class); bsg_class->devnode = bsg_devnode; diff --git a/block/genhd.c b/block/genhd.c index 2d58ac54043ace..90c402771bb570 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -475,12 +475,10 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, if (ret) goto out_device_del; - if (!sysfs_deprecated) { - ret = sysfs_create_link(block_depr, &ddev->kobj, - kobject_name(&ddev->kobj)); - if (ret) - goto out_device_del; - } + ret = sysfs_create_link(block_depr, &ddev->kobj, + kobject_name(&ddev->kobj)); + if (ret) + goto out_device_del; /* * avoid probable deadlock caused by allocating memory with @@ -563,8 +561,7 @@ out_put_holder_dir: out_del_integrity: blk_integrity_del(disk); out_del_block_link: - if (!sysfs_deprecated) - sysfs_remove_link(block_depr, dev_name(ddev)); + sysfs_remove_link(block_depr, dev_name(ddev)); out_device_del: device_del(ddev); out_free_ext_minor: @@ -666,8 +663,7 @@ void del_gendisk(struct gendisk *disk) part_stat_set_all(disk->part0, 0); disk->part0->bd_stamp = 0; - if (!sysfs_deprecated) - sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); + sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); pm_runtime_set_memalloc_noio(disk_to_dev(disk), false); device_del(disk_to_dev(disk)); @@ -912,7 +908,6 @@ static int __init genhd_device_init(void) { int error; - block_class.dev_kobj = sysfs_dev_block_kobj; error = class_register(&block_class); if (unlikely(error)) return error; @@ -921,8 +916,7 @@ static int __init genhd_device_init(void) register_blkdev(BLOCK_EXT_MAJOR, "blkext"); /* create top-level block dir */ - if (!sysfs_deprecated) - block_depr = kobject_create_and_add("block", NULL); + block_depr = kobject_create_and_add("block", NULL); return 0; } diff --git a/drivers/accel/drm_accel.c b/drivers/accel/drm_accel.c index 1b69824286fd3f..4a9baf02439e42 100644 --- a/drivers/accel/drm_accel.c +++ b/drivers/accel/drm_accel.c @@ -34,7 +34,7 @@ static char *accel_devnode(const struct device *dev, umode_t *mode) static int accel_sysfs_init(void) { - accel_class = class_create(THIS_MODULE, "accel"); + accel_class = class_create("accel"); if (IS_ERR(accel_class)) return PTR_ERR(accel_class); diff --git a/drivers/accel/habanalabs/common/habanalabs_drv.c b/drivers/accel/habanalabs/common/habanalabs_drv.c index a4b3f50f1cba04..d9df64e75f33ad 100644 --- a/drivers/accel/habanalabs/common/habanalabs_drv.c +++ b/drivers/accel/habanalabs/common/habanalabs_drv.c @@ -696,7 +696,7 @@ static int __init hl_init(void) hl_major = MAJOR(dev); - hl_class = class_create(THIS_MODULE, HL_NAME); + hl_class = class_create(HL_NAME); if (IS_ERR(hl_class)) { pr_err("failed to allocate class\n"); rc = PTR_ERR(hl_class); diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c index 3843d2576d3fa8..c5598b6d5db8b0 100644 --- a/drivers/acpi/acpi_lpit.c +++ b/drivers/acpi/acpi_lpit.c @@ -98,6 +98,12 @@ EXPORT_SYMBOL_GPL(lpit_read_residency_count_address); static void lpit_update_residency(struct lpit_residency_info *info, struct acpi_lpit_native *lpit_native) { + struct device *dev_root = bus_get_dev_root(&cpu_subsys); + + /* Silently fail, if cpuidle attribute group is not present */ + if (!dev_root) + return; + info->frequency = lpit_native->counter_frequency ? lpit_native->counter_frequency : tsc_khz * 1000; if (!info->frequency) @@ -108,18 +114,18 @@ static void lpit_update_residency(struct lpit_residency_info *info, info->iomem_addr = ioremap(info->gaddr.address, info->gaddr.bit_width / 8); if (!info->iomem_addr) - return; + goto exit; - /* Silently fail, if cpuidle attribute group is not present */ - sysfs_add_file_to_group(&cpu_subsys.dev_root->kobj, + sysfs_add_file_to_group(&dev_root->kobj, &dev_attr_low_power_idle_system_residency_us.attr, "cpuidle"); } else if (info->gaddr.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { - /* Silently fail, if cpuidle attribute group is not present */ - sysfs_add_file_to_group(&cpu_subsys.dev_root->kobj, + sysfs_add_file_to_group(&dev_root->kobj, &dev_attr_low_power_idle_cpu_residency_us.attr, "cpuidle"); } +exit: + put_device(dev_root); } static void lpit_process(u64 begin, u64 end) diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c index ef2c29a752691d..1af64d435d3c28 100644 --- a/drivers/ata/pata_parport/pata_parport.c +++ b/drivers/ata/pata_parport/pata_parport.c @@ -557,8 +557,7 @@ void pata_parport_unregister_driver(struct pi_protocol *pr) } EXPORT_SYMBOL_GPL(pata_parport_unregister_driver); -static ssize_t new_device_store(struct bus_type *bus, const char *buf, - size_t count) +static ssize_t new_device_store(const struct bus_type *bus, const char *buf, size_t count) { char port[12] = "auto"; char protocol[8] = "auto"; @@ -632,8 +631,7 @@ static void pi_remove_one(struct device *dev) /* pata_parport_dev_release will do ida_free(dev->id) and kfree(pi) */ } -static ssize_t delete_device_store(struct bus_type *bus, const char *buf, - size_t count) +static ssize_t delete_device_store(const struct bus_type *bus, const char *buf, size_t count) { struct device *dev; diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 6f04b831a5c041..2b8fd6bb7da0b8 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -230,4 +230,16 @@ config GENERIC_ARCH_NUMA Enable support for generic NUMA implementation. Currently, RISC-V and ARM64 use it. +config FW_DEVLINK_SYNC_STATE_TIMEOUT + bool "sync_state() behavior defaults to timeout instead of strict" + help + This is build time equivalent of adding kernel command line parameter + "fw_devlink.sync_state=timeout". Give up waiting on consumers and + call sync_state() on any devices that haven't yet received their + sync_state() calls after deferred_probe_timeout has expired or by + late_initcall() if !CONFIG_MODULES. You should almost always want to + select N here unless you have already successfully tested with the + command line option on every system/board your kernel is expected to + work on. + endmenu diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index b1c1dd38ab011a..b741b5ba82bd6e 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -835,18 +835,19 @@ void __init init_cpu_topology(void) if (ret) { /* * Discard anything that was parsed if we hit an error so we - * don't use partial information. + * don't use partial information. But do not return yet to give + * arch-specific early cache level detection a chance to run. */ reset_cpu_topology(); - return; } for_each_possible_cpu(cpu) { ret = fetch_cache_info(cpu); - if (ret) { + if (!ret) + continue; + else if (ret != -ENOENT) pr_err("Early cacheinfo failed, ret = %d\n", ret); - break; - } + return; } } diff --git a/drivers/base/base.h b/drivers/base/base.h index 726a12a244c061..eb4c0ace924201 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -27,11 +27,13 @@ * on this bus. * @bus - pointer back to the struct bus_type that this structure is associated * with. + * @dev_root: Default device to use as the parent. * * @glue_dirs - "glue" directory to put in-between the parent device to * avoid namespace conflicts * @class - pointer back to the struct class that this structure is associated * with. + * @lock_key: Lock class key for use by the lock validator * * This structure is the one that is the actual kobject allowing struct * bus_type/class to be statically allocated safely. Nothing outside of the @@ -48,10 +50,11 @@ struct subsys_private { struct klist klist_drivers; struct blocking_notifier_head bus_notifier; unsigned int drivers_autoprobe:1; - struct bus_type *bus; + const struct bus_type *bus; + struct device *dev_root; struct kset glue_dirs; - struct class *class; + const struct class *class; struct lock_class_key lock_key; }; @@ -70,6 +73,8 @@ static inline void subsys_put(struct subsys_private *sp) kset_put(&sp->subsys); } +struct subsys_private *class_to_subsys(const struct class *class); + struct driver_private { struct kobject kobj; struct klist klist_devices; @@ -122,69 +127,73 @@ struct device_private { container_of(obj, struct device_private, knode_class) /* initialisation functions */ -extern int devices_init(void); -extern int buses_init(void); -extern int classes_init(void); -extern int firmware_init(void); +int devices_init(void); +int buses_init(void); +int classes_init(void); +int firmware_init(void); #ifdef CONFIG_SYS_HYPERVISOR -extern int hypervisor_init(void); +int hypervisor_init(void); #else static inline int hypervisor_init(void) { return 0; } #endif -extern int platform_bus_init(void); -extern void cpu_dev_init(void); -extern void container_dev_init(void); +int platform_bus_init(void); +void cpu_dev_init(void); +void container_dev_init(void); #ifdef CONFIG_AUXILIARY_BUS -extern void auxiliary_bus_init(void); +void auxiliary_bus_init(void); #else static inline void auxiliary_bus_init(void) { } #endif struct kobject *virtual_device_parent(struct device *dev); -extern int bus_add_device(struct device *dev); -extern void bus_probe_device(struct device *dev); -extern void bus_remove_device(struct device *dev); +int bus_add_device(struct device *dev); +void bus_probe_device(struct device *dev); +void bus_remove_device(struct device *dev); void bus_notify(struct device *dev, enum bus_notifier_event value); bool bus_is_registered(const struct bus_type *bus); -extern int bus_add_driver(struct device_driver *drv); -extern void bus_remove_driver(struct device_driver *drv); -extern void device_release_driver_internal(struct device *dev, - struct device_driver *drv, - struct device *parent); +int bus_add_driver(struct device_driver *drv); +void bus_remove_driver(struct device_driver *drv); +void device_release_driver_internal(struct device *dev, struct device_driver *drv, + struct device *parent); -extern void driver_detach(struct device_driver *drv); -extern void driver_deferred_probe_del(struct device *dev); -extern void device_set_deferred_probe_reason(const struct device *dev, - struct va_format *vaf); +void driver_detach(struct device_driver *drv); +void driver_deferred_probe_del(struct device *dev); +void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf); static inline int driver_match_device(struct device_driver *drv, struct device *dev) { return drv->bus->match ? drv->bus->match(dev, drv) : 1; } -extern int driver_add_groups(struct device_driver *drv, - const struct attribute_group **groups); -extern void driver_remove_groups(struct device_driver *drv, - const struct attribute_group **groups); +static inline void dev_sync_state(struct device *dev) +{ + if (dev->bus->sync_state) + dev->bus->sync_state(dev); + else if (dev->driver && dev->driver->sync_state) + dev->driver->sync_state(dev); +} + +int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups); +void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups); void device_driver_detach(struct device *dev); -extern int devres_release_all(struct device *dev); -extern void device_block_probing(void); -extern void device_unblock_probing(void); -extern void deferred_probe_extend_timeout(void); -extern void driver_deferred_probe_trigger(void); +int devres_release_all(struct device *dev); +void device_block_probing(void); +void device_unblock_probing(void); +void deferred_probe_extend_timeout(void); +void driver_deferred_probe_trigger(void); const char *device_get_devnode(const struct device *dev, umode_t *mode, kuid_t *uid, kgid_t *gid, const char **tmp); /* /sys/devices directory */ extern struct kset *devices_kset; -extern void devices_kset_move_last(struct device *dev); +void devices_kset_move_last(struct device *dev); #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) -extern void module_add_driver(struct module *mod, struct device_driver *drv); -extern void module_remove_driver(struct device_driver *drv); +void module_add_driver(struct module *mod, struct device_driver *drv); +void module_remove_driver(struct device_driver *drv); #else static inline void module_add_driver(struct module *mod, struct device_driver *drv) { } @@ -192,23 +201,34 @@ static inline void module_remove_driver(struct device_driver *drv) { } #endif #ifdef CONFIG_DEVTMPFS -extern int devtmpfs_init(void); +int devtmpfs_init(void); #else static inline int devtmpfs_init(void) { return 0; } #endif +#ifdef CONFIG_BLOCK +extern struct class block_class; +static inline bool is_blockdev(struct device *dev) +{ + return dev->class == &block_class; +} +#else +static inline bool is_blockdev(struct device *dev) { return false; } +#endif + /* Device links support */ -extern int device_links_read_lock(void); -extern void device_links_read_unlock(int idx); -extern int device_links_read_lock_held(void); -extern int device_links_check_suppliers(struct device *dev); -extern void device_links_force_bind(struct device *dev); -extern void device_links_driver_bound(struct device *dev); -extern void device_links_driver_cleanup(struct device *dev); -extern void device_links_no_driver(struct device *dev); -extern bool device_links_busy(struct device *dev); -extern void device_links_unbind_consumers(struct device *dev); -extern void fw_devlink_drivers_done(void); +int device_links_read_lock(void); +void device_links_read_unlock(int idx); +int device_links_read_lock_held(void); +int device_links_check_suppliers(struct device *dev); +void device_links_force_bind(struct device *dev); +void device_links_driver_bound(struct device *dev); +void device_links_driver_cleanup(struct device *dev); +void device_links_no_driver(struct device *dev); +bool device_links_busy(struct device *dev); +void device_links_unbind_consumers(struct device *dev); +void fw_devlink_drivers_done(void); +void fw_devlink_probing_done(void); /* device pm support */ void device_pm_move_to_tail(struct device *dev); diff --git a/drivers/base/bus.c b/drivers/base/bus.c index dd4b82d7510f68..84a21084d67d16 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -84,7 +84,7 @@ done: return sp; } -static struct bus_type *bus_get(struct bus_type *bus) +static const struct bus_type *bus_get(const struct bus_type *bus) { struct subsys_private *sp = bus_to_subsys(bus); @@ -233,7 +233,7 @@ static const struct kset_uevent_ops bus_uevent_ops = { static ssize_t unbind_store(struct device_driver *drv, const char *buf, size_t count) { - struct bus_type *bus = bus_get(drv->bus); + const struct bus_type *bus = bus_get(drv->bus); struct device *dev; int err = -ENODEV; @@ -256,7 +256,7 @@ static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store); static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t count) { - struct bus_type *bus = bus_get(drv->bus); + const struct bus_type *bus = bus_get(drv->bus); struct device *dev; int err = -ENODEV; @@ -274,7 +274,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, } static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store); -static ssize_t drivers_autoprobe_show(struct bus_type *bus, char *buf) +static ssize_t drivers_autoprobe_show(const struct bus_type *bus, char *buf) { struct subsys_private *sp = bus_to_subsys(bus); int ret; @@ -287,7 +287,7 @@ static ssize_t drivers_autoprobe_show(struct bus_type *bus, char *buf) return ret; } -static ssize_t drivers_autoprobe_store(struct bus_type *bus, +static ssize_t drivers_autoprobe_store(const struct bus_type *bus, const char *buf, size_t count) { struct subsys_private *sp = bus_to_subsys(bus); @@ -304,7 +304,7 @@ static ssize_t drivers_autoprobe_store(struct bus_type *bus, return count; } -static ssize_t drivers_probe_store(struct bus_type *bus, +static ssize_t drivers_probe_store(const struct bus_type *bus, const char *buf, size_t count) { struct device *dev; @@ -769,7 +769,7 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, * attached and rescan it against existing drivers to see if it matches * any by calling device_attach() for the unbound devices. */ -int bus_rescan_devices(struct bus_type *bus) +int bus_rescan_devices(const struct bus_type *bus) { return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); } @@ -808,7 +808,7 @@ static void klist_devices_put(struct klist_node *n) put_device(dev); } -static ssize_t bus_uevent_store(struct bus_type *bus, +static ssize_t bus_uevent_store(const struct bus_type *bus, const char *buf, size_t count) { struct subsys_private *sp = bus_to_subsys(bus); @@ -841,7 +841,7 @@ static struct bus_attribute bus_attr_uevent = __ATTR(uevent, 0200, NULL, * infrastructure, then register the children subsystems it has: * the devices and drivers that belong to the subsystem. */ -int bus_register(struct bus_type *bus) +int bus_register(const struct bus_type *bus) { int retval; struct subsys_private *priv; @@ -935,8 +935,8 @@ void bus_unregister(const struct bus_type *bus) return; pr_debug("bus: '%s': unregistering\n", bus->name); - if (bus->dev_root) - device_unregister(bus->dev_root); + if (sp->dev_root) + device_unregister(sp->dev_root); bus_kobj = &sp->subsys.kobj; sysfs_remove_groups(bus_kobj, bus->bus_groups); @@ -1198,6 +1198,7 @@ static int subsys_register(struct bus_type *subsys, const struct attribute_group **groups, struct kobject *parent_of_root) { + struct subsys_private *sp; struct device *dev; int err; @@ -1205,6 +1206,12 @@ static int subsys_register(struct bus_type *subsys, if (err < 0) return err; + sp = bus_to_subsys(subsys); + if (!sp) { + err = -EINVAL; + goto err_sp; + } + dev = kzalloc(sizeof(struct device), GFP_KERNEL); if (!dev) { err = -ENOMEM; @@ -1223,7 +1230,8 @@ static int subsys_register(struct bus_type *subsys, if (err < 0) goto err_dev_reg; - subsys->dev_root = dev; + sp->dev_root = dev; + subsys_put(sp); return 0; err_dev_reg: @@ -1232,6 +1240,8 @@ err_dev_reg: err_name: kfree(dev); err_dev: + subsys_put(sp); +err_sp: bus_unregister(subsys); return err; } @@ -1297,7 +1307,7 @@ EXPORT_SYMBOL_GPL(subsys_virtual_register); * from being unregistered or unloaded while the caller is using it. * The caller is responsible for preventing this. */ -struct device_driver *driver_find(const char *name, struct bus_type *bus) +struct device_driver *driver_find(const char *name, const struct bus_type *bus) { struct subsys_private *sp = bus_to_subsys(bus); struct kobject *k; @@ -1349,9 +1359,15 @@ bool bus_is_registered(const struct bus_type *bus) */ struct device *bus_get_dev_root(const struct bus_type *bus) { - if (bus) - return get_device(bus->dev_root); - return NULL; + struct subsys_private *sp = bus_to_subsys(bus); + struct device *dev_root; + + if (!sp) + return NULL; + + dev_root = get_device(sp->dev_root); + subsys_put(sp); + return dev_root; } EXPORT_SYMBOL_GPL(bus_get_dev_root); diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 41f0eadf193138..bba3482ddeb82e 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -28,6 +28,9 @@ static DEFINE_PER_CPU(struct cpu_cacheinfo, ci_cpu_cacheinfo); #define per_cpu_cacheinfo_idx(cpu, idx) \ (per_cpu_cacheinfo(cpu) + (idx)) +/* Set if no cache information is found in DT/ACPI. */ +static bool use_arch_info; + struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu) { return ci_cacheinfo(cpu); @@ -38,11 +41,11 @@ static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, { /* * For non DT/ACPI systems, assume unique level 1 caches, - * system-wide shared caches for all other levels. This will be used - * only if arch specific code has not populated shared_cpu_map + * system-wide shared caches for all other levels. */ - if (!(IS_ENABLED(CONFIG_OF) || IS_ENABLED(CONFIG_ACPI))) - return !(this_leaf->level == 1); + if (!(IS_ENABLED(CONFIG_OF) || IS_ENABLED(CONFIG_ACPI)) || + use_arch_info) + return (this_leaf->level != 1) && (sib_leaf->level != 1); if ((sib_leaf->attributes & CACHE_ID) && (this_leaf->attributes & CACHE_ID)) @@ -79,6 +82,9 @@ bool last_level_cache_is_shared(unsigned int cpu_x, unsigned int cpu_y) } #ifdef CONFIG_OF + +static bool of_check_cache_nodes(struct device_node *np); + /* OF properties to query for a given cache type */ struct cache_type_info { const char *size_prop; @@ -206,6 +212,11 @@ static int cache_setup_of_node(unsigned int cpu) return -ENOENT; } + if (!of_check_cache_nodes(np)) { + of_node_put(np); + return -ENOENT; + } + prev = np; while (index < cache_leaves(cpu)) { @@ -230,6 +241,25 @@ static int cache_setup_of_node(unsigned int cpu) return 0; } +static bool of_check_cache_nodes(struct device_node *np) +{ + struct device_node *next; + + if (of_property_present(np, "cache-size") || + of_property_present(np, "i-cache-size") || + of_property_present(np, "d-cache-size") || + of_property_present(np, "cache-unified")) + return true; + + next = of_find_next_cache_node(np); + if (next) { + of_node_put(next); + return true; + } + + return false; +} + static int of_count_cache_leaves(struct device_node *np) { unsigned int leaves = 0; @@ -261,6 +291,11 @@ int init_of_cache_level(unsigned int cpu) struct device_node *prev = NULL; unsigned int levels = 0, leaves, level; + if (!of_check_cache_nodes(np)) { + of_node_put(np); + return -ENOENT; + } + leaves = of_count_cache_leaves(np); if (leaves > 0) levels = 1; @@ -312,6 +347,10 @@ static int cache_setup_properties(unsigned int cpu) else if (!acpi_disabled) ret = cache_setup_acpi(cpu); + // Assume there is no cache information available in DT/ACPI from now. + if (ret && use_arch_cache_info()) + use_arch_info = true; + return ret; } @@ -330,7 +369,7 @@ static int cache_shared_cpu_map_setup(unsigned int cpu) * to update the shared cpu_map if the cache attributes were * populated early before all the cpus are brought online */ - if (!last_level_cache_is_valid(cpu)) { + if (!last_level_cache_is_valid(cpu) && !use_arch_info) { ret = cache_setup_properties(cpu); if (ret) return ret; @@ -398,6 +437,11 @@ static void free_cache_attributes(unsigned int cpu) cache_shared_cpu_map_remove(cpu); } +int __weak early_cache_level(unsigned int cpu) +{ + return -ENOENT; +} + int __weak init_cache_level(unsigned int cpu) { return -ENOENT; @@ -423,56 +467,82 @@ int allocate_cache_info(int cpu) int fetch_cache_info(unsigned int cpu) { - struct cpu_cacheinfo *this_cpu_ci; + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); unsigned int levels = 0, split_levels = 0; int ret; if (acpi_disabled) { ret = init_of_cache_level(cpu); - if (ret < 0) - return ret; } else { ret = acpi_get_cache_info(cpu, &levels, &split_levels); - if (ret < 0) + if (!ret) { + this_cpu_ci->num_levels = levels; + /* + * This assumes that: + * - there cannot be any split caches (data/instruction) + * above a unified cache + * - data/instruction caches come by pair + */ + this_cpu_ci->num_leaves = levels + split_levels; + } + } + + if (ret || !cache_leaves(cpu)) { + ret = early_cache_level(cpu); + if (ret) return ret; - this_cpu_ci = get_cpu_cacheinfo(cpu); - this_cpu_ci->num_levels = levels; - /* - * This assumes that: - * - there cannot be any split caches (data/instruction) - * above a unified cache - * - data/instruction caches come by pair - */ - this_cpu_ci->num_leaves = levels + split_levels; + if (!cache_leaves(cpu)) + return -ENOENT; + + this_cpu_ci->early_ci_levels = true; } - if (!cache_leaves(cpu)) - return -ENOENT; return allocate_cache_info(cpu); } -int detect_cache_attributes(unsigned int cpu) +static inline int init_level_allocate_ci(unsigned int cpu) { - int ret; + unsigned int early_leaves = cache_leaves(cpu); /* Since early initialization/allocation of the cacheinfo is allowed * via fetch_cache_info() and this also gets called as CPU hotplug * callbacks via cacheinfo_cpu_online, the init/alloc can be skipped * as it will happen only once (the cacheinfo memory is never freed). - * Just populate the cacheinfo. + * Just populate the cacheinfo. However, if the cacheinfo has been + * allocated early through the arch-specific early_cache_level() call, + * there is a chance the info is wrong (this can happen on arm64). In + * that case, call init_cache_level() anyway to give the arch-specific + * code a chance to make things right. */ - if (per_cpu_cacheinfo(cpu)) - goto populate_leaves; + if (per_cpu_cacheinfo(cpu) && !ci_cacheinfo(cpu)->early_ci_levels) + return 0; if (init_cache_level(cpu) || !cache_leaves(cpu)) return -ENOENT; - ret = allocate_cache_info(cpu); + /* + * Now that we have properly initialized the cache level info, make + * sure we don't try to do that again the next time we are called + * (e.g. as CPU hotplug callbacks). + */ + ci_cacheinfo(cpu)->early_ci_levels = false; + + if (cache_leaves(cpu) <= early_leaves) + return 0; + + kfree(per_cpu_cacheinfo(cpu)); + return allocate_cache_info(cpu); +} + +int detect_cache_attributes(unsigned int cpu) +{ + int ret; + + ret = init_level_allocate_ci(cpu); if (ret) return ret; -populate_leaves: /* * If LLC is valid the cache leaves were already populated so just go to * update the cpu map. diff --git a/drivers/base/class.c b/drivers/base/class.c index 2373b3e210d897..ac1808d1a2e8f0 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -20,8 +20,52 @@ #include <linux/mutex.h> #include "base.h" +/* /sys/class */ +static struct kset *class_kset; + #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) +/** + * class_to_subsys - Turn a struct class into a struct subsys_private + * + * @class: pointer to the struct bus_type to look up + * + * The driver core internals need to work on the subsys_private structure, not + * the external struct class pointer. This function walks the list of + * registered classes in the system and finds the matching one and returns the + * internal struct subsys_private that relates to that class. + * + * Note, the reference count of the return value is INCREMENTED if it is not + * NULL. A call to subsys_put() must be done when finished with the pointer in + * order for it to be properly freed. + */ +struct subsys_private *class_to_subsys(const struct class *class) +{ + struct subsys_private *sp = NULL; + struct kobject *kobj; + + if (!class || !class_kset) + return NULL; + + spin_lock(&class_kset->list_lock); + + if (list_empty(&class_kset->list)) + goto done; + + list_for_each_entry(kobj, &class_kset->list, entry) { + struct kset *kset = container_of(kobj, struct kset, kobj); + + sp = container_of_const(kset, struct subsys_private, subsys); + if (sp->class == class) + goto done; + } + sp = NULL; +done: + sp = subsys_get(sp); + spin_unlock(&class_kset->list_lock); + return sp; +} + static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { @@ -49,25 +93,24 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, static void class_release(struct kobject *kobj) { struct subsys_private *cp = to_subsys_private(kobj); - struct class *class = cp->class; + const struct class *class = cp->class; pr_debug("class '%s': release.\n", class->name); - class->p = NULL; - if (class->class_release) class->class_release(class); else pr_debug("class '%s' does not have a release() function, " "be careful\n", class->name); + lockdep_unregister_key(&cp->lock_key); kfree(cp); } static const struct kobj_ns_type_operations *class_child_ns_type(const struct kobject *kobj) { const struct subsys_private *cp = to_subsys_private(kobj); - struct class *class = cp->class; + const struct class *class = cp->class; return class->ns_type; } @@ -83,44 +126,34 @@ static const struct kobj_type class_ktype = { .child_ns_type = class_child_ns_type, }; -/* Hotplug events for classes go to the class subsys */ -static struct kset *class_kset; - - -int class_create_file_ns(struct class *cls, const struct class_attribute *attr, +int class_create_file_ns(const struct class *cls, const struct class_attribute *attr, const void *ns) { + struct subsys_private *sp = class_to_subsys(cls); int error; - if (cls) - error = sysfs_create_file_ns(&cls->p->subsys.kobj, - &attr->attr, ns); - else - error = -EINVAL; + if (!sp) + return -EINVAL; + + error = sysfs_create_file_ns(&sp->subsys.kobj, &attr->attr, ns); + subsys_put(sp); + return error; } EXPORT_SYMBOL_GPL(class_create_file_ns); -void class_remove_file_ns(struct class *cls, const struct class_attribute *attr, +void class_remove_file_ns(const struct class *cls, const struct class_attribute *attr, const void *ns) { - if (cls) - sysfs_remove_file_ns(&cls->p->subsys.kobj, &attr->attr, ns); -} -EXPORT_SYMBOL_GPL(class_remove_file_ns); + struct subsys_private *sp = class_to_subsys(cls); -static struct class *class_get(struct class *cls) -{ - if (cls) - kset_get(&cls->p->subsys); - return cls; -} + if (!sp) + return; -static void class_put(struct class *cls) -{ - if (cls) - kset_put(&cls->p->subsys); + sysfs_remove_file_ns(&sp->subsys.kobj, &attr->attr, ns); + subsys_put(sp); } +EXPORT_SYMBOL_GPL(class_remove_file_ns); static struct device *klist_class_to_dev(struct klist_node *n) { @@ -142,21 +175,10 @@ static void klist_class_dev_put(struct klist_node *n) put_device(dev); } -static int class_add_groups(struct class *cls, - const struct attribute_group **groups) -{ - return sysfs_create_groups(&cls->p->subsys.kobj, groups); -} - -static void class_remove_groups(struct class *cls, - const struct attribute_group **groups) -{ - return sysfs_remove_groups(&cls->p->subsys.kobj, groups); -} - -int __class_register(struct class *cls, struct lock_class_key *key) +int class_register(const struct class *cls) { struct subsys_private *cp; + struct lock_class_key *key; int error; pr_debug("device class '%s': registering\n", cls->name); @@ -167,6 +189,8 @@ int __class_register(struct class *cls, struct lock_class_key *key) klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put); INIT_LIST_HEAD(&cp->interfaces); kset_init(&cp->glue_dirs); + key = &cp->lock_key; + lockdep_register_key(key); __mutex_init(&cp->mutex, "subsys mutex", key); error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); if (error) { @@ -174,27 +198,15 @@ int __class_register(struct class *cls, struct lock_class_key *key) return error; } - /* set the default /sys/dev directory for devices of this class */ - if (!cls->dev_kobj) - cls->dev_kobj = sysfs_dev_char_kobj; - -#if defined(CONFIG_BLOCK) - /* let the block class directory show up in the root of sysfs */ - if (!sysfs_deprecated || cls != &block_class) - cp->subsys.kobj.kset = class_kset; -#else cp->subsys.kobj.kset = class_kset; -#endif cp->subsys.kobj.ktype = &class_ktype; cp->class = cls; - cls->p = cp; error = kset_register(&cp->subsys); if (error) goto err_out; - error = class_add_groups(class_get(cls), cls->class_groups); - class_put(cls); + error = sysfs_create_groups(&cp->subsys.kobj, cls->class_groups); if (error) { kobject_del(&cp->subsys.kobj); kfree_const(cp->subsys.kobj.name); @@ -204,30 +216,34 @@ int __class_register(struct class *cls, struct lock_class_key *key) err_out: kfree(cp); - cls->p = NULL; return error; } -EXPORT_SYMBOL_GPL(__class_register); +EXPORT_SYMBOL_GPL(class_register); -void class_unregister(struct class *cls) +void class_unregister(const struct class *cls) { + struct subsys_private *sp = class_to_subsys(cls); + + if (!sp) + return; + pr_debug("device class '%s': unregistering\n", cls->name); - class_remove_groups(cls, cls->class_groups); - kset_unregister(&cls->p->subsys); + + sysfs_remove_groups(&sp->subsys.kobj, cls->class_groups); + kset_unregister(&sp->subsys); + subsys_put(sp); } EXPORT_SYMBOL_GPL(class_unregister); -static void class_create_release(struct class *cls) +static void class_create_release(const struct class *cls) { pr_debug("%s called for %s\n", __func__, cls->name); kfree(cls); } /** - * __class_create - create a struct class structure - * @owner: pointer to the module that is to "own" this struct class + * class_create - create a struct class structure * @name: pointer to a string for the name of this class. - * @key: the lock_class_key for this class; used by mutex lock debugging * * This is used to create a struct class pointer that can then be used * in calls to device_create(). @@ -237,8 +253,7 @@ static void class_create_release(struct class *cls) * Note, the pointer created here is to be destroyed when finished by * making a call to class_destroy(). */ -struct class *__class_create(struct module *owner, const char *name, - struct lock_class_key *key) +struct class *class_create(const char *name) { struct class *cls; int retval; @@ -250,10 +265,9 @@ struct class *__class_create(struct module *owner, const char *name, } cls->name = name; - cls->owner = owner; cls->class_release = class_create_release; - retval = __class_register(cls, key); + retval = class_register(cls); if (retval) goto error; @@ -263,7 +277,7 @@ error: kfree(cls); return ERR_PTR(retval); } -EXPORT_SYMBOL_GPL(__class_create); +EXPORT_SYMBOL_GPL(class_create); /** * class_destroy - destroys a struct class structure @@ -272,7 +286,7 @@ EXPORT_SYMBOL_GPL(__class_create); * Note, the pointer to be destroyed must have been created with a call * to class_create(). */ -void class_destroy(struct class *cls) +void class_destroy(const struct class *cls) { if (IS_ERR_OR_NULL(cls)) return; @@ -293,14 +307,18 @@ EXPORT_SYMBOL_GPL(class_destroy); * otherwise if it is NULL, the iteration starts at the beginning of * the list. */ -void class_dev_iter_init(struct class_dev_iter *iter, struct class *class, - struct device *start, const struct device_type *type) +void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, + const struct device *start, const struct device_type *type) { + struct subsys_private *sp = class_to_subsys(class); struct klist_node *start_knode = NULL; + if (!sp) + return; + if (start) start_knode = &start->p->knode_class; - klist_iter_init_node(&class->p->klist_devices, &iter->ki, start_knode); + klist_iter_init_node(&sp->klist_devices, &iter->ki, start_knode); iter->type = type; } EXPORT_SYMBOL_GPL(class_dev_iter_init); @@ -364,16 +382,17 @@ EXPORT_SYMBOL_GPL(class_dev_iter_exit); * @fn is allowed to do anything including calling back into class * code. There's no locking restriction. */ -int class_for_each_device(struct class *class, struct device *start, +int class_for_each_device(const struct class *class, const struct device *start, void *data, int (*fn)(struct device *, void *)) { + struct subsys_private *sp = class_to_subsys(class); struct class_dev_iter iter; struct device *dev; int error = 0; if (!class) return -EINVAL; - if (!class->p) { + if (!sp) { WARN(1, "%s called for class '%s' before it was initialized", __func__, class->name); return -EINVAL; @@ -386,6 +405,7 @@ int class_for_each_device(struct class *class, struct device *start, break; } class_dev_iter_exit(&iter); + subsys_put(sp); return error; } @@ -411,16 +431,17 @@ EXPORT_SYMBOL_GPL(class_for_each_device); * @match is allowed to do anything including calling back into class * code. There's no locking restriction. */ -struct device *class_find_device(struct class *class, struct device *start, +struct device *class_find_device(const struct class *class, const struct device *start, const void *data, int (*match)(struct device *, const void *)) { + struct subsys_private *sp = class_to_subsys(class); struct class_dev_iter iter; struct device *dev; if (!class) return NULL; - if (!class->p) { + if (!sp) { WARN(1, "%s called for class '%s' before it was initialized", __func__, class->name); return NULL; @@ -434,6 +455,7 @@ struct device *class_find_device(struct class *class, struct device *start, } } class_dev_iter_exit(&iter); + subsys_put(sp); return dev; } @@ -441,26 +463,33 @@ EXPORT_SYMBOL_GPL(class_find_device); int class_interface_register(struct class_interface *class_intf) { - struct class *parent; + struct subsys_private *sp; + const struct class *parent; struct class_dev_iter iter; struct device *dev; if (!class_intf || !class_intf->class) return -ENODEV; - parent = class_get(class_intf->class); - if (!parent) + parent = class_intf->class; + sp = class_to_subsys(parent); + if (!sp) return -EINVAL; - mutex_lock(&parent->p->mutex); - list_add_tail(&class_intf->node, &parent->p->interfaces); + /* + * Reference in sp is now incremented and will be dropped when + * the interface is removed in the call to class_interface_unregister() + */ + + mutex_lock(&sp->mutex); + list_add_tail(&class_intf->node, &sp->interfaces); if (class_intf->add_dev) { class_dev_iter_init(&iter, parent, NULL, NULL); while ((dev = class_dev_iter_next(&iter))) - class_intf->add_dev(dev, class_intf); + class_intf->add_dev(dev); class_dev_iter_exit(&iter); } - mutex_unlock(&parent->p->mutex); + mutex_unlock(&sp->mutex); return 0; } @@ -468,29 +497,40 @@ EXPORT_SYMBOL_GPL(class_interface_register); void class_interface_unregister(struct class_interface *class_intf) { - struct class *parent = class_intf->class; + struct subsys_private *sp; + const struct class *parent = class_intf->class; struct class_dev_iter iter; struct device *dev; if (!parent) return; - mutex_lock(&parent->p->mutex); + sp = class_to_subsys(parent); + if (!sp) + return; + + mutex_lock(&sp->mutex); list_del_init(&class_intf->node); if (class_intf->remove_dev) { class_dev_iter_init(&iter, parent, NULL, NULL); while ((dev = class_dev_iter_next(&iter))) - class_intf->remove_dev(dev, class_intf); + class_intf->remove_dev(dev); class_dev_iter_exit(&iter); } - mutex_unlock(&parent->p->mutex); + mutex_unlock(&sp->mutex); - class_put(parent); + /* + * Decrement the reference count twice, once for the class_to_subsys() + * call in the start of this function, and the second one from the + * reference increment in class_interface_register() + */ + subsys_put(sp); + subsys_put(sp); } EXPORT_SYMBOL_GPL(class_interface_unregister); -ssize_t show_class_attr_string(struct class *class, - struct class_attribute *attr, char *buf) +ssize_t show_class_attr_string(const struct class *class, + const struct class_attribute *attr, char *buf) { struct class_attribute_string *cs; @@ -587,6 +627,31 @@ void class_compat_remove_link(struct class_compat *cls, struct device *dev, } EXPORT_SYMBOL_GPL(class_compat_remove_link); +/** + * class_is_registered - determine if at this moment in time, a class is + * registered in the driver core or not. + * @class: the class to check + * + * Returns a boolean to state if the class is registered in the driver core + * or not. Note that the value could switch right after this call is made, + * so only use this in places where you "know" it is safe to do so (usually + * to determine if the specific class has been registered yet or not). + * + * Be careful in using this. + */ +bool class_is_registered(const struct class *class) +{ + struct subsys_private *sp = class_to_subsys(class); + bool is_initialized = false; + + if (sp) { + is_initialized = true; + subsys_put(sp); + } + return is_initialized; +} +EXPORT_SYMBOL_GPL(class_is_registered); + int __init classes_init(void) { class_kset = kset_create_and_add("class", NULL, NULL); diff --git a/drivers/base/core.c b/drivers/base/core.c index 6878dfcbf0d60b..3dff5037943e02 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -36,19 +36,6 @@ #include "physical_location.h" #include "power/power.h" -#ifdef CONFIG_SYSFS_DEPRECATED -#ifdef CONFIG_SYSFS_DEPRECATED_V2 -long sysfs_deprecated = 1; -#else -long sysfs_deprecated = 0; -#endif -static int __init sysfs_deprecated_setup(char *arg) -{ - return kstrtol(arg, 10, &sysfs_deprecated); -} -early_param("sysfs.deprecated", sysfs_deprecated_setup); -#endif - /* Device links support. */ static LIST_HEAD(deferred_sync); static unsigned int defer_sync_state_count = 1; @@ -550,13 +537,11 @@ static void devlink_dev_release(struct device *dev) static struct class devlink_class = { .name = "devlink", - .owner = THIS_MODULE, .dev_groups = devlink_groups, .dev_release = devlink_dev_release, }; -static int devlink_add_symlinks(struct device *dev, - struct class_interface *class_intf) +static int devlink_add_symlinks(struct device *dev) { int ret; size_t len; @@ -605,8 +590,7 @@ out: return ret; } -static void devlink_remove_symlinks(struct device *dev, - struct class_interface *class_intf) +static void devlink_remove_symlinks(struct device *dev) { struct device_link *link = to_devlink(dev); size_t len; @@ -1173,10 +1157,7 @@ static void device_links_flush_sync_list(struct list_head *list, if (dev != dont_lock_dev) device_lock(dev); - if (dev->bus->sync_state) - dev->bus->sync_state(dev); - else if (dev->driver && dev->driver->sync_state) - dev->driver->sync_state(dev); + dev_sync_state(dev); if (dev != dont_lock_dev) device_unlock(dev); @@ -1685,6 +1666,31 @@ static int __init fw_devlink_strict_setup(char *arg) } early_param("fw_devlink.strict", fw_devlink_strict_setup); +#define FW_DEVLINK_SYNC_STATE_STRICT 0 +#define FW_DEVLINK_SYNC_STATE_TIMEOUT 1 + +#ifndef CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT +static int fw_devlink_sync_state; +#else +static int fw_devlink_sync_state = FW_DEVLINK_SYNC_STATE_TIMEOUT; +#endif + +static int __init fw_devlink_sync_state_setup(char *arg) +{ + if (!arg) + return -EINVAL; + + if (strcmp(arg, "strict") == 0) { + fw_devlink_sync_state = FW_DEVLINK_SYNC_STATE_STRICT; + return 0; + } else if (strcmp(arg, "timeout") == 0) { + fw_devlink_sync_state = FW_DEVLINK_SYNC_STATE_TIMEOUT; + return 0; + } + return -EINVAL; +} +early_param("fw_devlink.sync_state", fw_devlink_sync_state_setup); + static inline u32 fw_devlink_get_flags(u8 fwlink_flags) { if (fwlink_flags & FWLINK_FLAG_CYCLE) @@ -1755,6 +1761,44 @@ void fw_devlink_drivers_done(void) device_links_write_unlock(); } +static int fw_devlink_dev_sync_state(struct device *dev, void *data) +{ + struct device_link *link = to_devlink(dev); + struct device *sup = link->supplier; + + if (!(link->flags & DL_FLAG_MANAGED) || + link->status == DL_STATE_ACTIVE || sup->state_synced || + !dev_has_sync_state(sup)) + return 0; + + if (fw_devlink_sync_state == FW_DEVLINK_SYNC_STATE_STRICT) { + dev_warn(sup, "sync_state() pending due to %s\n", + dev_name(link->consumer)); + return 0; + } + + if (!list_empty(&sup->links.defer_sync)) + return 0; + + dev_warn(sup, "Timed out. Forcing sync_state()\n"); + sup->state_synced = true; + get_device(sup); + list_add_tail(&sup->links.defer_sync, data); + + return 0; +} + +void fw_devlink_probing_done(void) +{ + LIST_HEAD(sync_list); + + device_links_write_lock(); + class_for_each_device(&devlink_class, NULL, &sync_list, + fw_devlink_dev_sync_state); + device_links_write_unlock(); + device_links_flush_sync_list(&sync_list, NULL); +} + /** * wait_for_init_devices_probe - Try to probe any device needed for init * @@ -2209,8 +2253,12 @@ static void fw_devlink_link_device(struct device *dev) int (*platform_notify)(struct device *dev) = NULL; int (*platform_notify_remove)(struct device *dev) = NULL; static struct kobject *dev_kobj; -struct kobject *sysfs_dev_char_kobj; -struct kobject *sysfs_dev_block_kobj; + +/* /sys/dev/char */ +static struct kobject *sysfs_dev_char_kobj; + +/* /sys/dev/block */ +static struct kobject *sysfs_dev_block_kobj; static DEFINE_MUTEX(device_hotplug_lock); @@ -2779,7 +2827,7 @@ EXPORT_SYMBOL_GPL(devm_device_add_groups); static int device_add_attrs(struct device *dev) { - struct class *class = dev->class; + const struct class *class = dev->class; const struct device_type *type = dev->type; int error; @@ -2846,7 +2894,7 @@ static int device_add_attrs(struct device *dev) static void device_remove_attrs(struct device *dev) { - struct class *class = dev->class; + const struct class *class = dev->class; const struct device_type *type = dev->type; if (dev->physical_location) { @@ -3079,7 +3127,7 @@ struct kobject *virtual_device_parent(struct device *dev) struct class_dir { struct kobject kobj; - struct class *class; + const struct class *class; }; #define to_class_dir(obj) container_of(obj, struct class_dir, kobj) @@ -3103,8 +3151,8 @@ static const struct kobj_type class_dir_ktype = { .child_ns_type = class_dir_child_ns_type }; -static struct kobject * -class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) +static struct kobject *class_dir_create_and_add(struct subsys_private *sp, + struct kobject *parent_kobj) { struct class_dir *dir; int retval; @@ -3113,12 +3161,12 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) if (!dir) return ERR_PTR(-ENOMEM); - dir->class = class; + dir->class = sp->class; kobject_init(&dir->kobj, &class_dir_ktype); - dir->kobj.kset = &class->p->glue_dirs; + dir->kobj.kset = &sp->glue_dirs; - retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); + retval = kobject_add(&dir->kobj, parent_kobj, "%s", sp->class->name); if (retval < 0) { kobject_put(&dir->kobj); return ERR_PTR(retval); @@ -3131,21 +3179,13 @@ static DEFINE_MUTEX(gdp_mutex); static struct kobject *get_device_parent(struct device *dev, struct device *parent) { + struct subsys_private *sp = class_to_subsys(dev->class); struct kobject *kobj = NULL; - if (dev->class) { + if (sp) { struct kobject *parent_kobj; struct kobject *k; -#ifdef CONFIG_BLOCK - /* block disks show up in /sys/block */ - if (sysfs_deprecated && dev->class == &block_class) { - if (parent && parent->class == &block_class) - return &parent->kobj; - return &block_class.p->subsys.kobj; - } -#endif - /* * If we have no parent, we live in "virtual". * Class-devices with a non class-device as parent, live @@ -3153,30 +3193,34 @@ static struct kobject *get_device_parent(struct device *dev, */ if (parent == NULL) parent_kobj = virtual_device_parent(dev); - else if (parent->class && !dev->class->ns_type) + else if (parent->class && !dev->class->ns_type) { + subsys_put(sp); return &parent->kobj; - else + } else { parent_kobj = &parent->kobj; + } mutex_lock(&gdp_mutex); /* find our class-directory at the parent and reference it */ - spin_lock(&dev->class->p->glue_dirs.list_lock); - list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) + spin_lock(&sp->glue_dirs.list_lock); + list_for_each_entry(k, &sp->glue_dirs.list, entry) if (k->parent == parent_kobj) { kobj = kobject_get(k); break; } - spin_unlock(&dev->class->p->glue_dirs.list_lock); + spin_unlock(&sp->glue_dirs.list_lock); if (kobj) { mutex_unlock(&gdp_mutex); + subsys_put(sp); return kobj; } /* or create a new class-directory at the parent device */ - k = class_dir_create_and_add(dev->class, parent_kobj); + k = class_dir_create_and_add(sp, parent_kobj); /* do not emit an uevent for this simple "glue" directory */ mutex_unlock(&gdp_mutex); + subsys_put(sp); return k; } @@ -3199,10 +3243,23 @@ static struct kobject *get_device_parent(struct device *dev, static inline bool live_in_glue_dir(struct kobject *kobj, struct device *dev) { - if (!kobj || !dev->class || - kobj->kset != &dev->class->p->glue_dirs) + struct subsys_private *sp; + bool retval; + + if (!kobj || !dev->class) return false; - return true; + + sp = class_to_subsys(dev->class); + if (!sp) + return false; + + if (kobj->kset == &sp->glue_dirs) + retval = true; + else + retval = false; + + subsys_put(sp); + return retval; } static inline struct kobject *get_glue_dir(struct device *dev) @@ -3299,6 +3356,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) static int device_add_class_symlinks(struct device *dev) { struct device_node *of_node = dev_of_node(dev); + struct subsys_private *sp; int error; if (of_node) { @@ -3308,12 +3366,11 @@ static int device_add_class_symlinks(struct device *dev) /* An error here doesn't warrant bringing down the device */ } - if (!dev->class) + sp = class_to_subsys(dev->class); + if (!sp) return 0; - error = sysfs_create_link(&dev->kobj, - &dev->class->p->subsys.kobj, - "subsystem"); + error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem"); if (error) goto out_devnode; @@ -3324,46 +3381,38 @@ static int device_add_class_symlinks(struct device *dev) goto out_subsys; } -#ifdef CONFIG_BLOCK - /* /sys/block has directories and does not need symlinks */ - if (sysfs_deprecated && dev->class == &block_class) - return 0; -#endif - /* link in the class directory pointing to the device */ - error = sysfs_create_link(&dev->class->p->subsys.kobj, - &dev->kobj, dev_name(dev)); + error = sysfs_create_link(&sp->subsys.kobj, &dev->kobj, dev_name(dev)); if (error) goto out_device; - - return 0; + goto exit; out_device: sysfs_remove_link(&dev->kobj, "device"); - out_subsys: sysfs_remove_link(&dev->kobj, "subsystem"); out_devnode: sysfs_remove_link(&dev->kobj, "of_node"); +exit: + subsys_put(sp); return error; } static void device_remove_class_symlinks(struct device *dev) { + struct subsys_private *sp = class_to_subsys(dev->class); + if (dev_of_node(dev)) sysfs_remove_link(&dev->kobj, "of_node"); - if (!dev->class) + if (!sp) return; if (dev->parent && device_is_not_partition(dev)) sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(&dev->kobj, "subsystem"); -#ifdef CONFIG_BLOCK - if (sysfs_deprecated && dev->class == &block_class) - return; -#endif - sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); + sysfs_delete_link(&sp->subsys.kobj, &dev->kobj, dev_name(dev)); + subsys_put(sp); } /** @@ -3383,27 +3432,13 @@ int dev_set_name(struct device *dev, const char *fmt, ...) } EXPORT_SYMBOL_GPL(dev_set_name); -/** - * device_to_dev_kobj - select a /sys/dev/ directory for the device - * @dev: device - * - * By default we select char/ for new entries. Setting class->dev_obj - * to NULL prevents an entry from being created. class->dev_kobj must - * be set (or cleared) before any devices are registered to the class - * otherwise device_create_sys_dev_entry() and - * device_remove_sys_dev_entry() will disagree about the presence of - * the link. - */ +/* select a /sys/dev/ directory for the device */ static struct kobject *device_to_dev_kobj(struct device *dev) { - struct kobject *kobj; - - if (dev->class) - kobj = dev->class->dev_kobj; + if (is_blockdev(dev)) + return sysfs_dev_block_kobj; else - kobj = sysfs_dev_char_kobj; - - return kobj; + return sysfs_dev_char_kobj; } static int device_create_sys_dev_entry(struct device *dev) @@ -3472,6 +3507,7 @@ static int device_private_init(struct device *dev) */ int device_add(struct device *dev) { + struct subsys_private *sp; struct device *parent; struct kobject *kobj; struct class_interface *class_intf; @@ -3600,18 +3636,18 @@ int device_add(struct device *dev) klist_add_tail(&dev->p->knode_parent, &parent->p->klist_children); - if (dev->class) { - mutex_lock(&dev->class->p->mutex); + sp = class_to_subsys(dev->class); + if (sp) { + mutex_lock(&sp->mutex); /* tie the class to the device */ - klist_add_tail(&dev->p->knode_class, - &dev->class->p->klist_devices); + klist_add_tail(&dev->p->knode_class, &sp->klist_devices); /* notify any interfaces that the device is here */ - list_for_each_entry(class_intf, - &dev->class->p->interfaces, node) + list_for_each_entry(class_intf, &sp->interfaces, node) if (class_intf->add_dev) - class_intf->add_dev(dev, class_intf); - mutex_unlock(&dev->class->p->mutex); + class_intf->add_dev(dev); + mutex_unlock(&sp->mutex); + subsys_put(sp); } done: put_device(dev); @@ -3731,6 +3767,7 @@ EXPORT_SYMBOL_GPL(kill_device); */ void device_del(struct device *dev) { + struct subsys_private *sp; struct device *parent = dev->parent; struct kobject *glue_dir = NULL; struct class_interface *class_intf; @@ -3757,18 +3794,20 @@ void device_del(struct device *dev) device_remove_sys_dev_entry(dev); device_remove_file(dev, &dev_attr_dev); } - if (dev->class) { + + sp = class_to_subsys(dev->class); + if (sp) { device_remove_class_symlinks(dev); - mutex_lock(&dev->class->p->mutex); + mutex_lock(&sp->mutex); /* notify any interfaces that the device is now gone */ - list_for_each_entry(class_intf, - &dev->class->p->interfaces, node) + list_for_each_entry(class_intf, &sp->interfaces, node) if (class_intf->remove_dev) - class_intf->remove_dev(dev, class_intf); + class_intf->remove_dev(dev); /* remove the device from the class list */ klist_del(&dev->p->knode_class); - mutex_unlock(&dev->class->p->mutex); + mutex_unlock(&sp->mutex); + subsys_put(sp); } device_remove_file(dev, &dev_attr_uevent); device_remove_attrs(dev); @@ -4231,7 +4270,7 @@ static void device_create_release(struct device *dev) } static __printf(6, 0) struct device * -device_create_groups_vargs(struct class *class, struct device *parent, +device_create_groups_vargs(const struct class *class, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, va_list args) @@ -4291,11 +4330,8 @@ error: * pointer. * * Returns &struct device pointer on success, or ERR_PTR() on error. - * - * Note: the struct class passed to this function must have previously - * been created with a call to class_create(). */ -struct device *device_create(struct class *class, struct device *parent, +struct device *device_create(const struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) { va_list vargs; @@ -4332,11 +4368,8 @@ EXPORT_SYMBOL_GPL(device_create); * pointer. * * Returns &struct device pointer on success, or ERR_PTR() on error. - * - * Note: the struct class passed to this function must have previously - * been created with a call to class_create(). */ -struct device *device_create_with_groups(struct class *class, +struct device *device_create_with_groups(const struct class *class, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, @@ -4361,7 +4394,7 @@ EXPORT_SYMBOL_GPL(device_create_with_groups); * This call unregisters and cleans up a device that was created with a * call to device_create(). */ -void device_destroy(struct class *class, dev_t devt) +void device_destroy(const struct class *class, dev_t devt) { struct device *dev; @@ -4383,9 +4416,12 @@ EXPORT_SYMBOL_GPL(device_destroy); * on the same device to ensure that new_name is valid and * won't conflict with other devices. * - * Note: Don't call this function. Currently, the networking layer calls this - * function, but that will change. The following text from Kay Sievers offers - * some insight: + * Note: given that some subsystems (networking and infiniband) use this + * function, with no immediate plans for this to change, we cannot assume or + * require that this function not be called at all. + * + * However, if you're writing new code, do not call this function. The following + * text from Kay Sievers offers some insight: * * Renaming devices is racy at many levels, symlinks and other stuff are not * replaced atomically, and you get a "move" uevent, but it's not easy to @@ -4399,13 +4435,6 @@ EXPORT_SYMBOL_GPL(device_destroy); * kernel device renaming. Besides that, it's not even implemented now for * other things than (driver-core wise very simple) network devices. * - * We are currently about to change network renaming in udev to completely - * disallow renaming of devices in the same namespace as the kernel uses, - * because we can't solve the problems properly, that arise with swapping names - * of multiple interfaces without races. Means, renaming of eth[0-9]* will only - * be allowed to some other name than eth[0-9]*, for the aforementioned - * reasons. - * * Make up a "real" name in the driver before you register anything, or add * some other attributes for userspace to find the device, or use udev to add * symlinks -- but never rename kernel devices later, it's a complete mess. We @@ -4431,9 +4460,16 @@ int device_rename(struct device *dev, const char *new_name) } if (dev->class) { - error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj, - kobj, old_device_name, + struct subsys_private *sp = class_to_subsys(dev->class); + + if (!sp) { + error = -EINVAL; + goto out; + } + + error = sysfs_rename_link_ns(&sp->subsys.kobj, kobj, old_device_name, new_name, kobject_namespace(kobj)); + subsys_put(sp); if (error) goto out; } @@ -4558,7 +4594,7 @@ static int device_attrs_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) { struct kobject *kobj = &dev->kobj; - struct class *class = dev->class; + const struct class *class = dev->class; const struct device_type *type = dev->type; int error; @@ -4616,6 +4652,7 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) { int error; struct kobject *kobj = &dev->kobj; + struct subsys_private *sp; dev = get_device(dev); if (!dev) @@ -4652,21 +4689,19 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) if (error) goto out; -#ifdef CONFIG_BLOCK - if (sysfs_deprecated && dev->class == &block_class) - goto out; -#endif - /* * Change the owner of the symlink located in the class directory of * the device class associated with @dev which points to the actual * directory entry for @dev to @kuid/@kgid. This ensures that the * symlink shows the same permissions as its target. */ - error = sysfs_link_change_owner(&dev->class->p->subsys.kobj, &dev->kobj, - dev_name(dev), kuid, kgid); - if (error) + sp = class_to_subsys(dev->class); + if (!sp) { + error = -EINVAL; goto out; + } + error = sysfs_link_change_owner(&sp->subsys.kobj, &dev->kobj, dev_name(dev), kuid, kgid); + subsys_put(sp); out: put_device(dev); @@ -4965,9 +5000,13 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) } else { if (fwnode_is_primary(fn)) { dev->fwnode = fn->secondary; + + /* Skip nullifying fn->secondary if the primary is shared */ + if (parent && fn == parent->fwnode) + return; + /* Set fn->secondary = NULL, so fn remains the primary fwnode */ - if (!(parent && fn == parent->fwnode)) - fn->secondary = NULL; + fn->secondary = NULL; } else { dev->fwnode = NULL; } diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 8def2ba08a8211..9c09ca5c4ab68e 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -315,6 +315,8 @@ static void deferred_probe_timeout_work_func(struct work_struct *work) list_for_each_entry(p, &deferred_probe_pending_list, deferred_probe) dev_info(p->device, "deferred probe pending\n"); mutex_unlock(&deferred_probe_mutex); + + fw_devlink_probing_done(); } static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func); @@ -364,6 +366,10 @@ static int deferred_probe_initcall(void) schedule_delayed_work(&deferred_probe_timeout_work, driver_deferred_probe_timeout * HZ); } + + if (!IS_ENABLED(CONFIG_MODULES)) + fw_devlink_probing_done(); + return 0; } late_initcall(deferred_probe_initcall); @@ -504,6 +510,27 @@ EXPORT_SYMBOL_GPL(device_bind_driver); static atomic_t probe_count = ATOMIC_INIT(0); static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); +static ssize_t state_synced_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret = 0; + + if (strcmp("1", buf)) + return -EINVAL; + + device_lock(dev); + if (!dev->state_synced) { + dev->state_synced = true; + dev_sync_state(dev); + } else { + ret = -EINVAL; + } + device_unlock(dev); + + return ret ? ret : count; +} + static ssize_t state_synced_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -515,7 +542,7 @@ static ssize_t state_synced_show(struct device *dev, return sysfs_emit(buf, "%u\n", val); } -static DEVICE_ATTR_RO(state_synced); +static DEVICE_ATTR_RW(state_synced); static void device_unbind_cleanup(struct device *dev) { @@ -708,7 +735,12 @@ static int really_probe_debug(struct device *dev, struct device_driver *drv) calltime = ktime_get(); ret = really_probe(dev, drv); rettime = ktime_get(); - pr_debug("probe of %s returned %d after %lld usecs\n", + /* + * Don't change this to pr_debug() because that requires + * CONFIG_DYNAMIC_DEBUG and we want a simple 'initcall_debug' on the + * kernel commandline to print this all the time at the debug level. + */ + printk(KERN_DEBUG "probe of %s returned %d after %lld usecs\n", dev_name(dev), ret, ktime_us_delta(rettime, calltime)); return ret; } diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c index 1c06781f711484..91536ee05f144e 100644 --- a/drivers/base/devcoredump.c +++ b/drivers/base/devcoredump.c @@ -167,7 +167,7 @@ static int devcd_free(struct device *dev, void *data) return 0; } -static ssize_t disabled_show(struct class *class, struct class_attribute *attr, +static ssize_t disabled_show(const struct class *class, const struct class_attribute *attr, char *buf) { return sysfs_emit(buf, "%d\n", devcd_disabled); @@ -197,7 +197,7 @@ static ssize_t disabled_show(struct class *class, struct class_attribute *attr, * so, above situation would not occur. */ -static ssize_t disabled_store(struct class *class, struct class_attribute *attr, +static ssize_t disabled_store(const struct class *class, const struct class_attribute *attr, const char *buf, size_t count) { long tmp = simple_strtol(buf, NULL, 10); @@ -226,7 +226,6 @@ ATTRIBUTE_GROUPS(devcd_class); static struct class devcd_class = { .name = "devcoredump", - .owner = THIS_MODULE, .dev_release = devcd_dev_release, .dev_groups = devcd_dev_groups, .class_groups = devcd_class_groups, diff --git a/drivers/base/devres.c b/drivers/base/devres.c index c0e100074aa395..5c998cfac335dd 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -722,20 +722,21 @@ static void devm_action_release(struct device *dev, void *res) } /** - * devm_add_action() - add a custom action to list of managed resources + * __devm_add_action() - add a custom action to list of managed resources * @dev: Device that owns the action * @action: Function that should be called * @data: Pointer to data passed to @action implementation + * @name: Name of the resource (for debugging purposes) * * This adds a custom action to the list of managed resources so that * it gets executed as part of standard resource unwinding. */ -int devm_add_action(struct device *dev, void (*action)(void *), void *data) +int __devm_add_action(struct device *dev, void (*action)(void *), void *data, const char *name) { struct action_devres *devres; - devres = devres_alloc(devm_action_release, - sizeof(struct action_devres), GFP_KERNEL); + devres = __devres_alloc_node(devm_action_release, sizeof(struct action_devres), + GFP_KERNEL, NUMA_NO_NODE, name); if (!devres) return -ENOMEM; @@ -745,7 +746,7 @@ int devm_add_action(struct device *dev, void (*action)(void *), void *data) devres_add(dev, devres); return 0; } -EXPORT_SYMBOL_GPL(devm_add_action); +EXPORT_SYMBOL_GPL(__devm_add_action); /** * devm_remove_action() - removes previously added custom action diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index ae72d4ba854725..b848764ef0187f 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -94,15 +94,6 @@ static struct file_system_type dev_fs_type = { .mount = public_dev_mount, }; -#ifdef CONFIG_BLOCK -static inline int is_blockdev(struct device *dev) -{ - return dev->class == &block_class; -} -#else -static inline int is_blockdev(struct device *dev) { return 0; } -#endif - static int devtmpfs_submit_req(struct req *req, const char *tmp) { init_completion(&req->done); diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig index 5166b323a0f879..5ca00e02fe82c5 100644 --- a/drivers/base/firmware_loader/Kconfig +++ b/drivers/base/firmware_loader/Kconfig @@ -3,6 +3,8 @@ menu "Firmware loader" config FW_LOADER tristate "Firmware loading facility" if EXPERT + select CRYPTO_HASH if FW_LOADER_DEBUG + select CRYPTO_SHA256 if FW_LOADER_DEBUG default y help This enables the firmware loading facility in the kernel. The kernel @@ -24,6 +26,17 @@ config FW_LOADER You also want to be sure to enable this built-in if you are going to enable built-in firmware (CONFIG_EXTRA_FIRMWARE). +config FW_LOADER_DEBUG + bool "Log filenames and checksums for loaded firmware" + depends on CRYPTO = FW_LOADER || CRYPTO=y + depends on DYNAMIC_DEBUG + depends on FW_LOADER + default FW_LOADER + help + Select this option to use dynamic debug to log firmware filenames and + SHA256 checksums to the kernel log for each firmware file that is + loaded. + if FW_LOADER config FW_LOADER_PAGED_BUF diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 017c4cdb219eb1..9d79d5ad910241 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -493,9 +493,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv, const void *in_buffer)) { size_t size; - int i, len; + int i, len, maxlen = 0; int rc = -ENOENT; - char *path; + char *path, *nt = NULL; size_t msize = INT_MAX; void *buffer = NULL; @@ -518,8 +518,17 @@ 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%s", - fw_path[i], fw_priv->fw_name, suffix); + /* strip off \n from customized path */ + maxlen = strlen(fw_path[i]); + if (i == 0) { + nt = strchr(fw_path[i], '\n'); + if (nt) + maxlen = nt - fw_path[i]; + } + + len = snprintf(path, PATH_MAX, "%.*s/%s%s", + maxlen, fw_path[i], + fw_priv->fw_name, suffix); if (len >= PATH_MAX) { rc = -ENAMETOOLONG; break; @@ -791,6 +800,50 @@ static void fw_abort_batch_reqs(struct firmware *fw) mutex_unlock(&fw_lock); } +#if defined(CONFIG_FW_LOADER_DEBUG) +#include <crypto/hash.h> +#include <crypto/sha2.h> + +static void fw_log_firmware_info(const struct firmware *fw, const char *name, struct device *device) +{ + struct shash_desc *shash; + struct crypto_shash *alg; + u8 *sha256buf; + char *outbuf; + + alg = crypto_alloc_shash("sha256", 0, 0); + if (!alg) + return; + + sha256buf = kmalloc(SHA256_DIGEST_SIZE, GFP_KERNEL); + outbuf = kmalloc(SHA256_BLOCK_SIZE + 1, GFP_KERNEL); + shash = kmalloc(sizeof(*shash) + crypto_shash_descsize(alg), GFP_KERNEL); + if (!sha256buf || !outbuf || !shash) + goto out_free; + + shash->tfm = alg; + + if (crypto_shash_digest(shash, fw->data, fw->size, sha256buf) < 0) + goto out_shash; + + for (int i = 0; i < SHA256_DIGEST_SIZE; i++) + sprintf(&outbuf[i * 2], "%02x", sha256buf[i]); + outbuf[SHA256_BLOCK_SIZE] = 0; + dev_dbg(device, "Loaded FW: %s, sha256: %s\n", name, outbuf); + +out_shash: + crypto_free_shash(alg); +out_free: + kfree(shash); + kfree(outbuf); + kfree(sha256buf); +} +#else +static void fw_log_firmware_info(const struct firmware *fw, const char *name, + struct device *device) +{} +#endif + /* called from request_firmware() and request_firmware_work_func() */ static int _request_firmware(const struct firmware **firmware_p, const char *name, @@ -861,11 +914,13 @@ _request_firmware(const struct firmware **firmware_p, const char *name, revert_creds(old_cred); put_cred(kern_cred); - out: +out: if (ret < 0) { fw_abort_batch_reqs(fw); release_firmware(fw); fw = NULL; + } else { + fw_log_firmware_info(fw, name, device); } *firmware_p = fw; diff --git a/drivers/base/firmware_loader/sysfs.c b/drivers/base/firmware_loader/sysfs.c index 56911d75b90a1f..c9c93b47d9a519 100644 --- a/drivers/base/firmware_loader/sysfs.c +++ b/drivers/base/firmware_loader/sysfs.c @@ -25,7 +25,7 @@ void __fw_load_abort(struct fw_priv *fw_priv) } #ifdef CONFIG_FW_LOADER_USER_HELPER -static ssize_t timeout_show(struct class *class, struct class_attribute *attr, +static ssize_t timeout_show(const struct class *class, const struct class_attribute *attr, char *buf) { return sysfs_emit(buf, "%d\n", __firmware_loading_timeout()); @@ -44,7 +44,7 @@ static ssize_t timeout_show(struct class *class, struct class_attribute *attr, * * Note: zero means 'wait forever'. **/ -static ssize_t timeout_store(struct class *class, struct class_attribute *attr, +static ssize_t timeout_store(const struct class *class, const struct class_attribute *attr, const char *buf, size_t count) { int tmp_loading_timeout = simple_strtol(buf, NULL, 10); diff --git a/drivers/base/physical_location.h b/drivers/base/physical_location.h index 82cde9f1b1613c..3f3f613079985e 100644 --- a/drivers/base/physical_location.h +++ b/drivers/base/physical_location.h @@ -8,7 +8,7 @@ #include <linux/device.h> #ifdef CONFIG_ACPI -extern bool dev_add_physical_location(struct device *dev); +bool dev_add_physical_location(struct device *dev); extern const struct attribute_group dev_attr_physical_location_group; #else static inline bool dev_add_physical_location(struct device *dev) { return false; }; diff --git a/drivers/base/power/wakeup_stats.c b/drivers/base/power/wakeup_stats.c index 924fac493c4f24..6732ed2869f9f3 100644 --- a/drivers/base/power/wakeup_stats.c +++ b/drivers/base/power/wakeup_stats.c @@ -210,7 +210,7 @@ void wakeup_source_sysfs_remove(struct wakeup_source *ws) static int __init wakeup_sources_sysfs_init(void) { - wakeup_class = class_create(THIS_MODULE, "wakeup"); + wakeup_class = class_create("wakeup"); return PTR_ERR_OR_ZERO(wakeup_class); } diff --git a/drivers/base/property.c b/drivers/base/property.c index 083a95791d3b3c..f6117ec9805c4b 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -37,8 +37,10 @@ EXPORT_SYMBOL_GPL(__dev_fwnode_const); * @propname: Name of the property * * Check if property @propname is present in the device firmware description. + * + * Return: true if property @propname is present. Otherwise, returns false. */ -bool device_property_present(struct device *dev, const char *propname) +bool device_property_present(const struct device *dev, const char *propname) { return fwnode_property_present(dev_fwnode(dev), propname); } @@ -48,6 +50,8 @@ EXPORT_SYMBOL_GPL(device_property_present); * fwnode_property_present - check if a property of a firmware node is present * @fwnode: Firmware node whose property to check * @propname: Name of the property + * + * Return: true if property @propname is present. Otherwise, returns false. */ bool fwnode_property_present(const struct fwnode_handle *fwnode, const char *propname) @@ -86,7 +90,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_present); * %-EOVERFLOW if the size of the property is not as expected. * %-ENXIO if no suitable firmware interface is present. */ -int device_property_read_u8_array(struct device *dev, const char *propname, +int device_property_read_u8_array(const struct device *dev, const char *propname, u8 *val, size_t nval) { return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval); @@ -114,7 +118,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u8_array); * %-EOVERFLOW if the size of the property is not as expected. * %-ENXIO if no suitable firmware interface is present. */ -int device_property_read_u16_array(struct device *dev, const char *propname, +int device_property_read_u16_array(const struct device *dev, const char *propname, u16 *val, size_t nval) { return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval); @@ -142,7 +146,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u16_array); * %-EOVERFLOW if the size of the property is not as expected. * %-ENXIO if no suitable firmware interface is present. */ -int device_property_read_u32_array(struct device *dev, const char *propname, +int device_property_read_u32_array(const struct device *dev, const char *propname, u32 *val, size_t nval) { return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval); @@ -170,7 +174,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u32_array); * %-EOVERFLOW if the size of the property is not as expected. * %-ENXIO if no suitable firmware interface is present. */ -int device_property_read_u64_array(struct device *dev, const char *propname, +int device_property_read_u64_array(const struct device *dev, const char *propname, u64 *val, size_t nval) { return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval); @@ -198,7 +202,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u64_array); * %-EOVERFLOW if the size of the property is not as expected. * %-ENXIO if no suitable firmware interface is present. */ -int device_property_read_string_array(struct device *dev, const char *propname, +int device_property_read_string_array(const struct device *dev, const char *propname, const char **val, size_t nval) { return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval); @@ -220,7 +224,7 @@ EXPORT_SYMBOL_GPL(device_property_read_string_array); * %-EPROTO or %-EILSEQ if the property type is not a string. * %-ENXIO if no suitable firmware interface is present. */ -int device_property_read_string(struct device *dev, const char *propname, +int device_property_read_string(const struct device *dev, const char *propname, const char **val) { return fwnode_property_read_string(dev_fwnode(dev), propname, val); @@ -242,7 +246,7 @@ EXPORT_SYMBOL_GPL(device_property_read_string); * %-EPROTO if the property is not an array of strings, * %-ENXIO if no suitable firmware interface is present. */ -int device_property_match_string(struct device *dev, const char *propname, +int device_property_match_string(const struct device *dev, const char *propname, const char *string) { return fwnode_property_match_string(dev_fwnode(dev), propname, string); @@ -508,10 +512,10 @@ EXPORT_SYMBOL_GPL(fwnode_property_match_string); * Obtain a reference based on a named property in an fwnode, with * integer arguments. * - * Caller is responsible to call fwnode_handle_put() on the returned - * args->fwnode pointer. + * The caller is responsible for calling fwnode_handle_put() on the returned + * @args->fwnode pointer. * - * Returns: %0 on success + * Return: %0 on success * %-ENOENT when the index is out of bounds, the index has an empty * reference or the property was not found * %-EINVAL on parse error @@ -547,8 +551,11 @@ EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args); * * @index can be used when the named reference holds a table of references. * - * Returns pointer to the reference fwnode, or ERR_PTR. Caller is responsible to - * call fwnode_handle_put() on the returned fwnode pointer. + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. + * + * Return: a pointer to the reference fwnode, when found. Otherwise, + * returns an error pointer. */ struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode, const char *name, @@ -567,7 +574,7 @@ EXPORT_SYMBOL_GPL(fwnode_find_reference); * fwnode_get_name - Return the name of a node * @fwnode: The firmware node * - * Returns a pointer to the node name. + * Return: a pointer to the node name, or %NULL. */ const char *fwnode_get_name(const struct fwnode_handle *fwnode) { @@ -579,7 +586,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_name); * fwnode_get_name_prefix - Return the prefix of node for printing purposes * @fwnode: The firmware node * - * Returns the prefix of a node, intended to be printed right before the node. + * Return: the prefix of a node, intended to be printed right before the node. * The prefix works also as a separator between the nodes. */ const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode) @@ -591,7 +598,10 @@ const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode) * fwnode_get_parent - Return parent firwmare node * @fwnode: Firmware whose parent is retrieved * - * Return parent firmware node of the given node if possible or %NULL if no + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. + * + * Return: parent firmware node of the given node if possible or %NULL if no * parent was available. */ struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode) @@ -608,8 +618,12 @@ EXPORT_SYMBOL_GPL(fwnode_get_parent); * on the passed node, making it suitable for iterating through a * node's parents. * - * Returns a node pointer with refcount incremented, use - * fwnode_handle_put() on it when done. + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. Note that this function also puts a reference to @fwnode + * unconditionally. + * + * Return: parent firmware node of the given node if possible or %NULL if no + * parent was available. */ struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode) { @@ -629,10 +643,12 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_parent); * firmware node that has a corresponding struct device and returns that struct * device. * - * The caller of this function is expected to call put_device() on the returned - * device when they are done. + * The caller is responsible for calling put_device() on the returned device + * pointer. + * + * Return: a pointer to the device of the @fwnode's closest ancestor. */ -struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode) +struct device *fwnode_get_next_parent_dev(const struct fwnode_handle *fwnode) { struct fwnode_handle *parent; struct device *dev; @@ -651,7 +667,7 @@ struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode) * fwnode_count_parents - Return the number of parents a node has * @fwnode: The node the parents of which are to be counted * - * Returns the number of parents a node has. + * Return: the number of parents a node has. */ unsigned int fwnode_count_parents(const struct fwnode_handle *fwnode) { @@ -670,12 +686,12 @@ EXPORT_SYMBOL_GPL(fwnode_count_parents); * @fwnode: The node the parent of which is requested * @depth: Distance of the parent from the node * - * Returns the nth parent of a node. If there is no parent at the requested + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. + * + * Return: the nth parent of a node. If there is no parent at the requested * @depth, %NULL is returned. If @depth is 0, the functionality is equivalent to * fwnode_handle_get(). For @depth == 1, it is fwnode_get_parent() and so on. - * - * The caller is responsible for calling fwnode_handle_put() for the returned - * node. */ struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode, unsigned int depth) @@ -700,9 +716,9 @@ EXPORT_SYMBOL_GPL(fwnode_get_nth_parent); * * A node is considered an ancestor of itself too. * - * Returns true if @ancestor is an ancestor of @child. Otherwise, returns false. + * Return: true if @ancestor is an ancestor of @child. Otherwise, returns false. */ -bool fwnode_is_ancestor_of(struct fwnode_handle *ancestor, struct fwnode_handle *child) +bool fwnode_is_ancestor_of(const struct fwnode_handle *ancestor, const struct fwnode_handle *child) { struct fwnode_handle *parent; @@ -725,6 +741,10 @@ bool fwnode_is_ancestor_of(struct fwnode_handle *ancestor, struct fwnode_handle * fwnode_get_next_child_node - Return the next child node handle for a node * @fwnode: Firmware node to find the next child node for. * @child: Handle to one of the node's child nodes or a %NULL handle. + * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. Note that this function also puts a reference to @child + * unconditionally. */ struct fwnode_handle * fwnode_get_next_child_node(const struct fwnode_handle *fwnode, @@ -735,10 +755,13 @@ fwnode_get_next_child_node(const struct fwnode_handle *fwnode, EXPORT_SYMBOL_GPL(fwnode_get_next_child_node); /** - * fwnode_get_next_available_child_node - Return the next - * available child node handle for a node + * fwnode_get_next_available_child_node - Return the next available child node handle for a node * @fwnode: Firmware node to find the next child node for. * @child: Handle to one of the node's child nodes or a %NULL handle. + * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. Note that this function also puts a reference to @child + * unconditionally. */ struct fwnode_handle * fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode, @@ -762,7 +785,11 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node); /** * device_get_next_child_node - Return the next child node handle for a device * @dev: Device to find the next child node for. - * @child: Handle to one of the device's child nodes or a null handle. + * @child: Handle to one of the device's child nodes or a %NULL handle. + * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. Note that this function also puts a reference to @child + * unconditionally. */ struct fwnode_handle *device_get_next_child_node(const struct device *dev, struct fwnode_handle *child) @@ -787,6 +814,9 @@ EXPORT_SYMBOL_GPL(device_get_next_child_node); * fwnode_get_named_child_node - Return first matching named child node handle * @fwnode: Firmware node to find the named child node for. * @childname: String to match child node name against. + * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. */ struct fwnode_handle * fwnode_get_named_child_node(const struct fwnode_handle *fwnode, @@ -800,6 +830,9 @@ EXPORT_SYMBOL_GPL(fwnode_get_named_child_node); * device_get_named_child_node - Return first matching named child node handle * @dev: Device to find the named child node for. * @childname: String to match child node name against. + * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. */ struct fwnode_handle *device_get_named_child_node(const struct device *dev, const char *childname) @@ -812,7 +845,10 @@ EXPORT_SYMBOL_GPL(device_get_named_child_node); * fwnode_handle_get - Obtain a reference to a device node * @fwnode: Pointer to the device node to obtain the reference to. * - * Returns the fwnode handle. + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. + * + * Return: the fwnode handle. */ struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode) { @@ -841,6 +877,8 @@ EXPORT_SYMBOL_GPL(fwnode_handle_put); * fwnode_device_is_available - check if a device is available for use * @fwnode: Pointer to the fwnode of the device. * + * Return: true if device is available for use. Otherwise, returns false. + * * For fwnode node types that don't implement the .device_is_available() * operation, this function returns true. */ @@ -859,6 +897,8 @@ EXPORT_SYMBOL_GPL(fwnode_device_is_available); /** * device_get_child_node_count - return the number of child nodes for device * @dev: Device to cound the child nodes for + * + * Return: the number of child nodes for a given device. */ unsigned int device_get_child_node_count(const struct device *dev) { @@ -895,7 +935,7 @@ EXPORT_SYMBOL_GPL(device_get_dma_attr); * 'phy-connection-type', and return its index in phy_modes table, or errno in * error case. */ -int fwnode_get_phy_mode(struct fwnode_handle *fwnode) +int fwnode_get_phy_mode(const struct fwnode_handle *fwnode) { const char *pm; int err, i; @@ -934,7 +974,7 @@ EXPORT_SYMBOL_GPL(device_get_phy_mode); * @fwnode: Pointer to the firmware node * @index: Index of the IO range * - * Returns a pointer to the mapped memory. + * Return: a pointer to the mapped memory. */ void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index) { @@ -947,8 +987,8 @@ EXPORT_SYMBOL(fwnode_iomap); * @fwnode: Pointer to the firmware node * @index: Zero-based index of the IRQ * - * Returns Linux IRQ number on success. Other values are determined - * accordingly to acpi_/of_ irq_get() operation. + * Return: Linux IRQ number on success. Other values are determined + * according to acpi_irq_get() or of_irq_get() operation. */ int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index) { @@ -967,8 +1007,7 @@ EXPORT_SYMBOL(fwnode_irq_get); * number of the IRQ resource corresponding to the index of the matched * string. * - * Return: - * Linux IRQ number on success, or negative errno otherwise. + * Return: Linux IRQ number on success, or negative errno otherwise. */ int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name) { @@ -990,7 +1029,11 @@ EXPORT_SYMBOL(fwnode_irq_get_byname); * @fwnode: Pointer to the parent firmware node * @prev: Previous endpoint node or %NULL to get the first * - * Returns an endpoint firmware node pointer or %NULL if no more endpoints + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. Note that this function also puts a reference to @prev + * unconditionally. + * + * Return: an endpoint firmware node pointer or %NULL if no more endpoints * are available. */ struct fwnode_handle * @@ -1030,6 +1073,9 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint); * fwnode_graph_get_port_parent - Return the device fwnode of a port endpoint * @endpoint: Endpoint firmware node of the port * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. + * * Return: the firmware node of the device the @endpoint belongs to. */ struct fwnode_handle * @@ -1051,6 +1097,9 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_port_parent); * @fwnode: Endpoint firmware node pointing to the remote endpoint * * Extracts firmware node of a remote device the @fwnode points to. + * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. */ struct fwnode_handle * fwnode_graph_get_remote_port_parent(const struct fwnode_handle *fwnode) @@ -1071,6 +1120,9 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent); * @fwnode: Endpoint firmware node pointing to the remote endpoint * * Extracts firmware node of a remote port the @fwnode points to. + * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. */ struct fwnode_handle * fwnode_graph_get_remote_port(const struct fwnode_handle *fwnode) @@ -1084,6 +1136,9 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port); * @fwnode: Endpoint firmware node pointing to the remote endpoint * * Extracts firmware node of a remote endpoint the @fwnode points to. + * + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. */ struct fwnode_handle * fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) @@ -1111,8 +1166,11 @@ static bool fwnode_graph_remote_available(struct fwnode_handle *ep) * @endpoint: identifier of the endpoint node under the port node * @flags: fwnode lookup flags * - * Return the fwnode handle of the local endpoint corresponding the port and - * endpoint IDs or NULL if not found. + * The caller is responsible for calling fwnode_handle_put() on the returned + * fwnode pointer. + * + * Return: the fwnode handle of the local endpoint corresponding the port and + * endpoint IDs or %NULL if not found. * * If FWNODE_GRAPH_ENDPOINT_NEXT is passed in @flags and the specified endpoint * has not been found, look for the closest endpoint ID greater than the @@ -1120,9 +1178,6 @@ static bool fwnode_graph_remote_available(struct fwnode_handle *ep) * * Does not return endpoints that belong to disabled devices or endpoints that * are unconnected, unless FWNODE_GRAPH_DEVICE_DISABLED is passed in @flags. - * - * The returned endpoint needs to be released by calling fwnode_handle_put() on - * it when it is not needed any more. */ struct fwnode_handle * fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode, @@ -1180,7 +1235,7 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id); * If FWNODE_GRAPH_DEVICE_DISABLED flag is specified, also unconnected endpoints * and endpoints connected to disabled devices are counted. */ -unsigned int fwnode_graph_get_endpoint_count(struct fwnode_handle *fwnode, +unsigned int fwnode_graph_get_endpoint_count(const struct fwnode_handle *fwnode, unsigned long flags) { struct fwnode_handle *ep; @@ -1328,7 +1383,8 @@ EXPORT_SYMBOL_GPL(fwnode_connection_find_match); * @fwnode and other device nodes. @match will be used to convert the * connection description to data the caller is expecting to be returned * through the @matches array. - * If @matches is NULL @matches_len is ignored and the total number of resolved + * + * If @matches is %NULL @matches_len is ignored and the total number of resolved * matches is returned. * * Return: Number of matches resolved, or negative errno. diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 0fb1d4ab9d8a63..8dec5228fde3d4 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -7,6 +7,7 @@ #include <linux/sysfs.h> #include <linux/init.h> +#include <linux/of.h> #include <linux/stat.h> #include <linux/slab.h> #include <linux/idr.h> @@ -110,6 +111,18 @@ static void soc_release(struct device *dev) kfree(soc_dev); } +static void soc_device_get_machine(struct soc_device_attribute *soc_dev_attr) +{ + struct device_node *np; + + if (soc_dev_attr->machine) + return; + + np = of_find_node_by_path("/"); + of_property_read_string(np, "model", &soc_dev_attr->machine); + of_node_put(np); +} + static struct soc_device_attribute *early_soc_dev_attr; struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr) @@ -118,6 +131,8 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr const struct attribute_group **soc_attr_groups; int ret; + soc_device_get_machine(soc_dev_attr); + if (!soc_bus_registered) { if (early_soc_dev_attr) return ERR_PTR(-EBUSY); diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 7a368c90467d1c..4c666f72203f14 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -290,7 +290,7 @@ aoechr_init(void) } init_completion(&emsgs_comp); spin_lock_init(&emsgs_lock); - aoe_class = class_create(THIS_MODULE, "aoe"); + aoe_class = class_create("aoe"); if (IS_ERR(aoe_class)) { unregister_chrdev(AOE_MAJOR, "aoechr"); return PTR_ERR(aoe_class); diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 5ae2a80db2c341..d5d7884cedd477 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -100,7 +100,8 @@ static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */ static mempool_t psd_pool; static struct bio_set pkt_bio_set; -static struct class *class_pktcdvd = NULL; /* /sys/class/pktcdvd */ +/* /sys/class/pktcdvd */ +static struct class class_pktcdvd; static struct dentry *pkt_debugfs_root = NULL; /* /sys/kernel/debug/pktcdvd */ /* forward declaration */ @@ -315,8 +316,8 @@ static const struct attribute_group *pkt_groups[] = { static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) { - if (class_pktcdvd) { - pd->dev = device_create_with_groups(class_pktcdvd, NULL, + if (class_is_registered(&class_pktcdvd)) { + pd->dev = device_create_with_groups(&class_pktcdvd, NULL, MKDEV(0, 0), pd, pkt_groups, "%s", pd->name); if (IS_ERR(pd->dev)) @@ -326,7 +327,7 @@ static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd) { - if (class_pktcdvd) + if (class_is_registered(&class_pktcdvd)) device_unregister(pd->dev); } @@ -338,12 +339,7 @@ static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd) device_map show mappings *******************************************************************/ -static void class_pktcdvd_release(struct class *cls) -{ - kfree(cls); -} - -static ssize_t device_map_show(struct class *c, struct class_attribute *attr, +static ssize_t device_map_show(const struct class *c, const struct class_attribute *attr, char *data) { int n = 0; @@ -364,7 +360,7 @@ static ssize_t device_map_show(struct class *c, struct class_attribute *attr, } static CLASS_ATTR_RO(device_map); -static ssize_t add_store(struct class *c, struct class_attribute *attr, +static ssize_t add_store(const struct class *c, const struct class_attribute *attr, const char *buf, size_t count) { unsigned int major, minor; @@ -385,7 +381,7 @@ static ssize_t add_store(struct class *c, struct class_attribute *attr, } static CLASS_ATTR_WO(add); -static ssize_t remove_store(struct class *c, struct class_attribute *attr, +static ssize_t remove_store(const struct class *c, const struct class_attribute *attr, const char *buf, size_t count) { unsigned int major, minor; @@ -405,36 +401,23 @@ static struct attribute *class_pktcdvd_attrs[] = { }; ATTRIBUTE_GROUPS(class_pktcdvd); +static struct class class_pktcdvd = { + .name = DRIVER_NAME, + .class_groups = class_pktcdvd_groups, +}; + static int pkt_sysfs_init(void) { - int ret = 0; - /* * create control files in sysfs * /sys/class/pktcdvd/... */ - class_pktcdvd = kzalloc(sizeof(*class_pktcdvd), GFP_KERNEL); - if (!class_pktcdvd) - return -ENOMEM; - class_pktcdvd->name = DRIVER_NAME; - class_pktcdvd->owner = THIS_MODULE; - class_pktcdvd->class_release = class_pktcdvd_release; - class_pktcdvd->class_groups = class_pktcdvd_groups; - ret = class_register(class_pktcdvd); - if (ret) { - kfree(class_pktcdvd); - class_pktcdvd = NULL; - pr_err("failed to create class pktcdvd\n"); - return ret; - } - return 0; + return class_register(&class_pktcdvd); } static void pkt_sysfs_cleanup(void) { - if (class_pktcdvd) - class_destroy(class_pktcdvd); - class_pktcdvd = NULL; + class_unregister(&class_pktcdvd); } /******************************************************************** diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 5cb008b9700a01..84ad3b17956f67 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -491,12 +491,12 @@ static bool single_major = true; module_param(single_major, bool, 0444); MODULE_PARM_DESC(single_major, "Use a single major number for all rbd devices (default: true)"); -static ssize_t add_store(struct bus_type *bus, const char *buf, size_t count); -static ssize_t remove_store(struct bus_type *bus, const char *buf, +static ssize_t add_store(const struct bus_type *bus, const char *buf, size_t count); +static ssize_t remove_store(const struct bus_type *bus, const char *buf, size_t count); -static ssize_t add_single_major_store(struct bus_type *bus, const char *buf, +static ssize_t add_single_major_store(const struct bus_type *bus, const char *buf, size_t count); -static ssize_t remove_single_major_store(struct bus_type *bus, const char *buf, +static ssize_t remove_single_major_store(const struct bus_type *bus, const char *buf, size_t count); static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth); @@ -538,7 +538,7 @@ static bool rbd_is_lock_owner(struct rbd_device *rbd_dev) return is_lock_owner; } -static ssize_t supported_features_show(struct bus_type *bus, char *buf) +static ssize_t supported_features_show(const struct bus_type *bus, char *buf) { return sprintf(buf, "0x%llx\n", RBD_FEATURES_SUPPORTED); } @@ -6967,9 +6967,7 @@ err_out_format: return ret; } -static ssize_t do_rbd_add(struct bus_type *bus, - const char *buf, - size_t count) +static ssize_t do_rbd_add(const char *buf, size_t count) { struct rbd_device *rbd_dev = NULL; struct ceph_options *ceph_opts = NULL; @@ -7081,18 +7079,18 @@ err_out_args: goto out; } -static ssize_t add_store(struct bus_type *bus, const char *buf, size_t count) +static ssize_t add_store(const struct bus_type *bus, const char *buf, size_t count) { if (single_major) return -EINVAL; - return do_rbd_add(bus, buf, count); + return do_rbd_add(buf, count); } -static ssize_t add_single_major_store(struct bus_type *bus, const char *buf, +static ssize_t add_single_major_store(const struct bus_type *bus, const char *buf, size_t count) { - return do_rbd_add(bus, buf, count); + return do_rbd_add(buf, count); } static void rbd_dev_remove_parent(struct rbd_device *rbd_dev) @@ -7122,9 +7120,7 @@ static void rbd_dev_remove_parent(struct rbd_device *rbd_dev) } } -static ssize_t do_rbd_remove(struct bus_type *bus, - const char *buf, - size_t count) +static ssize_t do_rbd_remove(const char *buf, size_t count) { struct rbd_device *rbd_dev = NULL; struct list_head *tmp; @@ -7196,18 +7192,18 @@ static ssize_t do_rbd_remove(struct bus_type *bus, return count; } -static ssize_t remove_store(struct bus_type *bus, const char *buf, size_t count) +static ssize_t remove_store(const struct bus_type *bus, const char *buf, size_t count) { if (single_major) return -EINVAL; - return do_rbd_remove(bus, buf, count); + return do_rbd_remove(buf, count); } -static ssize_t remove_single_major_store(struct bus_type *bus, const char *buf, +static ssize_t remove_single_major_store(const struct bus_type *bus, const char *buf, size_t count) { - return do_rbd_remove(bus, buf, count); + return do_rbd_remove(buf, count); } /* diff --git a/drivers/block/rnbd/rnbd-clt-sysfs.c b/drivers/block/rnbd/rnbd-clt-sysfs.c index e7c7d9a68168de..8c6087949794ec 100644 --- a/drivers/block/rnbd/rnbd-clt-sysfs.c +++ b/drivers/block/rnbd/rnbd-clt-sysfs.c @@ -646,7 +646,7 @@ int rnbd_clt_create_sysfs_files(void) { int err; - rnbd_dev_class = class_create(THIS_MODULE, "rnbd-client"); + rnbd_dev_class = class_create("rnbd-client"); if (IS_ERR(rnbd_dev_class)) return PTR_ERR(rnbd_dev_class); diff --git a/drivers/block/rnbd/rnbd-srv-sysfs.c b/drivers/block/rnbd/rnbd-srv-sysfs.c index 297a6924ff4e20..d5d9267e1fa5e4 100644 --- a/drivers/block/rnbd/rnbd-srv-sysfs.c +++ b/drivers/block/rnbd/rnbd-srv-sysfs.c @@ -215,7 +215,7 @@ int rnbd_srv_create_sysfs_files(void) { int err; - rnbd_dev_class = class_create(THIS_MODULE, "rnbd-server"); + rnbd_dev_class = class_create("rnbd-server"); if (IS_ERR(rnbd_dev_class)) return PTR_ERR(rnbd_dev_class); diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index afbef182820b50..6b8aa0d030f764 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -2311,7 +2311,7 @@ static int __init ublk_init(void) if (ret) goto unregister_mis; - ublk_chr_class = class_create(THIS_MODULE, "ublk-char"); + ublk_chr_class = class_create("ublk-char"); if (IS_ERR(ublk_chr_class)) { ret = PTR_ERR(ublk_chr_class); goto free_chrdev_region; diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index aa490da3cef233..d8217529be6fc7 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -2424,8 +2424,8 @@ static int zram_remove(struct zram *zram) * creates a new un-initialized zram device and returns back this device's * device_id (or an error code if it fails to create a new device). */ -static ssize_t hot_add_show(struct class *class, - struct class_attribute *attr, +static ssize_t hot_add_show(const struct class *class, + const struct class_attribute *attr, char *buf) { int ret; @@ -2438,11 +2438,12 @@ static ssize_t hot_add_show(struct class *class, return ret; return scnprintf(buf, PAGE_SIZE, "%d\n", ret); } +/* This attribute must be set to 0400, so CLASS_ATTR_RO() can not be used */ static struct class_attribute class_attr_hot_add = __ATTR(hot_add, 0400, hot_add_show, NULL); -static ssize_t hot_remove_store(struct class *class, - struct class_attribute *attr, +static ssize_t hot_remove_store(const struct class *class, + const struct class_attribute *attr, const char *buf, size_t count) { @@ -2481,7 +2482,6 @@ ATTRIBUTE_GROUPS(zram_control_class); static struct class zram_control_class = { .name = "zram-control", - .owner = THIS_MODULE, .class_groups = zram_control_class_groups, }; diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 36cb091a33b464..653e2d4c116f02 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -231,7 +231,7 @@ exit: return 0; } -static ssize_t rescan_store(struct bus_type *bus, +static ssize_t rescan_store(const struct bus_type *bus, const char *buf, size_t count) { unsigned long val; @@ -284,7 +284,7 @@ exit: return 0; } -static ssize_t autorescan_store(struct bus_type *bus, +static ssize_t autorescan_store(const struct bus_type *bus, const char *buf, size_t count) { bus_for_each_dev(bus, NULL, (void *)buf, fsl_mc_bus_set_autorescan); @@ -292,7 +292,7 @@ static ssize_t autorescan_store(struct bus_type *bus, return count; } -static ssize_t autorescan_show(struct bus_type *bus, char *buf) +static ssize_t autorescan_show(const struct bus_type *bus, char *buf) { bus_for_each_dev(bus, NULL, (void *)buf, fsl_mc_bus_get_autorescan); return strlen(buf); diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index d5f943938427f3..ff429ba02fa44f 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -293,7 +293,7 @@ static int __init bsr_init(void) if (!np) goto out_err; - bsr_class = class_create(THIS_MODULE, "bsr"); + bsr_class = class_create("bsr"); if (IS_ERR(bsr_class)) { printk(KERN_ERR "class_create() failed for bsr_class\n"); ret = PTR_ERR(bsr_class); diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 06749e295adaff..b3eaf3e5ef2e29 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -504,7 +504,7 @@ static int __init dsp56k_init_driver(void) printk("DSP56k driver: Unable to register driver\n"); return -ENODEV; } - dsp56k_class = class_create(THIS_MODULE, "dsp56k"); + dsp56k_class = class_create("dsp56k"); if (IS_ERR(dsp56k_class)) { err = PTR_ERR(dsp56k_class); goto out_chrdev; diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index d160fa4c73fec8..73e5a9e28f851d 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -860,7 +860,7 @@ static int __init init_ipmi_devintf(void) pr_info("ipmi device interface\n"); - ipmi_class = class_create(THIS_MODULE, "ipmi"); + ipmi_class = class_create("ipmi"); if (IS_ERR(ipmi_class)) { pr_err("ipmi: can't register device class\n"); return PTR_ERR(ipmi_class); diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 38aad99ebb6158..70cfc5140c2cb8 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -1049,7 +1049,7 @@ static int __init lp_init(void) return -EIO; } - lp_class = class_create(THIS_MODULE, "printer"); + lp_class = class_create("printer"); if (IS_ERR(lp_class)) { err = PTR_ERR(lp_class); goto out_reg; diff --git a/drivers/char/mem.c b/drivers/char/mem.c index ffb101d349f0b0..f494d31f2b9835 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -762,7 +762,7 @@ static int __init chr_dev_init(void) if (register_chrdev(MEM_MAJOR, "mem", &memory_fops)) printk("unable to get major %d for memory devs\n", MEM_MAJOR); - mem_class = class_create(THIS_MODULE, "mem"); + mem_class = class_create("mem"); if (IS_ERR(mem_class)) return PTR_ERR(mem_class); diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 7a1388b0572b99..1c44c29a666eb9 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -286,7 +286,7 @@ static int __init misc_init(void) struct proc_dir_entry *ret; ret = proc_create_seq("misc", 0, NULL, &misc_seq_ops); - misc_class = class_create(THIS_MODULE, "misc"); + misc_class = class_create("misc"); err = PTR_ERR(misc_class); if (IS_ERR(misc_class)) goto fail_remove; diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index e656f42a28ac23..7f96d8571a53e7 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -1878,7 +1878,7 @@ static int __init cmm_init(void) { int rc; - cmm_class = class_create(THIS_MODULE, "cardman_4000"); + cmm_class = class_create("cardman_4000"); if (IS_ERR(cmm_class)) return PTR_ERR(cmm_class); diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 827711911da410..11ff59e2b9633d 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -650,7 +650,7 @@ static int __init cm4040_init(void) { int rc; - cmx_class = class_create(THIS_MODULE, "cardman_4040"); + cmx_class = class_create("cardman_4040"); if (IS_ERR(cmx_class)) return PTR_ERR(cmx_class); diff --git a/drivers/char/pcmcia/scr24x_cs.c b/drivers/char/pcmcia/scr24x_cs.c index 1bdce08fae3db5..870781f5a08cd3 100644 --- a/drivers/char/pcmcia/scr24x_cs.c +++ b/drivers/char/pcmcia/scr24x_cs.c @@ -325,7 +325,7 @@ static int __init scr24x_init(void) { int ret; - scr24x_class = class_create(THIS_MODULE, "scr24x"); + scr24x_class = class_create("scr24x"); if (IS_ERR(scr24x_class)) return PTR_ERR(scr24x_class); diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 38b46c7d173711..81ed58157b1579 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -841,7 +841,7 @@ static int __init ppdev_init(void) pr_warn(CHRDEV ": unable to get major %d\n", PP_MAJOR); return -EIO; } - ppdev_class = class_create(THIS_MODULE, CHRDEV); + ppdev_class = class_create(CHRDEV); if (IS_ERR(ppdev_class)) { err = PTR_ERR(ppdev_class); goto out_chrdev; diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 6fdfa65a00c379..80aaa10f436ec8 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -282,7 +282,7 @@ static void tpm_dev_release(struct device *dev) * * Return: always 0 (i.e. success) */ -static int tpm_class_shutdown(struct device *dev) +int tpm_class_shutdown(struct device *dev) { struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev); @@ -337,7 +337,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, device_initialize(&chip->dev); chip->dev.class = tpm_class; - chip->dev.class->shutdown_pre = tpm_class_shutdown; chip->dev.release = tpm_dev_release; chip->dev.parent = pdev; chip->dev.groups = chip->groups; diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 7e513b7718320c..4463d00182909b 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -466,13 +466,15 @@ static int __init tpm_init(void) { int rc; - tpm_class = class_create(THIS_MODULE, "tpm"); + tpm_class = class_create("tpm"); if (IS_ERR(tpm_class)) { pr_err("couldn't create tpm class\n"); return PTR_ERR(tpm_class); } - tpmrm_class = class_create(THIS_MODULE, "tpmrm"); + tpm_class->shutdown_pre = tpm_class_shutdown; + + tpmrm_class = class_create("tpmrm"); if (IS_ERR(tpmrm_class)) { pr_err("couldn't create tpmrm class\n"); rc = PTR_ERR(tpmrm_class); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 88d3bd76e0760d..eaedf569219e67 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -256,6 +256,7 @@ int tpm1_get_pcr_allocation(struct tpm_chip *chip); unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal); int tpm_pm_suspend(struct device *dev); int tpm_pm_resume(struct device *dev); +int tpm_class_shutdown(struct device *dev); static inline void tpm_msleep(unsigned int delay_msec) { diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index d5ac4d955bc8ca..b65c809a4e978d 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -2244,7 +2244,7 @@ static int __init virtio_console_init(void) { int err; - pdrvdata.class = class_create(THIS_MODULE, "virtio-ports"); + pdrvdata.class = class_create("virtio-ports"); if (IS_ERR(pdrvdata.class)) { err = PTR_ERR(pdrvdata.class); pr_err("Error %d creating virtio-ports class\n", err); diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 74a4928aea1d37..a46f637da9599a 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -856,7 +856,7 @@ static int __init hwicap_module_init(void) dev_t devt; int retval; - icap_class = class_create(THIS_MODULE, "xilinx_config"); + icap_class = class_create("xilinx_config"); mutex_init(&icap_sem); devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR); diff --git a/drivers/char/xillybus/xillybus_class.c b/drivers/char/xillybus/xillybus_class.c index e9a288e61c1566..89926fe9d8130b 100644 --- a/drivers/char/xillybus/xillybus_class.c +++ b/drivers/char/xillybus/xillybus_class.c @@ -242,7 +242,7 @@ EXPORT_SYMBOL(xillybus_find_inode); static int __init xillybus_class_init(void) { - xillybus_class = class_create(THIS_MODULE, "xillybus"); + xillybus_class = class_create("xillybus"); if (IS_ERR(xillybus_class)) { pr_warn("Failed to register xillybus class\n"); diff --git a/drivers/comedi/comedi_fops.c b/drivers/comedi/comedi_fops.c index b982903aaa4650..8e43918d38c400 100644 --- a/drivers/comedi/comedi_fops.c +++ b/drivers/comedi/comedi_fops.c @@ -3383,7 +3383,7 @@ static int __init comedi_init(void) if (retval) goto out_unregister_chrdev_region; - comedi_class = class_create(THIS_MODULE, "comedi"); + comedi_class = class_create("comedi"); if (IS_ERR(comedi_class)) { retval = PTR_ERR(comedi_class); pr_err("failed to create class\n"); diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c index 0b5c0af1cebf05..c02dc19a679bde 100644 --- a/drivers/comedi/drivers/comedi_test.c +++ b/drivers/comedi/drivers/comedi_test.c @@ -795,7 +795,7 @@ static int __init comedi_test_init(void) } if (!config_mode) { - ctcls = class_create(THIS_MODULE, CLASS_NAME); + ctcls = class_create(CLASS_NAME); if (IS_ERR(ctcls)) { pr_warn("comedi_test: unable to create class\n"); goto clean3; diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index fcb54a6f659825..5a3d4aa0f45a6a 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -63,7 +63,6 @@ static struct cpufreq_driver *current_pstate_driver; static struct cpufreq_driver amd_pstate_driver; static struct cpufreq_driver amd_pstate_epp_driver; static int cppc_state = AMD_PSTATE_DISABLE; -struct kobject *amd_pstate_kobj; /* * AMD Energy Preference Performance (EPP) @@ -1013,6 +1012,7 @@ static struct attribute *pstate_global_attributes[] = { }; static const struct attribute_group amd_pstate_global_attr_group = { + .name = "amd_pstate", .attrs = pstate_global_attributes, }; @@ -1334,6 +1334,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = { static int __init amd_pstate_init(void) { + struct device *dev_root; int ret; if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) @@ -1380,24 +1381,19 @@ static int __init amd_pstate_init(void) if (ret) pr_err("failed to register with return %d\n", ret); - amd_pstate_kobj = kobject_create_and_add("amd_pstate", &cpu_subsys.dev_root->kobj); - if (!amd_pstate_kobj) { - ret = -EINVAL; - pr_err("global sysfs registration failed.\n"); - goto kobject_free; - } - - ret = sysfs_create_group(amd_pstate_kobj, &amd_pstate_global_attr_group); - if (ret) { - pr_err("sysfs attribute export failed with error %d.\n", ret); - goto global_attr_free; + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + ret = sysfs_create_group(&dev_root->kobj, &amd_pstate_global_attr_group); + put_device(dev_root); + if (ret) { + pr_err("sysfs attribute export failed with error %d.\n", ret); + goto global_attr_free; + } } return ret; global_attr_free: - kobject_put(amd_pstate_kobj); -kobject_free: cpufreq_unregister_driver(current_pstate_driver); return ret; } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2ac905c637ddca..6b52ebe5a89041 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2937,11 +2937,16 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); static int __init cpufreq_core_init(void) { struct cpufreq_governor *gov = cpufreq_default_governor(); + struct device *dev_root; if (cpufreq_disabled()) return -ENODEV; - cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj); + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + cpufreq_global_kobject = kobject_create_and_add("cpufreq", &dev_root->kobj); + put_device(dev_root); + } BUG_ON(!cpufreq_global_kobject); if (!strlen(default_governor)) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 2a1a6779d82d20..2548ec92faa282 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1473,10 +1473,13 @@ static struct kobject *intel_pstate_kobject; static void __init intel_pstate_sysfs_expose_params(void) { + struct device *dev_root = bus_get_dev_root(&cpu_subsys); int rc; - intel_pstate_kobject = kobject_create_and_add("intel_pstate", - &cpu_subsys.dev_root->kobj); + if (dev_root) { + intel_pstate_kobject = kobject_create_and_add("intel_pstate", &dev_root->kobj); + put_device(dev_root); + } if (WARN_ON(!intel_pstate_kobject)) return; diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 0b00f21cefe36f..8e929f6602cef5 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -808,7 +808,7 @@ static int __init cpuidle_init(void) if (cpuidle_disabled()) return -ENODEV; - return cpuidle_add_interface(cpu_subsys.dev_root); + return cpuidle_add_interface(); } module_param(off, int, 0444); diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h index 9f336af17fa603..52701d9588f1d8 100644 --- a/drivers/cpuidle/cpuidle.h +++ b/drivers/cpuidle/cpuidle.h @@ -30,7 +30,7 @@ extern int cpuidle_switch_governor(struct cpuidle_governor *gov); struct device; -extern int cpuidle_add_interface(struct device *dev); +extern int cpuidle_add_interface(void); extern void cpuidle_remove_interface(struct device *dev); extern int cpuidle_add_device_sysfs(struct cpuidle_device *device); extern void cpuidle_remove_device_sysfs(struct cpuidle_device *device); diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 48948b17174946..d6f5da61cb7d86 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -119,11 +119,18 @@ static struct attribute_group cpuidle_attr_group = { /** * cpuidle_add_interface - add CPU global sysfs attributes - * @dev: the target device */ -int cpuidle_add_interface(struct device *dev) +int cpuidle_add_interface(void) { - return sysfs_create_group(&dev->kobj, &cpuidle_attr_group); + struct device *dev_root = bus_get_dev_root(&cpu_subsys); + int retval; + + if (!dev_root) + return -EINVAL; + + retval = sysfs_create_group(&dev_root->kobj, &cpuidle_attr_group); + put_device(dev_root); + return retval; } /** diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 8b563ab4748474..ad0c042b5e665f 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -3690,7 +3690,7 @@ static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf, unsigned long *val, unsigned int *fun_index) { - struct bus_type *bus_type = qm->pdev->dev.bus; + const struct bus_type *bus_type = qm->pdev->dev.bus; char tbuf_bdf[QM_DBG_READ_LEN] = {0}; char val_buf[QM_DBG_READ_LEN] = {0}; struct pci_dev *pdev; diff --git a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c index 88c41d6fbb7ca5..29c4422f243c66 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c +++ b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c @@ -57,7 +57,7 @@ static int adf_chr_drv_create(void) return -EFAULT; } - adf_ctl_drv.drv_class = class_create(THIS_MODULE, DEVICE_NAME); + adf_ctl_drv.drv_class = class_create(DEVICE_NAME); if (IS_ERR(adf_ctl_drv.drv_class)) { pr_err("QAT: class_create failed for adf_ctl\n"); goto err_chrdev_unreg; diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index 4d1f9c5b5029a5..72b889af9917e9 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -1903,7 +1903,7 @@ bool schedule_cxl_memdev_detach(struct cxl_memdev *cxlmd) EXPORT_SYMBOL_NS_GPL(schedule_cxl_memdev_detach, CXL); /* for user tooling to ensure port disable work has completed */ -static ssize_t flush_store(struct bus_type *bus, const char *buf, size_t count) +static ssize_t flush_store(const struct bus_type *bus, const char *buf, size_t count) { if (sysfs_streq(buf, "1")) { flush_workqueue(cxl_bus_wq); diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c index 21ebd0af268bf2..fcc83ede09093a 100644 --- a/drivers/dca/dca-sysfs.c +++ b/drivers/dca/dca-sysfs.c @@ -74,7 +74,7 @@ int __init dca_sysfs_init(void) idr_init(&dca_idr); spin_lock_init(&dca_idr_lock); - dca_class = class_create(THIS_MODULE, "dca"); + dca_class = class_create("dca"); if (IS_ERR(dca_class)) { idr_destroy(&dca_idr); return PTR_ERR(dca_class); diff --git a/drivers/devfreq/devfreq-event.c b/drivers/devfreq/devfreq-event.c index f041edccd10784..3ebac2496679b5 100644 --- a/drivers/devfreq/devfreq-event.c +++ b/drivers/devfreq/devfreq-event.c @@ -469,7 +469,7 @@ ATTRIBUTE_GROUPS(devfreq_event); static int __init devfreq_event_init(void) { - devfreq_event_class = class_create(THIS_MODULE, "devfreq-event"); + devfreq_event_class = class_create("devfreq-event"); if (IS_ERR(devfreq_event_class)) { pr_err("%s: couldn't create class\n", __FILE__); return PTR_ERR(devfreq_event_class); diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 817c71da391a67..e36cbb920ec883 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -1988,7 +1988,7 @@ DEFINE_SHOW_ATTRIBUTE(devfreq_summary); static int __init devfreq_init(void) { - devfreq_class = class_create(THIS_MODULE, "devfreq"); + devfreq_class = class_create("devfreq"); if (IS_ERR(devfreq_class)) { pr_err("%s: couldn't create class\n", __FILE__); return PTR_ERR(devfreq_class); diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index c9e41e8a9e272c..84ae708fafe75c 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -314,7 +314,7 @@ static int dma_heap_init(void) if (ret) return ret; - dma_heap_class = class_create(THIS_MODULE, DEVNAME); + dma_heap_class = class_create(DEVNAME); if (IS_ERR(dma_heap_class)) { unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS); return PTR_ERR(dma_heap_class); diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c index 3df21615f88834..5fd38d1b9d2894 100644 --- a/drivers/dma/idxd/compat.c +++ b/drivers/dma/idxd/compat.c @@ -16,7 +16,7 @@ extern void device_driver_detach(struct device *dev); static ssize_t unbind_store(struct device_driver *drv, const char *buf, size_t count) { - struct bus_type *bus = drv->bus; + const struct bus_type *bus = drv->bus; struct device *dev; int rc = -ENODEV; @@ -32,7 +32,7 @@ static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store); static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t count) { - struct bus_type *bus = drv->bus; + const struct bus_type *bus = drv->bus; struct device *dev; struct device_driver *alt_drv = NULL; int rc = -ENODEV; diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c index ac678b4a21fcbf..010c26be58464d 100644 --- a/drivers/edac/edac_device_sysfs.c +++ b/drivers/edac/edac_device_sysfs.c @@ -228,8 +228,9 @@ static struct kobj_type ktype_device_ctrl = { */ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev) { + struct device *dev_root; struct bus_type *edac_subsys; - int err; + int err = -ENODEV; edac_dbg(1, "\n"); @@ -247,15 +248,16 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev) */ edac_dev->owner = THIS_MODULE; - if (!try_module_get(edac_dev->owner)) { - err = -ENODEV; + if (!try_module_get(edac_dev->owner)) goto err_out; - } /* register */ - err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl, - &edac_subsys->dev_root->kobj, - "%s", edac_dev->name); + dev_root = bus_get_dev_root(edac_subsys); + if (dev_root) { + err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl, + &dev_root->kobj, "%s", edac_dev->name); + put_device(dev_root); + } if (err) { edac_dbg(1, "Failed to register '.../edac/%s'\n", edac_dev->name); diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 888d5728ecef7f..287cc51dbc868a 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -337,8 +337,9 @@ static struct kobj_type ktype_edac_pci_main_kobj = { */ static int edac_pci_main_kobj_setup(void) { - int err; + int err = -ENODEV; struct bus_type *edac_subsys; + struct device *dev_root; edac_dbg(0, "\n"); @@ -357,7 +358,6 @@ static int edac_pci_main_kobj_setup(void) */ if (!try_module_get(THIS_MODULE)) { edac_dbg(1, "try_module_get() failed\n"); - err = -ENODEV; goto decrement_count_fail; } @@ -369,9 +369,13 @@ static int edac_pci_main_kobj_setup(void) } /* Instanstiate the pci object */ - err = kobject_init_and_add(edac_pci_top_main_kobj, - &ktype_edac_pci_main_kobj, - &edac_subsys->dev_root->kobj, "pci"); + dev_root = bus_get_dev_root(edac_subsys); + if (dev_root) { + err = kobject_init_and_add(edac_pci_top_main_kobj, + &ktype_edac_pci_main_kobj, + &dev_root->kobj, "pci"); + put_device(dev_root); + } if (err) { edac_dbg(1, "Failed to register '.../edac/pci'\n"); goto kobject_init_and_add_fail; diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index e1c71359b6051c..d43ba8e7260dd0 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -1013,7 +1013,7 @@ ATTRIBUTE_GROUPS(extcon); static int create_extcon_class(void) { if (!extcon_class) { - extcon_class = class_create(THIS_MODULE, "extcon"); + extcon_class = class_create("extcon"); if (IS_ERR(extcon_class)) return PTR_ERR(extcon_class); extcon_class->dev_groups = extcon_groups; diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 0953e6e4db041d..c41b3f2360a85f 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c @@ -417,7 +417,7 @@ static void fpga_bridge_dev_release(struct device *dev) static int __init fpga_bridge_dev_init(void) { - fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge"); + fpga_bridge_class = class_create("fpga_bridge"); if (IS_ERR(fpga_bridge_class)) return PTR_ERR(fpga_bridge_class); diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 8efa67620e2169..eb583f86a0b95e 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c @@ -971,7 +971,7 @@ static int __init fpga_mgr_class_init(void) { pr_info("FPGA manager framework\n"); - fpga_mgr_class = class_create(THIS_MODULE, "fpga_manager"); + fpga_mgr_class = class_create("fpga_manager"); if (IS_ERR(fpga_mgr_class)) return PTR_ERR(fpga_mgr_class); diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index 27ff9dea04ae3b..ccf6fdab136089 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -293,7 +293,7 @@ static void fpga_region_dev_release(struct device *dev) */ static int __init fpga_region_init(void) { - fpga_region_class = class_create(THIS_MODULE, "fpga_region"); + fpga_region_class = class_create("fpga_region"); if (IS_ERR(fpga_region_class)) return PTR_ERR(fpga_region_class); diff --git a/drivers/gnss/core.c b/drivers/gnss/core.c index 77a4b280c552ab..48f2ee0f78c4df 100644 --- a/drivers/gnss/core.c +++ b/drivers/gnss/core.c @@ -387,7 +387,7 @@ static int __init gnss_module_init(void) return ret; } - gnss_class = class_create(THIS_MODULE, "gnss"); + gnss_class = class_create("gnss"); if (IS_ERR(gnss_class)) { ret = PTR_ERR(gnss_class); pr_err("failed to create class: %d\n", ret); diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index c1cbf71329f00c..530dfd19d7b52e 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -437,8 +437,8 @@ ATTRIBUTE_GROUPS(gpiochip); * /sys/class/gpio/unexport ... write-only * integer N ... number of GPIO to unexport */ -static ssize_t export_store(struct class *class, - struct class_attribute *attr, +static ssize_t export_store(const struct class *class, + const struct class_attribute *attr, const char *buf, size_t len) { long gpio; @@ -489,8 +489,8 @@ done: } static CLASS_ATTR_WO(export); -static ssize_t unexport_store(struct class *class, - struct class_attribute *attr, +static ssize_t unexport_store(const struct class *class, + const struct class_attribute *attr, const char *buf, size_t len) { long gpio; @@ -534,8 +534,6 @@ ATTRIBUTE_GROUPS(gpio_class); static struct class gpio_class = { .name = "gpio", - .owner = THIS_MODULE, - .class_groups = gpio_class_groups, }; @@ -567,7 +565,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) int offset; /* can't export until sysfs is available ... */ - if (!gpio_class.p) { + if (!class_is_registered(&gpio_class)) { pr_debug("%s: called too early!\n", __func__); return -ENOENT; } @@ -741,7 +739,7 @@ int gpiochip_sysfs_register(struct gpio_device *gdev) * register later, in gpiolib_sysfs_init() ... here we just * verify that _some_ field of gpio_class got initialized. */ - if (!gpio_class.p) + if (!class_is_registered(&gpio_class)) return 0; /* diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 81d07ecf666d01..1b54a9aaae70cc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -93,7 +93,7 @@ int kfd_chardev_init(void) if (err < 0) goto err_register_chrdev; - kfd_class = class_create(THIS_MODULE, kfd_dev_name); + kfd_class = class_create(kfd_dev_name); err = PTR_ERR(kfd_class); if (IS_ERR(kfd_class)) goto err_class_create; diff --git a/drivers/gpu/drm/display/drm_dp_aux_dev.c b/drivers/gpu/drm/display/drm_dp_aux_dev.c index 098e482e65a288..29555b9f03c8c4 100644 --- a/drivers/gpu/drm/display/drm_dp_aux_dev.c +++ b/drivers/gpu/drm/display/drm_dp_aux_dev.c @@ -330,7 +330,7 @@ int drm_dp_aux_dev_init(void) { int res; - drm_dp_aux_dev_class = class_create(THIS_MODULE, "drm_dp_aux_dev"); + drm_dp_aux_dev_class = class_create("drm_dp_aux_dev"); if (IS_ERR(drm_dp_aux_dev_class)) { return PTR_ERR(drm_dp_aux_dev_class); } diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 18313035599725..3c22a803201dc8 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -112,7 +112,7 @@ int drm_sysfs_init(void) { int err; - drm_class = class_create(THIS_MODULE, "drm"); + drm_class = class_create("drm"); if (IS_ERR(drm_class)) return PTR_ERR(drm_class); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c index aefdaa62da994c..04724ff56ded3f 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c @@ -190,7 +190,7 @@ static int gsc_notifier(struct notifier_block *nb, unsigned long action, void *d return 0; } -void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus) +void intel_huc_register_gsc_notifier(struct intel_huc *huc, const struct bus_type *bus) { int ret; @@ -206,7 +206,7 @@ void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus } } -void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *bus) +void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, const struct bus_type *bus) { if (!huc->delayed_load.nb.notifier_call) return; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h index db555b3c1f5627..0789184d81a2a5 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h @@ -52,8 +52,8 @@ int intel_huc_check_status(struct intel_huc *huc); void intel_huc_update_auth_status(struct intel_huc *huc); bool intel_huc_is_authenticated(struct intel_huc *huc); -void intel_huc_register_gsc_notifier(struct intel_huc *huc, struct bus_type *bus); -void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *bus); +void intel_huc_register_gsc_notifier(struct intel_huc *huc, const struct bus_type *bus); +void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, const struct bus_type *bus); static inline bool intel_huc_is_supported(struct intel_huc *huc) { diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index d94ee0539421e7..ea6b79b3aeeb54 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c @@ -433,7 +433,7 @@ static int __init arvo_init(void) { int retval; - arvo_class = class_create(THIS_MODULE, "arvo"); + arvo_class = class_create("arvo"); if (IS_ERR(arvo_class)) return PTR_ERR(arvo_class); arvo_class->dev_groups = arvo_groups; diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index e95d59cd8d075d..3903a2cea00c2e 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c @@ -435,7 +435,7 @@ static struct hid_driver isku_driver = { static int __init isku_init(void) { int retval; - isku_class = class_create(THIS_MODULE, "isku"); + isku_class = class_create("isku"); if (IS_ERR(isku_class)) return PTR_ERR(isku_class); isku_class->dev_groups = isku_groups; diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 76da04801ca9bd..945ae236fb4587 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -890,7 +890,7 @@ static int __init kone_init(void) int retval; /* class name has to be same as driver name */ - kone_class = class_create(THIS_MODULE, "kone"); + kone_class = class_create("kone"); if (IS_ERR(kone_class)) return PTR_ERR(kone_class); kone_class->dev_groups = kone_groups; diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 1896c69ea512f7..97b83b6f53ddf7 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c @@ -549,7 +549,7 @@ static int __init koneplus_init(void) int retval; /* class name has to be same as driver name */ - koneplus_class = class_create(THIS_MODULE, "koneplus"); + koneplus_class = class_create("koneplus"); if (IS_ERR(koneplus_class)) return PTR_ERR(koneplus_class); koneplus_class->dev_groups = koneplus_groups; diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c index cf8eeb33a12571..a297756f24103d 100644 --- a/drivers/hid/hid-roccat-konepure.c +++ b/drivers/hid/hid-roccat-konepure.c @@ -207,7 +207,7 @@ static int __init konepure_init(void) { int retval; - konepure_class = class_create(THIS_MODULE, "konepure"); + konepure_class = class_create("konepure"); if (IS_ERR(konepure_class)) return PTR_ERR(konepure_class); konepure_class->dev_groups = konepure_groups; diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 6fb9b9563769df..1a1d96e116832f 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c @@ -638,7 +638,7 @@ static int __init kovaplus_init(void) { int retval; - kovaplus_class = class_create(THIS_MODULE, "kovaplus"); + kovaplus_class = class_create("kovaplus"); if (IS_ERR(kovaplus_class)) return PTR_ERR(kovaplus_class); kovaplus_class->dev_groups = kovaplus_groups; diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 4fcc8e7d276f22..15528c3b013c77 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -585,7 +585,7 @@ static int __init pyra_init(void) int retval; /* class name has to be same as driver name */ - pyra_class = class_create(THIS_MODULE, "pyra"); + pyra_class = class_create("pyra"); if (IS_ERR(pyra_class)) return PTR_ERR(pyra_class); pyra_class->dev_groups = pyra_groups; diff --git a/drivers/hid/hid-roccat-ryos.c b/drivers/hid/hid-roccat-ryos.c index 5bf1971a2b14d8..0eb17a3b925d0e 100644 --- a/drivers/hid/hid-roccat-ryos.c +++ b/drivers/hid/hid-roccat-ryos.c @@ -216,7 +216,7 @@ static int __init ryos_init(void) { int retval; - ryos_class = class_create(THIS_MODULE, "ryos"); + ryos_class = class_create("ryos"); if (IS_ERR(ryos_class)) return PTR_ERR(ryos_class); ryos_class->dev_groups = ryos_groups; diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index a784bb4ee6512d..93be7acef6733d 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c @@ -204,7 +204,7 @@ static int __init savu_init(void) { int retval; - savu_class = class_create(THIS_MODULE, "savu"); + savu_class = class_create("savu"); if (IS_ERR(savu_class)) return PTR_ERR(savu_class); savu_class->dev_groups = savu_groups; diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 197b1e7bf029e6..93e62b161501cc 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -618,7 +618,7 @@ int __init hidraw_init(void) hidraw_major = MAJOR(dev_id); - hidraw_class = class_create(THIS_MODULE, "hidraw"); + hidraw_class = class_create("hidraw"); if (IS_ERR(hidraw_class)) { result = PTR_ERR(hidraw_class); goto error_cdev; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index e9e1c4139e0da4..1ab4f91151002b 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -684,7 +684,7 @@ static const struct attribute_group vmbus_dev_group = { __ATTRIBUTE_GROUPS(vmbus_dev); /* Set up the attribute for /sys/bus/vmbus/hibernation */ -static ssize_t hibernation_show(struct bus_type *bus, char *buf) +static ssize_t hibernation_show(const struct bus_type *bus, char *buf) { return sprintf(buf, "%d\n", !!hv_is_hibernation_supported()); } diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c index e73b7bfc6af357..6bdd21aa005ab8 100644 --- a/drivers/hwmon/drivetemp.c +++ b/drivers/hwmon/drivetemp.c @@ -550,7 +550,7 @@ static const struct hwmon_chip_info drivetemp_chip_info = { * The device argument points to sdev->sdev_dev. Its parent is * sdev->sdev_gendev, which we can use to get the scsi_device pointer. */ -static int drivetemp_add(struct device *dev, struct class_interface *intf) +static int drivetemp_add(struct device *dev) { struct scsi_device *sdev = to_scsi_device(dev->parent); struct drivetemp_data *st; @@ -585,7 +585,7 @@ abort: return err; } -static void drivetemp_remove(struct device *dev, struct class_interface *intf) +static void drivetemp_remove(struct device *dev) { struct drivetemp_data *st, *tmp; diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 508cb768c2677f..573b83b6c08cc4 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -138,7 +138,6 @@ static void hwmon_dev_release(struct device *dev) static struct class hwmon_class = { .name = "hwmon", - .owner = THIS_MODULE, .dev_groups = hwmon_dev_attr_groups, .dev_release = hwmon_dev_release, }; diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 95a0b63ac560cf..a01b59e3599b53 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -751,7 +751,7 @@ static int __init i2c_dev_init(void) if (res) goto out; - i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); + i2c_dev_class = class_create("i2c-dev"); if (IS_ERR(i2c_dev_class)) { res = PTR_ERR(i2c_dev_class); goto out_unreg_chrdev; diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index f83954180a3389..0e9e04f8c6858f 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -1229,8 +1229,8 @@ static char *umad_devnode(const struct device *dev, umode_t *mode) return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev)); } -static ssize_t abi_version_show(struct class *class, - struct class_attribute *attr, char *buf) +static ssize_t abi_version_show(const struct class *class, + const struct class_attribute *attr, char *buf) { return sysfs_emit(buf, "%d\n", IB_USER_MAD_ABI_VERSION); } diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index bdb179a09d77cf..fbace69672ca92 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -1264,7 +1264,7 @@ static int __init ib_uverbs_init(void) goto out_alloc; } - uverbs_class = class_create(THIS_MODULE, "infiniband_verbs"); + uverbs_class = class_create("infiniband_verbs"); if (IS_ERR(uverbs_class)) { ret = PTR_ERR(uverbs_class); pr_err("user_verbs: couldn't create class infiniband_verbs\n"); diff --git a/drivers/infiniband/hw/hfi1/device.c b/drivers/infiniband/hw/hfi1/device.c index 1f44960321704a..05be0d119f796f 100644 --- a/drivers/infiniband/hw/hfi1/device.c +++ b/drivers/infiniband/hw/hfi1/device.c @@ -102,7 +102,7 @@ int __init dev_init(void) goto done; } - class = class_create(THIS_MODULE, class_name()); + class = class_create(class_name()); if (IS_ERR(class)) { ret = PTR_ERR(class); pr_err("Could not create device class (err %d)\n", -ret); @@ -111,7 +111,7 @@ int __init dev_init(void) } class->devnode = hfi1_devnode; - user_class = class_create(THIS_MODULE, class_name_user()); + user_class = class_create(class_name_user()); if (IS_ERR(user_class)) { ret = PTR_ERR(user_class); pr_err("Could not create device class for user accessible files (err %d)\n", diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index 815ea72ad47398..f22352f2b369f6 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c @@ -2326,7 +2326,7 @@ int __init qib_dev_init(void) goto done; } - qib_class = class_create(THIS_MODULE, "ipath"); + qib_class = class_create("ipath"); if (IS_ERR(qib_class)) { ret = PTR_ERR(qib_class); pr_err("Could not create device class (err %d)\n", -ret); diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index 80abf45a197ac0..edb2e3a25880b4 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -3163,7 +3163,7 @@ static int __init rtrs_client_init(void) { rtrs_rdma_dev_pd_init(0, &dev_pd); - rtrs_clt_dev_class = class_create(THIS_MODULE, "rtrs-client"); + rtrs_clt_dev_class = class_create("rtrs-client"); if (IS_ERR(rtrs_clt_dev_class)) { pr_err("Failed to create rtrs-client dev class\n"); return PTR_ERR(rtrs_clt_dev_class); diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c index d1703e2c0b82fc..c38901e2c8f421 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c @@ -2253,7 +2253,7 @@ static int __init rtrs_server_init(void) err); return err; } - rtrs_dev_class = class_create(THIS_MODULE, "rtrs-server"); + rtrs_dev_class = class_create("rtrs-server"); if (IS_ERR(rtrs_dev_class)) { err = PTR_ERR(rtrs_dev_class); goto out_err; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 10db680acaed5a..0b5e181998c9d6 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -89,7 +89,7 @@ static int iommu_bus_notifier(struct notifier_block *nb, unsigned long action, void *data); static int iommu_alloc_default_domain(struct iommu_group *group, struct device *dev); -static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, +static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus, unsigned type); static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev); @@ -1631,7 +1631,7 @@ static int iommu_get_def_domain_type(struct device *dev) return 0; } -static int iommu_group_alloc_default_domain(struct bus_type *bus, +static int iommu_group_alloc_default_domain(const struct bus_type *bus, struct iommu_group *group, unsigned int type) { @@ -1777,7 +1777,7 @@ static int probe_get_default_domain_type(struct device *dev, void *data) return 0; } -static void probe_alloc_default_domain(struct bus_type *bus, +static void probe_alloc_default_domain(const struct bus_type *bus, struct iommu_group *group) { struct __group_domain_type gtype; @@ -1832,7 +1832,7 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group) iommu_do_create_direct_mappings); } -int bus_iommu_probe(struct bus_type *bus) +int bus_iommu_probe(const struct bus_type *bus) { struct iommu_group *group, *next; LIST_HEAD(group_list); @@ -1876,7 +1876,7 @@ int bus_iommu_probe(struct bus_type *bus) return ret; } -bool iommu_present(struct bus_type *bus) +bool iommu_present(const struct bus_type *bus) { return bus->iommu_ops != NULL; } @@ -1951,7 +1951,7 @@ void iommu_set_fault_handler(struct iommu_domain *domain, } EXPORT_SYMBOL_GPL(iommu_set_fault_handler); -static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, +static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus, unsigned type) { struct iommu_domain *domain; @@ -1976,7 +1976,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, return domain; } -struct iommu_domain *iommu_domain_alloc(struct bus_type *bus) +struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus) { return __iommu_domain_alloc(bus, IOMMU_DOMAIN_UNMANAGED); } diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index f3faf5c9977064..30ca1bf7fc8bd4 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -245,11 +245,14 @@ static int mbigen_of_create_domain(struct platform_device *pdev, if (!of_property_read_bool(np, "interrupt-controller")) continue; - parent = platform_bus_type.dev_root; - child = of_platform_device_create(np, NULL, parent); - if (!child) { - of_node_put(np); - return -ENOMEM; + parent = bus_get_dev_root(&platform_bus_type); + if (parent) { + child = of_platform_device_create(np, NULL, parent); + put_device(parent); + if (!child) { + of_node_put(np); + return -ENOMEM; + } } if (of_property_read_u32(child->dev.of_node, "num-pins", diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 0f00be62438d5f..45a4043c504209 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1393,7 +1393,7 @@ static int __init capi_init(void) kcapi_exit(); return major_ret; } - capi_class = class_create(THIS_MODULE, "capi"); + capi_class = class_create("capi"); if (IS_ERR(capi_class)) { unregister_chrdev(capi_major, "capi20"); kcapi_exit(); diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c index 9120be5903258b..ab8513a7acd52d 100644 --- a/drivers/isdn/mISDN/core.c +++ b/drivers/isdn/mISDN/core.c @@ -152,18 +152,11 @@ static int mISDN_uevent(const struct device *dev, struct kobj_uevent_env *env) return 0; } -static void mISDN_class_release(struct class *cls) -{ - /* do nothing, it's static */ -} - static struct class mISDN_class = { .name = "mISDN", - .owner = THIS_MODULE, .dev_uevent = mISDN_uevent, .dev_groups = mISDN_groups, .dev_release = mISDN_dev_release, - .class_release = mISDN_class_release, }; static int diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c index cfbcd9e973c2e6..09b72f14d4b7b9 100644 --- a/drivers/isdn/mISDN/dsp_pipeline.c +++ b/drivers/isdn/mISDN/dsp_pipeline.c @@ -131,7 +131,7 @@ EXPORT_SYMBOL(mISDN_dsp_element_unregister); int dsp_pipeline_module_init(void) { - elements_class = class_create(THIS_MODULE, "dsp_pipeline"); + elements_class = class_create("dsp_pipeline"); if (IS_ERR(elements_class)) return PTR_ERR(elements_class); diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index a6b3adcd044a01..9255bc11f99d84 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -626,7 +626,7 @@ EXPORT_SYMBOL_GPL(devm_led_classdev_unregister); static int __init leds_init(void) { - leds_class = class_create(THIS_MODULE, "leds"); + leds_class = class_create("leds"); if (IS_ERR(leds_class)) return PTR_ERR(leds_class); leds_class->pm = &leds_class_dev_pm_ops; diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 23bd0c77ac1af3..57e987cf84b257 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -888,7 +888,7 @@ adbdev_init(void) return; } - adb_dev_class = class_create(THIS_MODULE, "adb"); + adb_dev_class = class_create("adb"); if (IS_ERR(adb_dev_class)) return; device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb"); diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 0ed087caf7f3b2..e9b3ce09e534c1 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -1063,7 +1063,7 @@ static int __init init_dvbdev(void) goto error; } - dvb_class = class_create(THIS_MODULE, "dvb"); + dvb_class = class_create("dvb"); if (IS_ERR(dvb_class)) { retval = PTR_ERR(dvb_class); goto error; diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index ee8087f29b2c4a..40e6c873c36d2a 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -3117,7 +3117,6 @@ static struct device_attribute ddb_attrs_fanspeed[] = { static struct class ddb_class = { .name = "ddbridge", - .owner = THIS_MODULE, .devnode = ddb_devnode, }; diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 25ab61dae126d4..043d23aaa3cbcc 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -785,7 +785,7 @@ int __init lirc_dev_init(void) { int retval; - lirc_class = class_create(THIS_MODULE, "lirc"); + lirc_class = class_create("lirc"); if (IS_ERR(lirc_class)) { pr_err("class_create failed\n"); return PTR_ERR(lirc_class); diff --git a/drivers/media/usb/pvrusb2/pvrusb2-main.c b/drivers/media/usb/pvrusb2/pvrusb2-main.c index ce4d566e4e5a36..721dafd2c14b57 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-main.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-main.c @@ -16,9 +16,7 @@ #include "pvrusb2-context.h" #include "pvrusb2-debug.h" #include "pvrusb2-v4l2.h" -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS #include "pvrusb2-sysfs.h" -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ #define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>" #define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner" @@ -36,10 +34,6 @@ int pvrusb2_debug = DEFAULT_DEBUG_MASK; module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR); MODULE_PARM_DESC(debug, "Debug trace mask"); -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS -static struct pvr2_sysfs_class *class_ptr = NULL; -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - static void pvr_setup_attach(struct pvr2_context *pvr) { /* Create association with v4l layer */ @@ -48,9 +42,7 @@ static void pvr_setup_attach(struct pvr2_context *pvr) /* Create association with dvb layer */ pvr2_dvb_create(pvr); #endif -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - pvr2_sysfs_create(pvr,class_ptr); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ + pvr2_sysfs_create(pvr); } static int pvr_probe(struct usb_interface *intf, @@ -115,9 +107,7 @@ static int __init pvr_init(void) return ret; } -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - class_ptr = pvr2_sysfs_class_create(); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ + pvr2_sysfs_class_create(); ret = usb_register(&pvr_driver); @@ -141,9 +131,7 @@ static void __exit pvr_exit(void) pvr2_context_global_done(); -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - pvr2_sysfs_class_destroy(class_ptr); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ + pvr2_sysfs_class_destroy(); pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete"); } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c index 3e42e209be3746..a8c0b513e58ee1 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c @@ -66,10 +66,6 @@ struct pvr2_sysfs_ctl_item { char name[80]; }; -struct pvr2_sysfs_class { - struct class class; -}; - static ssize_t show_name(struct device *class_dev, struct device_attribute *attr, char *buf) @@ -487,15 +483,6 @@ static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp) } -static void pvr2_sysfs_class_release(struct class *class) -{ - struct pvr2_sysfs_class *clp; - clp = container_of(class,struct pvr2_sysfs_class,class); - pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp); - kfree(clp); -} - - static void pvr2_sysfs_release(struct device *class_dev) { pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev); @@ -503,6 +490,12 @@ static void pvr2_sysfs_release(struct device *class_dev) } +static struct class pvr2_class = { + .name = "pvrusb2", + .dev_release = pvr2_sysfs_release, +}; + + static void class_dev_destroy(struct pvr2_sysfs *sfp) { struct device *dev; @@ -614,8 +607,7 @@ static ssize_t unit_number_show(struct device *class_dev, } -static void class_dev_create(struct pvr2_sysfs *sfp, - struct pvr2_sysfs_class *class_ptr) +static void class_dev_create(struct pvr2_sysfs *sfp) { struct usb_device *usb_dev; struct device *class_dev; @@ -628,7 +620,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp, pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); - class_dev->class = &class_ptr->class; + class_dev->class = &pvr2_class; dev_set_name(class_dev, "%s", pvr2_hdw_get_device_identifier(sfp->channel.hdw)); @@ -753,47 +745,30 @@ static void pvr2_sysfs_internal_check(struct pvr2_channel *chp) } -struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, - struct pvr2_sysfs_class *class_ptr) +void pvr2_sysfs_create(struct pvr2_context *mp) { struct pvr2_sysfs *sfp; sfp = kzalloc(sizeof(*sfp),GFP_KERNEL); - if (!sfp) return sfp; + if (!sfp) + return; pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp); pvr2_channel_init(&sfp->channel,mp); sfp->channel.check_func = pvr2_sysfs_internal_check; - class_dev_create(sfp,class_ptr); - return sfp; + class_dev_create(sfp); } - -struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) +void pvr2_sysfs_class_create(void) { - struct pvr2_sysfs_class *clp; - clp = kzalloc(sizeof(*clp),GFP_KERNEL); - if (!clp) return clp; - pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p", - clp); - clp->class.name = "pvrusb2"; - clp->class.class_release = pvr2_sysfs_class_release; - clp->class.dev_release = pvr2_sysfs_release; - if (class_register(&clp->class)) { - pvr2_sysfs_trace( - "Registration failed for pvr2_sysfs_class id=%p",clp); - kfree(clp); - clp = NULL; - } - return clp; + if (class_register(&pvr2_class)) + pvr2_sysfs_trace("Registration failed for pvr2_sysfs_class"); } -void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) +void pvr2_sysfs_class_destroy(void) { - pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp); - if (clp) - class_unregister(&clp->class); + class_unregister(&pvr2_class); } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-sysfs.h b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.h index ac580ff39b5fa4..375a5372e95ce7 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-sysfs.h +++ b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.h @@ -10,13 +10,15 @@ #include <linux/sysfs.h> #include "pvrusb2-context.h" -struct pvr2_sysfs; -struct pvr2_sysfs_class; +#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS +void pvr2_sysfs_class_create(void); +void pvr2_sysfs_class_destroy(void); +void pvr2_sysfs_create(struct pvr2_context *mp); +#else +static inline void pvr2_sysfs_class_create(void) { } +static inline void pvr2_sysfs_class_destroy(void) { } +static inline void pvr2_sysfs_create(struct pvr2_context *mp) { } +#endif -struct pvr2_sysfs_class *pvr2_sysfs_class_create(void); -void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *); - -struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *, - struct pvr2_sysfs_class *); #endif /* __PVRUSB2_SYSFS_H */ diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 02d4271dfe06bb..92f4dfccc3cc22 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -20,7 +20,6 @@ #define DRV_NAME "cros-ec-dev" static struct class cros_class = { - .owner = THIS_MODULE, .name = "chromeos", }; diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index fb9a1b49ff6de7..f574c83b82cf07 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c @@ -977,7 +977,7 @@ static int __init c2port_init(void) printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION " - (C) 2007 Rodolfo Giometti\n"); - c2port_class = class_create(THIS_MODULE, "c2port"); + c2port_class = class_create("c2port"); if (IS_ERR(c2port_class)) { printk(KERN_ERR "c2port: failed to allocate class\n"); return PTR_ERR(c2port_class); diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 5878329b011a06..144d1f2d78ce63 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -678,7 +678,7 @@ int __init cxl_file_init(void) pr_devel("CXL device allocated, MAJOR %i\n", MAJOR(cxl_dev)); - cxl_class = class_create(THIS_MODULE, "cxl"); + cxl_class = class_create("cxl"); if (IS_ERR(cxl_class)) { pr_err("Unable to create CXL class\n"); rc = PTR_ERR(cxl_class); diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 4ba966529458a0..76511d279aff8e 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -451,7 +451,6 @@ ATTRIBUTE_GROUPS(enclosure_class); static struct class enclosure_class = { .name = "enclosure", - .owner = THIS_MODULE, .dev_release = enclosure_release, .dev_groups = enclosure_class_groups, }; diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 5b63d179b24ea7..02628288cd0fda 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -1363,7 +1363,7 @@ static int __init genwqe_init_module(void) { int rc; - class_genwqe = class_create(THIS_MODULE, GENWQE_DEVNAME); + class_genwqe = class_create(GENWQE_DEVNAME); if (IS_ERR(class_genwqe)) { pr_err("[%s] create class failed\n", __func__); return -ENOMEM; diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 8d00df9243c438..2c3a991d6e88df 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -888,7 +888,7 @@ static int __init ilo_init(void) int error; dev_t dev; - ilo_class = class_create(THIS_MODULE, "iLO"); + ilo_class = class_create("iLO"); if (IS_ERR(ilo_class)) { error = PTR_ERR(ilo_class); goto out; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 632d4ae21e4655..76c771a424f768 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1275,7 +1275,7 @@ static int __init mei_init(void) { int ret; - mei_class = class_create(THIS_MODULE, "mei"); + mei_class = class_create("mei"); if (IS_ERR(mei_class)) { pr_err("couldn't create class\n"); ret = PTR_ERR(mei_class); diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index 3b058654b45b43..6e63f060e4cc1f 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -601,7 +601,7 @@ int ocxl_file_init(void) return rc; } - ocxl_class = class_create(THIS_MODULE, "ocxl"); + ocxl_class = class_create("ocxl"); if (IS_ERR(ocxl_class)) { pr_err("Unable to create ocxl class\n"); unregister_chrdev_region(ocxl_dev, OCXL_NUM_MINORS); diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index ce72e46a2e735b..7966a6b8b5b340 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -503,7 +503,7 @@ static int __init phantom_init(void) int retval; dev_t dev; - phantom_class = class_create(THIS_MODULE, "phantom"); + phantom_class = class_create("phantom"); if (IS_ERR(phantom_class)) { retval = PTR_ERR(phantom_class); printk(KERN_ERR "phantom: can't register phantom class\n"); diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index 07023397afc734..346bd7cf2e94f5 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -620,7 +620,7 @@ static int __init uacce_init(void) { int ret; - uacce_class = class_create(THIS_MODULE, UACCE_NAME); + uacce_class = class_create(UACCE_NAME); if (IS_ERR(uacce_class)) return PTR_ERR(uacce_class); diff --git a/drivers/most/most_cdev.c b/drivers/most/most_cdev.c index 4ee536980f71c5..3ed8f461e01eb1 100644 --- a/drivers/most/most_cdev.c +++ b/drivers/most/most_cdev.c @@ -491,7 +491,7 @@ static int __init most_cdev_init(void) { int err; - comp.class = class_create(THIS_MODULE, "most_cdev"); + comp.class = class_create("most_cdev"); if (IS_ERR(comp.class)) return PTR_ERR(comp.class); diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index a1a08c2b6f77b3..60670b2f70b9f9 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -63,7 +63,6 @@ static SIMPLE_DEV_PM_OPS(mtd_cls_pm_ops, mtd_cls_suspend, mtd_cls_resume); static struct class mtd_class = { .name = "mtd", - .owner = THIS_MODULE, .pm = MTD_CLS_PM_OPS, }; diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index ad025b2ee41773..9cd565daad3685 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -95,7 +95,7 @@ static DEFINE_SPINLOCK(ubi_devices_lock); /* "Show" method for files in '/<sysfs>/class/ubi/' */ /* UBI version attribute ('/<sysfs>/class/ubi/version') */ -static ssize_t version_show(struct class *class, struct class_attribute *attr, +static ssize_t version_show(const struct class *class, const struct class_attribute *attr, char *buf) { return sprintf(buf, "%d\n", UBI_VERSION); @@ -111,7 +111,6 @@ ATTRIBUTE_GROUPS(ubi_class); /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ struct class ubi_class = { .name = UBI_NAME_STR, - .owner = THIS_MODULE, .class_groups = ubi_class_groups, }; diff --git a/drivers/mux/core.c b/drivers/mux/core.c index 49bedbe6316c8a..990e7bc17c85fe 100644 --- a/drivers/mux/core.c +++ b/drivers/mux/core.c @@ -45,7 +45,6 @@ struct mux_state { static struct class mux_class = { .name = "mux", - .owner = THIS_MODULE, }; static DEFINE_IDA(mux_ida); diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 8996bd0a194ab6..0bb59da2492247 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -31,12 +31,12 @@ /* "show" function for the bond_masters attribute. * The class parameter is ignored. */ -static ssize_t bonding_show_bonds(struct class *cls, - struct class_attribute *attr, +static ssize_t bonding_show_bonds(const struct class *cls, + const struct class_attribute *attr, char *buf) { - struct bond_net *bn = - container_of(attr, struct bond_net, class_attr_bonding_masters); + const struct bond_net *bn = + container_of_const(attr, struct bond_net, class_attr_bonding_masters); int res = 0; struct bonding *bond; @@ -59,7 +59,7 @@ static ssize_t bonding_show_bonds(struct class *cls, return res; } -static struct net_device *bond_get_by_name(struct bond_net *bn, const char *ifname) +static struct net_device *bond_get_by_name(const struct bond_net *bn, const char *ifname) { struct bonding *bond; @@ -75,12 +75,12 @@ static struct net_device *bond_get_by_name(struct bond_net *bn, const char *ifna * * The class parameter is ignored. */ -static ssize_t bonding_store_bonds(struct class *cls, - struct class_attribute *attr, +static ssize_t bonding_store_bonds(const struct class *cls, + const struct class_attribute *attr, const char *buffer, size_t count) { - struct bond_net *bn = - container_of(attr, struct bond_net, class_attr_bonding_masters); + const struct bond_net *bn = + container_of_const(attr, struct bond_net, class_attr_bonding_masters); char command[IFNAMSIZ + 1] = {0, }; char *ifname; int rv, res = count; diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c index 9b26f0f2c74842..8a1027ad340d72 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.c +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c @@ -448,7 +448,7 @@ EXPORT_SYMBOL(hnae_ae_unregister); static int __init hnae_init(void) { - hnae_class = class_create(THIS_MODULE, "hnae"); + hnae_class = class_create("hnae"); return PTR_ERR_OR_ZERO(hnae_class); } diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c index dde272586e80b5..60944a4beadae6 100644 --- a/drivers/net/ipvlan/ipvtap.c +++ b/drivers/net/ipvlan/ipvtap.c @@ -38,7 +38,6 @@ static const void *ipvtap_net_namespace(const struct device *d) static struct class ipvtap_class = { .name = "ipvtap", - .owner = THIS_MODULE, .ns_type = &net_ns_type_operations, .namespace = ipvtap_net_namespace, }; diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 031344239f2714..bddcc127812edf 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -43,7 +43,6 @@ static const void *macvtap_net_namespace(const struct device *d) static struct class macvtap_class = { .name = "macvtap", - .owner = THIS_MODULE, .ns_type = &net_ns_type_operations, .namespace = macvtap_net_namespace, }; diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c index 0052968e881e7c..0787ad252dd9cd 100644 --- a/drivers/net/netdevsim/bus.c +++ b/drivers/net/netdevsim/bus.c @@ -132,7 +132,7 @@ static struct nsim_bus_dev * nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queues); static ssize_t -new_device_store(struct bus_type *bus, const char *buf, size_t count) +new_device_store(const struct bus_type *bus, const char *buf, size_t count) { unsigned int id, port_count, num_queues; struct nsim_bus_dev *nsim_bus_dev; @@ -186,7 +186,7 @@ static BUS_ATTR_WO(new_device); static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev); static ssize_t -del_device_store(struct bus_type *bus, const char *buf, size_t count) +del_device_store(const struct bus_type *bus, const char *buf, size_t count) { struct nsim_bus_dev *nsim_bus_dev, *tmp; unsigned int id; diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 1d71f5276241ca..a9beacd552cf82 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -1394,7 +1394,7 @@ static int __init ppp_init(void) goto out_net; } - ppp_class = class_create(THIS_MODULE, "ppp"); + ppp_class = class_create("ppp"); if (IS_ERR(ppp_class)) { err = PTR_ERR(ppp_class); goto out_chrdev; diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index fbcb9d05da649e..4eececc945138b 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -662,8 +662,7 @@ static int rionet_shutdown(struct notifier_block *nb, unsigned long code, return NOTIFY_DONE; } -static void rionet_remove_mport(struct device *dev, - struct class_interface *class_intf) +static void rionet_remove_mport(struct device *dev) { struct rio_mport *mport = to_rio_mport(dev); struct net_device *ndev; diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index 2211fa58fe4140..9a8faaf4c6b642 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -6556,7 +6556,7 @@ static int __init init_mac80211_hwsim(void) if (err) goto out_exit_netlink; - hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); + hwsim_class = class_create("mac80211_hwsim"); if (IS_ERR(hwsim_class)) { err = PTR_ERR(hwsim_class); goto out_exit_virtio; diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c index aa54fa6d5f90dc..284ab1f56391aa 100644 --- a/drivers/net/wwan/wwan_core.c +++ b/drivers/net/wwan/wwan_core.c @@ -1207,7 +1207,7 @@ static int __init wwan_init(void) if (err) return err; - wwan_class = class_create(THIS_MODULE, "wwan"); + wwan_class = class_create("wwan"); if (IS_ERR(wwan_class)) { err = PTR_ERR(wwan_class); goto unregister; diff --git a/drivers/net/wwan/wwan_hwsim.c b/drivers/net/wwan/wwan_hwsim.c index dfbdaa259a3f0a..ff3dd24ddb33f5 100644 --- a/drivers/net/wwan/wwan_hwsim.c +++ b/drivers/net/wwan/wwan_hwsim.c @@ -511,7 +511,7 @@ static int __init wwan_hwsim_init(void) if (!wwan_wq) return -ENOMEM; - wwan_hwsim_class = class_create(THIS_MODULE, "wwan_hwsim"); + wwan_hwsim_class = class_create("wwan_hwsim"); if (IS_ERR(wwan_hwsim_class)) { err = PTR_ERR(wwan_hwsim_class); goto err_wq_destroy; diff --git a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c index 88ae18b0efa8da..d6bbcc7b5b90d6 100644 --- a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c +++ b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c @@ -1470,8 +1470,7 @@ static int switchtec_ntb_reinit_peer(struct switchtec_ntb *sndev) return rc; } -static int switchtec_ntb_add(struct device *dev, - struct class_interface *class_intf) +static int switchtec_ntb_add(struct device *dev) { struct switchtec_dev *stdev = to_stdev(dev); struct switchtec_ntb *sndev; @@ -1541,8 +1540,7 @@ free_and_exit: return rc; } -static void switchtec_ntb_remove(struct device *dev, - struct class_interface *class_intf) +static void switchtec_ntb_remove(struct device *dev) { struct switchtec_dev *stdev = to_stdev(dev); struct switchtec_ntb *sndev = stdev->sndev; diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 4976a0069e9c31..954dbc105fc801 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -1320,7 +1320,7 @@ int __init nvdimm_bus_init(void) goto err_dimm_chrdev; nvdimm_major = rc; - nd_class = class_create(THIS_MODULE, "nd"); + nd_class = class_create("nd"); if (IS_ERR(nd_class)) { rc = PTR_ERR(nd_class); goto err_class; diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1bfd52eae2eeb8..ccb6eb1282f82d 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -5389,14 +5389,14 @@ static int __init nvme_core_init(void) if (result < 0) goto destroy_delete_wq; - nvme_class = class_create(THIS_MODULE, "nvme"); + nvme_class = class_create("nvme"); if (IS_ERR(nvme_class)) { result = PTR_ERR(nvme_class); goto unregister_chrdev; } nvme_class->dev_uevent = nvme_class_uevent; - nvme_subsys_class = class_create(THIS_MODULE, "nvme-subsystem"); + nvme_subsys_class = class_create("nvme-subsystem"); if (IS_ERR(nvme_subsys_class)) { result = PTR_ERR(nvme_subsys_class); goto destroy_class; @@ -5407,7 +5407,7 @@ static int __init nvme_core_init(void) if (result < 0) goto destroy_subsys_class; - nvme_ns_chr_class = class_create(THIS_MODULE, "nvme-generic"); + nvme_ns_chr_class = class_create("nvme-generic"); if (IS_ERR(nvme_ns_chr_class)) { result = PTR_ERR(nvme_ns_chr_class); goto unregister_generic_ns; diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index bbaa04a0c502bf..0069ebff85df1e 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c @@ -1254,7 +1254,7 @@ static int __init nvmf_init(void) if (!nvmf_default_host) return -ENOMEM; - nvmf_class = class_create(THIS_MODULE, "nvme-fabrics"); + nvmf_class = class_create("nvme-fabrics"); if (IS_ERR(nvmf_class)) { pr_err("couldn't register class nvme-fabrics\n"); ret = PTR_ERR(nvmf_class); diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 456ee42a613343..2ed75923507dab 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -3875,7 +3875,6 @@ static const struct attribute_group *nvme_fc_attr_groups[] = { static struct class fc_class = { .name = "fc", .dev_groups = nvme_fc_attr_groups, - .owner = THIS_MODULE, }; static int __init nvme_fc_init_module(void) diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index c780af36c1d4a5..e940a7d37a9dc6 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c @@ -1568,7 +1568,7 @@ static int __init fcloop_init(void) { int ret; - fcloop_class = class_create(THIS_MODULE, "fcloop"); + fcloop_class = class_create("fcloop"); if (IS_ERR(fcloop_class)) { pr_err("couldn't register class fcloop\n"); ret = PTR_ERR(fcloop_class); diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index 9440d9811eea50..46c9a5c3ca14b2 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -860,7 +860,7 @@ EXPORT_SYMBOL_GPL(__devm_pci_epc_create); static int __init pci_epc_init(void) { - pci_epc_class = class_create(THIS_MODULE, "pci_epc"); + pci_epc_class = class_create("pci_epc"); if (IS_ERR(pci_epc_class)) { pr_err("failed to create pci epc class --> %ld\n", PTR_ERR(pci_epc_class)); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index dd0d9d9bc5097e..ab32a91f287b4b 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -428,7 +428,7 @@ static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(msi_bus); -static ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count) +static ssize_t rescan_store(const struct bus_type *bus, const char *buf, size_t count) { unsigned long val; struct pci_bus *b = NULL; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 199024beaee967..5ede93222bc127 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -6684,7 +6684,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) } } -static ssize_t resource_alignment_show(struct bus_type *bus, char *buf) +static ssize_t resource_alignment_show(const struct bus_type *bus, char *buf) { size_t count = 0; @@ -6696,7 +6696,7 @@ static ssize_t resource_alignment_show(struct bus_type *bus, char *buf) return count; } -static ssize_t resource_alignment_store(struct bus_type *bus, +static ssize_t resource_alignment_store(const struct bus_type *bus, const char *buf, size_t count) { char *param, *old, *end; diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c index 3d6f17ff242996..d837da055921a4 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c @@ -1804,7 +1804,7 @@ static int __init switchtec_init(void) if (rc) return rc; - switchtec_class = class_create(THIS_MODULE, "switchtec"); + switchtec_class = class_create("switchtec"); if (IS_ERR(switchtec_class)) { rc = PTR_ERR(switchtec_class); goto err_create_class; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index e3224e49c43fd6..5658745c398f57 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -824,7 +824,7 @@ static int pcmcia_socket_uevent(const struct device *dev, static struct completion pcmcia_unload; -static void pcmcia_release_socket_class(struct class *data) +static void pcmcia_release_socket_class(const struct class *data) { complete(&pcmcia_unload); } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index c8087efa5e4aff..d500e5dbbc3f5e 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1335,8 +1335,7 @@ static struct pcmcia_callback pcmcia_bus_callback = { .resume = pcmcia_bus_resume, }; -static int pcmcia_bus_add_socket(struct device *dev, - struct class_interface *class_intf) +static int pcmcia_bus_add_socket(struct device *dev) { struct pcmcia_socket *socket = dev_get_drvdata(dev); int ret; @@ -1369,8 +1368,7 @@ static int pcmcia_bus_add_socket(struct device *dev, return 0; } -static void pcmcia_bus_remove_socket(struct device *dev, - struct class_interface *class_intf) +static void pcmcia_bus_remove_socket(struct device *dev) { struct pcmcia_socket *socket = dev_get_drvdata(dev); diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index ad1141fddb4ccc..471e0c5815f390 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -1200,8 +1200,7 @@ static const struct attribute_group rsrc_attributes = { .attrs = pccard_rsrc_attributes, }; -static int pccard_sysfs_add_rsrc(struct device *dev, - struct class_interface *class_intf) +static int pccard_sysfs_add_rsrc(struct device *dev) { struct pcmcia_socket *s = dev_get_drvdata(dev); @@ -1210,8 +1209,7 @@ static int pccard_sysfs_add_rsrc(struct device *dev, return sysfs_create_group(&dev->kobj, &rsrc_attributes); } -static void pccard_sysfs_remove_rsrc(struct device *dev, - struct class_interface *class_intf) +static void pccard_sysfs_remove_rsrc(struct device *dev) { struct pcmcia_socket *s = dev_get_drvdata(dev); diff --git a/drivers/peci/sysfs.c b/drivers/peci/sysfs.c index db9ef05776e3bd..c04244075794c7 100644 --- a/drivers/peci/sysfs.c +++ b/drivers/peci/sysfs.c @@ -15,7 +15,7 @@ static int rescan_controller(struct device *dev, void *data) return peci_controller_scan_devices(to_peci_controller(dev)); } -static ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count) +static ssize_t rescan_store(const struct bus_type *bus, const char *buf, size_t count) { bool res; int ret; diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 9951efc03eaaf8..6464dcb56d56d0 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -1233,7 +1233,7 @@ static void phy_release(struct device *dev) static int __init phy_core_init(void) { - phy_class = class_create(THIS_MODULE, "phy"); + phy_class = class_create("phy"); if (IS_ERR(phy_class)) { pr_err("failed to create phy class --> %ld\n", PTR_ERR(phy_class)); diff --git a/drivers/platform/chrome/wilco_ec/event.c b/drivers/platform/chrome/wilco_ec/event.c index 69ceead8cdaa1c..a40f60bcefb619 100644 --- a/drivers/platform/chrome/wilco_ec/event.c +++ b/drivers/platform/chrome/wilco_ec/event.c @@ -58,7 +58,6 @@ #define DRV_NAME EVENT_DEV_NAME #define EVENT_DEV_NAME_FMT (EVENT_DEV_NAME "%d") static struct class event_class = { - .owner = THIS_MODULE, .name = EVENT_CLASS_NAME, }; diff --git a/drivers/platform/chrome/wilco_ec/telemetry.c b/drivers/platform/chrome/wilco_ec/telemetry.c index 60da7a29f2ff2d..54708aa6c70011 100644 --- a/drivers/platform/chrome/wilco_ec/telemetry.c +++ b/drivers/platform/chrome/wilco_ec/telemetry.c @@ -42,7 +42,6 @@ #define DRV_NAME TELEM_DEV_NAME #define TELEM_DEV_NAME_FMT (TELEM_DEV_NAME "%d") static struct class telem_class = { - .owner = THIS_MODULE, .name = TELEM_CLASS_NAME, }; diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index 5fc665f7d9b35d..2ab7d9ac542d18 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c @@ -199,16 +199,26 @@ static int rtl_setup_sysfs(void) { ret = subsys_system_register(&rtl_subsys, NULL); if (!ret) { - for (i = 0; rtl_attributes[i]; i ++) - device_create_file(rtl_subsys.dev_root, rtl_attributes[i]); + struct device *dev_root = bus_get_dev_root(&rtl_subsys); + + if (dev_root) { + for (i = 0; rtl_attributes[i]; i ++) + device_create_file(dev_root, rtl_attributes[i]); + put_device(dev_root); + } } return ret; } static void rtl_teardown_sysfs(void) { + struct device *dev_root = bus_get_dev_root(&rtl_subsys); int i; - for (i = 0; rtl_attributes[i]; i ++) - device_remove_file(rtl_subsys.dev_root, rtl_attributes[i]); + + if (dev_root) { + for (i = 0; rtl_attributes[i]; i ++) + device_remove_file(dev_root, rtl_attributes[i]); + put_device(dev_root); + } bus_unregister(&rtl_subsys); } diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c index 0b96d75f5924f4..f32a233470deab 100644 --- a/drivers/platform/x86/intel/pmt/class.c +++ b/drivers/platform/x86/intel/pmt/class.c @@ -155,7 +155,6 @@ ATTRIBUTE_GROUPS(intel_pmt); static struct class intel_pmt_class = { .name = "intel_pmt", - .owner = THIS_MODULE, .dev_groups = intel_pmt_groups, }; diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c index cb24de9e97dc5a..1a300e14f350cc 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c @@ -224,9 +224,15 @@ int uncore_freq_common_init(int (*read_control_freq)(struct uncore_data *data, u uncore_write = write_control_freq; uncore_read_freq = read_freq; - if (!uncore_root_kobj) - uncore_root_kobj = kobject_create_and_add("intel_uncore_frequency", - &cpu_subsys.dev_root->kobj); + if (!uncore_root_kobj) { + struct device *dev_root = bus_get_dev_root(&cpu_subsys); + + if (dev_root) { + uncore_root_kobj = kobject_create_and_add("intel_uncore_frequency", + &dev_root->kobj); + put_device(dev_root); + } + } if (uncore_root_kobj) ++uncore_instance_count; mutex_unlock(&uncore_lock); diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index e7a3e34028178a..6851d10d658252 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -82,7 +82,6 @@ static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */ static struct class intel_scu_ipc_class = { .name = "intel_scu_ipc", - .owner = THIS_MODULE, }; /** diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 5bf35025cd9053..bd3c37309d2020 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -1462,7 +1462,7 @@ EXPORT_SYMBOL_GPL(power_supply_get_drvdata); static int __init power_supply_class_init(void) { - power_supply_class = class_create(THIS_MODULE, "power_supply"); + power_supply_class = class_create("power_supply"); if (IS_ERR(power_supply_class)) return PTR_ERR(power_supply_class); diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 22a65ad4e46e6b..5d19baae6a380a 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c @@ -456,7 +456,7 @@ static int __init pps_init(void) { int err; - pps_class = class_create(THIS_MODULE, "pps"); + pps_class = class_create("pps"); if (IS_ERR(pps_class)) { pr_err("failed to allocate class\n"); return PTR_ERR(pps_class); diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 62d4d29e7c056f..790f9250b3815b 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -460,7 +460,7 @@ static int __init ptp_init(void) { int err; - ptp_class = class_create(THIS_MODULE, "ptp"); + ptp_class = class_create("ptp"); if (IS_ERR(ptp_class)) { pr_err("ptp: failed to allocate class\n"); return PTR_ERR(ptp_class); diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 2b63f34876452e..ab8cab4d1560d0 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -34,7 +34,6 @@ #define PCI_DEVICE_ID_OROLIA_ARTCARD 0xa000 static struct class timecard_class = { - .owner = THIS_MODULE, .name = "timecard", }; diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c index e7db8e45001cf3..1a106ec3293929 100644 --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -475,7 +475,6 @@ static DEFINE_SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_r static struct class pwm_class = { .name = "pwm", - .owner = THIS_MODULE, .dev_groups = pwm_chip_groups, .pm = pm_sleep_ptr(&pwm_class_pm_ops), }; diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 43db495f198612..a115730ebf1461 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -2536,10 +2536,8 @@ static void mport_cdev_remove(struct mport_dev *md) /* * mport_add_mport() - Add rio_mport from LDM device struct * @dev: Linux device model struct - * @class_intf: Linux class_interface */ -static int mport_add_mport(struct device *dev, - struct class_interface *class_intf) +static int mport_add_mport(struct device *dev) { struct rio_mport *mport = NULL; struct mport_dev *chdev = NULL; @@ -2559,8 +2557,7 @@ static int mport_add_mport(struct device *dev, * mport_remove_mport() - Remove rio_mport from global list * TODO remove device from global mport_dev list */ -static void mport_remove_mport(struct device *dev, - struct class_interface *class_intf) +static void mport_remove_mport(struct device *dev) { struct rio_mport *mport = NULL; struct mport_dev *chdev; @@ -2603,7 +2600,7 @@ static int __init mport_init(void) int ret; /* Create device class needed by udev */ - dev_class = class_create(THIS_MODULE, DRV_NAME); + dev_class = class_create(DRV_NAME); if (IS_ERR(dev_class)) { rmcd_error("Unable to create " DRV_NAME " class"); return PTR_ERR(dev_class); diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index e60e49769bed80..1b3b4c2e015d34 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c @@ -223,7 +223,6 @@ static int rio_uevent(const struct device *dev, struct kobj_uevent_env *env) struct class rio_mport_class = { .name = "rapidio_port", - .owner = THIS_MODULE, .dev_groups = rio_mport_groups, }; EXPORT_SYMBOL_GPL(rio_mport_class); diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index f7679602498ed9..90d39121053382 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c @@ -286,7 +286,7 @@ const struct attribute_group *rio_dev_groups[] = { NULL, }; -static ssize_t scan_store(struct bus_type *bus, const char *buf, size_t count) +static ssize_t scan_store(const struct bus_type *bus, const char *buf, size_t count) { long val; int rc; diff --git a/drivers/rapidio/rio_cm.c b/drivers/rapidio/rio_cm.c index db4c265287ae6e..49f8d111e54623 100644 --- a/drivers/rapidio/rio_cm.c +++ b/drivers/rapidio/rio_cm.c @@ -2087,13 +2087,11 @@ static int riocm_cdev_add(dev_t devno) /* * riocm_add_mport - add new local mport device into channel management core * @dev: device object associated with mport - * @class_intf: class interface * * When a new mport device is added, CM immediately reserves inbound and * outbound RapidIO mailboxes that will be used. */ -static int riocm_add_mport(struct device *dev, - struct class_interface *class_intf) +static int riocm_add_mport(struct device *dev) { int rc; int i; @@ -2166,14 +2164,12 @@ static int riocm_add_mport(struct device *dev, /* * riocm_remove_mport - remove local mport device from channel management core * @dev: device object associated with mport - * @class_intf: class interface * * Removes a local mport device from the list of registered devices that provide * channel management services. Returns an error if the specified mport is not * registered with the CM core. */ -static void riocm_remove_mport(struct device *dev, - struct class_interface *class_intf) +static void riocm_remove_mport(struct device *dev) { struct rio_mport *mport = to_rio_mport(dev); struct cm_dev *cm; @@ -2297,7 +2293,7 @@ static int __init riocm_init(void) int ret; /* Create device class needed by udev */ - dev_class = class_create(THIS_MODULE, DRV_NAME); + dev_class = class_create(DRV_NAME); if (IS_ERR(dev_class)) { riocm_error("Cannot create " DRV_NAME " class"); return PTR_ERR(dev_class); diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index a2207c0cf43217..5039df757127a9 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -694,7 +694,7 @@ static int __init rpmsg_init(void) { int ret; - rpmsg_class = class_create(THIS_MODULE, "rpmsg"); + rpmsg_class = class_create("rpmsg"); if (IS_ERR(rpmsg_class)) { pr_err("failed to create rpmsg class\n"); return PTR_ERR(rpmsg_class); diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index e5b7b48cffac06..edfd942f8c5494 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -475,7 +475,7 @@ EXPORT_SYMBOL_GPL(devm_rtc_device_register); static int __init rtc_init(void) { - rtc_class = class_create(THIS_MODULE, "rtc"); + rtc_class = class_create("rtc"); if (IS_ERR(rtc_class)) { pr_err("couldn't create class\n"); return PTR_ERR(rtc_class); diff --git a/drivers/s390/char/hmcdrv_dev.c b/drivers/s390/char/hmcdrv_dev.c index cb8fdf057ecafe..8d50c894711f8b 100644 --- a/drivers/s390/char/hmcdrv_dev.c +++ b/drivers/s390/char/hmcdrv_dev.c @@ -308,7 +308,7 @@ int hmcdrv_dev_init(void) * /proc/devices), but not under /dev nor /sys/devices/virtual. So * we have to create an associated class (see /sys/class). */ - hmcdrv_dev_class = class_create(THIS_MODULE, HMCDRV_DEV_CLASS); + hmcdrv_dev_class = class_create(HMCDRV_DEV_CLASS); if (IS_ERR(hmcdrv_dev_class)) { rc = PTR_ERR(hmcdrv_dev_class); diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 09d7570d3b7d4b..7115c0f8565076 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -1319,7 +1319,7 @@ static int raw3270_init(void) if (rc == 0) { /* Create attributes for early (= console) device. */ mutex_lock(&raw3270_mutex); - class3270 = class_create(THIS_MODULE, "3270"); + class3270 = class_create("3270"); list_for_each_entry(rp, &raw3270_devices, list) { get_device(&rp->cdev->dev); raw3270_create_attributes(rp); diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index c21dc68e05a043..277a0f903d11bf 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -117,7 +117,7 @@ EXPORT_SYMBOL(unregister_tape_dev); static int __init tape_init(void) { - tape_class = class_create(THIS_MODULE, "tape390"); + tape_class = class_create("tape390"); return 0; } diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index ed970ecfafdf11..6946ba9a9de2c5 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -699,7 +699,7 @@ static int vmlogrdr_register_driver(void) if (ret) goto out_iucv; - vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr"); + vmlogrdr_class = class_create("vmlogrdr"); if (IS_ERR(vmlogrdr_class)) { ret = PTR_ERR(vmlogrdr_class); vmlogrdr_class = NULL; diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 131293f7f15217..82efdd20ad01ed 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -1022,7 +1022,7 @@ static int __init ur_init(void) debug_set_level(vmur_dbf, 6); - vmur_class = class_create(THIS_MODULE, "vmur"); + vmur_class = class_create("vmur"); if (IS_ERR(vmur_class)) { rc = PTR_ERR(vmur_class); goto fail_free_dbf; diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index f4cc1720156f2a..5a99e0b1828975 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1166,12 +1166,12 @@ EXPORT_SYMBOL(ap_parse_mask_str); * AP bus attributes. */ -static ssize_t ap_domain_show(struct bus_type *bus, char *buf) +static ssize_t ap_domain_show(const struct bus_type *bus, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index); } -static ssize_t ap_domain_store(struct bus_type *bus, +static ssize_t ap_domain_store(const struct bus_type *bus, const char *buf, size_t count) { int domain; @@ -1193,7 +1193,7 @@ static ssize_t ap_domain_store(struct bus_type *bus, static BUS_ATTR_RW(ap_domain); -static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf) +static ssize_t ap_control_domain_mask_show(const struct bus_type *bus, char *buf) { if (!ap_qci_info) /* QCI not supported */ return scnprintf(buf, PAGE_SIZE, "not supported\n"); @@ -1208,7 +1208,7 @@ static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf) static BUS_ATTR_RO(ap_control_domain_mask); -static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf) +static ssize_t ap_usage_domain_mask_show(const struct bus_type *bus, char *buf) { if (!ap_qci_info) /* QCI not supported */ return scnprintf(buf, PAGE_SIZE, "not supported\n"); @@ -1223,7 +1223,7 @@ static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf) static BUS_ATTR_RO(ap_usage_domain_mask); -static ssize_t ap_adapter_mask_show(struct bus_type *bus, char *buf) +static ssize_t ap_adapter_mask_show(const struct bus_type *bus, char *buf) { if (!ap_qci_info) /* QCI not supported */ return scnprintf(buf, PAGE_SIZE, "not supported\n"); @@ -1238,7 +1238,7 @@ static ssize_t ap_adapter_mask_show(struct bus_type *bus, char *buf) static BUS_ATTR_RO(ap_adapter_mask); -static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf) +static ssize_t ap_interrupts_show(const struct bus_type *bus, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", ap_irq_flag ? 1 : 0); @@ -1246,12 +1246,12 @@ static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf) static BUS_ATTR_RO(ap_interrupts); -static ssize_t config_time_show(struct bus_type *bus, char *buf) +static ssize_t config_time_show(const struct bus_type *bus, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", ap_config_time); } -static ssize_t config_time_store(struct bus_type *bus, +static ssize_t config_time_store(const struct bus_type *bus, const char *buf, size_t count) { int time; @@ -1265,12 +1265,12 @@ static ssize_t config_time_store(struct bus_type *bus, static BUS_ATTR_RW(config_time); -static ssize_t poll_thread_show(struct bus_type *bus, char *buf) +static ssize_t poll_thread_show(const struct bus_type *bus, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0); } -static ssize_t poll_thread_store(struct bus_type *bus, +static ssize_t poll_thread_store(const struct bus_type *bus, const char *buf, size_t count) { int flag, rc; @@ -1289,12 +1289,12 @@ static ssize_t poll_thread_store(struct bus_type *bus, static BUS_ATTR_RW(poll_thread); -static ssize_t poll_timeout_show(struct bus_type *bus, char *buf) +static ssize_t poll_timeout_show(const struct bus_type *bus, char *buf) { return scnprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout); } -static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf, +static ssize_t poll_timeout_store(const struct bus_type *bus, const char *buf, size_t count) { unsigned long long time; @@ -1318,21 +1318,21 @@ static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf, static BUS_ATTR_RW(poll_timeout); -static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf) +static ssize_t ap_max_domain_id_show(const struct bus_type *bus, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", ap_max_domain_id); } static BUS_ATTR_RO(ap_max_domain_id); -static ssize_t ap_max_adapter_id_show(struct bus_type *bus, char *buf) +static ssize_t ap_max_adapter_id_show(const struct bus_type *bus, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", ap_max_adapter_id); } static BUS_ATTR_RO(ap_max_adapter_id); -static ssize_t apmask_show(struct bus_type *bus, char *buf) +static ssize_t apmask_show(const struct bus_type *bus, char *buf) { int rc; @@ -1393,7 +1393,7 @@ static int apmask_commit(unsigned long *newapm) return 0; } -static ssize_t apmask_store(struct bus_type *bus, const char *buf, +static ssize_t apmask_store(const struct bus_type *bus, const char *buf, size_t count) { int rc, changes = 0; @@ -1425,7 +1425,7 @@ done: static BUS_ATTR_RW(apmask); -static ssize_t aqmask_show(struct bus_type *bus, char *buf) +static ssize_t aqmask_show(const struct bus_type *bus, char *buf) { int rc; @@ -1486,7 +1486,7 @@ static int aqmask_commit(unsigned long *newaqm) return 0; } -static ssize_t aqmask_store(struct bus_type *bus, const char *buf, +static ssize_t aqmask_store(const struct bus_type *bus, const char *buf, size_t count) { int rc, changes = 0; @@ -1518,13 +1518,13 @@ done: static BUS_ATTR_RW(aqmask); -static ssize_t scans_show(struct bus_type *bus, char *buf) +static ssize_t scans_show(const struct bus_type *bus, char *buf) { return scnprintf(buf, PAGE_SIZE, "%llu\n", atomic64_read(&ap_scan_bus_count)); } -static ssize_t scans_store(struct bus_type *bus, const char *buf, +static ssize_t scans_store(const struct bus_type *bus, const char *buf, size_t count) { AP_DBF_INFO("%s force AP bus rescan\n", __func__); @@ -1536,7 +1536,7 @@ static ssize_t scans_store(struct bus_type *bus, const char *buf, static BUS_ATTR_RW(scans); -static ssize_t bindings_show(struct bus_type *bus, char *buf) +static ssize_t bindings_show(const struct bus_type *bus, char *buf) { int rc; unsigned int apqns, n; diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 6fe05bb82c7725..cff2eea88f98de 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -340,8 +340,8 @@ static const struct attribute_group *zcdn_dev_attr_groups[] = { NULL }; -static ssize_t zcdn_create_store(struct class *class, - struct class_attribute *attr, +static ssize_t zcdn_create_store(const struct class *class, + const struct class_attribute *attr, const char *buf, size_t count) { int rc; @@ -357,8 +357,8 @@ static ssize_t zcdn_create_store(struct class *class, static const struct class_attribute class_attr_zcdn_create = __ATTR(create, 0600, NULL, zcdn_create_store); -static ssize_t zcdn_destroy_store(struct class *class, - struct class_attribute *attr, +static ssize_t zcdn_destroy_store(const struct class *class, + const struct class_attribute *attr, const char *buf, size_t count) { int rc; @@ -2171,7 +2171,7 @@ static int __init zcdn_init(void) int rc; /* create a new class 'zcrypt' */ - zcrypt_class = class_create(THIS_MODULE, ZCRYPT_NAME); + zcrypt_class = class_create(ZCRYPT_NAME); if (IS_ERR(zcrypt_class)) { rc = PTR_ERR(zcrypt_class); goto out_class_create_failed; diff --git a/drivers/sbus/char/oradax.c b/drivers/sbus/char/oradax.c index d698ca506ccab7..aafce8d0000042 100644 --- a/drivers/sbus/char/oradax.c +++ b/drivers/sbus/char/oradax.c @@ -323,7 +323,7 @@ static int __init dax_attach(void) goto done; } - cl = class_create(THIS_MODULE, DAX_NAME); + cl = class_create(DAX_NAME); if (IS_ERR(cl)) { dax_err("class_create failed"); ret = PTR_ERR(cl); diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 72fe6df78bc591..ac648bb8f7e7f4 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -995,7 +995,7 @@ static int __init init_ch_module(void) int rc; printk(KERN_INFO "SCSI Media Changer driver v" VERSION " \n"); - ch_sysfs_class = class_create(THIS_MODULE, "scsi_changer"); + ch_sysfs_class = class_create("scsi_changer"); if (IS_ERR(ch_sysfs_class)) { rc = PTR_ERR(ch_sysfs_class); return rc; diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 395b00b942f703..debd3697411974 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -3880,7 +3880,7 @@ static int cxlflash_class_init(void) cxlflash_major = MAJOR(devno); - cxlflash_class = class_create(THIS_MODULE, "cxlflash"); + cxlflash_class = class_create("cxlflash"); if (IS_ERR(cxlflash_class)) { rc = PTR_ERR(cxlflash_class); pr_err("%s: class_create failed rc=%d\n", __func__, rc); diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c index 6260aa5ea6af80..e17957f8085c2e 100644 --- a/drivers/scsi/fcoe/fcoe_sysfs.c +++ b/drivers/scsi/fcoe/fcoe_sysfs.c @@ -659,17 +659,17 @@ static const struct device_type fcoe_fcf_device_type = { .release = fcoe_fcf_device_release, }; -static ssize_t ctlr_create_store(struct bus_type *bus, const char *buf, +static ssize_t ctlr_create_store(const struct bus_type *bus, const char *buf, size_t count) { - return fcoe_ctlr_create_store(bus, buf, count); + return fcoe_ctlr_create_store(buf, count); } static BUS_ATTR_WO(ctlr_create); -static ssize_t ctlr_destroy_store(struct bus_type *bus, const char *buf, +static ssize_t ctlr_destroy_store(const struct bus_type *bus, const char *buf, size_t count) { - return fcoe_ctlr_destroy_store(bus, buf, count); + return fcoe_ctlr_destroy_store(buf, count); } static BUS_ATTR_WO(ctlr_destroy); diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index 62341c6353a72e..46b0bf237be1d4 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -745,8 +745,7 @@ static int libfcoe_device_notification(struct notifier_block *notifier, return NOTIFY_OK; } -ssize_t fcoe_ctlr_create_store(struct bus_type *bus, - const char *buf, size_t count) +ssize_t fcoe_ctlr_create_store(const char *buf, size_t count) { struct net_device *netdev = NULL; struct fcoe_transport *ft = NULL; @@ -808,8 +807,7 @@ out_nodev: return count; } -ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus, - const char *buf, size_t count) +ssize_t fcoe_ctlr_destroy_store(const char *buf, size_t count) { int rc = -ENODEV; struct net_device *netdev = NULL; diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 23c5230dbed496..9415a481947048 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -5346,7 +5346,7 @@ static int __init pmcraid_init(void) } pmcraid_major = MAJOR(dev); - pmcraid_class = class_create(THIS_MODULE, PMCRAID_DEVFILE); + pmcraid_class = class_create(PMCRAID_DEVFILE); if (IS_ERR(pmcraid_class)) { error = PTR_ERR(pmcraid_class); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 4bb87043e6dba2..1624d528aa1f9c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -587,7 +587,6 @@ ATTRIBUTE_GROUPS(sd_disk); static struct class sd_disk_class = { .name = "scsi_disk", - .owner = THIS_MODULE, .dev_release = scsi_disk_release, .dev_groups = sd_disk_groups, }; diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index b54f2c6c08c362..d7d0c35c58b80e 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -662,8 +662,7 @@ static void ses_match_to_enclosure(struct enclosure_device *edev, } } -static int ses_intf_add(struct device *cdev, - struct class_interface *intf) +static int ses_intf_add(struct device *cdev) { struct scsi_device *sdev = to_scsi_device(cdev->parent); struct scsi_device *tmp_sdev; @@ -865,8 +864,7 @@ static void ses_intf_remove_enclosure(struct scsi_device *sdev) enclosure_unregister(edev); } -static void ses_intf_remove(struct device *cdev, - struct class_interface *intf) +static void ses_intf_remove(struct device *cdev) { struct scsi_device *sdev = to_scsi_device(cdev->parent); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index a91049213203f8..037f8c98a6d364 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -96,8 +96,8 @@ static int scatter_elem_sz_prev = SG_SCATTER_SZ; #define SG_SECTOR_SZ 512 -static int sg_add_device(struct device *, struct class_interface *); -static void sg_remove_device(struct device *, struct class_interface *); +static int sg_add_device(struct device *); +static void sg_remove_device(struct device *); static DEFINE_IDR(sg_index_idr); static DEFINE_RWLOCK(sg_index_lock); /* Also used to lock @@ -1488,7 +1488,7 @@ out_unlock: } static int -sg_add_device(struct device *cl_dev, struct class_interface *cl_intf) +sg_add_device(struct device *cl_dev) { struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); Sg_device *sdp = NULL; @@ -1578,7 +1578,7 @@ sg_device_destroy(struct kref *kref) } static void -sg_remove_device(struct device *cl_dev, struct class_interface *cl_intf) +sg_remove_device(struct device *cl_dev) { struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); Sg_device *sdp = dev_get_drvdata(cl_dev); @@ -1677,7 +1677,7 @@ init_sg(void) SG_MAX_DEVS, "sg"); if (rc) return rc; - sg_sysfs_class = class_create(THIS_MODULE, "scsi_generic"); + sg_sysfs_class = class_create("scsi_generic"); if ( IS_ERR(sg_sysfs_class) ) { rc = PTR_ERR(sg_sysfs_class); goto err_out; diff --git a/drivers/sh/intc/userimask.c b/drivers/sh/intc/userimask.c index f9f043a3d90a23..abe9091827cd68 100644 --- a/drivers/sh/intc/userimask.c +++ b/drivers/sh/intc/userimask.c @@ -61,10 +61,18 @@ static DEVICE_ATTR(userimask, S_IRUSR | S_IWUSR, static int __init userimask_sysdev_init(void) { + struct device *dev_root; + int ret = 0; + if (unlikely(!uimask)) return -ENXIO; - return device_create_file(intc_subsys.dev_root, &dev_attr_userimask); + dev_root = bus_get_dev_root(&intc_subsys); + if (dev_root) { + ret = device_create_file(dev_root, &dev_attr_userimask); + put_device(dev_root); + } + return ret; } late_initcall(userimask_sysdev_init); diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c index 165f7548401bc7..6abb730344aba0 100644 --- a/drivers/soc/amlogic/meson-gx-socinfo.c +++ b/drivers/soc/amlogic/meson-gx-socinfo.c @@ -174,11 +174,6 @@ static int __init meson_gx_socinfo_init(void) return -ENODEV; soc_dev_attr->family = "Amlogic Meson"; - - np = of_find_node_by_path("/"); - of_property_read_string(np, "model", &soc_dev_attr->machine); - of_node_put(np); - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x:%x - %x:%x", socinfo_to_major(socinfo), socinfo_to_minor(socinfo), diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c index 0d31377f178d5c..ce48a9f3b4c87f 100644 --- a/drivers/soc/qcom/rmtfs_mem.c +++ b/drivers/soc/qcom/rmtfs_mem.c @@ -126,7 +126,6 @@ static int qcom_rmtfs_mem_release(struct inode *inode, struct file *filp) } static struct class rmtfs_class = { - .owner = THIS_MODULE, .name = "rmtfs", }; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index a1ad8f41fb8644..a12420e28640bb 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2777,7 +2777,6 @@ static void spi_controller_release(struct device *dev) static struct class spi_master_class = { .name = "spi_master", - .owner = THIS_MODULE, .dev_release = spi_controller_release, .dev_groups = spi_master_groups, }; @@ -2880,7 +2879,6 @@ static const struct attribute_group *spi_slave_groups[] = { static struct class spi_slave_class = { .name = "spi_slave", - .owner = THIS_MODULE, .dev_release = spi_controller_release, .dev_groups = spi_slave_groups, }; diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index a399c617ca25f7..39d94c8508390f 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -877,7 +877,7 @@ static int __init spidev_init(void) if (status < 0) return status; - spidev_class = class_create(THIS_MODULE, "spidev"); + spidev_class = class_create("spidev"); if (IS_ERR(spidev_class)) { unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); return PTR_ERR(spidev_class); diff --git a/drivers/staging/fieldbus/anybuss/arcx-anybus.c b/drivers/staging/fieldbus/anybuss/arcx-anybus.c index afef35bbea74bf..f135b9f52c8d9f 100644 --- a/drivers/staging/fieldbus/anybuss/arcx-anybus.c +++ b/drivers/staging/fieldbus/anybuss/arcx-anybus.c @@ -351,7 +351,7 @@ static int __init controller_init(void) { int err; - controller_class = class_create(THIS_MODULE, "arcx_anybus_controller"); + controller_class = class_create("arcx_anybus_controller"); if (IS_ERR(controller_class)) return PTR_ERR(controller_class); err = platform_driver_register(&controller_driver); diff --git a/drivers/staging/fieldbus/dev_core.c b/drivers/staging/fieldbus/dev_core.c index 5f54f2674bd19b..bf1812d8924fa5 100644 --- a/drivers/staging/fieldbus/dev_core.c +++ b/drivers/staging/fieldbus/dev_core.c @@ -154,7 +154,6 @@ __ATTRIBUTE_GROUPS(fieldbus); static struct class fieldbus_class = { .name = "fieldbus_dev", - .owner = THIS_MODULE, .dev_groups = fieldbus_groups, }; diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index 297e69f011c7e1..7e01790a4659de 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -402,7 +402,7 @@ int cap_init(void) { int ret; - cap_class = class_create(THIS_MODULE, "gb_authenticate"); + cap_class = class_create("gb_authenticate"); if (IS_ERR(cap_class)) return PTR_ERR(cap_class); diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c index 3342b84597dadc..cd9141e4b794f3 100644 --- a/drivers/staging/greybus/fw-management.c +++ b/drivers/staging/greybus/fw-management.c @@ -696,7 +696,7 @@ int fw_mgmt_init(void) { int ret; - fw_mgmt_class = class_create(THIS_MODULE, "gb_fw_mgmt"); + fw_mgmt_class = class_create("gb_fw_mgmt"); if (IS_ERR(fw_mgmt_class)) return PTR_ERR(fw_mgmt_class); diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index 1a61fce9805634..d7b39f3bb6525f 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -100,7 +100,6 @@ struct gb_loopback { static struct class loopback_class = { .name = "gb_loopback", - .owner = THIS_MODULE, }; static DEFINE_IDA(loopback_ida); diff --git a/drivers/staging/greybus/raw.c b/drivers/staging/greybus/raw.c index 2a375f407d3894..8bca8cb12cc6f2 100644 --- a/drivers/staging/greybus/raw.c +++ b/drivers/staging/greybus/raw.c @@ -340,7 +340,7 @@ static int raw_init(void) dev_t dev; int retval; - raw_class = class_create(THIS_MODULE, "gb_raw"); + raw_class = class_create("gb_raw"); if (IS_ERR(raw_class)) { retval = PTR_ERR(raw_class); goto error_class; diff --git a/drivers/staging/greybus/vibrator.c b/drivers/staging/greybus/vibrator.c index 0e2b188e5ca3f5..227e18d92a958a 100644 --- a/drivers/staging/greybus/vibrator.c +++ b/drivers/staging/greybus/vibrator.c @@ -107,7 +107,6 @@ ATTRIBUTE_GROUPS(vibrator); static struct class vibrator_class = { .name = "vibrator", - .owner = THIS_MODULE, .dev_groups = vibrator_groups, }; diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c index b59f6a4cb611a5..f08fdf06d5666a 100644 --- a/drivers/staging/pi433/pi433_if.c +++ b/drivers/staging/pi433/pi433_if.c @@ -1400,7 +1400,7 @@ static int __init pi433_init(void) if (status < 0) return status; - pi433_class = class_create(THIS_MODULE, "pi433"); + pi433_class = class_create("pi433"); if (IS_ERR(pi433_class)) { unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); diff --git a/drivers/staging/vme_user/vme_user.c b/drivers/staging/vme_user/vme_user.c index 4e533c0bfe6db2..b9367b575d004d 100644 --- a/drivers/staging/vme_user/vme_user.c +++ b/drivers/staging/vme_user/vme_user.c @@ -614,7 +614,7 @@ static int vme_user_probe(struct vme_dev *vdev) } /* Create sysfs entries - on udev systems this creates the dev files */ - vme_user_sysfs_class = class_create(THIS_MODULE, driver_name); + vme_user_sysfs_class = class_create(driver_name); if (IS_ERR(vme_user_sysfs_class)) { dev_err(&vdev->dev, "Error creating vme_user class.\n"); err = PTR_ERR(vme_user_sysfs_class); diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 452cbb8ad48416..0eb342de0b0018 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -1226,7 +1226,7 @@ static int __init tee_init(void) { int rc; - tee_class = class_create(THIS_MODULE, "tee"); + tee_class = class_create("tee"); if (IS_ERR(tee_class)) { pr_err("couldn't create class\n"); return PTR_ERR(tee_class); diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 07394fdaf5225d..2b1c8ab99dbaf2 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -931,7 +931,7 @@ static void __init unix98_pty_init(void) if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) panic("Couldn't register /dev/ptmx driver"); - device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); + device_create(&tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); } #else diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index cfb3da0dee4711..c84be40fb8dfae 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3070,7 +3070,7 @@ static struct device *tty_get_device(struct tty_struct *tty) { dev_t devt = tty_devnum(tty); - return class_find_device_by_devt(tty_class, devt); + return class_find_device_by_devt(&tty_class, devt); } @@ -3143,8 +3143,6 @@ int tty_put_char(struct tty_struct *tty, unsigned char ch) } EXPORT_SYMBOL_GPL(tty_put_char); -struct class *tty_class; - static int tty_cdev_add(struct tty_driver *driver, dev_t dev, unsigned int index, unsigned int count) { @@ -3239,7 +3237,7 @@ struct device *tty_register_device_attr(struct tty_driver *driver, return ERR_PTR(-ENOMEM); dev->devt = devt; - dev->class = tty_class; + dev->class = &tty_class; dev->parent = device; dev->release = tty_device_create_release; dev_set_name(dev, "%s", name); @@ -3294,8 +3292,7 @@ EXPORT_SYMBOL_GPL(tty_register_device_attr); */ void tty_unregister_device(struct tty_driver *driver, unsigned index) { - device_destroy(tty_class, - MKDEV(driver->major, driver->minor_start) + index); + device_destroy(&tty_class, MKDEV(driver->major, driver->minor_start) + index); if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { cdev_del(driver->cdevs[index]); driver->cdevs[index] = NULL; @@ -3510,13 +3507,14 @@ static char *tty_devnode(const struct device *dev, umode_t *mode) return NULL; } +const struct class tty_class = { + .name = "tty", + .devnode = tty_devnode, +}; + static int __init tty_class_init(void) { - tty_class = class_create(THIS_MODULE, "tty"); - if (IS_ERR(tty_class)) - return PTR_ERR(tty_class); - tty_class->devnode = tty_devnode; - return 0; + return class_register(&tty_class); } postcore_initcall(tty_class_init); @@ -3625,13 +3623,13 @@ int __init tty_init(void) if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) panic("Couldn't register /dev/tty driver\n"); - device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); + device_create(&tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); cdev_init(&console_cdev, &console_fops); if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) panic("Couldn't register /dev/console driver\n"); - consdev = device_create_with_groups(tty_class, NULL, + consdev = device_create_with_groups(&tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, cons_dev_groups, "console"); if (IS_ERR(consdev)) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 1dc07f9214d575..498ba9c0ee9374 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -804,7 +804,7 @@ int __init vcs_init(void) if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) panic("unable to get major %d for vcs device", VCS_MAJOR); - vc_class = class_create(THIS_MODULE, "vc"); + vc_class = class_create("vc"); device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 64), NULL, "vcsu"); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 5c5ca74c03afec..1e8e57b456882b 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3541,7 +3541,7 @@ int __init vty_init(const struct file_operations *console_fops) if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) panic("Couldn't register /dev/tty0 driver\n"); - tty0dev = device_create_with_groups(tty_class, NULL, + tty0dev = device_create_with_groups(&tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, vt_dev_groups, "tty0"); if (IS_ERR(tty0dev)) @@ -4242,7 +4242,7 @@ static int __init vtconsole_class_init(void) { int i; - vtconsole_class = class_create(THIS_MODULE, "vtconsole"); + vtconsole_class = class_create("vtconsole"); if (IS_ERR(vtconsole_class)) { pr_warn("Unable to create vt console class; errno = %ld\n", PTR_ERR(vtconsole_class)); diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index a98b2108376ae2..8305a5dfb91047 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -90,7 +90,7 @@ static void ulpi_remove(struct device *dev) drv->remove(to_ulpi_dev(dev)); } -static struct bus_type ulpi_bus = { +static const struct bus_type ulpi_bus = { .name = "ulpi", .match = ulpi_match, .uevent = ulpi_uevent, diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index a0e076c6f3a495..f58a0299fb3bd3 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -2025,7 +2025,7 @@ int usb_disable_usb2_hardware_lpm(struct usb_device *udev) #endif /* CONFIG_PM */ -struct bus_type usb_bus_type = { +const struct bus_type usb_bus_type = { .name = "usb", .match = usb_device_match, .uevent = usb_uevent, diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index da7d88e069e6c0..c4ed3310e06965 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -88,7 +88,7 @@ static int init_usb_class(void) } kref_init(&usb_class->kref); - usb_class->class = class_create(THIS_MODULE, "usbmisc"); + usb_class->class = class_create("usbmisc"); if (IS_ERR(usb_class->class)) { result = PTR_ERR(usb_class->class); printk(KERN_ERR "class_create failed for usb devices\n"); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 3f14e15f07f640..ffe3f6818e9cfa 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -141,7 +141,7 @@ static inline int usb_disable_usb2_hardware_lpm(struct usb_device *udev) #endif -extern struct bus_type usb_bus_type; +extern const struct bus_type usb_bus_type; extern struct mutex usb_port_peer_mutex; extern struct device_type usb_device_type; extern struct device_type usb_if_device_type; diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index a8da3b4a2855a1..9f6b101341210d 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -1325,7 +1325,7 @@ int ghid_setup(struct usb_gadget *g, int count) int status; dev_t dev; - hidg_class = class_create(THIS_MODULE, "hidg"); + hidg_class = class_create("hidg"); if (IS_ERR(hidg_class)) { status = PTR_ERR(hidg_class); hidg_class = NULL; diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 4903d761a87241..28db3e336e7db8 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1512,7 +1512,7 @@ static int gprinter_setup(int count) int status; dev_t devt; - usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); + usb_gadget_class = class_create("usb_printer_gadget"); if (IS_ERR(usb_gadget_class)) { status = PTR_ERR(usb_gadget_class); usb_gadget_class = NULL; diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 1c5403ce9e7c03..4641153e9706b1 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -26,7 +26,7 @@ static DEFINE_IDA(gadget_id_numbers); -static struct bus_type gadget_bus_type; +static const struct bus_type gadget_bus_type; /** * struct usb_udc - describes one usb device controller @@ -1837,7 +1837,7 @@ static int usb_udc_uevent(const struct device *dev, struct kobj_uevent_env *env) return 0; } -static struct bus_type gadget_bus_type = { +static const struct bus_type gadget_bus_type = { .name = "gadget", .probe = gadget_bind_driver, .remove = gadget_unbind_driver, @@ -1848,7 +1848,7 @@ static int __init usb_udc_init(void) { int rc; - udc_class = class_create(THIS_MODULE, "udc"); + udc_class = class_create("udc"); if (IS_ERR(udc_class)) { pr_err("failed to create udc class --> %ld\n", PTR_ERR(udc_class)); diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index abb1cd35d8a67b..952c5678925856 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -1379,7 +1379,7 @@ int __init mon_bin_init(void) { int rc; - mon_bin_class = class_create(THIS_MODULE, "usbmon"); + mon_bin_class = class_create("usbmon"); if (IS_ERR(mon_bin_class)) { rc = PTR_ERR(mon_bin_class); goto err_class; diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index 56814ef80c24a5..0395bd5dbd3efe 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -392,7 +392,7 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get_drvdata); static int __init usb_roles_init(void) { - role_class = class_create(THIS_MODULE, "usb_role"); + role_class = class_create("usb_role"); return PTR_ERR_OR_ZERO(role_class); } subsys_initcall(usb_roles_init); diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 9e38142acd38cc..3eb8dc3a1a8f52 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -144,7 +144,7 @@ static void free_dynids(struct usb_serial_driver *drv) spin_unlock(&drv->dynids.lock); } -struct bus_type usb_serial_bus_type = { +const struct bus_type usb_serial_bus_type = { .name = "usb-serial", .match = usb_serial_device_match, .probe = usb_serial_device_probe, diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c index 098f0efaa58d18..fe5b9a2e61f58a 100644 --- a/drivers/usb/typec/bus.c +++ b/drivers/usb/typec/bus.c @@ -431,7 +431,7 @@ static void typec_remove(struct device *dev) adev->ops = NULL; } -struct bus_type typec_bus = { +const struct bus_type typec_bus = { .name = "typec", .dev_groups = typec_groups, .match = typec_match, diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h index c8916885741725..643b8c81786dfe 100644 --- a/drivers/usb/typec/bus.h +++ b/drivers/usb/typec/bus.h @@ -28,7 +28,7 @@ struct altmode { #define to_altmode(d) container_of(d, struct altmode, adev) -extern struct bus_type typec_bus; +extern const struct bus_type typec_bus; extern const struct device_type typec_altmode_dev_type; #define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index cc3182f7067304..349cc2030c9037 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -22,7 +22,6 @@ static DEFINE_IDA(typec_index_ida); struct class typec_class = { .name = "typec", - .owner = THIS_MODULE, }; /* ------------------------------------------------------------------------- */ diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index c7177ddd4f127c..d9eaf9a0b0bfd7 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -514,5 +514,4 @@ EXPORT_SYMBOL_GPL(typec_mux_get_drvdata); struct class typec_mux_class = { .name = "typec_mux", - .owner = THIS_MODULE, }; diff --git a/drivers/usb/typec/pd.c b/drivers/usb/typec/pd.c index 59c537a5e60007..0bcde1ff4d39b9 100644 --- a/drivers/usb/typec/pd.c +++ b/drivers/usb/typec/pd.c @@ -15,7 +15,6 @@ static DEFINE_IDA(pd_ida); static struct class pd_class = { .name = "usb_power_delivery", - .owner = THIS_MODULE, }; #define to_pdo(o) container_of(o, struct pdo, dev) diff --git a/drivers/usb/typec/retimer.c b/drivers/usb/typec/retimer.c index 0481e82f6bbc8e..4a7d1b5c4d866b 100644 --- a/drivers/usb/typec/retimer.c +++ b/drivers/usb/typec/retimer.c @@ -157,5 +157,4 @@ EXPORT_SYMBOL_GPL(typec_retimer_get_drvdata); struct class retimer_class = { .name = "retimer", - .owner = THIS_MODULE, }; diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index 0c3b48616a9f36..c421b83f6fa2f4 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1793,7 +1793,7 @@ static int vduse_init(void) int ret; struct device *dev; - vduse_class = class_create(THIS_MODULE, "vduse"); + vduse_class = class_create("vduse"); if (IS_ERR(vduse_class)) return PTR_ERR(vduse_class); diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c index 27d5ba7cf9dcd4..fc75c1000d7401 100644 --- a/drivers/vfio/group.c +++ b/drivers/vfio/group.c @@ -878,7 +878,7 @@ int __init vfio_group_init(void) return ret; /* /dev/vfio/$GROUP */ - vfio.class = class_create(THIS_MODULE, "vfio"); + vfio.class = class_create("vfio"); if (IS_ERR(vfio.class)) { ret = PTR_ERR(vfio.class); goto err_group_class; diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 89497c9334907e..f0ca33b2e1dfdd 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -1409,7 +1409,7 @@ static int __init vfio_init(void) goto err_virqfd; /* /sys/class/vfio-dev/vfioX */ - vfio.device_class = class_create(THIS_MODULE, "vfio-dev"); + vfio.device_class = class_create("vfio-dev"); if (IS_ERR(vfio.device_class)) { ret = PTR_ERR(vfio.device_class); goto err_dev_class; diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index 7be9d9d8f01c81..135ad39958cc8f 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -1140,7 +1140,7 @@ static int vhost_vdpa_alloc_domain(struct vhost_vdpa *v) struct vdpa_device *vdpa = v->vdpa; const struct vdpa_config_ops *ops = vdpa->config; struct device *dma_dev = vdpa_get_dma_dev(vdpa); - struct bus_type *bus; + const struct bus_type *bus; int ret; /* Device want to do DMA by itself */ diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 6eea72aa8dbff6..9a885d398c2289 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -751,7 +751,7 @@ static void __exit backlight_class_exit(void) static int __init backlight_class_init(void) { - backlight_class = class_create(THIS_MODULE, "backlight"); + backlight_class = class_create("backlight"); if (IS_ERR(backlight_class)) { pr_warn("Unable to create backlight class; errno = %ld\n", PTR_ERR(backlight_class)); diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index db56e465aaff31..77c5cb2a44e25d 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -323,7 +323,7 @@ static void __exit lcd_class_exit(void) static int __init lcd_class_init(void) { - lcd_class = class_create(THIS_MODULE, "lcd"); + lcd_class = class_create("lcd"); if (IS_ERR(lcd_class)) { pr_warn("Unable to create backlight class; errno = %ld\n", PTR_ERR(lcd_class)); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 3fd95a79e4c334..e808dc86001cc9 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1751,7 +1751,7 @@ fbmem_init(void) goto err_chrdev; } - fb_class = class_create(THIS_MODULE, "graphics"); + fb_class = class_create("graphics"); if (IS_ERR(fb_class)) { ret = PTR_ERR(fb_class); pr_warn("Unable to create fb class; errno = %d\n", ret); diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 0122e879687975..12a6f020b6b595 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -1005,7 +1005,6 @@ static struct miscdevice watchdog_miscdev = { static struct class watchdog_class = { .name = "watchdog", - .owner = THIS_MODULE, .dev_groups = wdt_groups, }; diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index b39580ad4ce514..3c31485884916b 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -361,7 +361,7 @@ static int __init init_coda_psdev(void) __func__, CODA_PSDEV_MAJOR); return -EIO; } - coda_psdev_class = class_create(THIS_MODULE, "coda"); + coda_psdev_class = class_create("coda"); if (IS_ERR(coda_psdev_class)) { err = PTR_ERR(coda_psdev_class); goto out_chrdev; diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 179a5c5e28fdb6..91e89e68177ee4 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c @@ -623,7 +623,7 @@ static int __init cuse_init(void) /* CUSE is not prepared for FUSE_DEV_IOC_CLONE */ cuse_channel_fops.unlocked_ioctl = NULL; - cuse_class = class_create(THIS_MODULE, "cuse"); + cuse_class = class_create("cuse"); if (IS_ERR(cuse_class)) return PTR_ERR(cuse_class); diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 90de0e49837111..45b6919903e6b8 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -17,7 +17,7 @@ #include "kernfs-internal.h" -static DEFINE_SPINLOCK(kernfs_rename_lock); /* kn->parent and ->name */ +static DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */ /* * Don't use rename_lock to piggy back on pr_cont_buf. We don't want to * call pr_cont() while holding rename_lock. Because sometimes pr_cont() @@ -196,9 +196,9 @@ int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen) unsigned long flags; int ret; - spin_lock_irqsave(&kernfs_rename_lock, flags); + read_lock_irqsave(&kernfs_rename_lock, flags); ret = kernfs_name_locked(kn, buf, buflen); - spin_unlock_irqrestore(&kernfs_rename_lock, flags); + read_unlock_irqrestore(&kernfs_rename_lock, flags); return ret; } @@ -224,9 +224,9 @@ int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from, unsigned long flags; int ret; - spin_lock_irqsave(&kernfs_rename_lock, flags); + read_lock_irqsave(&kernfs_rename_lock, flags); ret = kernfs_path_from_node_locked(to, from, buf, buflen); - spin_unlock_irqrestore(&kernfs_rename_lock, flags); + read_unlock_irqrestore(&kernfs_rename_lock, flags); return ret; } EXPORT_SYMBOL_GPL(kernfs_path_from_node); @@ -294,10 +294,10 @@ struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn) struct kernfs_node *parent; unsigned long flags; - spin_lock_irqsave(&kernfs_rename_lock, flags); + read_lock_irqsave(&kernfs_rename_lock, flags); parent = kn->parent; kernfs_get(parent); - spin_unlock_irqrestore(&kernfs_rename_lock, flags); + read_unlock_irqrestore(&kernfs_rename_lock, flags); return parent; } @@ -770,12 +770,15 @@ int kernfs_add_one(struct kernfs_node *kn) goto out_unlock; /* Update timestamps on the parent */ + down_write(&root->kernfs_iattr_rwsem); + ps_iattr = parent->iattr; if (ps_iattr) { ktime_get_real_ts64(&ps_iattr->ia_ctime); ps_iattr->ia_mtime = ps_iattr->ia_ctime; } + up_write(&root->kernfs_iattr_rwsem); up_write(&root->kernfs_rwsem); /* @@ -940,6 +943,8 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops, idr_init(&root->ino_idr); init_rwsem(&root->kernfs_rwsem); + init_rwsem(&root->kernfs_iattr_rwsem); + init_rwsem(&root->kernfs_supers_rwsem); INIT_LIST_HEAD(&root->supers); /* @@ -1462,11 +1467,14 @@ static void __kernfs_remove(struct kernfs_node *kn) pos->parent ? pos->parent->iattr : NULL; /* update timestamps on the parent */ + down_write(&kernfs_root(kn)->kernfs_iattr_rwsem); + if (ps_iattr) { ktime_get_real_ts64(&ps_iattr->ia_ctime); ps_iattr->ia_mtime = ps_iattr->ia_ctime; } + up_write(&kernfs_root(kn)->kernfs_iattr_rwsem); kernfs_put(pos); } @@ -1723,7 +1731,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, kernfs_get(new_parent); /* rename_lock protects ->parent and ->name accessors */ - spin_lock_irq(&kernfs_rename_lock); + write_lock_irq(&kernfs_rename_lock); old_parent = kn->parent; kn->parent = new_parent; @@ -1734,7 +1742,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, kn->name = new_name; } - spin_unlock_irq(&kernfs_rename_lock); + write_unlock_irq(&kernfs_rename_lock); kn->hash = kernfs_name_hash(kn->name, kn->ns); kernfs_link_sibling(kn); diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index e4a50e4ff0d234..40c4661f15b7c3 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -922,8 +922,8 @@ repeat: root = kernfs_root(kn); /* kick fsnotify */ - down_write(&root->kernfs_rwsem); + down_read(&root->kernfs_supers_rwsem); list_for_each_entry(info, &kernfs_root(kn)->supers, node) { struct kernfs_node *parent; struct inode *p_inode = NULL; @@ -960,7 +960,7 @@ repeat: iput(inode); } - up_write(&root->kernfs_rwsem); + up_read(&root->kernfs_supers_rwsem); kernfs_put(kn); goto repeat; } diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 30494dcb0df347..b22b74d1a11509 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -101,9 +101,9 @@ int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) int ret; struct kernfs_root *root = kernfs_root(kn); - down_write(&root->kernfs_rwsem); + down_write(&root->kernfs_iattr_rwsem); ret = __kernfs_setattr(kn, iattr); - up_write(&root->kernfs_rwsem); + up_write(&root->kernfs_iattr_rwsem); return ret; } @@ -119,7 +119,7 @@ int kernfs_iop_setattr(struct mnt_idmap *idmap, struct dentry *dentry, return -EINVAL; root = kernfs_root(kn); - down_write(&root->kernfs_rwsem); + down_write(&root->kernfs_iattr_rwsem); error = setattr_prepare(&nop_mnt_idmap, dentry, iattr); if (error) goto out; @@ -132,7 +132,7 @@ int kernfs_iop_setattr(struct mnt_idmap *idmap, struct dentry *dentry, setattr_copy(&nop_mnt_idmap, inode, iattr); out: - up_write(&root->kernfs_rwsem); + up_write(&root->kernfs_iattr_rwsem); return error; } @@ -189,10 +189,10 @@ int kernfs_iop_getattr(struct mnt_idmap *idmap, struct kernfs_node *kn = inode->i_private; struct kernfs_root *root = kernfs_root(kn); - down_read(&root->kernfs_rwsem); + down_read(&root->kernfs_iattr_rwsem); kernfs_refresh_inode(kn, inode); generic_fillattr(&nop_mnt_idmap, inode, stat); - up_read(&root->kernfs_rwsem); + up_read(&root->kernfs_iattr_rwsem); return 0; } @@ -285,10 +285,10 @@ int kernfs_iop_permission(struct mnt_idmap *idmap, kn = inode->i_private; root = kernfs_root(kn); - down_read(&root->kernfs_rwsem); + down_read(&root->kernfs_iattr_rwsem); kernfs_refresh_inode(kn, inode); ret = generic_permission(&nop_mnt_idmap, inode, mask); - up_read(&root->kernfs_rwsem); + up_read(&root->kernfs_iattr_rwsem); return ret; } diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 236c3a6113f1ef..a9b854cdfdb5f7 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -47,6 +47,8 @@ struct kernfs_root { wait_queue_head_t deactivate_waitq; struct rw_semaphore kernfs_rwsem; + struct rw_semaphore kernfs_iattr_rwsem; + struct rw_semaphore kernfs_supers_rwsem; }; /* +1 to avoid triggering overflow warning when negating it */ diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index e08e8d9998070d..d49606accb07b1 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -351,9 +351,9 @@ int kernfs_get_tree(struct fs_context *fc) } sb->s_flags |= SB_ACTIVE; - down_write(&root->kernfs_rwsem); + down_write(&root->kernfs_supers_rwsem); list_add(&info->node, &info->root->supers); - up_write(&root->kernfs_rwsem); + up_write(&root->kernfs_supers_rwsem); } fc->root = dget(sb->s_root); @@ -380,9 +380,9 @@ void kernfs_kill_sb(struct super_block *sb) struct kernfs_super_info *info = kernfs_info(sb); struct kernfs_root *root = info->root; - down_write(&root->kernfs_rwsem); + down_write(&root->kernfs_supers_rwsem); list_del(&info->node); - up_write(&root->kernfs_rwsem); + up_write(&root->kernfs_supers_rwsem); /* * Remove the superblock from fs_supers/s_instances diff --git a/fs/ksmbd/server.c b/fs/ksmbd/server.c index 0d8242789dc8fd..0979577fd23ef0 100644 --- a/fs/ksmbd/server.c +++ b/fs/ksmbd/server.c @@ -415,7 +415,7 @@ int server_queue_ctrl_reset_work(void) return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET); } -static ssize_t stats_show(struct class *class, struct class_attribute *attr, +static ssize_t stats_show(const struct class *class, const struct class_attribute *attr, char *buf) { /* @@ -434,8 +434,8 @@ static ssize_t stats_show(struct class *class, struct class_attribute *attr, server_conf.ipc_last_active / HZ); } -static ssize_t kill_server_store(struct class *class, - struct class_attribute *attr, const char *buf, +static ssize_t kill_server_store(const struct class *class, + const struct class_attribute *attr, const char *buf, size_t len) { if (!sysfs_streq(buf, "hard")) @@ -455,7 +455,7 @@ static const char * const debug_type_strings[] = {"smb", "auth", "vfs", "oplock", "ipc", "conn", "rdma"}; -static ssize_t debug_show(struct class *class, struct class_attribute *attr, +static ssize_t debug_show(const struct class *class, const struct class_attribute *attr, char *buf) { ssize_t sz = 0; @@ -473,7 +473,7 @@ static ssize_t debug_show(struct class *class, struct class_attribute *attr, return sz; } -static ssize_t debug_store(struct class *class, struct class_attribute *attr, +static ssize_t debug_store(const struct class *class, const struct class_attribute *attr, const char *buf, size_t len) { int i; @@ -513,7 +513,6 @@ ATTRIBUTE_GROUPS(ksmbd_control_class); static struct class ksmbd_control_class = { .name = "ksmbd-control", - .owner = THIS_MODULE, .class_groups = ksmbd_control_class_groups, }; diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c index ab82e5f0534641..aa178304bc036d 100644 --- a/fs/pstore/pmsg.c +++ b/fs/pstore/pmsg.c @@ -64,7 +64,7 @@ void pstore_register_pmsg(void) goto err; } - pmsg_class = class_create(THIS_MODULE, PMSG_NAME); + pmsg_class = class_create(PMSG_NAME); if (IS_ERR(pmsg_class)) { pr_err("device class file already in use\n"); goto err_class; diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h index 908e19d17f493d..a5cfd44fab45b4 100644 --- a/include/linux/cacheinfo.h +++ b/include/linux/cacheinfo.h @@ -76,9 +76,11 @@ struct cpu_cacheinfo { unsigned int num_levels; unsigned int num_leaves; bool cpu_map_populated; + bool early_ci_levels; }; struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu); +int early_cache_level(unsigned int cpu); int init_cache_level(unsigned int cpu); int init_of_cache_level(unsigned int cpu); int populate_cache_leaves(unsigned int cpu); @@ -129,4 +131,10 @@ static inline int get_cpu_cacheinfo_id(int cpu, int level) return -1; } +#ifdef CONFIG_ARM64 +#define use_arch_cache_info() (true) +#else +#define use_arch_cache_info() (false) +#endif + #endif /* _LINUX_CACHEINFO_H */ diff --git a/include/linux/device.h b/include/linux/device.h index 1508e637bb2666..472dd24d4823a6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -243,21 +243,26 @@ void __iomem *devm_of_iomap(struct device *dev, resource_size_t *size); /* allows to add/remove a custom action to devres stack */ -int devm_add_action(struct device *dev, void (*action)(void *), void *data); void devm_remove_action(struct device *dev, void (*action)(void *), void *data); void devm_release_action(struct device *dev, void (*action)(void *), void *data); -static inline int devm_add_action_or_reset(struct device *dev, - void (*action)(void *), void *data) +int __devm_add_action(struct device *dev, void (*action)(void *), void *data, const char *name); +#define devm_add_action(release, action, data) \ + __devm_add_action(release, action, data, #action) + +static inline int __devm_add_action_or_reset(struct device *dev, void (*action)(void *), + void *data, const char *name) { int ret; - ret = devm_add_action(dev, action, data); + ret = __devm_add_action(dev, action, data, name); if (ret) action(data); return ret; } +#define devm_add_action_or_reset(release, action, data) \ + __devm_add_action_or_reset(release, action, data, #action) /** * devm_alloc_percpu - Resource-managed alloc_percpu @@ -561,7 +566,7 @@ struct device { const char *init_name; /* initial name of the device */ const struct device_type *type; - struct bus_type *bus; /* type of bus device is on */ + const struct bus_type *bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ void *platform_data; /* Platform specific data, device @@ -626,7 +631,7 @@ struct device { spinlock_t devres_lock; struct list_head devres_head; - struct class *class; + const struct class *class; const struct attribute_group **groups; /* optional groups */ void (*release)(struct device *dev); @@ -1010,13 +1015,13 @@ bool device_is_bound(struct device *dev); * Easy functions for dynamically creating devices on the fly */ __printf(5, 6) struct device * -device_create(struct class *cls, struct device *parent, dev_t devt, +device_create(const struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...); __printf(6, 7) struct device * -device_create_with_groups(struct class *cls, struct device *parent, dev_t devt, +device_create_with_groups(const struct class *cls, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, ...); -void device_destroy(struct class *cls, dev_t devt); +void device_destroy(const struct class *cls, dev_t devt); int __must_check device_add_groups(struct device *dev, const struct attribute_group **groups); @@ -1083,8 +1088,7 @@ void device_link_remove(void *consumer, struct device *supplier); void device_links_supplier_sync_state_pause(void); void device_links_supplier_sync_state_resume(void); -extern __printf(3, 4) -int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); +__printf(3, 4) int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); /* Create alias, so I can be autoloaded. */ #define MODULE_ALIAS_CHARDEV(major,minor) \ @@ -1092,10 +1096,4 @@ int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); #define MODULE_ALIAS_CHARDEV_MAJOR(major) \ MODULE_ALIAS("char-major-" __stringify(major) "-*") -#ifdef CONFIG_SYSFS_DEPRECATED -extern long sysfs_deprecated; -#else -#define sysfs_deprecated 0 -#endif - #endif /* _DEVICE_H_ */ diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index 6ce32ef4b8fd49..ae10c432275437 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -26,7 +26,6 @@ struct fwnode_handle; * * @name: The name of the bus. * @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id). - * @dev_root: Default device to use as the parent. * @bus_groups: Default attributes of the bus. * @dev_groups: Default attributes of the devices on the bus. * @drv_groups: Default attributes of the device drivers on the bus. @@ -66,7 +65,6 @@ struct fwnode_handle; * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU * driver implementations to a bus and allow the driver to do * bus-specific setup - * @lock_key: Lock class key for use by the lock validator * @need_parent_lock: When probing or removing a device on this bus, the * device core should lock the device's parent. * @@ -82,7 +80,6 @@ struct fwnode_handle; struct bus_type { const char *name; const char *dev_name; - struct device *dev_root; const struct attribute_group **bus_groups; const struct attribute_group **dev_groups; const struct attribute_group **drv_groups; @@ -112,16 +109,16 @@ struct bus_type { bool need_parent_lock; }; -extern int __must_check bus_register(struct bus_type *bus); +int __must_check bus_register(const struct bus_type *bus); -extern void bus_unregister(const struct bus_type *bus); +void bus_unregister(const struct bus_type *bus); -extern int __must_check bus_rescan_devices(struct bus_type *bus); +int __must_check bus_rescan_devices(const struct bus_type *bus); struct bus_attribute { struct attribute attr; - ssize_t (*show)(struct bus_type *bus, char *buf); - ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count); + ssize_t (*show)(const struct bus_type *bus, char *buf); + ssize_t (*store)(const struct bus_type *bus, const char *buf, size_t count); }; #define BUS_ATTR_RW(_name) \ @@ -246,10 +243,8 @@ void bus_sort_breadthfirst(struct bus_type *bus, */ struct notifier_block; -extern int bus_register_notifier(const struct bus_type *bus, - struct notifier_block *nb); -extern int bus_unregister_notifier(const struct bus_type *bus, - struct notifier_block *nb); +int bus_register_notifier(const struct bus_type *bus, struct notifier_block *nb); +int bus_unregister_notifier(const struct bus_type *bus, struct notifier_block *nb); /** * enum bus_notifier_event - Bus Notifier events that have happened @@ -281,7 +276,7 @@ enum bus_notifier_event { BUS_NOTIFY_DRIVER_NOT_BOUND, }; -extern struct kset *bus_get_kset(const struct bus_type *bus); +struct kset *bus_get_kset(const struct bus_type *bus); struct device *bus_get_dev_root(const struct bus_type *bus); #endif diff --git a/include/linux/device/class.h b/include/linux/device/class.h index 42cc3fb44a8463..9deeaeb457bbaa 100644 --- a/include/linux/device/class.h +++ b/include/linux/device/class.h @@ -25,10 +25,8 @@ struct fwnode_handle; /** * struct class - device classes * @name: Name of the class. - * @owner: The module owner. * @class_groups: Default attributes of this class. * @dev_groups: Default attributes of the devices that belong to the class. - * @dev_kobj: The kobject that represents this class and links it into the hierarchy. * @dev_uevent: Called when a device is added, removed from this class, or a * few other things that generate uevents to add the environment * variables. @@ -53,16 +51,14 @@ struct fwnode_handle; */ struct class { const char *name; - struct module *owner; const struct attribute_group **class_groups; const struct attribute_group **dev_groups; - struct kobject *dev_kobj; int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env); char *(*devnode)(const struct device *dev, umode_t *mode); - void (*class_release)(struct class *class); + void (*class_release)(const struct class *class); void (*dev_release)(struct device *dev); int (*shutdown_pre)(struct device *dev); @@ -73,8 +69,6 @@ struct class { void (*get_ownership)(const struct device *dev, kuid_t *uid, kgid_t *gid); const struct dev_pm_ops *pm; - - struct subsys_private *p; }; struct class_dev_iter { @@ -82,19 +76,9 @@ struct class_dev_iter { const struct device_type *type; }; -extern struct kobject *sysfs_dev_block_kobj; -extern struct kobject *sysfs_dev_char_kobj; -extern int __must_check __class_register(struct class *class, - struct lock_class_key *key); -extern void class_unregister(struct class *class); - -/* This is a #define to keep the compiler from merging different - * instances of the __key variable */ -#define class_register(class) \ -({ \ - static struct lock_class_key __key; \ - __class_register(class, &__key); \ -}) +int __must_check class_register(const struct class *class); +void class_unregister(const struct class *class); +bool class_is_registered(const struct class *class); struct class_compat; struct class_compat *class_compat_register(const char *name); @@ -104,19 +88,15 @@ int class_compat_create_link(struct class_compat *cls, struct device *dev, void class_compat_remove_link(struct class_compat *cls, struct device *dev, struct device *device_link); -extern void class_dev_iter_init(struct class_dev_iter *iter, - struct class *class, - struct device *start, - const struct device_type *type); -extern struct device *class_dev_iter_next(struct class_dev_iter *iter); -extern void class_dev_iter_exit(struct class_dev_iter *iter); +void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, + const struct device *start, const struct device_type *type); +struct device *class_dev_iter_next(struct class_dev_iter *iter); +void class_dev_iter_exit(struct class_dev_iter *iter); -extern int class_for_each_device(struct class *class, struct device *start, - void *data, - int (*fn)(struct device *dev, void *data)); -extern struct device *class_find_device(struct class *class, - struct device *start, const void *data, - int (*match)(struct device *, const void *)); +int class_for_each_device(const struct class *class, const struct device *start, void *data, + int (*fn)(struct device *dev, void *data)); +struct device *class_find_device(const struct class *class, const struct device *start, + const void *data, int (*match)(struct device *, const void *)); /** * class_find_device_by_name - device iterator for locating a particular device @@ -124,7 +104,7 @@ extern struct device *class_find_device(struct class *class, * @class: class type * @name: name of the device to match */ -static inline struct device *class_find_device_by_name(struct class *class, +static inline struct device *class_find_device_by_name(const struct class *class, const char *name) { return class_find_device(class, NULL, name, device_match_name); @@ -136,8 +116,8 @@ static inline struct device *class_find_device_by_name(struct class *class, * @class: class type * @np: of_node of the device to match. */ -static inline struct device * -class_find_device_by_of_node(struct class *class, const struct device_node *np) +static inline struct device *class_find_device_by_of_node(const struct class *class, + const struct device_node *np) { return class_find_device(class, NULL, np, device_match_of_node); } @@ -148,9 +128,8 @@ class_find_device_by_of_node(struct class *class, const struct device_node *np) * @class: class type * @fwnode: fwnode of the device to match. */ -static inline struct device * -class_find_device_by_fwnode(struct class *class, - const struct fwnode_handle *fwnode) +static inline struct device *class_find_device_by_fwnode(const struct class *class, + const struct fwnode_handle *fwnode) { return class_find_device(class, NULL, fwnode, device_match_fwnode); } @@ -161,7 +140,7 @@ class_find_device_by_fwnode(struct class *class, * @class: class type * @devt: device type of the device to match. */ -static inline struct device *class_find_device_by_devt(struct class *class, +static inline struct device *class_find_device_by_devt(const struct class *class, dev_t devt) { return class_find_device(class, NULL, &devt, device_match_devt); @@ -175,14 +154,14 @@ struct acpi_device; * @class: class type * @adev: ACPI_COMPANION device to match. */ -static inline struct device * -class_find_device_by_acpi_dev(struct class *class, const struct acpi_device *adev) +static inline struct device *class_find_device_by_acpi_dev(const struct class *class, + const struct acpi_device *adev) { return class_find_device(class, NULL, adev, device_match_acpi_dev); } #else -static inline struct device * -class_find_device_by_acpi_dev(struct class *class, const void *adev) +static inline struct device *class_find_device_by_acpi_dev(const struct class *class, + const void *adev) { return NULL; } @@ -190,10 +169,10 @@ class_find_device_by_acpi_dev(struct class *class, const void *adev) struct class_attribute { struct attribute attr; - ssize_t (*show)(struct class *class, struct class_attribute *attr, + ssize_t (*show)(const struct class *class, const struct class_attribute *attr, char *buf); - ssize_t (*store)(struct class *class, struct class_attribute *attr, - const char *buf, size_t count); + ssize_t (*store)(const struct class *class, const struct class_attribute *attr, + const char *buf, size_t count); }; #define CLASS_ATTR_RW(_name) \ @@ -203,20 +182,18 @@ struct class_attribute { #define CLASS_ATTR_WO(_name) \ struct class_attribute class_attr_##_name = __ATTR_WO(_name) -extern int __must_check class_create_file_ns(struct class *class, - const struct class_attribute *attr, - const void *ns); -extern void class_remove_file_ns(struct class *class, - const struct class_attribute *attr, - const void *ns); +int __must_check class_create_file_ns(const struct class *class, const struct class_attribute *attr, + const void *ns); +void class_remove_file_ns(const struct class *class, const struct class_attribute *attr, + const void *ns); -static inline int __must_check class_create_file(struct class *class, - const struct class_attribute *attr) +static inline int __must_check class_create_file(const struct class *class, + const struct class_attribute *attr) { return class_create_file_ns(class, attr, NULL); } -static inline void class_remove_file(struct class *class, +static inline void class_remove_file(const struct class *class, const struct class_attribute *attr) { return class_remove_file_ns(class, attr, NULL); @@ -235,46 +212,21 @@ struct class_attribute_string { struct class_attribute_string class_attr_##_name = \ _CLASS_ATTR_STRING(_name, _mode, _str) -extern ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr, - char *buf); +ssize_t show_class_attr_string(const struct class *class, const struct class_attribute *attr, + char *buf); struct class_interface { struct list_head node; - struct class *class; + const struct class *class; - int (*add_dev) (struct device *, struct class_interface *); - void (*remove_dev) (struct device *, struct class_interface *); + int (*add_dev) (struct device *dev); + void (*remove_dev) (struct device *dev); }; -extern int __must_check class_interface_register(struct class_interface *); -extern void class_interface_unregister(struct class_interface *); - -extern struct class * __must_check __class_create(struct module *owner, - const char *name, - struct lock_class_key *key); -extern void class_destroy(struct class *cls); - -/* This is a #define to keep the compiler from merging different - * instances of the __key variable */ - -/** - * class_create - create a struct class structure - * @owner: pointer to the module that is to "own" this struct class - * @name: pointer to a string for the name of this class. - * - * This is used to create a struct class pointer that can then be used - * in calls to device_create(). - * - * Returns &struct class pointer on success, or ERR_PTR() on error. - * - * Note, the pointer created here is to be destroyed when finished by - * making a call to class_destroy(). - */ -#define class_create(owner, name) \ -({ \ - static struct lock_class_key __key; \ - __class_create(owner, name, &__key); \ -}) +int __must_check class_interface_register(struct class_interface *); +void class_interface_unregister(struct class_interface *); +struct class * __must_check class_create(const char *name); +void class_destroy(const struct class *cls); #endif /* _DEVICE_CLASS_H_ */ diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index 50d0a416a5e74d..c244267a67443e 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -95,7 +95,7 @@ enum probe_type { */ struct device_driver { const char *name; - struct bus_type *bus; + const struct bus_type *bus; struct module *owner; const char *mod_name; /* used for built-in modules */ @@ -122,13 +122,12 @@ struct device_driver { }; -extern int __must_check driver_register(struct device_driver *drv); -extern void driver_unregister(struct device_driver *drv); +int __must_check driver_register(struct device_driver *drv); +void driver_unregister(struct device_driver *drv); -extern struct device_driver *driver_find(const char *name, - struct bus_type *bus); -extern int driver_probe_done(void); -extern void wait_for_device_probe(void); +struct device_driver *driver_find(const char *name, const struct bus_type *bus); +int driver_probe_done(void); +void wait_for_device_probe(void); void __init wait_for_init_devices_probe(void); /* sysfs interface for exporting driver attributes */ @@ -147,18 +146,15 @@ struct driver_attribute { #define DRIVER_ATTR_WO(_name) \ struct driver_attribute driver_attr_##_name = __ATTR_WO(_name) -extern int __must_check driver_create_file(struct device_driver *driver, - const struct driver_attribute *attr); -extern void driver_remove_file(struct device_driver *driver, - const struct driver_attribute *attr); +int __must_check driver_create_file(struct device_driver *driver, + const struct driver_attribute *attr); +void driver_remove_file(struct device_driver *driver, + const struct driver_attribute *attr); int driver_set_override(struct device *dev, const char **override, const char *s, size_t len); -extern int __must_check driver_for_each_device(struct device_driver *drv, - struct device *start, - void *data, - int (*fn)(struct device *dev, - void *)); +int __must_check driver_for_each_device(struct device_driver *drv, struct device *start, + void *data, int (*fn)(struct device *dev, void *)); struct device *driver_find_device(struct device_driver *drv, struct device *start, const void *data, int (*match)(struct device *dev, const void *data)); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 6595454d4f48de..0fd4e6734d5b25 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -455,11 +455,11 @@ static inline const struct iommu_ops *dev_iommu_ops(struct device *dev) return dev->iommu->iommu_dev->ops; } -extern int bus_iommu_probe(struct bus_type *bus); -extern bool iommu_present(struct bus_type *bus); +extern int bus_iommu_probe(const struct bus_type *bus); +extern bool iommu_present(const struct bus_type *bus); extern bool device_iommu_capable(struct device *dev, enum iommu_cap cap); extern bool iommu_group_has_isolated_msi(struct iommu_group *group); -extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus); +extern struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus); extern struct iommu_group *iommu_group_get_by_id(int id); extern void iommu_domain_free(struct iommu_domain *domain); extern int iommu_attach_device(struct iommu_domain *domain, @@ -732,7 +732,7 @@ struct iommu_device {}; struct iommu_fault_param {}; struct iommu_iotlb_gather {}; -static inline bool iommu_present(struct bus_type *bus) +static inline bool iommu_present(const struct bus_type *bus) { return false; } @@ -742,7 +742,7 @@ static inline bool device_iommu_capable(struct device *dev, enum iommu_cap cap) return false; } -static inline struct iommu_domain *iommu_domain_alloc(struct bus_type *bus) +static inline struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus) { return NULL; } diff --git a/include/linux/kobject.h b/include/linux/kobject.h index bdab370a24f4ef..c392c811d9ad97 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -79,43 +79,37 @@ struct kobject { unsigned int uevent_suppress:1; }; -extern __printf(2, 3) -int kobject_set_name(struct kobject *kobj, const char *name, ...); -extern __printf(2, 0) -int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, - va_list vargs); +__printf(2, 3) int kobject_set_name(struct kobject *kobj, const char *name, ...); +__printf(2, 0) int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list vargs); static inline const char *kobject_name(const struct kobject *kobj) { return kobj->name; } -extern void kobject_init(struct kobject *kobj, const struct kobj_type *ktype); -extern __printf(3, 4) __must_check -int kobject_add(struct kobject *kobj, struct kobject *parent, - const char *fmt, ...); -extern __printf(4, 5) __must_check -int kobject_init_and_add(struct kobject *kobj, - const struct kobj_type *ktype, struct kobject *parent, - const char *fmt, ...); +void kobject_init(struct kobject *kobj, const struct kobj_type *ktype); +__printf(3, 4) __must_check int kobject_add(struct kobject *kobj, + struct kobject *parent, + const char *fmt, ...); +__printf(4, 5) __must_check int kobject_init_and_add(struct kobject *kobj, + const struct kobj_type *ktype, + struct kobject *parent, + const char *fmt, ...); -extern void kobject_del(struct kobject *kobj); +void kobject_del(struct kobject *kobj); -extern struct kobject * __must_check kobject_create_and_add(const char *name, - struct kobject *parent); +struct kobject * __must_check kobject_create_and_add(const char *name, struct kobject *parent); -extern int __must_check kobject_rename(struct kobject *, const char *new_name); -extern int __must_check kobject_move(struct kobject *, struct kobject *); +int __must_check kobject_rename(struct kobject *, const char *new_name); +int __must_check kobject_move(struct kobject *, struct kobject *); -extern struct kobject *kobject_get(struct kobject *kobj); -extern struct kobject * __must_check kobject_get_unless_zero( - struct kobject *kobj); -extern void kobject_put(struct kobject *kobj); +struct kobject *kobject_get(struct kobject *kobj); +struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj); +void kobject_put(struct kobject *kobj); -extern const void *kobject_namespace(const struct kobject *kobj); -extern void kobject_get_ownership(const struct kobject *kobj, - kuid_t *uid, kgid_t *gid); -extern char *kobject_get_path(const struct kobject *kobj, gfp_t flag); +const void *kobject_namespace(const struct kobject *kobj); +void kobject_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid); +char *kobject_get_path(const struct kobject *kobj, gfp_t flag); struct kobj_type { void (*release)(struct kobject *kobj); @@ -176,12 +170,11 @@ struct kset { const struct kset_uevent_ops *uevent_ops; } __randomize_layout; -extern void kset_init(struct kset *kset); -extern int __must_check kset_register(struct kset *kset); -extern void kset_unregister(struct kset *kset); -extern struct kset * __must_check kset_create_and_add(const char *name, - const struct kset_uevent_ops *u, - struct kobject *parent_kobj); +void kset_init(struct kset *kset); +int __must_check kset_register(struct kset *kset); +void kset_unregister(struct kset *kset); +struct kset * __must_check kset_create_and_add(const char *name, const struct kset_uevent_ops *u, + struct kobject *parent_kobj); static inline struct kset *to_kset(struct kobject *kobj) { @@ -203,7 +196,7 @@ static inline const struct kobj_type *get_ktype(const struct kobject *kobj) return kobj->ktype; } -extern struct kobject *kset_find_obj(struct kset *, const char *); +struct kobject *kset_find_obj(struct kset *, const char *); /* The global /sys/kernel/ kobject for people to chain off of */ extern struct kobject *kernel_kobj; diff --git a/include/linux/property.h b/include/linux/property.h index 0a29db15ff345d..66df1a15d5181e 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -16,7 +16,6 @@ #include <linux/types.h> struct device; -struct net_device; enum dev_prop_type { DEV_PROP_U8, @@ -40,20 +39,20 @@ struct fwnode_handle *__dev_fwnode(struct device *dev); const struct device *: __dev_fwnode_const, \ struct device *: __dev_fwnode)(dev) -bool device_property_present(struct device *dev, const char *propname); -int device_property_read_u8_array(struct device *dev, const char *propname, +bool device_property_present(const struct device *dev, const char *propname); +int device_property_read_u8_array(const struct device *dev, const char *propname, u8 *val, size_t nval); -int device_property_read_u16_array(struct device *dev, const char *propname, +int device_property_read_u16_array(const struct device *dev, const char *propname, u16 *val, size_t nval); -int device_property_read_u32_array(struct device *dev, const char *propname, +int device_property_read_u32_array(const struct device *dev, const char *propname, u32 *val, size_t nval); -int device_property_read_u64_array(struct device *dev, const char *propname, +int device_property_read_u64_array(const struct device *dev, const char *propname, u64 *val, size_t nval); -int device_property_read_string_array(struct device *dev, const char *propname, +int device_property_read_string_array(const struct device *dev, const char *propname, const char **val, size_t nval); -int device_property_read_string(struct device *dev, const char *propname, +int device_property_read_string(const struct device *dev, const char *propname, const char **val); -int device_property_match_string(struct device *dev, +int device_property_match_string(const struct device *dev, const char *propname, const char *string); bool fwnode_property_present(const struct fwnode_handle *fwnode, @@ -105,11 +104,11 @@ struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode); for (parent = fwnode_get_parent(fwnode); parent; \ parent = fwnode_get_next_parent(parent)) -struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode); +struct device *fwnode_get_next_parent_dev(const struct fwnode_handle *fwnode); unsigned int fwnode_count_parents(const struct fwnode_handle *fwn); struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwn, unsigned int depth); -bool fwnode_is_ancestor_of(struct fwnode_handle *ancestor, struct fwnode_handle *child); +bool fwnode_is_ancestor_of(const struct fwnode_handle *ancestor, const struct fwnode_handle *child); struct fwnode_handle *fwnode_get_next_child_node( const struct fwnode_handle *fwnode, struct fwnode_handle *child); struct fwnode_handle *fwnode_get_next_available_child_node( @@ -143,57 +142,57 @@ int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name); unsigned int device_get_child_node_count(const struct device *dev); -static inline bool device_property_read_bool(struct device *dev, +static inline bool device_property_read_bool(const struct device *dev, const char *propname) { return device_property_present(dev, propname); } -static inline int device_property_read_u8(struct device *dev, +static inline int device_property_read_u8(const struct device *dev, const char *propname, u8 *val) { return device_property_read_u8_array(dev, propname, val, 1); } -static inline int device_property_read_u16(struct device *dev, +static inline int device_property_read_u16(const struct device *dev, const char *propname, u16 *val) { return device_property_read_u16_array(dev, propname, val, 1); } -static inline int device_property_read_u32(struct device *dev, +static inline int device_property_read_u32(const struct device *dev, const char *propname, u32 *val) { return device_property_read_u32_array(dev, propname, val, 1); } -static inline int device_property_read_u64(struct device *dev, +static inline int device_property_read_u64(const struct device *dev, const char *propname, u64 *val) { return device_property_read_u64_array(dev, propname, val, 1); } -static inline int device_property_count_u8(struct device *dev, const char *propname) +static inline int device_property_count_u8(const struct device *dev, const char *propname) { return device_property_read_u8_array(dev, propname, NULL, 0); } -static inline int device_property_count_u16(struct device *dev, const char *propname) +static inline int device_property_count_u16(const struct device *dev, const char *propname) { return device_property_read_u16_array(dev, propname, NULL, 0); } -static inline int device_property_count_u32(struct device *dev, const char *propname) +static inline int device_property_count_u32(const struct device *dev, const char *propname) { return device_property_read_u32_array(dev, propname, NULL, 0); } -static inline int device_property_count_u64(struct device *dev, const char *propname) +static inline int device_property_count_u64(const struct device *dev, const char *propname) { return device_property_read_u64_array(dev, propname, NULL, 0); } -static inline int device_property_string_array_count(struct device *dev, +static inline int device_property_string_array_count(const struct device *dev, const char *propname) { return device_property_read_string_array(dev, propname, NULL, 0); @@ -396,7 +395,7 @@ enum dev_dma_attr device_get_dma_attr(const struct device *dev); const void *device_get_match_data(const struct device *dev); int device_get_phy_mode(struct device *dev); -int fwnode_get_phy_mode(struct fwnode_handle *fwnode); +int fwnode_get_phy_mode(const struct fwnode_handle *fwnode); void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index); @@ -433,7 +432,7 @@ static inline bool fwnode_graph_is_endpoint(const struct fwnode_handle *fwnode) struct fwnode_handle * fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode, u32 port, u32 endpoint, unsigned long flags); -unsigned int fwnode_graph_get_endpoint_count(struct fwnode_handle *fwnode, +unsigned int fwnode_graph_get_endpoint_count(const struct fwnode_handle *fwnode, unsigned long flags); #define fwnode_graph_for_each_endpoint(fwnode, child) \ diff --git a/include/linux/tty.h b/include/linux/tty.h index 60871a9d32123b..e8d5d9997aca62 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -387,7 +387,7 @@ extern struct ktermios tty_std_termios; int vcs_init(void); -extern struct class *tty_class; +extern const struct class tty_class; /** * tty_kref_get - get a tty reference diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index f7bfedb740f56e..7eeb5f9c4f0d3f 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -378,7 +378,7 @@ void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, int usb_serial_bus_register(struct usb_serial_driver *device); void usb_serial_bus_deregister(struct usb_serial_driver *device); -extern struct bus_type usb_serial_bus_type; +extern const struct bus_type usb_serial_bus_type; extern struct tty_driver *usb_serial_tty_driver; static inline void usb_serial_debug_data(struct device *dev, diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 279782156373ad..8300ef1a982e8e 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -397,10 +397,8 @@ int fcoe_transport_attach(struct fcoe_transport *ft); int fcoe_transport_detach(struct fcoe_transport *ft); /* sysfs store handler for ctrl_control interface */ -ssize_t fcoe_ctlr_create_store(struct bus_type *bus, - const char *buf, size_t count); -ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus, - const char *buf, size_t count); +ssize_t fcoe_ctlr_create_store(const char *buf, size_t count); +ssize_t fcoe_ctlr_destroy_store(const char *buf, size_t count); #endif /* _LIBFCOE_H */ diff --git a/init/Kconfig b/init/Kconfig index c9ec6e8e4d5d5d..32c24950c4ced9 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1269,44 +1269,6 @@ config SCHED_AUTOGROUP desktop applications. Task group autogeneration is currently based upon task session. -config SYSFS_DEPRECATED - bool "Enable deprecated sysfs features to support old userspace tools" - depends on SYSFS - default n - help - This option adds code that switches the layout of the "block" class - devices, to not show up in /sys/class/block/, but only in - /sys/block/. - - This switch is only active when the sysfs.deprecated=1 boot option is - passed or the SYSFS_DEPRECATED_V2 option is set. - - This option allows new kernels to run on old distributions and tools, - which might get confused by /sys/class/block/. Since 2007/2008 all - major distributions and tools handle this just fine. - - Recent distributions and userspace tools after 2009/2010 depend on - the existence of /sys/class/block/, and will not work with this - option enabled. - - Only if you are using a new kernel on an old distribution, you might - need to say Y here. - -config SYSFS_DEPRECATED_V2 - bool "Enable deprecated sysfs features by default" - default n - depends on SYSFS - depends on SYSFS_DEPRECATED - help - Enable deprecated sysfs by default. - - See the CONFIG_SYSFS_DEPRECATED option for more details about this - option. - - Only if you are using a new kernel on an old distribution, you might - need to say Y here. Even then, odds are you would not need it - enabled, you can always pass the boot option if absolutely necessary. - config RELAY bool "Kernel->user space relay support (formerly relayfs)" select IRQ_WORK diff --git a/kernel/cpu.c b/kernel/cpu.c index 6c0a92ca6bb59c..c59b73d13a3a5d 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -2569,22 +2569,33 @@ static const struct attribute_group cpuhp_smt_attr_group = { static int __init cpu_smt_sysfs_init(void) { - return sysfs_create_group(&cpu_subsys.dev_root->kobj, - &cpuhp_smt_attr_group); + struct device *dev_root; + int ret = -ENODEV; + + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + ret = sysfs_create_group(&dev_root->kobj, &cpuhp_smt_attr_group); + put_device(dev_root); + } + return ret; } static int __init cpuhp_sysfs_init(void) { + struct device *dev_root; int cpu, ret; ret = cpu_smt_sysfs_init(); if (ret) return ret; - ret = sysfs_create_group(&cpu_subsys.dev_root->kobj, - &cpuhp_cpu_root_attr_group); - if (ret) - return ret; + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + ret = sysfs_create_group(&dev_root->kobj, &cpuhp_cpu_root_attr_group); + put_device(dev_root); + if (ret) + return ret; + } for_each_possible_cpu(cpu) { struct device *dev = get_cpu_device(cpu); diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 0408aab80941b6..aad7a3bfd846e9 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -39,7 +39,7 @@ static struct kobj_attribute _name##_attr = __ATTR_RW(_name) static ssize_t uevent_seqnum_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%llu\n", (unsigned long long)uevent_seqnum); + return sysfs_emit(buf, "%llu\n", (unsigned long long)uevent_seqnum); } KERNEL_ATTR_RO(uevent_seqnum); @@ -64,7 +64,7 @@ KERNEL_ATTR_RO(address_bits); static ssize_t uevent_helper_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%s\n", uevent_helper); + return sysfs_emit(buf, "%s\n", uevent_helper); } static ssize_t uevent_helper_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -85,7 +85,7 @@ KERNEL_ATTR_RW(uevent_helper); static ssize_t profiling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", prof_on); + return sysfs_emit(buf, "%d\n", prof_on); } static ssize_t profiling_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -116,14 +116,14 @@ KERNEL_ATTR_RW(profiling); static ssize_t kexec_loaded_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", !!kexec_image); + return sysfs_emit(buf, "%d\n", !!kexec_image); } KERNEL_ATTR_RO(kexec_loaded); static ssize_t kexec_crash_loaded_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", kexec_crash_loaded()); + return sysfs_emit(buf, "%d\n", kexec_crash_loaded()); } KERNEL_ATTR_RO(kexec_crash_loaded); @@ -135,7 +135,7 @@ static ssize_t kexec_crash_size_show(struct kobject *kobj, if (size < 0) return size; - return sprintf(buf, "%zd\n", size); + return sysfs_emit(buf, "%zd\n", size); } static ssize_t kexec_crash_size_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -160,8 +160,8 @@ static ssize_t vmcoreinfo_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { phys_addr_t vmcore_base = paddr_vmcoreinfo_note(); - return sprintf(buf, "%pa %x\n", &vmcore_base, - (unsigned int)VMCOREINFO_NOTE_SIZE); + return sysfs_emit(buf, "%pa %x\n", &vmcore_base, + (unsigned int)VMCOREINFO_NOTE_SIZE); } KERNEL_ATTR_RO(vmcoreinfo); @@ -171,7 +171,7 @@ KERNEL_ATTR_RO(vmcoreinfo); static ssize_t fscaps_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", file_caps_enabled); + return sysfs_emit(buf, "%d\n", file_caps_enabled); } KERNEL_ATTR_RO(fscaps); @@ -180,7 +180,7 @@ int rcu_expedited; static ssize_t rcu_expedited_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", READ_ONCE(rcu_expedited)); + return sysfs_emit(buf, "%d\n", READ_ONCE(rcu_expedited)); } static ssize_t rcu_expedited_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -197,7 +197,7 @@ int rcu_normal; static ssize_t rcu_normal_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", READ_ONCE(rcu_normal)); + return sysfs_emit(buf, "%d\n", READ_ONCE(rcu_normal)); } static ssize_t rcu_normal_store(struct kobject *kobj, struct kobj_attribute *attr, diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 1637b65ba07aca..0b2340a79b653b 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -280,6 +280,45 @@ static const struct file_operations sched_dynamic_fops = { __read_mostly bool sched_debug_verbose; +#ifdef CONFIG_SMP +static struct dentry *sd_dentry; + + +static ssize_t sched_verbose_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + ssize_t result; + bool orig; + + cpus_read_lock(); + mutex_lock(&sched_domains_mutex); + + orig = sched_debug_verbose; + result = debugfs_write_file_bool(filp, ubuf, cnt, ppos); + + if (sched_debug_verbose && !orig) + update_sched_domain_debugfs(); + else if (!sched_debug_verbose && orig) { + debugfs_remove(sd_dentry); + sd_dentry = NULL; + } + + mutex_unlock(&sched_domains_mutex); + cpus_read_unlock(); + + return result; +} +#else +#define sched_verbose_write debugfs_write_file_bool +#endif + +static const struct file_operations sched_verbose_fops = { + .read = debugfs_read_file_bool, + .write = sched_verbose_write, + .open = simple_open, + .llseek = default_llseek, +}; + static const struct seq_operations sched_debug_sops; static int sched_debug_open(struct inode *inode, struct file *filp) @@ -303,7 +342,7 @@ static __init int sched_init_debug(void) debugfs_sched = debugfs_create_dir("sched", NULL); debugfs_create_file("features", 0644, debugfs_sched, NULL, &sched_feat_fops); - debugfs_create_bool("verbose", 0644, debugfs_sched, &sched_debug_verbose); + debugfs_create_file_unsafe("verbose", 0644, debugfs_sched, &sched_debug_verbose, &sched_verbose_fops); #ifdef CONFIG_PREEMPT_DYNAMIC debugfs_create_file("preempt", 0644, debugfs_sched, NULL, &sched_dynamic_fops); #endif @@ -345,7 +384,6 @@ late_initcall(sched_init_debug); #ifdef CONFIG_SMP static cpumask_var_t sd_sysctl_cpus; -static struct dentry *sd_dentry; static int sd_flags_show(struct seq_file *m, void *v) { @@ -402,15 +440,23 @@ void update_sched_domain_debugfs(void) if (!debugfs_sched) return; + if (!sched_debug_verbose) + return; + if (!cpumask_available(sd_sysctl_cpus)) { if (!alloc_cpumask_var(&sd_sysctl_cpus, GFP_KERNEL)) return; cpumask_copy(sd_sysctl_cpus, cpu_possible_mask); } - if (!sd_dentry) + if (!sd_dentry) { sd_dentry = debugfs_create_dir("domains", debugfs_sched); + /* rebuild sd_sysctl_cpus if empty since it gets cleared below */ + if (cpumask_empty(sd_sysctl_cpus)) + cpumask_copy(sd_sysctl_cpus, cpu_online_mask); + } + for_each_cpu(cpu, sd_sysctl_cpus) { struct sched_domain *sd; struct dentry *d_cpu; diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 7e5dff602585db..82b28ab0f328a1 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -81,8 +81,7 @@ struct rtc_device *alarmtimer_get_rtcdev(void) } EXPORT_SYMBOL_GPL(alarmtimer_get_rtcdev); -static int alarmtimer_rtc_add_device(struct device *dev, - struct class_interface *class_intf) +static int alarmtimer_rtc_add_device(struct device *dev) { unsigned long flags; struct rtc_device *rtc = to_rtc_device(dev); diff --git a/kernel/workqueue.c b/kernel/workqueue.c index b8b541caed4854..209917792fa45f 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -5826,13 +5826,19 @@ static struct device_attribute wq_sysfs_cpumask_attr = static int __init wq_sysfs_init(void) { + struct device *dev_root; int err; err = subsys_virtual_register(&wq_subsys, NULL); if (err) return err; - return device_create_file(wq_subsys.dev_root, &wq_sysfs_cpumask_attr); + dev_root = bus_get_dev_root(&wq_subsys); + if (dev_root) { + err = device_create_file(dev_root, &wq_sysfs_cpumask_attr); + put_device(dev_root); + } + return err; } core_initcall(wq_sysfs_init); diff --git a/lib/kobject.c b/lib/kobject.c index 6e2f0bee356042..f79a434e123166 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -10,6 +10,8 @@ * about using the kobject interface. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kobject.h> #include <linux/string.h> #include <linux/export.h> @@ -127,7 +129,7 @@ static int fill_kobj_path(const struct kobject *kobj, char *path, int length) *(path + --length) = '/'; } - pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj), + pr_debug("'%s' (%p): %s: path = '%s'\n", kobject_name(kobj), kobj, __func__, path); return 0; @@ -223,7 +225,7 @@ static int kobject_add_internal(struct kobject *kobj) kobj->parent = parent; } - pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", + pr_debug("'%s' (%p): %s: parent: '%s', set: '%s'\n", kobject_name(kobj), kobj, __func__, parent ? kobject_name(parent) : "<NULL>", kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>"); @@ -338,7 +340,7 @@ void kobject_init(struct kobject *kobj, const struct kobj_type *ktype) /* do not error out as sometimes we can recover */ pr_err("kobject (%p): tried to init an initialized object, something is seriously wrong.\n", kobj); - dump_stack(); + dump_stack_lvl(KERN_ERR); } kobject_init_internal(kobj); @@ -347,7 +349,7 @@ void kobject_init(struct kobject *kobj, const struct kobj_type *ktype) error: pr_err("kobject (%p): %s\n", kobj, err_str); - dump_stack(); + dump_stack_lvl(KERN_ERR); } EXPORT_SYMBOL(kobject_init); @@ -359,7 +361,7 @@ static __printf(3, 0) int kobject_add_varg(struct kobject *kobj, retval = kobject_set_name_vargs(kobj, fmt, vargs); if (retval) { - pr_err("kobject: can not set name properly!\n"); + pr_err("can not set name properly!\n"); return retval; } kobj->parent = parent; @@ -411,7 +413,7 @@ int kobject_add(struct kobject *kobj, struct kobject *parent, if (!kobj->state_initialized) { pr_err("kobject '%s' (%p): tried to add an uninitialized object, something is seriously wrong.\n", kobject_name(kobj), kobj); - dump_stack(); + dump_stack_lvl(KERN_ERR); return -EINVAL; } va_start(args, fmt); @@ -588,7 +590,7 @@ static void __kobject_del(struct kobject *kobj) /* send "remove" if the caller did not do it but sent "add" */ if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) { - pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n", + pr_debug("'%s' (%p): auto cleanup 'remove' event\n", kobject_name(kobj), kobj); kobject_uevent(kobj, KOBJ_REMOVE); } @@ -658,16 +660,16 @@ static void kobject_cleanup(struct kobject *kobj) const struct kobj_type *t = get_ktype(kobj); const char *name = kobj->name; - pr_debug("kobject: '%s' (%p): %s, parent %p\n", + pr_debug("'%s' (%p): %s, parent %p\n", kobject_name(kobj), kobj, __func__, kobj->parent); if (t && !t->release) - pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.\n", + pr_debug("'%s' (%p): does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.\n", kobject_name(kobj), kobj); /* remove from sysfs if the caller did not do it */ if (kobj->state_in_sysfs) { - pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n", + pr_debug("'%s' (%p): auto cleanup kobject_del\n", kobject_name(kobj), kobj); __kobject_del(kobj); } else { @@ -676,14 +678,14 @@ static void kobject_cleanup(struct kobject *kobj) } if (t && t->release) { - pr_debug("kobject: '%s' (%p): calling ktype release\n", + pr_debug("'%s' (%p): calling ktype release\n", kobject_name(kobj), kobj); t->release(kobj); } /* free name if we allocated it */ if (name) { - pr_debug("kobject: '%s': free name\n", name); + pr_debug("'%s': free name\n", name); kfree_const(name); } @@ -703,8 +705,8 @@ static void kobject_release(struct kref *kref) struct kobject *kobj = container_of(kref, struct kobject, kref); #ifdef CONFIG_DEBUG_KOBJECT_RELEASE unsigned long delay = HZ + HZ * get_random_u32_below(4); - pr_info("kobject: '%s' (%p): %s, parent %p (delayed %ld)\n", - kobject_name(kobj), kobj, __func__, kobj->parent, delay); + pr_info("'%s' (%p): %s, parent %p (delayed %ld)\n", + kobject_name(kobj), kobj, __func__, kobj->parent, delay); INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup); schedule_delayed_work(&kobj->release, delay); @@ -733,7 +735,7 @@ EXPORT_SYMBOL(kobject_put); static void dynamic_kobj_release(struct kobject *kobj) { - pr_debug("kobject: (%p): %s\n", kobj, __func__); + pr_debug("(%p): %s\n", kobj, __func__); kfree(kobj); } @@ -910,7 +912,7 @@ EXPORT_SYMBOL_GPL(kset_find_obj); static void kset_release(struct kobject *kobj) { struct kset *kset = container_of(kobj, struct kset, kobj); - pr_debug("kobject: '%s' (%p): %s\n", + pr_debug("'%s' (%p): %s\n", kobject_name(kobj), kobj, __func__); kfree(kset); } diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 30d2d0386fdb91..43b48750b491ef 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -347,7 +347,7 @@ ATTRIBUTE_GROUPS(bdi_dev); static __init int bdi_class_init(void) { - bdi_class = class_create(THIS_MODULE, "bdi"); + bdi_class = class_create("bdi"); if (IS_ERR(bdi_class)) return PTR_ERR(bdi_class); diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 08542dfc2dc53b..2934d7f4d564d9 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -112,7 +112,7 @@ void hci_init_sysfs(struct hci_dev *hdev) int __init bt_sysfs_init(void) { - bt_class = class_create(THIS_MODULE, "bluetooth"); + bt_class = class_create("bluetooth"); return PTR_ERR_OR_ZERO(bt_class); } diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index 8d36303f393514..db720efa811d58 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -490,7 +490,7 @@ static int __init idletimer_tg_init(void) { int err; - idletimer_tg_class = class_create(THIS_MODULE, "xt_idletimer"); + idletimer_tg_class = class_create("xt_idletimer"); err = PTR_ERR(idletimer_tg_class); if (IS_ERR(idletimer_tg_class)) { pr_debug("couldn't register device class\n"); diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index cdb638647e0b65..268f670835e952 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -157,7 +157,6 @@ static const void *wiphy_namespace(const struct device *d) struct class ieee80211_class = { .name = "ieee80211", - .owner = THIS_MODULE, .dev_release = wiphy_dev_release, .dev_groups = ieee80211_groups, .pm = WIPHY_PM_OPS, diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 19391dda5fbaee..c6c6b5d2667095 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1421,7 +1421,7 @@ static int __init mbochs_dev_init(void) if (ret) goto err_cdev; - mbochs_class = class_create(THIS_MODULE, MBOCHS_CLASS_NAME); + mbochs_class = class_create(MBOCHS_CLASS_NAME); if (IS_ERR(mbochs_class)) { pr_err("Error: failed to register mbochs_dev class\n"); ret = PTR_ERR(mbochs_class); diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index 5f48aef3699568..a62ea11e20ecd7 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -708,7 +708,7 @@ static int __init mdpy_dev_init(void) if (ret) goto err_cdev; - mdpy_class = class_create(THIS_MODULE, MDPY_CLASS_NAME); + mdpy_class = class_create(MDPY_CLASS_NAME); if (IS_ERR(mdpy_class)) { pr_err("Error: failed to register mdpy_dev class\n"); ret = PTR_ERR(mdpy_class); diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 35460901b9f79a..a60801fb866068 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -1319,7 +1319,7 @@ static int __init mtty_dev_init(void) if (ret) goto err_cdev; - mtty_dev.vd_class = class_create(THIS_MODULE, MTTY_CLASS_NAME); + mtty_dev.vd_class = class_create(MTTY_CLASS_NAME); if (IS_ERR(mtty_dev.vd_class)) { pr_err("Error: failed to register mtty_dev class\n"); diff --git a/sound/sound_core.c b/sound/sound_core.c index 3e7dd6fcb7cf9d..4f6911274d5648 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -45,7 +45,7 @@ static int __init init_soundcore(void) if (rc) return rc; - sound_class = class_create(THIS_MODULE, "sound"); + sound_class = class_create("sound"); if (IS_ERR(sound_class)) { cleanup_oss_soundcore(); return PTR_ERR(sound_class); diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index 01ceb98c15a08e..3eba10c1e3e8f6 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -921,7 +921,7 @@ static __init int ndtest_init(void) nfit_test_setup(ndtest_resource_lookup, NULL); - ndtest_dimm_class = class_create(THIS_MODULE, "nfit_test_dimm"); + ndtest_dimm_class = class_create("nfit_test_dimm"); if (IS_ERR(ndtest_dimm_class)) { rc = PTR_ERR(ndtest_dimm_class); goto err_register; diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 745c4a27bc35ae..e4e2d1650dd506 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -3282,7 +3282,7 @@ static __init int nfit_test_init(void) if (!nfit_wq) return -ENOMEM; - nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm"); + nfit_test_dimm = class_create("nfit_test_dimm"); if (IS_ERR(nfit_test_dimm)) { rc = PTR_ERR(nfit_test_dimm); goto err_register; |
