aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2024-05-02 14:50:11 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2024-05-02 14:50:11 +1000
commit3d00d05e524720ff57a6a7215a235e03c6605fb3 (patch)
tree9cd967de45859603a38693b483da3cf6b1e3a4be
parentd0793a6018934249c7ec951f06cb9dbda60d833f (diff)
parente5019b14230a0bc1f6641c9850ae39cfe76ad2aa (diff)
downloadlinux-next-history-3d00d05e524720ff57a6a7215a235e03c6605fb3.tar.gz
Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
-rw-r--r--arch/powerpc/platforms/powernv/opal.c10
-rw-r--r--drivers/acpi/bgrt.c9
-rw-r--r--drivers/base/base.h9
-rw-r--r--drivers/base/bus.c9
-rw-r--r--drivers/base/core.c8
-rw-r--r--drivers/base/module.c42
-rw-r--r--drivers/firmware/dmi_scan.c12
-rw-r--r--drivers/firmware/efi/rci2-table.c10
-rw-r--r--drivers/gpu/drm/i915/gvt/firmware.c26
-rw-r--r--drivers/thermal/intel/int340x_thermal/int3400_thermal.c9
-rw-r--r--fs/sysfs/file.c27
-rw-r--r--include/linux/device.h11
-rw-r--r--include/linux/sysfs.h15
-rw-r--r--init/initramfs.c10
-rw-r--r--kernel/module/sysfs.c13
15 files changed, 101 insertions, 119 deletions
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 45dd77e3ccf6f8..5d0f35bb917ebc 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -792,14 +792,6 @@ static int __init opal_sysfs_init(void)
return 0;
}
-static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
- loff_t off, size_t count)
-{
- return memory_read_from_buffer(buf, count, &off, bin_attr->private,
- bin_attr->size);
-}
-
static int opal_add_one_export(struct kobject *parent, const char *export_name,
struct device_node *np, const char *prop_name)
{
@@ -826,7 +818,7 @@ static int opal_add_one_export(struct kobject *parent, const char *export_name,
sysfs_bin_attr_init(attr);
attr->attr.name = name;
attr->attr.mode = 0400;
- attr->read = export_attr_read;
+ attr->read = sysfs_bin_attr_simple_read;
attr->private = __va(vals[0]);
attr->size = vals[1];
diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c
index e4fb9e225ddfcb..d1d9c9289087a1 100644
--- a/drivers/acpi/bgrt.c
+++ b/drivers/acpi/bgrt.c
@@ -29,14 +29,7 @@ BGRT_SHOW(type, image_type);
BGRT_SHOW(xoffset, image_offset_x);
BGRT_SHOW(yoffset, image_offset_y);
-static ssize_t image_read(struct file *file, struct kobject *kobj,
- struct bin_attribute *attr, char *buf, loff_t off, size_t count)
-{
- memcpy(buf, attr->private + off, count);
- return count;
-}
-
-static BIN_ATTR_RO(image, 0); /* size gets filled in later */
+static BIN_ATTR_SIMPLE_RO(image);
static struct attribute *bgrt_attributes[] = {
&bgrt_attr_version.attr,
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 0738ccad08b2e0..db4f910e8e36e9 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -192,11 +192,14 @@ extern struct kset *devices_kset;
void devices_kset_move_last(struct device *dev);
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
-void module_add_driver(struct module *mod, struct device_driver *drv);
+int 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) { }
+static inline int module_add_driver(struct module *mod,
+ struct device_driver *drv)
+{
+ return 0;
+}
static inline void module_remove_driver(struct device_driver *drv) { }
#endif
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index daee55c9b2d9e1..ffea0728b8b2fb 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -674,7 +674,12 @@ int bus_add_driver(struct device_driver *drv)
if (error)
goto out_del_list;
}
- module_add_driver(drv->owner, drv);
+ error = module_add_driver(drv->owner, drv);
+ if (error) {
+ printk(KERN_ERR "%s: failed to create module links for %s\n",
+ __func__, drv->name);
+ goto out_detach;
+ }
error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
@@ -699,6 +704,8 @@ int bus_add_driver(struct device_driver *drv)
return 0;
+out_detach:
+ driver_detach(drv);
out_del_list:
klist_del(&priv->knode_bus);
out_unregister:
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 5f4e03336e68ef..4d51928c408870 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2346,8 +2346,6 @@ static void fw_devlink_link_device(struct device *dev)
/* Device links support end. */
-int (*platform_notify)(struct device *dev) = NULL;
-int (*platform_notify_remove)(struct device *dev) = NULL;
static struct kobject *dev_kobj;
/* /sys/dev/char */
@@ -2395,16 +2393,10 @@ static void device_platform_notify(struct device *dev)
acpi_device_notify(dev);
software_node_notify(dev);
-
- if (platform_notify)
- platform_notify(dev);
}
static void device_platform_notify_remove(struct device *dev)
{
- if (platform_notify_remove)
- platform_notify_remove(dev);
-
software_node_notify_remove(dev);
acpi_device_notify_remove(dev);
diff --git a/drivers/base/module.c b/drivers/base/module.c
index 46ad4d636731dd..a1b55da07127d8 100644
--- a/drivers/base/module.c
+++ b/drivers/base/module.c
@@ -30,14 +30,14 @@ static void module_create_drivers_dir(struct module_kobject *mk)
mutex_unlock(&drivers_dir_mutex);
}
-void module_add_driver(struct module *mod, struct device_driver *drv)
+int module_add_driver(struct module *mod, struct device_driver *drv)
{
char *driver_name;
- int no_warn;
struct module_kobject *mk = NULL;
+ int ret;
if (!drv)
- return;
+ return 0;
if (mod)
mk = &mod->mkobj;
@@ -56,17 +56,37 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
}
if (!mk)
- return;
+ return 0;
+
+ ret = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
+ if (ret)
+ return ret;
- /* Don't check return codes; these calls are idempotent */
- no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
driver_name = make_driver_name(drv);
- if (driver_name) {
- module_create_drivers_dir(mk);
- no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
- driver_name);
- kfree(driver_name);
+ if (!driver_name) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ module_create_drivers_dir(mk);
+ if (!mk->drivers_dir) {
+ ret = -EINVAL;
+ goto out;
}
+
+ ret = sysfs_create_link(mk->drivers_dir, &drv->p->kobj, driver_name);
+ if (ret)
+ goto out;
+
+ kfree(driver_name);
+
+ return 0;
+out:
+ sysfs_remove_link(&drv->p->kobj, "module");
+ sysfs_remove_link(mk->drivers_dir, driver_name);
+ kfree(driver_name);
+
+ return ret;
}
void module_remove_driver(struct device_driver *drv)
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 015c95a825d315..3d0f773ab876b0 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -746,16 +746,8 @@ static void __init dmi_scan_machine(void)
pr_info("DMI not present or invalid.\n");
}
-static ssize_t raw_table_read(struct file *file, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t pos, size_t count)
-{
- memcpy(buf, attr->private + pos, count);
- return count;
-}
-
-static BIN_ATTR(smbios_entry_point, S_IRUSR, raw_table_read, NULL, 0);
-static BIN_ATTR(DMI, S_IRUSR, raw_table_read, NULL, 0);
+static BIN_ATTR_SIMPLE_ADMIN_RO(smbios_entry_point);
+static BIN_ATTR_SIMPLE_ADMIN_RO(DMI);
static int __init dmi_init(void)
{
diff --git a/drivers/firmware/efi/rci2-table.c b/drivers/firmware/efi/rci2-table.c
index de1a9a1f9f1467..4fd45d6f69a4d8 100644
--- a/drivers/firmware/efi/rci2-table.c
+++ b/drivers/firmware/efi/rci2-table.c
@@ -40,15 +40,7 @@ static u8 *rci2_base;
static u32 rci2_table_len;
unsigned long rci2_table_phys __ro_after_init = EFI_INVALID_TABLE_ADDR;
-static ssize_t raw_table_read(struct file *file, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t pos, size_t count)
-{
- memcpy(buf, attr->private + pos, count);
- return count;
-}
-
-static BIN_ATTR(rci2, S_IRUSR, raw_table_read, NULL, 0);
+static BIN_ATTR_SIMPLE_ADMIN_RO(rci2);
static u16 checksum(void)
{
diff --git a/drivers/gpu/drm/i915/gvt/firmware.c b/drivers/gpu/drm/i915/gvt/firmware.c
index d800d267f0e9bd..221a3ae81baf5b 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -51,21 +51,7 @@ struct gvt_firmware_header {
#define dev_to_drm_minor(d) dev_get_drvdata((d))
-static ssize_t
-gvt_firmware_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t offset, size_t count)
-{
- memcpy(buf, attr->private + offset, count);
- return count;
-}
-
-static struct bin_attribute firmware_attr = {
- .attr = {.name = "gvt_firmware", .mode = (S_IRUSR)},
- .read = gvt_firmware_read,
- .write = NULL,
- .mmap = NULL,
-};
+static BIN_ATTR_SIMPLE_ADMIN_RO(gvt_firmware);
static int expose_firmware_sysfs(struct intel_gvt *gvt)
{
@@ -108,10 +94,10 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
crc32_start = offsetof(struct gvt_firmware_header, version);
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
- firmware_attr.size = size;
- firmware_attr.private = firmware;
+ bin_attr_gvt_firmware.size = size;
+ bin_attr_gvt_firmware.private = firmware;
- ret = device_create_bin_file(&pdev->dev, &firmware_attr);
+ ret = device_create_bin_file(&pdev->dev, &bin_attr_gvt_firmware);
if (ret) {
vfree(firmware);
return ret;
@@ -123,8 +109,8 @@ static void clean_firmware_sysfs(struct intel_gvt *gvt)
{
struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
- device_remove_bin_file(&pdev->dev, &firmware_attr);
- vfree(firmware_attr.private);
+ device_remove_bin_file(&pdev->dev, &bin_attr_gvt_firmware);
+ vfree(bin_attr_gvt_firmware.private);
}
/**
diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
index f8ebdd19d3402f..fa96972266e4b0 100644
--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
@@ -73,14 +73,7 @@ struct odvp_attr {
struct device_attribute attr;
};
-static ssize_t data_vault_read(struct file *file, struct kobject *kobj,
- struct bin_attribute *attr, char *buf, loff_t off, size_t count)
-{
- memcpy(buf, attr->private + off, count);
- return count;
-}
-
-static BIN_ATTR_RO(data_vault, 0);
+static BIN_ATTR_SIMPLE_RO(data_vault);
static struct bin_attribute *data_attributes[] = {
&bin_attr_data_vault,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 7cd64021d453de..d1995e2d6c943a 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -785,3 +785,30 @@ int sysfs_emit_at(char *buf, int at, const char *fmt, ...)
return len;
}
EXPORT_SYMBOL_GPL(sysfs_emit_at);
+
+/**
+ * sysfs_bin_attr_simple_read - read callback to simply copy from memory.
+ * @file: attribute file which is being read.
+ * @kobj: object to which the attribute belongs.
+ * @attr: attribute descriptor.
+ * @buf: destination buffer.
+ * @off: offset in bytes from which to read.
+ * @count: maximum number of bytes to read.
+ *
+ * Simple ->read() callback for bin_attributes backed by a buffer in memory.
+ * The @private and @size members in struct bin_attribute must be set to the
+ * buffer's location and size before the bin_attribute is created in sysfs.
+ *
+ * Bounds check for @off and @count is done in sysfs_kf_bin_read().
+ * Negative value check for @off is done in vfs_setpos() and default_llseek().
+ *
+ * Returns number of bytes written to @buf.
+ */
+ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ memcpy(buf, attr->private + off, count);
+ return count;
+}
+EXPORT_SYMBOL_GPL(sysfs_bin_attr_simple_read);
diff --git a/include/linux/device.h b/include/linux/device.h
index b9f5464f44ed81..07f4d2af1e3c47 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1207,17 +1207,6 @@ int __must_check devm_device_add_group(struct device *dev,
const struct attribute_group *grp);
/*
- * Platform "fixup" functions - allow the platform to have their say
- * about devices and actions that the general device layer doesn't
- * know about.
- */
-/* Notify platform of device discovery */
-extern int (*platform_notify)(struct device *dev);
-
-extern int (*platform_notify_remove)(struct device *dev);
-
-
-/*
* get_device - atomically increment the reference count for the device.
*
*/
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 326341c623857e..a7d725fbf73937 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -371,6 +371,17 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RO(_name, _size)
#define BIN_ATTR_ADMIN_RW(_name, _size) \
struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RW(_name, _size)
+#define __BIN_ATTR_SIMPLE_RO(_name, _mode) { \
+ .attr = { .name = __stringify(_name), .mode = _mode }, \
+ .read = sysfs_bin_attr_simple_read, \
+}
+
+#define BIN_ATTR_SIMPLE_RO(_name) \
+struct bin_attribute bin_attr_##_name = __BIN_ATTR_SIMPLE_RO(_name, 0444)
+
+#define BIN_ATTR_SIMPLE_ADMIN_RO(_name) \
+struct bin_attribute bin_attr_##_name = __BIN_ATTR_SIMPLE_RO(_name, 0400)
+
struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *, char *);
ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
@@ -478,6 +489,10 @@ int sysfs_emit(char *buf, const char *fmt, ...);
__printf(3, 4)
int sysfs_emit_at(char *buf, int at, const char *fmt, ...);
+ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count);
+
#else /* CONFIG_SYSFS */
static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
diff --git a/init/initramfs.c b/init/initramfs.c
index a298a3854a8018..814241b648274f 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -575,15 +575,7 @@ extern unsigned long __initramfs_size;
#include <linux/initrd.h>
#include <linux/kexec.h>
-static ssize_t raw_read(struct file *file, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t pos, size_t count)
-{
- memcpy(buf, attr->private + pos, count);
- return count;
-}
-
-static BIN_ATTR(initrd, 0440, raw_read, NULL, 0);
+static BIN_ATTR(initrd, 0440, sysfs_bin_attr_simple_read, NULL, 0);
void __init reserve_initrd_mem(void)
{
diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c
index d964167c665868..26efe1305c120e 100644
--- a/kernel/module/sysfs.c
+++ b/kernel/module/sysfs.c
@@ -146,17 +146,6 @@ struct module_notes_attrs {
struct bin_attribute attrs[] __counted_by(notes);
};
-static ssize_t module_notes_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t pos, size_t count)
-{
- /*
- * The caller checked the pos and count against our size.
- */
- memcpy(buf, bin_attr->private + pos, count);
- return count;
-}
-
static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
unsigned int i)
{
@@ -205,7 +194,7 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
nattr->attr.mode = 0444;
nattr->size = info->sechdrs[i].sh_size;
nattr->private = (void *)info->sechdrs[i].sh_addr;
- nattr->read = module_notes_read;
+ nattr->read = sysfs_bin_attr_simple_read;
++nattr;
}
++loaded;