Merge tag 'driver-core-7.2-rc1' of gitolite.kernel.org:pub/scm/linux/kernel/git/driver-core/driver-core

Pull driver core updates from Danilo Krummrich:
 "Deferred probe:
   - Fix race where deferred probe timeout work could be permanently
     canceled by using mod_delayed_work()
   - Fix missing jiffies conversion in deferred_probe_extend_timeout()
   - Guard timeout extension with delayed_work_pending() to prevent
     premature firing
   - Use system_percpu_wq instead of the deprecated system_wq
   - Update deferred_probe_timeout documentation

  device:
   - Replace direct struct device bitfield access (can_match, dma_iommu,
     dma_skip_sync, dma_ops_bypass, state_synced, dma_coherent,
     of_node_reused, offline, offline_disabled) with flag-based
     accessors using bit operations
   - Reject devices with unregistered buses
   - Delete unused DEVICE_ATTR_PREALLOC()
   - Add low-level device attribute macros with const show/store
     callbacks, allowing device attributes to reside in read-only memory
   - Move core device attributes to read-only memory
   - Constify group array pointers in driver_add_groups() /
     driver_remove_groups(), struct bus_type, and struct device_driver

  device property:
   - Fix fwnode reference leak in fwnode_graph_get_endpoint_by_id()
   - Initialize all fields of fwnode_handle in fwnode_init()
   - Provide swnode_get()/swnode_put() wrappers around kobject_get/put()
   - Allow passing struct software_node_ref_args pointers directly to
     PROPERTY_ENTRY_REF()

  driver_override:
   - Migrate amba, cdx, vmbus, and rpmsg to the generic driver_override
     infrastructure, fixing a UAF from unsynchronized access to
     driver_override in bus match() callbacks
   - Remove the now-unused driver_set_override()

  firmware loader:
   - Fix recursive lock deadlock in device_cache_fw_images() when async
     work falls back to synchronous execution
   - Fix device reference leak in firmware_upload_register()

  platform:
   - Pass KBUILD_MODNAME through the platform driver registration macro
     to create module symlinks in sysfs for built-in drivers; move
     module_kset initialization to a pure_initcall and tegra cbb
     registration to core_initcall to ensure correct ordering
   - Pass THIS_MODULE implicitly through a coresight_init_driver() macro

  sysfs:
   - Upgrade OOB write detection in sysfs_kf_seq_show() from printk to
     WARN
   - Add return value clamping to sysfs_kf_read()

  Rust:
   - ACPI:

     Fix missing match data for PRP0001 by exporting
     acpi_of_match_device()

   - Auxiliary:

     Replace drvdata() with dedicated registration data on
     auxiliary_device. drvdata() exposed the driver's bus device private
     data beyond the driver's own scope, creating ordering constraints
     and forcing the data to outlive all registrations that access it.
     Registration data is instead scoped structurally to the
     Registration object, making lifecycle ordering enforced by
     construction rather than convention.

   - Rust-native device driver lifetimes (HRT):

     Allow Rust device drivers to carry a lifetime parameter on their
     bus device private data, tied to the device binding scope -- the
     interval during which a bus device is bound to a driver. Device
     resources like pci::Bar<'a> and IoMem<'a> can be stored directly in
     the driver's bus device private data with a lifetime bounded by the
     binding scope, so the compiler enforces at build time that they do
     not outlive the binding. This removes Devres indirection from every
     access site and eliminates try_access() failure paths in
     destructors.

     Bus driver traits use a Generic Associated Type (GAT) Data<'bound>
     to introduce the lifetime on the private data, rather than
     parameterizing the Driver trait itself. Auxiliary registration
     data, where the lifetime is not introduced by a trait callback but
     must be threaded through Registration, uses the ForLt trait (a
     type-level abstraction for types generic over a lifetime).

  Misc:
   - Fix DT overlayed devices not probing by reverting the broken
     treewide overlay fix and re-running fw_devlink consumer pickup when
     an overlay is applied to a bound device
   - Use root_device_register() for faux bus root device; add sanity
     check for failed bus init
   - Fix dev_has_sync_state() data race with READ_ONCE() and move it to
     base.h
   - Avoid spurious device_links warning when removing a device while
     its supplier is unbinding
   - Switch ISA bus to dynamic root device
   - Fix suspicious RCU usage in kernfs_put()
   - Remove devcoredump exit callback
   - Constify devfreq_event_class"

* tag 'driver-core-7.2-rc1' of gitolite.kernel.org:pub/scm/linux/kernel/git/driver-core/driver-core: (81 commits)
  software node: allow passing reference args to PROPERTY_ENTRY_REF()
  driver core: platform: set mod_name in driver registration
  coresight: pass THIS_MODULE implicitly through a macro
  kernel: param: initialize module_kset in a pure_initcall
  soc/tegra: cbb: Move driver registration from pure_initcall to core_initcall
  firmware_loader: Fix recursive lock in device_cache_fw_images()
  driver core: Use system_percpu_wq instead of system_wq
  driver core: remove driver_set_override()
  rpmsg: use generic driver_override infrastructure
  Drivers: hv: vmbus: use generic driver_override infrastructure
  cdx: use generic driver_override infrastructure
  amba: use generic driver_override infrastructure
  rust: devres: add 'static bound to Devres<T>
  samples: rust: rust_driver_auxiliary: showcase lifetime-bound registration data
  rust: auxiliary: generalize Registration over ForLt
  rust: types: add `ForLt` trait for higher-ranked lifetime support
  gpu: nova-core: separate driver type from driver data
  samples: rust: rust_driver_pci: use HRT lifetime for Bar
  rust: io: make IoMem and ExclusiveIoMem lifetime-parameterized
  rust: pci: make Bar lifetime-parameterized
  ...
This commit is contained in:
Linus Torvalds
2026-06-15 12:41:17 +05:30
128 changed files with 1805 additions and 1125 deletions

View File

@@ -1228,8 +1228,9 @@ Kernel parameters
deferred probe to give up waiting on dependencies to
probe. Only specific dependencies (subsystems or
drivers) that have opted in will be ignored. A timeout
of 0 will timeout at the end of initcalls. If the time
out hasn't expired, it'll be restarted by each
of 0 will timeout at the end of initcalls; a negative
value is treated as an infinite timeout value. If the
timeout hasn't expired, it'll be restarted by each
successful driver registration. This option will also
dump out devices still on the deferred probe list after
retrying.

View File

@@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
provides helpers to register and unregister an array of drivers::
int __platform_register_drivers(struct platform_driver * const *drivers,
unsigned int count, struct module *owner);
unsigned int count, struct module *owner,
const char *mod_name);
void platform_unregister_drivers(struct platform_driver * const *drivers,
unsigned int count);

View File

@@ -297,6 +297,7 @@ F: include/linux/acpi.h
F: include/linux/fwnode.h
F: include/linux/fw_table.h
F: lib/fw_table.c
F: rust/helpers/acpi.c
F: rust/kernel/acpi.rs
F: tools/power/acpi/

View File

@@ -98,8 +98,8 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
* DMA buffers.
*/
if (is_isa_arcv2() && ioc_enable && coherent)
dev->dma_coherent = true;
dev_set_dma_coherent(dev);
dev_info(dev, "use %scoherent DMA ops\n",
dev->dma_coherent ? "" : "non");
dev_dma_coherent(dev) ? "" : "non");
}

View File

@@ -98,7 +98,7 @@ static int highbank_platform_notifier(struct notifier_block *nb,
if (of_property_read_bool(dev->of_node, "dma-coherent")) {
val = readl(sregs_base + reg);
writel(val | 0xff01, sregs_base + reg);
dev->dma_coherent = true;
dev_set_dma_coherent(dev);
}
return NOTIFY_OK;

View File

@@ -95,7 +95,7 @@ static int mvebu_hwcc_notifier(struct notifier_block *nb,
if (event != BUS_NOTIFY_ADD_DEVICE)
return NOTIFY_DONE;
dev->dma_coherent = true;
dev_set_dma_coherent(dev);
return NOTIFY_OK;
}

View File

@@ -42,11 +42,11 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
* enough to check if MPU is in use or not since in absence of
* MPU system memory map is used.
*/
dev->dma_coherent = cacheid ? coherent : true;
dev_assign_dma_coherent(dev, cacheid ? coherent : true);
} else {
/*
* Assume coherent DMA in case MMU/MPU has not been set up.
*/
dev->dma_coherent = (get_cr() & CR_M) ? coherent : true;
dev_assign_dma_coherent(dev, (get_cr() & CR_M) ? coherent : true);
}
}

View File

@@ -1076,7 +1076,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
struct page **pages;
void *addr = NULL;
int coherent_flag = dev->dma_coherent ? COHERENT : NORMAL;
int coherent_flag = dev_dma_coherent(dev) ? COHERENT : NORMAL;
*handle = DMA_MAPPING_ERROR;
size = PAGE_ALIGN(size);
@@ -1124,7 +1124,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
if (vma->vm_pgoff >= nr_pages)
return -ENXIO;
if (!dev->dma_coherent)
if (!dev_dma_coherent(dev))
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
err = vm_map_pages(vma, pages, nr_pages);
@@ -1141,7 +1141,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
static void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t handle, unsigned long attrs)
{
int coherent_flag = dev->dma_coherent ? COHERENT : NORMAL;
int coherent_flag = dev_dma_coherent(dev) ? COHERENT : NORMAL;
struct page **pages;
size = PAGE_ALIGN(size);
@@ -1202,7 +1202,7 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
phys_addr_t phys = page_to_phys(sg_page(s));
unsigned int len = PAGE_ALIGN(s->offset + s->length);
if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
if (!dev_dma_coherent(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
arch_sync_dma_for_device(sg_phys(s), s->length, dir);
prot = __dma_info_to_prot(dir, attrs);
@@ -1304,7 +1304,7 @@ static void arm_iommu_unmap_sg(struct device *dev,
if (sg_dma_len(s))
__iommu_remove_mapping(dev, sg_dma_address(s),
sg_dma_len(s));
if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
if (!dev_dma_coherent(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
arch_sync_dma_for_cpu(sg_phys(s), s->length, dir);
}
}
@@ -1323,7 +1323,7 @@ static void arm_iommu_sync_sg_for_cpu(struct device *dev,
struct scatterlist *s;
int i;
if (dev->dma_coherent)
if (dev_dma_coherent(dev))
return;
for_each_sg(sg, s, nents, i)
@@ -1345,7 +1345,7 @@ static void arm_iommu_sync_sg_for_device(struct device *dev,
struct scatterlist *s;
int i;
if (dev->dma_coherent)
if (dev_dma_coherent(dev))
return;
for_each_sg(sg, s, nents, i)
@@ -1371,7 +1371,7 @@ static dma_addr_t arm_iommu_map_phys(struct device *dev, phys_addr_t phys,
dma_addr_t dma_addr;
int ret, prot;
if (!dev->dma_coherent &&
if (!dev_dma_coherent(dev) &&
!(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO)))
arch_sync_dma_for_device(phys, size, dir);
@@ -1412,7 +1412,7 @@ static void arm_iommu_unmap_phys(struct device *dev, dma_addr_t handle,
if (!iova)
return;
if (!dev->dma_coherent &&
if (!dev_dma_coherent(dev) &&
!(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO))) {
phys_addr_t phys = iommu_iova_to_phys(mapping->domain, iova);
@@ -1431,7 +1431,7 @@ static void arm_iommu_sync_single_for_cpu(struct device *dev,
unsigned int offset = handle & ~PAGE_MASK;
phys_addr_t phys;
if (dev->dma_coherent || !iova)
if (dev_dma_coherent(dev) || !iova)
return;
phys = iommu_iova_to_phys(mapping->domain, iova);
@@ -1446,7 +1446,7 @@ static void arm_iommu_sync_single_for_device(struct device *dev,
unsigned int offset = handle & ~PAGE_MASK;
phys_addr_t phys;
if (dev->dma_coherent || !iova)
if (dev_dma_coherent(dev) || !iova)
return;
phys = iommu_iova_to_phys(mapping->domain, iova);
@@ -1701,13 +1701,13 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
void arch_setup_dma_ops(struct device *dev, bool coherent)
{
/*
* Due to legacy code that sets the ->dma_coherent flag from a bus
* notifier we can't just assign coherent to the ->dma_coherent flag
* Due to legacy code that sets the dma_coherent flag from a bus
* notifier we can't just assign coherent to the dma_coherent flag
* here, but instead have to make sure we only set but never clear it
* for now.
*/
if (coherent)
dev->dma_coherent = true;
dev_set_dma_coherent(dev);
/*
* Don't override the dma_ops if they have already been set. Ideally

View File

@@ -4052,7 +4052,7 @@ static int enable_mismatched_32bit_el0(unsigned int cpu)
*/
lucky_winner = cpu_32bit ? cpu : cpumask_any_and(cpu_32bit_el0_mask,
cpu_active_mask);
get_cpu_device(lucky_winner)->offline_disabled = true;
dev_set_offline_disabled(get_cpu_device(lucky_winner));
setup_elf_hwcaps(compat_elf_hwcaps);
elf_hwcap_fixup();
pr_info("Asymmetric 32-bit EL0 support detected on CPU %u; CPU hot-unplug disabled on CPU %u\n",

View File

@@ -48,7 +48,7 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
dev_driver_string(dev), dev_name(dev),
ARCH_DMA_MINALIGN, cls);
dev->dma_coherent = coherent;
dev_assign_dma_coherent(dev, coherent);
xen_setup_dma_ops(dev);
}

View File

@@ -23,7 +23,6 @@ extern void mips_mt_set_cpuoptions(void);
static inline void mips_mt_set_cpuoptions(void) { }
#endif
struct class;
extern const struct class mt_class;
#endif /* __ASM_MIPS_MT_H */

View File

@@ -139,6 +139,6 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
#ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
void arch_setup_dma_ops(struct device *dev, bool coherent)
{
dev->dma_coherent = coherent;
dev_assign_dma_coherent(dev, coherent);
}
#endif

View File

@@ -67,7 +67,7 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
}
bool arch_dma_alloc_direct(struct device *dev)
{
if (dev->dma_ops_bypass && dev->bus_dma_limit)
if (dev_dma_ops_bypass(dev) && dev->bus_dma_limit)
return true;
return false;
@@ -75,7 +75,7 @@ bool arch_dma_alloc_direct(struct device *dev)
bool arch_dma_free_direct(struct device *dev, dma_addr_t dma_handle)
{
if (!dev->dma_ops_bypass || !dev->bus_dma_limit)
if (!dev_dma_ops_bypass(dev) || !dev->bus_dma_limit)
return false;
return is_direct_handle(dev, dma_handle);
@@ -164,7 +164,7 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask)
* fixed ops will be used for RAM. This is limited by
* bus_dma_limit which is set when RAM is pre-mapped.
*/
dev->dma_ops_bypass = true;
dev_set_dma_ops_bypass(dev);
dev_info(dev, "iommu: 64-bit OK but direct DMA is limited by %llx\n",
dev->bus_dma_limit);
return 1;
@@ -185,7 +185,7 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask)
}
dev_dbg(dev, "iommu: not 64-bit, using default ops\n");
dev->dma_ops_bypass = false;
dev_clear_dma_ops_bypass(dev);
return 1;
}

View File

@@ -213,9 +213,9 @@ static int dlpar_change_lmb_state(struct drmem_lmb *lmb, bool online)
return -EINVAL;
}
if (online && mem_block->dev.offline)
if (online && dev_offline(&mem_block->dev))
rc = device_online(&mem_block->dev);
else if (!online && !mem_block->dev.offline)
else if (!online && !dev_offline(&mem_block->dev))
rc = device_offline(&mem_block->dev);
else
rc = 0;

View File

@@ -140,7 +140,7 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
"%s %s: device non-coherent but no non-coherent operations supported",
dev_driver_string(dev), dev_name(dev));
dev->dma_coherent = coherent;
dev_assign_dma_coherent(dev, coherent);
}
void riscv_noncoherent_supported(void)

View File

@@ -898,9 +898,9 @@ const struct acpi_device *acpi_companion_match(const struct device *dev)
* identifiers and a _DSD object with the "compatible" property, use that
* property to match against the given list of identifiers.
*/
static bool acpi_of_match_device(const struct acpi_device *adev,
const struct of_device_id *of_match_table,
const struct of_device_id **of_id)
bool acpi_of_match_device(const struct acpi_device *adev,
const struct of_device_id *of_match_table,
const struct of_device_id **of_id)
{
const union acpi_object *of_compatible, *obj;
int i, nval;

View File

@@ -122,7 +122,7 @@ bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent)
mutex_lock_nested(&adev->physical_node_lock, SINGLE_DEPTH_NESTING);
list_for_each_entry(pn, &adev->physical_node_list, node)
if (device_supports_offline(pn->dev) && !pn->dev->offline) {
if (device_supports_offline(pn->dev) && !dev_offline(pn->dev)) {
if (uevent)
kobject_uevent_env(&pn->dev->kobj, KOBJ_CHANGE, envp);

View File

@@ -82,33 +82,6 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
}
static ssize_t driver_override_show(struct device *_dev,
struct device_attribute *attr, char *buf)
{
struct amba_device *dev = to_amba_device(_dev);
ssize_t len;
device_lock(_dev);
len = sprintf(buf, "%s\n", dev->driver_override);
device_unlock(_dev);
return len;
}
static ssize_t driver_override_store(struct device *_dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct amba_device *dev = to_amba_device(_dev);
int ret;
ret = driver_set_override(_dev, &dev->driver_override, buf, count);
if (ret)
return ret;
return count;
}
static DEVICE_ATTR_RW(driver_override);
#define amba_attr_func(name,fmt,arg...) \
static ssize_t name##_show(struct device *_dev, \
struct device_attribute *attr, char *buf) \
@@ -126,7 +99,6 @@ amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
static struct attribute *amba_dev_attrs[] = {
&dev_attr_id.attr,
&dev_attr_resource.attr,
&dev_attr_driver_override.attr,
NULL,
};
ATTRIBUTE_GROUPS(amba_dev);
@@ -209,10 +181,11 @@ static int amba_match(struct device *dev, const struct device_driver *drv)
{
struct amba_device *pcdev = to_amba_device(dev);
const struct amba_driver *pcdrv = to_amba_driver(drv);
int ret;
mutex_lock(&pcdev->periphid_lock);
if (!pcdev->periphid) {
int ret = amba_read_periphid(pcdev);
ret = amba_read_periphid(pcdev);
/*
* Returning any error other than -EPROBE_DEFER from bus match
@@ -230,8 +203,9 @@ static int amba_match(struct device *dev, const struct device_driver *drv)
mutex_unlock(&pcdev->periphid_lock);
/* When driver_override is set, only bind to the matching driver */
if (pcdev->driver_override)
return !strcmp(pcdev->driver_override, drv->name);
ret = device_match_driver_override(dev, drv);
if (ret >= 0)
return ret;
return amba_lookup(pcdrv->id_table, pcdev) != NULL;
}
@@ -436,6 +410,7 @@ static const struct dev_pm_ops amba_pm = {
const struct bus_type amba_bustype = {
.name = "amba",
.dev_groups = amba_dev_groups,
.driver_override = true,
.match = amba_match,
.uevent = amba_uevent,
.probe = amba_probe,

View File

@@ -86,18 +86,6 @@ struct driver_private {
};
#define to_driver(obj) container_of(obj, struct driver_private, kobj)
#ifdef CONFIG_RUST
/**
* struct driver_type - Representation of a Rust driver type.
*/
struct driver_type {
/**
* @id: Representation of core::any::TypeId.
*/
u8 id[16];
} __packed;
#endif
/**
* struct device_private - structure to hold the private to the driver core
* portions of the device structure.
@@ -115,7 +103,6 @@ struct driver_type {
* dev_err_probe() for later retrieval via debugfs
* @device: pointer back to the struct device that this structure is
* associated with.
* @driver_type: The type of the bound Rust driver.
* @dead: This device is currently either in the process of or has been
* removed from the system. Any asynchronous events scheduled for this
* device should exit without taking any action.
@@ -132,9 +119,6 @@ struct device_private {
const struct device_driver *async_driver;
char *deferred_probe_reason;
struct device *device;
#ifdef CONFIG_RUST
struct driver_type driver_type;
#endif
u8 dead:1;
};
#define to_device_private_parent(obj) \
@@ -188,6 +172,20 @@ static inline int driver_match_device(const struct device_driver *drv,
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
static inline bool dev_has_sync_state(struct device *dev)
{
struct device_driver *drv;
if (!dev)
return false;
drv = READ_ONCE(dev->driver);
if (drv && drv->sync_state)
return true;
if (dev->bus && dev->bus->sync_state)
return true;
return false;
}
static inline void dev_sync_state(struct device *dev)
{
if (dev->bus->sync_state)
@@ -196,8 +194,10 @@ static inline void dev_sync_state(struct device *dev)
dev->driver->sync_state(dev);
}
int driver_add_groups(const struct device_driver *drv, const struct attribute_group **groups);
void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups);
int driver_add_groups(const struct device_driver *drv,
const struct attribute_group *const *groups);
void driver_remove_groups(const struct device_driver *drv,
const struct attribute_group *const *groups);
void device_driver_detach(struct device *dev);
static inline void device_set_driver(struct device *dev, const struct device_driver *drv)

View File

@@ -544,10 +544,10 @@ static const struct attribute_group driver_override_dev_group = {
*/
int bus_add_device(struct device *dev)
{
struct subsys_private *sp = bus_to_subsys(dev->bus);
struct subsys_private *sp;
int error;
if (!sp) {
if (!dev->bus) {
/*
* This is a normal operation for many devices that do not
* have a bus assigned to them, just say that all went
@@ -556,6 +556,13 @@ int bus_add_device(struct device *dev)
return 0;
}
sp = bus_to_subsys(dev->bus);
if (!sp) {
pr_err("%s: cannot add device '%s' to unregistered bus '%s'\n",
__func__, dev_name(dev), dev->bus->name);
return -EINVAL;
}
/*
* Reference in sp is now incremented and will be dropped when
* the device is removed from the bus

View File

@@ -235,6 +235,79 @@ static void __fw_devlink_pickup_dangling_consumers(struct fwnode_handle *fwnode,
__fw_devlink_pickup_dangling_consumers(child, new_sup);
}
static void fw_devlink_pickup_dangling_consumers(struct device *dev)
{
struct fwnode_handle *child;
guard(mutex)(&fwnode_link_lock);
fwnode_for_each_available_child_node(dev->fwnode, child)
__fw_devlink_pickup_dangling_consumers(child, dev->fwnode);
__fw_devlink_link_to_consumers(dev);
}
/**
* fw_devlink_refresh_fwnode - Recheck the tree under this firmware node
* @fwnode: The fwnode under which the fwnode tree has changed
*
* This function is mainly meant to adjust the supplier/consumer dependencies
* after a fwnode tree overlay has occurred.
*/
void fw_devlink_refresh_fwnode(struct fwnode_handle *fwnode)
{
struct device *dev;
/*
* Find the closest ancestor fwnode that has been converted to a device
* that can bind to a driver (bus device).
*/
fwnode_handle_get(fwnode);
do {
if (fwnode_test_flag(fwnode, FWNODE_FLAG_NOT_DEVICE))
continue;
dev = get_dev_from_fwnode(fwnode);
if (!dev)
continue;
if (dev->bus)
break;
put_device(dev);
} while ((fwnode = fwnode_get_next_parent(fwnode)));
/*
* If none of the ancestor fwnodes have (yet) been converted to a device
* that can bind to a driver, there's nothing to fix up.
*/
if (!fwnode)
return;
WARN(device_is_bound(dev) && dev->links.status != DL_DEV_DRIVER_BOUND,
"Don't multithread overlaying and probing the same device!\n");
/*
* If the device has already bound to a driver, then we need to redo
* some of the work that was done after the device was bound to a
* driver. If the device hasn't bound to a driver, running things too
* soon would incorrectly pick up consumers that it shouldn't.
*/
if (dev->links.status == DL_DEV_DRIVER_BOUND) {
fw_devlink_pickup_dangling_consumers(dev);
/*
* Some of dangling consumers could have been put previously in
* the deferred probe list due to the unavailability of their
* suppliers. Those consumers have been picked up and some of
* their suppliers links have been updated. Time to re-try their
* probe sequence.
*/
driver_deferred_probe_trigger();
}
put_device(dev);
fwnode_handle_put(fwnode);
}
static DEFINE_MUTEX(device_links_lock);
DEFINE_STATIC_SRCU(device_links_srcu);
@@ -422,7 +495,7 @@ void device_pm_move_to_tail(struct device *dev)
#define to_devlink(dev) container_of((dev), struct device_link, link_dev)
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
const struct device_attribute *attr, char *buf)
{
const char *output;
@@ -452,10 +525,10 @@ static ssize_t status_show(struct device *dev,
return sysfs_emit(buf, "%s\n", output);
}
static DEVICE_ATTR_RO(status);
static const DEVICE_ATTR_RO(status);
static ssize_t auto_remove_on_show(struct device *dev,
struct device_attribute *attr, char *buf)
const struct device_attribute *attr, char *buf)
{
struct device_link *link = to_devlink(dev);
const char *output;
@@ -469,27 +542,27 @@ static ssize_t auto_remove_on_show(struct device *dev,
return sysfs_emit(buf, "%s\n", output);
}
static DEVICE_ATTR_RO(auto_remove_on);
static const DEVICE_ATTR_RO(auto_remove_on);
static ssize_t runtime_pm_show(struct device *dev,
struct device_attribute *attr, char *buf)
const struct device_attribute *attr, char *buf)
{
struct device_link *link = to_devlink(dev);
return sysfs_emit(buf, "%d\n", device_link_test(link, DL_FLAG_PM_RUNTIME));
}
static DEVICE_ATTR_RO(runtime_pm);
static const DEVICE_ATTR_RO(runtime_pm);
static ssize_t sync_state_only_show(struct device *dev,
struct device_attribute *attr, char *buf)
const struct device_attribute *attr, char *buf)
{
struct device_link *link = to_devlink(dev);
return sysfs_emit(buf, "%d\n", device_link_test(link, DL_FLAG_SYNC_STATE_ONLY));
}
static DEVICE_ATTR_RO(sync_state_only);
static const DEVICE_ATTR_RO(sync_state_only);
static struct attribute *devlink_attrs[] = {
static const struct attribute *const devlink_attrs[] = {
&dev_attr_status.attr,
&dev_attr_auto_remove_on.attr,
&dev_attr_runtime_pm.attr,
@@ -1011,7 +1084,7 @@ static void device_links_missing_supplier(struct device *dev)
static bool dev_is_best_effort(struct device *dev)
{
return (fw_devlink_best_effort && dev->can_match) ||
return (fw_devlink_best_effort && dev_can_match(dev)) ||
(dev->fwnode && fwnode_test_flag(dev->fwnode, FWNODE_FLAG_BEST_EFFORT));
}
@@ -1079,7 +1152,7 @@ int device_links_check_suppliers(struct device *dev)
if (dev_is_best_effort(dev) &&
device_link_test(link, DL_FLAG_INFERRED) &&
!link->supplier->can_match) {
!dev_can_match(link->supplier)) {
ret = -EAGAIN;
continue;
}
@@ -1123,7 +1196,7 @@ static void __device_links_queue_sync_state(struct device *dev,
if (!dev_has_sync_state(dev))
return;
if (dev->state_synced)
if (dev_state_synced(dev))
return;
list_for_each_entry(link, &dev->links.consumers, s_node) {
@@ -1138,7 +1211,7 @@ static void __device_links_queue_sync_state(struct device *dev,
* than once. This can happen if new consumers get added to the device
* and probed before the list is flushed.
*/
dev->state_synced = true;
dev_set_state_synced(dev);
if (WARN_ON(!list_empty(&dev->links.defer_sync)))
return;
@@ -1233,7 +1306,7 @@ static void device_link_drop_managed(struct device_link *link)
}
static ssize_t waiting_for_supplier_show(struct device *dev,
struct device_attribute *attr,
const struct device_attribute *attr,
char *buf)
{
bool val;
@@ -1244,7 +1317,7 @@ static ssize_t waiting_for_supplier_show(struct device *dev,
device_unlock(dev);
return sysfs_emit(buf, "%u\n", val);
}
static DEVICE_ATTR_RO(waiting_for_supplier);
static const DEVICE_ATTR_RO(waiting_for_supplier);
/**
* device_links_force_bind - Prepares device to be force bound
@@ -1312,16 +1385,8 @@ void device_links_driver_bound(struct device *dev)
* child firmware node.
*/
if (dev->fwnode && dev->fwnode->dev == dev) {
struct fwnode_handle *child;
fwnode_links_purge_suppliers(dev->fwnode);
guard(mutex)(&fwnode_link_lock);
fwnode_for_each_available_child_node(dev->fwnode, child)
__fw_devlink_pickup_dangling_consumers(child,
dev->fwnode);
__fw_devlink_link_to_consumers(dev);
fw_devlink_pickup_dangling_consumers(dev);
}
device_remove_file(dev, &dev_attr_waiting_for_supplier);
@@ -1370,7 +1435,7 @@ void device_links_driver_bound(struct device *dev)
} else if (dev_is_best_effort(dev) &&
device_link_test(link, DL_FLAG_INFERRED) &&
link->status != DL_STATE_CONSUMER_PROBE &&
!link->supplier->can_match) {
!dev_can_match(link->supplier)) {
/*
* When dev_is_best_effort() is true, we ignore device
* links to suppliers that don't have a driver. If the
@@ -1435,7 +1500,8 @@ static void __device_links_no_driver(struct device *dev)
if (link->supplier->links.status == DL_DEV_DRIVER_BOUND) {
WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
} else {
WARN_ON(!device_link_test(link, DL_FLAG_SYNC_STATE_ONLY));
WARN_ON(link->supplier->links.status != DL_DEV_UNBINDING &&
!device_link_test(link, DL_FLAG_SYNC_STATE_ONLY));
WRITE_ONCE(link->status, DL_STATE_DORMANT);
}
}
@@ -1758,7 +1824,7 @@ static int fw_devlink_no_driver(struct device *dev, void *data)
{
struct device_link *link = to_devlink(dev);
if (!link->supplier->can_match)
if (!dev_can_match(link->supplier))
fw_devlink_relax_link(link);
return 0;
@@ -1779,7 +1845,7 @@ static int fw_devlink_dev_sync_state(struct device *dev, void *data)
struct device *sup = link->supplier;
if (!device_link_test(link, DL_FLAG_MANAGED) ||
link->status == DL_STATE_ACTIVE || sup->state_synced ||
link->status == DL_STATE_ACTIVE || dev_state_synced(sup) ||
!dev_has_sync_state(sup))
return 0;
@@ -1793,7 +1859,7 @@ static int fw_devlink_dev_sync_state(struct device *dev, void *data)
return 0;
dev_warn(sup, "Timed out. Forcing sync_state()\n");
sup->state_synced = true;
dev_set_state_synced(sup);
get_device(sup);
list_add_tail(&sup->links.defer_sync, data);
@@ -2419,9 +2485,11 @@ static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
if (dev_attr->show)
ret = dev_attr->show(dev, dev_attr, buf);
else if (dev_attr->show_const)
ret = dev_attr->show_const(dev, dev_attr, buf);
if (ret >= (ssize_t)PAGE_SIZE) {
printk("dev_attr_show: %pS returned bad count\n",
dev_attr->show);
printk("dev_attr_show: %pS/%pS returned bad count\n",
dev_attr->show, dev_attr->show_const);
}
return ret;
}
@@ -2435,6 +2503,8 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr,
if (dev_attr->store)
ret = dev_attr->store(dev, dev_attr, buf, count);
else if (dev_attr->store_const)
ret = dev_attr->store_const(dev, dev_attr, buf, count);
return ret;
}
@@ -2722,7 +2792,7 @@ static const struct kset_uevent_ops device_uevent_ops = {
.uevent = dev_uevent,
};
static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
static ssize_t uevent_show(struct device *dev, const struct device_attribute *attr,
char *buf)
{
struct kobject *top_kobj;
@@ -2765,7 +2835,7 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
return len;
}
static ssize_t uevent_store(struct device *dev, struct device_attribute *attr,
static ssize_t uevent_store(struct device *dev, const struct device_attribute *attr,
const char *buf, size_t count)
{
int rc;
@@ -2779,20 +2849,20 @@ static ssize_t uevent_store(struct device *dev, struct device_attribute *attr,
return count;
}
static DEVICE_ATTR_RW(uevent);
static const DEVICE_ATTR_RW(uevent);
static ssize_t online_show(struct device *dev, struct device_attribute *attr,
static ssize_t online_show(struct device *dev, const struct device_attribute *attr,
char *buf)
{
bool val;
device_lock(dev);
val = !dev->offline;
val = !dev_offline(dev);
device_unlock(dev);
return sysfs_emit(buf, "%u\n", val);
}
static ssize_t online_store(struct device *dev, struct device_attribute *attr,
static ssize_t online_store(struct device *dev, const struct device_attribute *attr,
const char *buf, size_t count)
{
bool val;
@@ -2810,9 +2880,9 @@ static ssize_t online_store(struct device *dev, struct device_attribute *attr,
unlock_device_hotplug();
return ret < 0 ? ret : count;
}
static DEVICE_ATTR_RW(online);
static const DEVICE_ATTR_RW(online);
static ssize_t removable_show(struct device *dev, struct device_attribute *attr,
static ssize_t removable_show(struct device *dev, const struct device_attribute *attr,
char *buf)
{
const char *loc;
@@ -2829,7 +2899,7 @@ static ssize_t removable_show(struct device *dev, struct device_attribute *attr,
}
return sysfs_emit(buf, "%s\n", loc);
}
static DEVICE_ATTR_RO(removable);
static const DEVICE_ATTR_RO(removable);
int device_add_groups(struct device *dev,
const struct attribute_group *const *groups)
@@ -2913,7 +2983,7 @@ static int device_add_attrs(struct device *dev)
if (error)
goto err_remove_type_groups;
if (device_supports_offline(dev) && !dev->offline_disabled) {
if (device_supports_offline(dev) && !dev_offline_disabled(dev)) {
error = device_create_file(dev, &dev_attr_online);
if (error)
goto err_remove_dev_groups;
@@ -2980,12 +3050,12 @@ static void device_remove_attrs(struct device *dev)
device_remove_groups(dev, class->dev_groups);
}
static ssize_t dev_show(struct device *dev, struct device_attribute *attr,
static ssize_t dev_show(struct device *dev, const struct device_attribute *attr,
char *buf)
{
return print_dev_t(buf, dev->devt);
}
static DEVICE_ATTR_RO(dev);
static const DEVICE_ATTR_RO(dev);
/* /sys/devices/ */
struct kset *devices_kset;
@@ -3047,10 +3117,10 @@ int device_create_file(struct device *dev,
int error = 0;
if (dev) {
WARN(((attr->attr.mode & S_IWUGO) && !attr->store),
WARN(((attr->attr.mode & S_IWUGO) && !(attr->store || attr->store_const)),
"Attribute %s: write permission without 'store'\n",
attr->attr.name);
WARN(((attr->attr.mode & S_IRUGO) && !attr->show),
WARN(((attr->attr.mode & S_IRUGO) && !(attr->show || attr->show_const)),
"Attribute %s: read permission without 'show'\n",
attr->attr.name);
error = sysfs_create_file(&dev->kobj, &attr->attr);
@@ -3170,11 +3240,7 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD(&dev->links.suppliers);
INIT_LIST_HEAD(&dev->links.defer_sync);
dev->links.status = DL_DEV_NO_DRIVER;
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
dev->dma_coherent = dma_default_coherent;
#endif
dev_assign_dma_coherent(dev, dma_default_coherent);
swiotlb_dev_init(dev);
}
EXPORT_SYMBOL_GPL(device_initialize);
@@ -3710,7 +3776,7 @@ int device_add(struct device *dev)
* match with any driver, don't block its consumers from probing in
* case the consumer device is able to operate without this supplier.
*/
if (dev->fwnode && fw_devlink_drv_reg_done && !dev->can_match)
if (dev->fwnode && fw_devlink_drv_reg_done && !dev_can_match(dev))
fw_devlink_unblock_consumers(dev);
if (parent)
@@ -4180,7 +4246,7 @@ static int device_check_offline(struct device *dev, void *not_used)
if (ret)
return ret;
return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0;
return device_supports_offline(dev) && !dev_offline(dev) ? -EBUSY : 0;
}
/**
@@ -4198,7 +4264,7 @@ int device_offline(struct device *dev)
{
int ret;
if (dev->offline_disabled)
if (dev_offline_disabled(dev))
return -EPERM;
ret = device_for_each_child(dev, NULL, device_check_offline);
@@ -4207,13 +4273,13 @@ int device_offline(struct device *dev)
device_lock(dev);
if (device_supports_offline(dev)) {
if (dev->offline) {
if (dev_offline(dev)) {
ret = 1;
} else {
ret = dev->bus->offline(dev);
if (!ret) {
kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
dev->offline = true;
dev_set_offline(dev);
}
}
}
@@ -4238,11 +4304,11 @@ int device_online(struct device *dev)
device_lock(dev);
if (device_supports_offline(dev)) {
if (dev->offline) {
if (dev_offline(dev)) {
ret = dev->bus->online(dev);
if (!ret) {
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
dev->offline = false;
dev_clear_offline(dev);
}
} else {
ret = 1;
@@ -4716,7 +4782,7 @@ static int device_attrs_change_owner(struct device *dev, kuid_t kuid,
if (error)
return error;
if (device_supports_offline(dev) && !dev->offline_disabled) {
if (device_supports_offline(dev) && !dev_offline_disabled(dev)) {
/* Change online device attributes of @dev to @kuid/@kgid. */
error = sysfs_file_change_owner(kobj, dev_attr_online.attr.name,
kuid, kgid);
@@ -5283,7 +5349,7 @@ void device_set_of_node_from_dev(struct device *dev, const struct device *dev2)
{
of_node_put(dev->of_node);
dev->of_node = of_node_get(dev2->of_node);
dev->of_node_reused = true;
dev_set_of_node_reused(dev);
}
EXPORT_SYMBOL_GPL(device_set_of_node_from_dev);

View File

@@ -422,8 +422,8 @@ int register_cpu(struct cpu *cpu, int num)
cpu->dev.id = num;
cpu->dev.bus = &cpu_subsys;
cpu->dev.release = cpu_device_release;
cpu->dev.offline_disabled = !cpu->hotpluggable;
cpu->dev.offline = !cpu_online(num);
dev_assign_offline_disabled(&cpu->dev, !cpu->hotpluggable);
dev_assign_offline(&cpu->dev, !cpu_online(num));
cpu->dev.of_node = of_get_cpu_node(num, NULL);
cpu->dev.groups = common_cpu_attr_groups;
if (cpu->hotpluggable)

View File

@@ -132,7 +132,7 @@ static DECLARE_WORK(deferred_probe_work, deferred_probe_work_func);
void driver_deferred_probe_add(struct device *dev)
{
if (!dev->can_match)
if (!dev_can_match(dev))
return;
mutex_lock(&deferred_probe_mutex);
@@ -323,12 +323,11 @@ void deferred_probe_extend_timeout(void)
* If the work hasn't been queued yet or if the work expired, don't
* start a new one.
*/
if (cancel_delayed_work(&deferred_probe_timeout_work)) {
schedule_delayed_work(&deferred_probe_timeout_work,
driver_deferred_probe_timeout * HZ);
if (delayed_work_pending(&deferred_probe_timeout_work) &&
mod_delayed_work(system_percpu_wq, &deferred_probe_timeout_work,
secs_to_jiffies(driver_deferred_probe_timeout)))
pr_debug("Extended deferred probe timeout by %d secs\n",
driver_deferred_probe_timeout);
}
}
/**
@@ -569,12 +568,10 @@ static ssize_t state_synced_store(struct device *dev,
return -EINVAL;
device_lock(dev);
if (!dev->state_synced) {
dev->state_synced = true;
if (!dev_test_and_set_state_synced(dev))
dev_sync_state(dev);
} else {
else
ret = -EINVAL;
}
device_unlock(dev);
return ret ? ret : count;
@@ -586,7 +583,7 @@ static ssize_t state_synced_show(struct device *dev,
bool val;
device_lock(dev);
val = dev->state_synced;
val = dev_state_synced(dev);
device_unlock(dev);
return sysfs_emit(buf, "%u\n", val);
@@ -595,9 +592,9 @@ static DEVICE_ATTR_RW(state_synced);
static void device_unbind_cleanup(struct device *dev)
{
devres_release_all(dev);
if (dev->driver->p_cb.post_unbind_rust)
dev->driver->p_cb.post_unbind_rust(dev);
devres_release_all(dev);
arch_teardown_dma_ops(dev);
kfree(dev->dma_range_map);
dev->dma_range_map = NULL;
@@ -849,14 +846,14 @@ static int __driver_probe_device(const struct device_driver *drv, struct device
return dev_err_probe(dev, -EPROBE_DEFER, "Device not ready to probe\n");
/*
* Set can_match = true after calling dev_ready_to_probe(), so
* Call dev_set_can_match() after calling dev_ready_to_probe(), so
* driver_deferred_probe_add() won't actually add the device to the
* deferred probe list when dev_ready_to_probe() returns false.
*
* When dev_ready_to_probe() returns false, it means that device_add()
* will do another probe() attempt for us.
*/
dev->can_match = true;
dev_set_can_match(dev);
dev_dbg(dev, "bus: '%s': %s: matched device with driver %s\n",
drv->bus->name, __func__, drv->name);
@@ -1002,7 +999,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
return 0;
} else if (ret == -EPROBE_DEFER) {
dev_dbg(dev, "Device match requests probe deferral\n");
dev->can_match = true;
dev_set_can_match(dev);
driver_deferred_probe_add(dev);
/*
* Device can't match with a driver right now, so don't attempt
@@ -1254,7 +1251,7 @@ static int __driver_attach(struct device *dev, void *data)
return 0;
} else if (ret == -EPROBE_DEFER) {
dev_dbg(dev, "Device match requests probe deferral\n");
dev->can_match = true;
dev_set_can_match(dev);
driver_deferred_probe_add(dev);
/*
* Driver could not match with device, but may match with

View File

@@ -471,10 +471,3 @@ static int __init devcoredump_init(void)
return class_register(&devcd_class);
}
__initcall(devcoredump_init);
static void __exit devcoredump_exit(void)
{
class_for_each_device(&devcd_class, NULL, NULL, devcd_free);
class_unregister(&devcd_class);
}
__exitcall(devcoredump_exit);

View File

@@ -30,81 +30,6 @@ static struct device *next_device(struct klist_iter *i)
return dev;
}
/**
* driver_set_override() - Helper to set or clear driver override.
* @dev: Device to change
* @override: Address of string to change (e.g. &device->driver_override);
* The contents will be freed and hold newly allocated override.
* @s: NUL-terminated string, new driver name to force a match, pass empty
* string to clear it ("" or "\n", where the latter is only for sysfs
* interface).
* @len: length of @s
*
* Helper to set or clear driver override in a device, intended for the cases
* when the driver_override field is allocated by driver/bus code.
*
* Returns: 0 on success or a negative error code on failure.
*/
int driver_set_override(struct device *dev, const char **override,
const char *s, size_t len)
{
const char *new, *old;
char *cp;
if (!override || !s)
return -EINVAL;
/*
* The stored value will be used in sysfs show callback (sysfs_emit()),
* which has a length limit of PAGE_SIZE and adds a trailing newline.
* Thus we can store one character less to avoid truncation during sysfs
* show.
*/
if (len >= (PAGE_SIZE - 1))
return -EINVAL;
/*
* Compute the real length of the string in case userspace sends us a
* bunch of \0 characters like python likes to do.
*/
len = strlen(s);
if (!len) {
/* Empty string passed - clear override */
device_lock(dev);
old = *override;
*override = NULL;
device_unlock(dev);
kfree(old);
return 0;
}
cp = strnchr(s, len, '\n');
if (cp)
len = cp - s;
new = kstrndup(s, len, GFP_KERNEL);
if (!new)
return -ENOMEM;
device_lock(dev);
old = *override;
if (cp != s) {
*override = new;
} else {
/* "\n" passed - clear override */
kfree(new);
*override = NULL;
}
device_unlock(dev);
kfree(old);
return 0;
}
EXPORT_SYMBOL_GPL(driver_set_override);
/**
* driver_for_each_device - Iterator for devices bound to a driver.
* @drv: Driver we're iterating.
@@ -203,13 +128,13 @@ void driver_remove_file(const struct device_driver *drv,
EXPORT_SYMBOL_GPL(driver_remove_file);
int driver_add_groups(const struct device_driver *drv,
const struct attribute_group **groups)
const struct attribute_group *const *groups)
{
return sysfs_create_groups(&drv->p->kobj, groups);
}
void driver_remove_groups(const struct device_driver *drv,
const struct attribute_group **groups)
const struct attribute_group *const *groups)
{
sysfs_remove_groups(&drv->p->kobj, groups);
}

View File

@@ -133,6 +133,9 @@ struct faux_device *faux_device_create_with_groups(const char *name,
struct device *dev;
int ret;
if (!faux_bus_root)
return NULL;
faux_obj = kzalloc_obj(*faux_obj);
if (!faux_obj)
return NULL;
@@ -232,34 +235,29 @@ EXPORT_SYMBOL_GPL(faux_device_destroy);
int __init faux_bus_init(void)
{
struct device *root;
int ret;
faux_bus_root = kzalloc_obj(*faux_bus_root);
if (!faux_bus_root)
return -ENOMEM;
dev_set_name(faux_bus_root, "faux");
ret = device_register(faux_bus_root);
if (ret) {
put_device(faux_bus_root);
return ret;
}
root = root_device_register("faux");
if (IS_ERR(root))
return PTR_ERR(root);
ret = bus_register(&faux_bus_type);
if (ret)
goto error_bus;
goto err_deregister_root;
ret = driver_register(&faux_driver);
if (ret)
goto error_driver;
goto err_deregister_bus;
return ret;
faux_bus_root = root;
error_driver:
return 0;
err_deregister_bus:
bus_unregister(&faux_bus_type);
err_deregister_root:
root_device_unregister(root);
error_bus:
device_unregister(faux_bus_root);
return ret;
}

View File

@@ -1503,9 +1503,10 @@ static void device_cache_fw_images(void)
mutex_lock(&fw_lock);
fwc->state = FW_LOADER_START_CACHE;
dpm_for_each_dev(NULL, dev_cache_fw_image);
mutex_unlock(&fw_lock);
dpm_for_each_dev(NULL, dev_cache_fw_image);
/* wait for completion of caching firmware for all devices */
async_synchronize_full_domain(&fw_cache_domain);

View File

@@ -343,7 +343,6 @@ firmware_upload_register(struct module *module, struct device *parent,
goto free_fw_upload_priv;
}
fw_upload->priv = fw_sysfs;
fw_sysfs->fw_upload_priv = fw_upload_priv;
fw_dev = &fw_sysfs->dev;
ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, NULL, 0, 0,
@@ -351,10 +350,12 @@ firmware_upload_register(struct module *module, struct device *parent,
if (ret != 0) {
if (ret > 0)
ret = -EINVAL;
goto free_fw_sysfs;
put_device(fw_dev);
goto free_fw_upload_priv;
}
fw_priv->is_paged_buf = true;
fw_sysfs->fw_priv = fw_priv;
fw_sysfs->fw_upload_priv = fw_upload_priv;
ret = device_add(fw_dev);
if (ret) {
@@ -365,9 +366,6 @@ firmware_upload_register(struct module *module, struct device *parent,
return fw_upload;
free_fw_sysfs:
kfree(fw_sysfs);
free_fw_upload_priv:
kfree(fw_upload_priv);

View File

@@ -11,9 +11,7 @@
#include <linux/dma-mapping.h>
#include <linux/isa.h>
static struct device isa_bus = {
.init_name = "isa"
};
static struct device *isa_bus;
struct isa_dev {
struct device dev;
@@ -131,7 +129,7 @@ int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev)
break;
}
isa_dev->dev.parent = &isa_bus;
isa_dev->dev.parent = isa_bus;
isa_dev->dev.bus = &isa_bus_type;
dev_set_name(&isa_dev->dev, "%s.%u",
@@ -169,9 +167,11 @@ static int __init isa_bus_init(void)
error = bus_register(&isa_bus_type);
if (!error) {
error = device_register(&isa_bus);
if (error)
isa_bus = root_device_register("isa");
if (IS_ERR(isa_bus)) {
error = PTR_ERR(isa_bus);
bus_unregister(&isa_bus_type);
}
}
return error;
}

View File

@@ -697,7 +697,7 @@ static int __add_memory_block(struct memory_block *memory)
memory->dev.id = memory->start_section_nr / sections_per_block;
memory->dev.release = memory_block_release;
memory->dev.groups = memory_memblk_attr_groups;
memory->dev.offline = memory->state == MEM_OFFLINE;
dev_assign_offline(&memory->dev, memory->state == MEM_OFFLINE);
ret = device_register(&memory->dev);
if (ret) {

View File

@@ -24,7 +24,7 @@ int pinctrl_bind_pins(struct device *dev)
{
int ret;
if (dev->of_node_reused)
if (dev_of_node_reused(dev))
return 0;
dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);

View File

@@ -870,7 +870,7 @@ struct platform_device *platform_device_register_full(const struct platform_devi
pdev->dev.parent = pdevinfo->parent;
pdev->dev.fwnode = pdevinfo->fwnode;
pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode));
pdev->dev.of_node_reused = pdevinfo->of_node_reused;
dev_assign_of_node_reused(&pdev->dev, pdevinfo->of_node_reused);
if (pdevinfo->dma_mask) {
pdev->platform_dma_mask = pdevinfo->dma_mask;
@@ -915,11 +915,14 @@ EXPORT_SYMBOL_GPL(platform_device_register_full);
* __platform_driver_register - register a driver for platform-level devices
* @drv: platform driver structure
* @owner: owning module/driver
* @mod_name: module name string
*/
int __platform_driver_register(struct platform_driver *drv, struct module *owner)
int __platform_driver_register(struct platform_driver *drv, struct module *owner,
const char *mod_name)
{
drv->driver.owner = owner;
drv->driver.bus = &platform_bus_type;
drv->driver.mod_name = mod_name;
return driver_register(&drv->driver);
}
@@ -952,6 +955,7 @@ static int is_bound_to_driver(struct device *dev, void *driver)
* @drv: platform driver structure
* @probe: the driver probe routine, probably from an __init section
* @module: module which will be the owner of the driver
* @mod_name: module name string
*
* Use this instead of platform_driver_register() when you know the device
* is not hotpluggable and has already been registered, and you want to
@@ -969,7 +973,8 @@ static int is_bound_to_driver(struct device *dev, void *driver)
*/
int __init_or_module __platform_driver_probe(struct platform_driver *drv,
int (*probe)(struct platform_device *),
struct module *module)
struct module *module,
const char *mod_name)
{
int retval;
@@ -997,7 +1002,7 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv,
/* temporary section violation during probe() */
drv->probe = probe;
retval = __platform_driver_register(drv, module);
retval = __platform_driver_register(drv, module, mod_name);
if (retval)
return retval;
@@ -1025,6 +1030,7 @@ EXPORT_SYMBOL_GPL(__platform_driver_probe);
* @data: platform specific data for this platform device
* @size: size of platform specific data
* @module: module which will be the owner of the driver
* @mod_name: module name string
*
* Use this in legacy-style modules that probe hardware directly and
* register a single platform device and corresponding platform driver.
@@ -1035,7 +1041,7 @@ struct platform_device * __init_or_module
__platform_create_bundle(struct platform_driver *driver,
int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
const void *data, size_t size, struct module *module)
const void *data, size_t size, struct module *module, const char *mod_name)
{
struct platform_device *pdev;
int error;
@@ -1058,7 +1064,7 @@ __platform_create_bundle(struct platform_driver *driver,
if (error)
goto err_pdev_put;
error = __platform_driver_probe(driver, probe, module);
error = __platform_driver_probe(driver, probe, module, mod_name);
if (error)
goto err_pdev_del;
@@ -1078,6 +1084,7 @@ EXPORT_SYMBOL_GPL(__platform_create_bundle);
* @drivers: an array of drivers to register
* @count: the number of drivers to register
* @owner: module owning the drivers
* @mod_name: module name string
*
* Registers platform drivers specified by an array. On failure to register a
* driver, all previously registered drivers will be unregistered. Callers of
@@ -1087,7 +1094,7 @@ EXPORT_SYMBOL_GPL(__platform_create_bundle);
* Returns: 0 on success or a negative error code on failure.
*/
int __platform_register_drivers(struct platform_driver * const *drivers,
unsigned int count, struct module *owner)
unsigned int count, struct module *owner, const char *mod_name)
{
unsigned int i;
int err;
@@ -1095,7 +1102,7 @@ int __platform_register_drivers(struct platform_driver * const *drivers,
for (i = 0; i < count; i++) {
pr_debug("registering platform driver %ps\n", drivers[i]);
err = __platform_driver_register(drivers[i], owner);
err = __platform_driver_register(drivers[i], owner, mod_name);
if (err < 0) {
pr_err("failed to register platform driver %ps: %d\n",
drivers[i], err);

View File

@@ -1277,8 +1277,10 @@ fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
if (fwnode_ep.port != port)
continue;
if (fwnode_ep.id == endpoint)
if (fwnode_ep.id == endpoint) {
fwnode_handle_put(best_ep);
return ep;
}
if (!endpoint_next)
continue;

View File

@@ -374,20 +374,28 @@ EXPORT_SYMBOL_GPL(property_entries_free);
/* -------------------------------------------------------------------------- */
/* fwnode operations */
static struct swnode *swnode_get(struct swnode *swnode)
{
kobject_get(&swnode->kobj);
return swnode;
}
static void swnode_put(struct swnode *swnode)
{
kobject_put(&swnode->kobj);
}
static struct fwnode_handle *software_node_get(struct fwnode_handle *fwnode)
{
struct swnode *swnode = to_swnode(fwnode);
kobject_get(&swnode->kobj);
struct swnode *swnode = swnode_get(to_swnode(fwnode));
return &swnode->fwnode;
}
static void software_node_put(struct fwnode_handle *fwnode)
{
struct swnode *swnode = to_swnode(fwnode);
kobject_put(&swnode->kobj);
swnode_put(to_swnode(fwnode));
}
static bool software_node_property_present(const struct fwnode_handle *fwnode,
@@ -493,7 +501,7 @@ software_node_get_named_child_node(const struct fwnode_handle *fwnode,
list_for_each_entry(child, &swnode->children, entry) {
if (!strcmp(childname, kobject_name(&child->kobj))) {
kobject_get(&child->kobj);
swnode_get(child);
return &child->fwnode;
}
}
@@ -737,7 +745,7 @@ software_node_find_by_name(const struct software_node *parent, const char *name)
swnode = kobj_to_swnode(k);
if (parent == swnode->node->parent && swnode->node->name &&
!strcmp(name, swnode->node->name)) {
kobject_get(&swnode->kobj);
swnode_get(swnode);
break;
}
swnode = NULL;
@@ -835,13 +843,13 @@ swnode_register(const struct software_node *node, struct swnode *parent,
parent ? &parent->kobj : NULL,
"node%d", swnode->id);
if (ret) {
kobject_put(&swnode->kobj);
swnode_put(swnode);
return ERR_PTR(ret);
}
/*
* Assign the flag only in the successful case, so
* the above kobject_put() won't mess up with properties.
* the above swnode_put() won't mess up with properties.
*/
swnode->allocated = allocated;
@@ -978,7 +986,7 @@ void fwnode_remove_software_node(struct fwnode_handle *fwnode)
if (!swnode)
return;
kobject_put(&swnode->kobj);
swnode_put(swnode);
}
EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
@@ -1002,7 +1010,7 @@ int device_add_software_node(struct device *dev, const struct software_node *nod
swnode = software_node_to_swnode(node);
if (swnode) {
kobject_get(&swnode->kobj);
swnode_get(swnode);
} else {
ret = software_node_register(node);
if (ret)
@@ -1044,7 +1052,7 @@ void device_remove_software_node(struct device *dev)
software_node_notify_remove(dev);
set_secondary_fwnode(dev, NULL);
kobject_put(&swnode->kobj);
swnode_put(swnode);
}
EXPORT_SYMBOL_GPL(device_remove_software_node);
@@ -1097,7 +1105,7 @@ void software_node_notify(struct device *dev)
if (!swnode)
return;
kobject_get(&swnode->kobj);
swnode_get(swnode);
ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
if (ret)
return;
@@ -1119,11 +1127,11 @@ void software_node_notify_remove(struct device *dev)
sysfs_remove_link(&swnode->kobj, dev_name(dev));
sysfs_remove_link(&dev->kobj, "software_node");
kobject_put(&swnode->kobj);
swnode_put(swnode);
if (swnode->managed) {
set_secondary_fwnode(dev, NULL);
kobject_put(&swnode->kobj);
swnode_put(swnode);
}
}

View File

@@ -327,12 +327,6 @@ static int of_weim_notify(struct notifier_block *nb, unsigned long action,
"Failed to setup timing for '%pOF'\n", rd->dn);
if (!of_node_check_flag(rd->dn, OF_POPULATED)) {
/*
* Clear the flag before adding the device so that
* fw_devlink doesn't skip adding consumers to this
* device.
*/
fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE);
if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) {
dev_err(&pdev->dev,
"Failed to create child device '%pOF'\n",

View File

@@ -156,8 +156,6 @@ static int cdx_unregister_device(struct device *dev,
} else {
cdx_destroy_res_attr(cdx_dev, MAX_CDX_DEV_RESOURCES);
debugfs_remove_recursive(cdx_dev->debugfs_dir);
kfree(cdx_dev->driver_override);
cdx_dev->driver_override = NULL;
}
/*
@@ -268,6 +266,7 @@ static int cdx_bus_match(struct device *dev, const struct device_driver *drv)
const struct cdx_driver *cdx_drv = to_cdx_driver(drv);
const struct cdx_device_id *found_id = NULL;
const struct cdx_device_id *ids;
int ret;
if (cdx_dev->is_bus)
return false;
@@ -275,7 +274,8 @@ static int cdx_bus_match(struct device *dev, const struct device_driver *drv)
ids = cdx_drv->match_id_table;
/* When driver_override is set, only bind to the matching driver */
if (cdx_dev->driver_override && strcmp(cdx_dev->driver_override, drv->name))
ret = device_match_driver_override(dev, drv);
if (ret == 0)
return false;
found_id = cdx_match_id(ids, cdx_dev);
@@ -289,7 +289,7 @@ static int cdx_bus_match(struct device *dev, const struct device_driver *drv)
*/
if (!found_id->override_only)
return true;
if (cdx_dev->driver_override)
if (ret > 0)
return true;
ids = found_id + 1;
@@ -453,36 +453,6 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(modalias);
static ssize_t driver_override_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct cdx_device *cdx_dev = to_cdx_device(dev);
int ret;
if (WARN_ON(dev->bus != &cdx_bus_type))
return -EINVAL;
ret = driver_set_override(dev, &cdx_dev->driver_override, buf, count);
if (ret)
return ret;
return count;
}
static ssize_t driver_override_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct cdx_device *cdx_dev = to_cdx_device(dev);
ssize_t len;
device_lock(dev);
len = sysfs_emit(buf, "%s\n", cdx_dev->driver_override);
device_unlock(dev);
return len;
}
static DEVICE_ATTR_RW(driver_override);
static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -552,7 +522,6 @@ static struct attribute *cdx_dev_attrs[] = {
&dev_attr_class.attr,
&dev_attr_revision.attr,
&dev_attr_modalias.attr,
&dev_attr_driver_override.attr,
NULL,
};
@@ -646,6 +615,7 @@ ATTRIBUTE_GROUPS(cdx_bus);
const struct bus_type cdx_bus_type = {
.name = "cdx",
.driver_override = true,
.match = cdx_bus_match,
.probe = cdx_probe,
.remove = cdx_remove,

View File

@@ -201,12 +201,13 @@ fn register_em(policy: &mut cpufreq::Policy) {
impl platform::Driver for CPUFreqDTDriver {
type IdInfo = ();
type Data<'bound> = Self;
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
fn probe(
pdev: &platform::Device<Core>,
_id_info: Option<&Self::IdInfo>,
) -> impl PinInit<Self, Error> {
fn probe<'bound>(
pdev: &'bound platform::Device<Core<'_>>,
_id_info: Option<&'bound Self::IdInfo>,
) -> impl PinInit<Self, Error> + 'bound {
cpufreq::Registration::<CPUFreqDTDriver>::new_foreign_owned(pdev.as_ref())?;
Ok(Self {})
}

View File

@@ -17,7 +17,13 @@
#include <linux/list.h>
#include <linux/of.h>
static struct class *devfreq_event_class;
static struct attribute *devfreq_event_attrs[];
ATTRIBUTE_GROUPS(devfreq_event);
static const struct class devfreq_event_class = {
.name = "devfreq-event",
.dev_groups = devfreq_event_groups
};
/* The list of all devfreq event list */
static LIST_HEAD(devfreq_event_list);
@@ -321,7 +327,7 @@ struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
edev->desc = desc;
edev->enable_count = 0;
edev->dev.parent = dev;
edev->dev.class = devfreq_event_class;
edev->dev.class = &devfreq_event_class;
edev->dev.release = devfreq_event_release_edev;
dev_set_name(&edev->dev, "event%d", atomic_inc_return(&event_no));
@@ -461,18 +467,15 @@ static struct attribute *devfreq_event_attrs[] = {
&dev_attr_enable_count.attr,
NULL,
};
ATTRIBUTE_GROUPS(devfreq_event);
static int __init devfreq_event_init(void)
{
devfreq_event_class = class_create("devfreq-event");
if (IS_ERR(devfreq_event_class)) {
int err;
err = class_register(&devfreq_event_class);
if (err)
pr_err("%s: couldn't create class\n", __FILE__);
return PTR_ERR(devfreq_event_class);
}
devfreq_event_class->dev_groups = devfreq_event_groups;
return 0;
return err;
}
subsys_initcall(devfreq_event_init);

View File

@@ -312,7 +312,7 @@ k3_udma_glue_request_tx_chn_common(struct device *dev,
if (xudma_is_pktdma(tx_chn->common.udmax)) {
/* prepare the channel device as coherent */
tx_chn->common.chan_dev.dma_coherent = true;
dev_set_dma_coherent(&tx_chn->common.chan_dev);
dma_coerce_mask_and_coherent(&tx_chn->common.chan_dev,
DMA_BIT_MASK(48));
}
@@ -1003,7 +1003,7 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name,
if (xudma_is_pktdma(rx_chn->common.udmax)) {
/* prepare the channel device as coherent */
rx_chn->common.chan_dev.dma_coherent = true;
dev_set_dma_coherent(&rx_chn->common.chan_dev);
dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev,
DMA_BIT_MASK(48));
}
@@ -1104,7 +1104,7 @@ k3_udma_glue_request_remote_rx_chn_common(struct k3_udma_glue_rx_channel *rx_chn
if (xudma_is_pktdma(rx_chn->common.udmax)) {
/* prepare the channel device as coherent */
rx_chn->common.chan_dev.dma_coherent = true;
dev_set_dma_coherent(&rx_chn->common.chan_dev);
dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev,
DMA_BIT_MASK(48));
rx_chn->single_fdq = false;

View File

@@ -428,18 +428,18 @@ static void k3_configure_chan_coherency(struct dma_chan *chan, u32 asel)
/* No special handling for the channel */
chan->dev->chan_dma_dev = false;
chan_dev->dma_coherent = false;
dev_clear_dma_coherent(chan_dev);
chan_dev->dma_parms = NULL;
} else if (asel == 14 || asel == 15) {
chan->dev->chan_dma_dev = true;
chan_dev->dma_coherent = true;
dev_set_dma_coherent(chan_dev);
dma_coerce_mask_and_coherent(chan_dev, DMA_BIT_MASK(48));
chan_dev->dma_parms = chan_dev->parent->dma_parms;
} else {
dev_warn(chan->device->dev, "Invalid ASEL value: %u\n", asel);
chan_dev->dma_coherent = false;
dev_clear_dma_coherent(chan_dev);
chan_dev->dma_parms = NULL;
}
}

View File

@@ -51,9 +51,13 @@ pub(crate) struct NovaData {
impl auxiliary::Driver for NovaDriver {
type IdInfo = ();
type Data<'bound> = Self;
const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;
fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
fn probe<'bound>(
adev: &'bound auxiliary::Device<Core<'_>>,
_info: &'bound Self::IdInfo,
) -> impl PinInit<Self, Error> + 'bound {
let data = try_pin_init!(NovaData { adev: adev.into() });
let drm = drm::Device::<Self>::new(adev.as_ref(), data)?;

View File

@@ -37,7 +37,7 @@
regs, //
};
pub(crate) type IoMem = kernel::io::mem::IoMem<SZ_2M>;
pub(crate) type IoMem = kernel::io::mem::IoMem<'static, SZ_2M>;
pub(crate) struct TyrDrmDriver;
@@ -91,12 +91,13 @@ fn issue_soft_reset(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> Result {
impl platform::Driver for TyrPlatformDriverData {
type IdInfo = ();
type Data<'bound> = Self;
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
fn probe(
pdev: &platform::Device<Core>,
_info: Option<&Self::IdInfo>,
) -> impl PinInit<Self, Error> {
fn probe<'bound>(
pdev: &'bound platform::Device<Core<'_>>,
_info: Option<&'bound Self::IdInfo>,
) -> impl PinInit<Self, Error> + 'bound {
let core_clk = Clk::get(pdev.as_ref(), Some(c"core"))?;
let stacks_clk = OptionalClk::get(pdev.as_ref(), Some(c"stacks"))?;
let coregroup_clk = OptionalClk::get(pdev.as_ref(), Some(c"coregroup"))?;
@@ -109,7 +110,7 @@ fn probe(
let sram_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"sram")?;
let request = pdev.io_request_by_index(0).ok_or(ENODEV)?;
let iomem = Arc::pin_init(request.iomap_sized::<SZ_2M>(), GFP_KERNEL)?;
let iomem = Arc::new(request.iomap_sized::<SZ_2M>()?.into_devres()?, GFP_KERNEL)?;
issue_soft_reset(pdev.as_ref(), &iomem)?;
gpu::l2_power_on(pdev.as_ref(), &iomem)?;

View File

@@ -3,7 +3,6 @@
use kernel::{
auxiliary,
device::Core,
devres::Devres,
dma::Device,
dma::DmaMask,
pci,
@@ -21,6 +20,7 @@
},
Arc,
},
types::ForLt,
};
use crate::gpu::Gpu;
@@ -29,13 +29,15 @@
static AUXILIARY_ID_COUNTER: Atomic<u32> = Atomic::new(0);
#[pin_data]
pub(crate) struct NovaCore {
pub(crate) struct NovaCore<'bound> {
#[pin]
pub(crate) gpu: Gpu,
#[pin]
_reg: Devres<auxiliary::Registration>,
#[allow(clippy::type_complexity)]
_reg: auxiliary::Registration<'bound, ForLt!(())>,
}
pub(crate) struct NovaCoreDriver;
const BAR0_SIZE: usize = SZ_16M;
// For now we only support Ampere which can use up to 47-bit DMA addresses.
@@ -46,12 +48,12 @@ pub(crate) struct NovaCore {
// DMA addresses. These systems should be quite rare.
const GPU_DMA_BITS: u32 = 47;
pub(crate) type Bar0 = pci::Bar<BAR0_SIZE>;
pub(crate) type Bar0 = pci::Bar<'static, BAR0_SIZE>;
kernel::pci_device_table!(
PCI_TABLE,
MODULE_PCI_TABLE,
<NovaCore as pci::Driver>::IdInfo,
<NovaCoreDriver as pci::Driver>::IdInfo,
[
// Modern NVIDIA GPUs will show up as either VGA or 3D controllers.
(
@@ -73,11 +75,15 @@ pub(crate) struct NovaCore {
]
);
impl pci::Driver for NovaCore {
impl pci::Driver for NovaCoreDriver {
type IdInfo = ();
type Data<'bound> = NovaCore<'bound>;
const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
fn probe<'bound>(
pdev: &'bound pci::Device<Core<'_>>,
_info: &'bound Self::IdInfo,
) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
pin_init::pin_init_scope(move || {
dev_dbg!(pdev, "Probe Nova Core GPU driver.\n");
@@ -89,26 +95,28 @@ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, E
// other threads of execution.
unsafe { pdev.dma_set_mask_and_coherent(DmaMask::new::<GPU_DMA_BITS>())? };
let bar = Arc::pin_init(
pdev.iomap_region_sized::<BAR0_SIZE>(0, c"nova-core/bar0"),
let bar = Arc::new(
pdev.iomap_region_sized::<BAR0_SIZE>(0, c"nova-core/bar0")?
.into_devres()?,
GFP_KERNEL,
)?;
Ok(try_pin_init!(Self {
Ok(try_pin_init!(NovaCore {
gpu <- Gpu::new(pdev, bar.clone(), bar.access(pdev.as_ref())?),
_reg <- auxiliary::Registration::new(
_reg: auxiliary::Registration::new(
pdev.as_ref(),
c"nova-drm",
// TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling. For
// now, use a simple atomic counter that never recycles IDs.
AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
crate::MODULE_NAME
),
crate::MODULE_NAME,
(),
)?,
}))
})
}
fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
fn unbind<'bound>(pdev: &'bound pci::Device<Core<'_>>, this: Pin<&Self::Data<'bound>>) {
this.gpu.unbind(pdev.as_ref());
}
}

View File

@@ -278,7 +278,7 @@ pub(crate) fn new<'a>(
/// Called when the corresponding [`Device`](device::Device) is unbound.
///
/// Note: This method must only be called from `Driver::unbind`.
pub(crate) fn unbind(&self, dev: &device::Device<device::Core>) {
pub(crate) fn unbind(&self, dev: &device::Device<device::Core<'_>>) {
kernel::warn_on!(self
.bar
.access(dev)

View File

@@ -47,7 +47,7 @@ struct NovaCoreModule {
// Fields are dropped in declaration order, so `_driver` is dropped first,
// then `_debugfs_guard` clears `DEBUGFS_ROOT`.
#[pin]
_driver: Registration<pci::Adapter<driver::NovaCore>>,
_driver: Registration<pci::Adapter<driver::NovaCoreDriver>>,
_debugfs_guard: DebugfsRootGuard,
}

View File

@@ -548,34 +548,6 @@ static ssize_t device_show(struct device *dev,
}
static DEVICE_ATTR_RO(device);
static ssize_t driver_override_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct hv_device *hv_dev = device_to_hv_device(dev);
int ret;
ret = driver_set_override(dev, &hv_dev->driver_override, buf, count);
if (ret)
return ret;
return count;
}
static ssize_t driver_override_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct hv_device *hv_dev = device_to_hv_device(dev);
ssize_t len;
device_lock(dev);
len = sysfs_emit(buf, "%s\n", hv_dev->driver_override);
device_unlock(dev);
return len;
}
static DEVICE_ATTR_RW(driver_override);
/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
static struct attribute *vmbus_dev_attrs[] = {
&dev_attr_id.attr,
@@ -606,7 +578,6 @@ static struct attribute *vmbus_dev_attrs[] = {
&dev_attr_channel_vp_mapping.attr,
&dev_attr_vendor.attr,
&dev_attr_device.attr,
&dev_attr_driver_override.attr,
NULL,
};
@@ -718,9 +689,11 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id(const struct hv_driver *
{
const guid_t *guid = &dev->dev_type;
const struct hv_vmbus_device_id *id;
int ret;
/* When driver_override is set, only bind to the matching driver */
if (dev->driver_override && strcmp(dev->driver_override, drv->name))
/* If a driver override is set, only bind to the matching driver */
ret = device_match_driver_override(&dev->device, &drv->driver);
if (ret == 0)
return NULL;
/* Look at the dynamic ids first, before the static ones */
@@ -728,8 +701,11 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id(const struct hv_driver *
if (!id)
id = hv_vmbus_dev_match(drv->id_table, guid);
/* driver_override will always match, send a dummy id */
if (!id && dev->driver_override)
/*
* If there's a matching driver override, this function should succeed,
* thus return a dummy device ID if no matching ID is found.
*/
if (!id && ret > 0)
id = &vmbus_device_null;
return id;
@@ -1031,6 +1007,7 @@ static const struct dev_pm_ops vmbus_pm = {
/* The one and only one */
static const struct bus_type hv_bus = {
.name = "vmbus",
.driver_override = true,
.match = vmbus_match,
.shutdown = vmbus_shutdown,
.remove = vmbus_remove,

View File

@@ -706,7 +706,7 @@ static int __init catu_init(void)
{
int ret;
ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver, THIS_MODULE);
ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver);
tmc_etr_set_catu_ops(&etr_catu_buf_ops);
return ret;
}

View File

@@ -1694,8 +1694,9 @@ static void __exit coresight_exit(void)
module_init(coresight_init);
module_exit(coresight_exit);
int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
struct platform_driver *pdev_drv, struct module *owner)
int coresight_init_driver_with_owner(const char *drv, struct amba_driver *amba_drv,
struct platform_driver *pdev_drv, struct module *owner,
const char *mod_name)
{
int ret;
@@ -1705,7 +1706,7 @@ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
return ret;
}
ret = __platform_driver_register(pdev_drv, owner);
ret = __platform_driver_register(pdev_drv, owner, mod_name);
if (!ret)
return 0;
@@ -1713,7 +1714,7 @@ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
amba_driver_unregister(amba_drv);
return ret;
}
EXPORT_SYMBOL_GPL(coresight_init_driver);
EXPORT_SYMBOL_GPL(coresight_init_driver_with_owner);
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv)

View File

@@ -757,8 +757,7 @@ static struct platform_driver debug_platform_driver = {
static int __init debug_init(void)
{
return coresight_init_driver("debug", &debug_driver, &debug_platform_driver,
THIS_MODULE);
return coresight_init_driver("debug", &debug_driver, &debug_platform_driver);
}
static void __exit debug_exit(void)

View File

@@ -412,8 +412,7 @@ static struct amba_driver dynamic_funnel_driver = {
static int __init funnel_init(void)
{
return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver,
THIS_MODULE);
return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver);
}
static void __exit funnel_exit(void)

View File

@@ -418,8 +418,7 @@ static struct amba_driver dynamic_replicator_driver = {
static int __init replicator_init(void)
{
return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver,
THIS_MODULE);
return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver);
}
static void __exit replicator_exit(void)

View File

@@ -1050,7 +1050,7 @@ static struct platform_driver stm_platform_driver = {
static int __init stm_init(void)
{
return coresight_init_driver("stm", &stm_driver, &stm_platform_driver, THIS_MODULE);
return coresight_init_driver("stm", &stm_driver, &stm_platform_driver);
}
static void __exit stm_exit(void)

View File

@@ -1046,7 +1046,7 @@ static struct platform_driver tmc_platform_driver = {
static int __init tmc_init(void)
{
return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver, THIS_MODULE);
return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver);
}
static void __exit tmc_exit(void)

View File

@@ -344,7 +344,7 @@ static struct platform_driver itnoc_driver = {
static int __init tnoc_init(void)
{
return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver, THIS_MODULE);
return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver);
}
static void __exit tnoc_exit(void)

View File

@@ -1563,8 +1563,7 @@ static struct platform_driver static_tpdm_driver = {
static int __init tpdm_init(void)
{
return coresight_init_driver("tpdm", &dynamic_tpdm_driver, &static_tpdm_driver,
THIS_MODULE);
return coresight_init_driver("tpdm", &dynamic_tpdm_driver, &static_tpdm_driver);
}
static void __exit tpdm_exit(void)

View File

@@ -310,7 +310,7 @@ static struct platform_driver tpiu_platform_driver = {
static int __init tpiu_init(void)
{
return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver, THIS_MODULE);
return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver);
}
static void __exit tpiu_exit(void)

View File

@@ -176,11 +176,6 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
return NOTIFY_OK;
}
/*
* Clear the flag before adding the device so that fw_devlink
* doesn't skip adding consumers to this device.
*/
fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE);
client = of_i2c_register_device(adap, rd->dn);
if (IS_ERR(client)) {
dev_err(&adap->dev, "failed to create client for '%pOF'\n",

View File

@@ -2149,18 +2149,21 @@ EXPORT_SYMBOL_GPL(dma_iova_destroy);
void iommu_setup_dma_ops(struct device *dev, struct iommu_domain *domain)
{
bool dma_iommu;
if (dev_is_pci(dev))
dev->iommu->pci_32bit_workaround = !iommu_dma_forcedac;
dev->dma_iommu = iommu_is_dma_domain(domain);
if (dev->dma_iommu && iommu_dma_init_domain(domain, dev))
dma_iommu = iommu_is_dma_domain(domain);
dev_assign_dma_iommu(dev, dma_iommu);
if (dma_iommu && iommu_dma_init_domain(domain, dev))
goto out_err;
return;
out_err:
pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
dev_name(dev));
dev->dma_iommu = false;
dev_clear_dma_iommu(dev);
}
static bool has_msi_cookie(const struct iommu_domain *domain)

View File

@@ -611,9 +611,8 @@ static void iommu_deinit_device(struct device *dev)
dev->iommu_group = NULL;
module_put(ops->owner);
dev_iommu_free(dev);
#ifdef CONFIG_IOMMU_DMA
dev->dma_iommu = false;
#endif
if (IS_ENABLED(CONFIG_IOMMU_DMA))
dev_clear_dma_iommu(dev);
}
static struct iommu_domain *pasid_array_entry_to_domain(void *entry)

View File

@@ -349,7 +349,7 @@ static int xpcs_plat_init_dev(struct dw_xpcs_plat *pxpcs)
* up later. Make sure DD-core is aware of the OF-node being re-used.
*/
device_set_node(&mdiodev->dev, fwnode_handle_get(dev_fwnode(dev)));
mdiodev->dev.of_node_reused = true;
dev_set_of_node_reused(&mdiodev->dev);
/* Pass the data further so the DW XPCS driver core could use it */
mdiodev->dev.platform_data = (void *)device_get_match_data(dev);

View File

@@ -26,7 +26,7 @@
const struct of_device_id *of_match_device(const struct of_device_id *matches,
const struct device *dev)
{
if (!matches || !dev->of_node || dev->of_node_reused)
if (!matches || !dev->of_node || dev_of_node_reused(dev))
return NULL;
return of_match_node(matches, dev->of_node);
}
@@ -192,7 +192,7 @@ ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len)
{
ssize_t sl;
if (!dev || !dev->of_node || dev->of_node_reused)
if (!dev || !dev->of_node || dev_of_node_reused(dev))
return -ENODEV;
sl = of_modalias(dev->of_node, str, len - 2);
@@ -254,7 +254,7 @@ int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *
{
int sl;
if ((!dev) || (!dev->of_node) || dev->of_node_reused)
if ((!dev) || (!dev->of_node) || dev_of_node_reused(dev))
return -ENODEV;
/* Devicetree modalias is tricky, we add it in 2 steps */

View File

@@ -225,7 +225,6 @@ static void __of_attach_node(struct device_node *np)
np->sibling = np->parent->child;
np->parent->child = np;
of_node_clear_flag(np, OF_DETACHED);
fwnode_set_flag(&np->fwnode, FWNODE_FLAG_NOT_DEVICE);
raw_spin_unlock_irqrestore(&devtree_lock, flags);

View File

@@ -185,6 +185,15 @@ static int overlay_notify(struct overlay_changeset *ovcs,
return 0;
}
static void overlay_fw_devlink_refresh(struct overlay_changeset *ovcs)
{
for (int i = 0; i < ovcs->count; i++) {
struct device_node *np = ovcs->fragments[i].target;
fw_devlink_refresh_fwnode(of_fwnode_handle(np));
}
}
/*
* The values of properties in the "/__symbols__" node are paths in
* the ovcs->overlay_root. When duplicating the properties, the paths
@@ -951,6 +960,12 @@ static int of_overlay_apply(struct overlay_changeset *ovcs,
pr_err("overlay apply changeset entry notify error %d\n", ret);
/* notify failure is not fatal, continue */
/*
* Needs to happen after changeset notify to give the listeners a chance
* to finish creating all the devices they need to create.
*/
overlay_fw_devlink_refresh(ovcs);
ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_APPLY);
if (ret_tmp)
if (!ret)

View File

@@ -744,11 +744,6 @@ static int of_platform_notify(struct notifier_block *nb,
if (of_node_check_flag(rd->dn, OF_POPULATED))
return NOTIFY_OK;
/*
* Clear the flag before adding the device so that fw_devlink
* doesn't skip adding consumers to this device.
*/
fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE);
/* pdev_parent may be NULL when no bus platform device */
pdev_parent = of_find_device_by_node(parent);
pdev = of_platform_device_create(rd->dn, NULL,

View File

@@ -38,7 +38,7 @@ int pci_set_of_node(struct pci_dev *dev)
struct device *pdev __free(put_device) =
bus_find_device_by_of_node(&platform_bus_type, node);
if (pdev)
dev->bus->dev.of_node_reused = true;
dev_set_of_node_reused(&dev->bus->dev);
device_set_node(&dev->dev, of_fwnode_handle(no_free_ptr(node)));
return 0;

View File

@@ -39,7 +39,7 @@ static int pci_pwrctrl_notify(struct notifier_block *nb, unsigned long action,
* If we got here then the PCI device is the second after the
* power control platform device. Mark its OF node as reused.
*/
dev->of_node_reused = true;
dev_set_of_node_reused(dev);
break;
}

View File

@@ -92,7 +92,7 @@ struct Th1520WfHw {
#[pin_data(PinnedDrop)]
struct Th1520PwmDriverData {
#[pin]
iomem: devres::Devres<IoMem<TH1520_PWM_REG_SIZE>>,
iomem: devres::Devres<IoMem<'static, TH1520_PWM_REG_SIZE>>,
clk: Clk,
}
@@ -316,12 +316,13 @@ fn drop(self: Pin<&mut Self>) {
impl platform::Driver for Th1520PwmPlatformDriver {
type IdInfo = ();
type Data<'bound> = Self;
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
fn probe(
pdev: &platform::Device<Core>,
_id_info: Option<&Self::IdInfo>,
) -> impl PinInit<Self, Error> {
fn probe<'bound>(
pdev: &'bound platform::Device<Core<'_>>,
_id_info: Option<&'bound Self::IdInfo>,
) -> impl PinInit<Self, Error> + 'bound {
let dev = pdev.as_ref();
let request = pdev.io_request_by_index(0).ok_or(ENODEV)?;
@@ -351,7 +352,7 @@ fn probe(
dev,
TH1520_MAX_PWM_NUM,
try_pin_init!(Th1520PwmDriverData {
iomem <- request.iomap_sized::<TH1520_PWM_REG_SIZE>(),
iomem <- request.iomap_sized::<TH1520_PWM_REG_SIZE>()?.into_devres(),
clk <- clk,
}),
)?;

View File

@@ -1626,7 +1626,6 @@ static void qcom_glink_rpdev_release(struct device *dev)
{
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
kfree(rpdev->driver_override);
kfree(rpdev);
}
@@ -1862,7 +1861,6 @@ static void qcom_glink_device_release(struct device *dev)
/* Release qcom_glink_alloc_channel() reference */
kref_put(&channel->refcount, qcom_glink_channel_release);
kfree(rpdev->driver_override);
kfree(rpdev);
}

View File

@@ -358,33 +358,6 @@ rpmsg_show_attr(src, src, "0x%x\n");
rpmsg_show_attr(dst, dst, "0x%x\n");
rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
static ssize_t driver_override_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
int ret;
ret = driver_set_override(dev, &rpdev->driver_override, buf, count);
if (ret)
return ret;
return count;
}
static ssize_t driver_override_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
ssize_t len;
device_lock(dev);
len = sysfs_emit(buf, "%s\n", rpdev->driver_override);
device_unlock(dev);
return len;
}
static DEVICE_ATTR_RW(driver_override);
static ssize_t modalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -405,7 +378,6 @@ static struct attribute *rpmsg_dev_attrs[] = {
&dev_attr_dst.attr,
&dev_attr_src.attr,
&dev_attr_announce.attr,
&dev_attr_driver_override.attr,
NULL,
};
ATTRIBUTE_GROUPS(rpmsg_dev);
@@ -424,9 +396,11 @@ static int rpmsg_dev_match(struct device *dev, const struct device_driver *drv)
const struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv);
const struct rpmsg_device_id *ids = rpdrv->id_table;
unsigned int i;
int ret;
if (rpdev->driver_override)
return !strcmp(rpdev->driver_override, drv->name);
ret = device_match_driver_override(dev, drv);
if (ret >= 0)
return ret;
if (ids)
for (i = 0; ids[i].name[0]; i++)
@@ -535,6 +509,7 @@ static const struct bus_type rpmsg_bus = {
.name = "rpmsg",
.match = rpmsg_dev_match,
.dev_groups = rpmsg_dev_groups,
.driver_override = true,
.uevent = rpmsg_uevent,
.probe = rpmsg_dev_probe,
.remove = rpmsg_dev_remove,
@@ -560,11 +535,9 @@ int rpmsg_register_device_override(struct rpmsg_device *rpdev,
device_initialize(dev);
if (driver_override) {
ret = driver_set_override(dev, &rpdev->driver_override,
driver_override,
strlen(driver_override));
ret = device_set_driver_override(dev, driver_override);
if (ret) {
dev_err(dev, "device_set_override failed: %d\n", ret);
dev_err(dev, "device_set_driver_override() failed: %d\n", ret);
put_device(dev);
return ret;
}
@@ -573,8 +546,6 @@ int rpmsg_register_device_override(struct rpmsg_device *rpdev,
ret = device_add(dev);
if (ret) {
dev_err(dev, "device_add failed: %d\n", ret);
kfree(rpdev->driver_override);
rpdev->driver_override = NULL;
put_device(dev);
}

View File

@@ -374,7 +374,6 @@ static void virtio_rpmsg_release_device(struct device *dev)
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev);
kfree(rpdev->driver_override);
kfree(vch);
}

View File

@@ -2342,7 +2342,7 @@ static int __init tegra194_cbb_init(void)
{
return platform_driver_register(&tegra194_cbb_driver);
}
pure_initcall(tegra194_cbb_init);
core_initcall(tegra194_cbb_init);
static void __exit tegra194_cbb_exit(void)
{

View File

@@ -1774,7 +1774,7 @@ static int __init tegra234_cbb_init(void)
{
return platform_driver_register(&tegra234_cbb_driver);
}
pure_initcall(tegra234_cbb_init);
core_initcall(tegra234_cbb_init);
static void __exit tegra234_cbb_exit(void)
{

View File

@@ -5003,11 +5003,6 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action,
return NOTIFY_OK;
}
/*
* Clear the flag before adding the device so that fw_devlink
* doesn't skip adding consumers to this device.
*/
fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE);
spi = of_register_spi_device(ctlr, rd->dn);
put_device(&ctlr->dev);

View File

@@ -74,7 +74,7 @@ static int serial_base_device_init(struct uart_port *port,
dev->parent = parent_dev;
dev->bus = &serial_base_bus_type;
dev->release = release;
dev->of_node_reused = true;
dev_set_of_node_reused(dev);
device_set_node(dev, fwnode_handle_get(dev_fwnode(parent_dev)));

View File

@@ -593,7 +593,7 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
d->gadget.max_speed = USB_SPEED_HIGH;
d->gadget.speed = USB_SPEED_UNKNOWN;
d->gadget.dev.of_node = vhub->pdev->dev.of_node;
d->gadget.dev.of_node_reused = true;
dev_set_of_node_reused(&d->gadget.dev);
rc = usb_add_gadget_udc(d->port_dev, &d->gadget);
if (rc != 0)

View File

@@ -597,10 +597,13 @@ void kernfs_put(struct kernfs_node *kn)
*/
parent = kernfs_parent(kn);
WARN_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS,
"kernfs_put: %s/%s: released with incorrect active_ref %d\n",
parent ? rcu_dereference(parent->name) : "",
rcu_dereference(kn->name), atomic_read(&kn->active));
if (atomic_read(&kn->active) != KN_DEACTIVATED_BIAS) {
guard(rcu)();
WARN_ONCE(1,
"kernfs_put: %s/%s: released with incorrect active_ref %d\n",
parent ? rcu_dereference(parent->name) : "",
rcu_dereference(kn->name), atomic_read(&kn->active));
}
if (kernfs_type(kn) == KERNFS_LINK)
kernfs_put(kn->symlink.target_kn);

View File

@@ -70,9 +70,8 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
* The code works fine with PAGE_SIZE return but it's likely to
* indicate truncated result or overflow in normal use cases.
*/
if (count >= (ssize_t)PAGE_SIZE) {
printk("fill_read_buffer: %pS returned bad count\n",
ops->show);
if (count >= PAGE_SIZE) {
WARN(1, "OOB write or bad count %zd at %pS\n", count, ops->show);
/* Try to struggle along */
count = PAGE_SIZE - 1;
}
@@ -120,6 +119,10 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf,
len = ops->show(kobj, of->kn->priv, buf);
if (len < 0)
return len;
if (len >= (ssize_t)PAGE_SIZE) {
printk("fill_read_buffer: %pS returned bad count\n", ops->show);
len = PAGE_SIZE - 1;
}
if (pos) {
if (len <= pos)
return 0;

View File

@@ -189,6 +189,10 @@ struct acpi_driver {
* -----------
*/
bool acpi_of_match_device(const struct acpi_device *adev,
const struct of_device_id *of_match_table,
const struct of_device_id **of_id);
/* Status (_STA) */
struct acpi_device_status {
@@ -996,6 +1000,13 @@ int acpi_scan_add_dep(acpi_handle handle, struct acpi_handle_list *dep_devices);
u32 arch_acpi_add_auto_dep(acpi_handle handle);
#else /* CONFIG_ACPI */
static inline bool acpi_of_match_device(const struct acpi_device *adev,
const struct of_device_id *of_match_table,
const struct of_device_id **of_id)
{
return false;
}
static inline int register_acpi_bus_type(void *bus) { return 0; }
static inline int unregister_acpi_bus_type(void *bus) { return 0; }

View File

@@ -71,11 +71,6 @@ struct amba_device {
unsigned int cid;
struct amba_cs_uci_id uci;
unsigned int irq[AMBA_NR_IRQS];
/*
* Driver name to force a match. Do not set directly, because core
* frees it. Use driver_set_override() to set or clear it.
*/
const char *driver_override;
};
struct amba_driver {

View File

@@ -62,6 +62,9 @@
* @sysfs.irqs: irqs xarray contains irq indices which are used by the device,
* @sysfs.lock: Synchronize irq sysfs creation,
* @sysfs.irq_dir_exists: whether "irqs" directory exists,
* @registration_data_rust: private data owned by the registering (parent)
* driver; valid for as long as the device is
* registered with the driver core,
*
* An auxiliary_device represents a part of its parent device's functionality.
* It is given a name that, combined with the registering drivers
@@ -148,6 +151,7 @@ struct auxiliary_device {
struct mutex lock; /* Synchronize irq sysfs creation */
bool irq_dir_exists;
} sysfs;
void *registration_data_rust;
};
/**

View File

@@ -137,9 +137,6 @@ struct cdx_controller {
* @enabled: is this bus enabled
* @msi_dev_id: MSI Device ID associated with CDX device
* @num_msi: Number of MSI's supported by the device
* @driver_override: driver name to force a match; do not set directly,
* because core frees it; use driver_set_override() to
* set or clear it.
* @irqchip_lock: lock to synchronize irq/msi configuration
* @msi_write_pending: MSI write pending for this device
*/
@@ -165,7 +162,6 @@ struct cdx_device {
bool enabled;
u32 msi_dev_id;
u32 num_msi;
const char *driver_override;
struct mutex irqchip_lock;
bool msi_write_pending;
};

View File

@@ -691,8 +691,11 @@ coresight_find_output_type(struct coresight_platform_data *pdata,
enum coresight_dev_type type,
union coresight_dev_subtype subtype);
int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
struct platform_driver *pdev_drv, struct module *owner);
int coresight_init_driver_with_owner(const char *drv, struct amba_driver *amba_drv,
struct platform_driver *pdev_drv, struct module *owner,
const char *mod_name);
#define coresight_init_driver(drv, amba_drv, pdev_drv) \
coresight_init_driver_with_owner(drv, amba_drv, pdev_drv, THIS_MODULE, KBUILD_MODNAME)
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv);

View File

@@ -38,7 +38,6 @@ struct device_private;
struct device_driver;
struct driver_private;
struct module;
struct class;
struct subsys_private;
struct device_node;
struct fwnode_handle;
@@ -104,10 +103,18 @@ struct device_type {
*/
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
__SYSFS_FUNCTION_ALTERNATIVE(
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*show_const)(struct device *dev, const struct device_attribute *attr,
char *buf);
);
__SYSFS_FUNCTION_ALTERNATIVE(
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
ssize_t (*store_const)(struct device *dev, const struct device_attribute *attr,
const char *buf, size_t count);
);
};
/**
@@ -135,6 +142,77 @@ ssize_t device_store_bool(struct device *dev, struct device_attribute *attr,
ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
char *buf);
typedef ssize_t __device_show_handler_const(struct device *dev, const struct device_attribute *attr,
char *buf);
typedef ssize_t __device_store_handler_const(struct device *dev, const struct device_attribute *attr,
const char *buf, size_t count);
#ifdef CONFIG_CFI
#define __DEVICE_ATTR_SHOW_STORE(_show, _store) \
.show = _Generic(_show, \
__device_show_handler_const * : NULL, \
default : _show \
), \
.show_const = _Generic(_show, \
__device_show_handler_const * : _show, \
default : NULL \
), \
.store = _Generic(_store, \
__device_store_handler_const * : NULL, \
default : _store \
), \
.store_const = _Generic(_store, \
__device_store_handler_const * : _store, \
default : NULL \
),
#else
#define __DEVICE_ATTR_SHOW_STORE(_show, _store) \
.show = _Generic(_show, \
__device_show_handler_const * : (void *)_show, \
default : _show \
), \
.store = _Generic(_store, \
__device_store_handler_const * : (void *)_store, \
default : _store \
), \
#endif
#define __DEVICE_ATTR(_name, _mode, _show, _store) { \
.attr = {.name = __stringify(_name), \
.mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
__DEVICE_ATTR_SHOW_STORE(_show, _store) \
}
#define __DEVICE_ATTR_RO_MODE(_name, _mode) \
__DEVICE_ATTR(_name, _mode, _name##_show, NULL)
#define __DEVICE_ATTR_RO(_name) \
__DEVICE_ATTR_RO_MODE(_name, 0444)
#define __DEVICE_ATTR_WO(_name) \
__DEVICE_ATTR(_name, 0200, NULL, _name##_store)
#define __DEVICE_ATTR_RW_MODE(_name, _mode) \
__DEVICE_ATTR(_name, _mode, _name##_show, _name##_store)
#define __DEVICE_ATTR_RW(_name) \
__DEVICE_ATTR_RW_MODE(_name, 0644)
#ifdef CONFIG_DEBUG_LOCK_ALLOC
#define __DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) { \
.attr = {.name = __stringify(_name), .mode = _mode, \
.ignore_lockdep = true }, \
__DEVICE_ATTR_SHOW_STORE(_show, _store) \
}
#else
#define __DEVICE_ATTR_IGNORE_LOCKDEP __DEVICE_ATTR
#endif
/**
* DEVICE_ATTR - Define a device attribute.
* @_name: Attribute name.
@@ -155,20 +233,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
* };
*/
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
/**
* DEVICE_ATTR_PREALLOC - Define a preallocated device attribute.
* @_name: Attribute name.
* @_mode: File mode.
* @_show: Show handler. Optional, but mandatory if attribute is readable.
* @_store: Store handler. Optional, but mandatory if attribute is writable.
*
* Like DEVICE_ATTR(), but ``SYSFS_PREALLOC`` is set on @_mode.
*/
#define DEVICE_ATTR_PREALLOC(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = \
__ATTR_PREALLOC(_name, _mode, _show, _store)
struct device_attribute dev_attr_##_name = __DEVICE_ATTR(_name, _mode, _show, _store)
/**
* DEVICE_ATTR_RW - Define a read-write device attribute.
@@ -178,7 +243,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
* and @_store is <_name>_store.
*/
#define DEVICE_ATTR_RW(_name) \
struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
struct device_attribute dev_attr_##_name = __DEVICE_ATTR_RW(_name)
/**
* DEVICE_ATTR_ADMIN_RW - Define an admin-only read-write device attribute.
@@ -187,7 +252,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
* Like DEVICE_ATTR_RW(), but @_mode is 0600.
*/
#define DEVICE_ATTR_ADMIN_RW(_name) \
struct device_attribute dev_attr_##_name = __ATTR_RW_MODE(_name, 0600)
struct device_attribute dev_attr_##_name = __DEVICE_ATTR_RW_MODE(_name, 0600)
/**
* DEVICE_ATTR_RW_NAMED - Define a read-write device attribute with a sysfs name
@@ -201,8 +266,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
#define DEVICE_ATTR_RW_NAMED(_name, _attrname) \
struct device_attribute dev_attr_##_name = { \
.attr = { .name = _attrname, .mode = 0644 }, \
.show = _name##_show, \
.store = _name##_store, \
__DEVICE_ATTR_SHOW_STORE(_name##_show, _name##_store) \
}
/**
@@ -212,7 +276,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
* Like DEVICE_ATTR(), but @_mode is 0444 and @_show is <_name>_show.
*/
#define DEVICE_ATTR_RO(_name) \
struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
struct device_attribute dev_attr_##_name = __DEVICE_ATTR_RO(_name)
/**
* DEVICE_ATTR_ADMIN_RO - Define an admin-only readable device attribute.
@@ -221,7 +285,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
* Like DEVICE_ATTR_RO(), but @_mode is 0400.
*/
#define DEVICE_ATTR_ADMIN_RO(_name) \
struct device_attribute dev_attr_##_name = __ATTR_RO_MODE(_name, 0400)
struct device_attribute dev_attr_##_name = __DEVICE_ATTR_RO_MODE(_name, 0400)
/**
* DEVICE_ATTR_RO_NAMED - Define a read-only device attribute with a sysfs name
@@ -235,7 +299,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
#define DEVICE_ATTR_RO_NAMED(_name, _attrname) \
struct device_attribute dev_attr_##_name = { \
.attr = { .name = _attrname, .mode = 0444 }, \
.show = _name##_show, \
__DEVICE_ATTR_SHOW_STORE(_name##_show, NULL) \
}
/**
@@ -245,7 +309,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
* Like DEVICE_ATTR(), but @_mode is 0200 and @_store is <_name>_store.
*/
#define DEVICE_ATTR_WO(_name) \
struct device_attribute dev_attr_##_name = __ATTR_WO(_name)
struct device_attribute dev_attr_##_name = __DEVICE_ATTR_WO(_name)
/**
* DEVICE_ATTR_WO_NAMED - Define a read-only device attribute with a sysfs name
@@ -259,7 +323,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
#define DEVICE_ATTR_WO_NAMED(_name, _attrname) \
struct device_attribute dev_attr_##_name = { \
.attr = { .name = _attrname, .mode = 0200 }, \
.store = _name##_store, \
__DEVICE_ATTR_SHOW_STORE(NULL, _name##_store) \
}
/**
@@ -273,7 +337,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
*/
#define DEVICE_ULONG_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_##_name = \
{ __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
{ __DEVICE_ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
/**
* DEVICE_INT_ATTR - Define a device attribute backed by an int.
@@ -285,7 +349,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
*/
#define DEVICE_INT_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_##_name = \
{ __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) }
{ __DEVICE_ATTR(_name, _mode, device_show_int, device_store_int), &(_var) }
/**
* DEVICE_BOOL_ATTR - Define a device attribute backed by a bool.
@@ -297,7 +361,7 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
*/
#define DEVICE_BOOL_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_##_name = \
{ __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) }
{ __DEVICE_ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) }
/**
* DEVICE_STRING_ATTR_RO - Define a device attribute backed by a r/o string.
@@ -310,11 +374,11 @@ ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
*/
#define DEVICE_STRING_ATTR_RO(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_##_name = \
{ __ATTR(_name, (_mode) & ~0222, device_show_string, NULL), (_var) }
{ __DEVICE_ATTR(_name, (_mode) & ~0222, device_show_string, NULL), (_var) }
#define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = \
__ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
__DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
int device_create_file(struct device *device,
const struct device_attribute *entry);
@@ -512,10 +576,40 @@ struct device_physical_location {
*
* @DEV_FLAG_READY_TO_PROBE: If set then device_add() has finished enough
* initialization that probe could be called.
* @DEV_FLAG_CAN_MATCH: The device has matched with a driver at least once or it
* is in a bus (like AMBA) which can't check for matching drivers
* until other devices probe successfully.
* @DEV_FLAG_DMA_IOMMU: Device is using default IOMMU implementation for DMA and
* doesn't rely on dma_ops structure.
* @DEV_FLAG_DMA_SKIP_SYNC: DMA sync operations can be skipped for coherent
* buffers.
* @DEV_FLAG_DMA_OPS_BYPASS: If set then the dma_ops are bypassed for the
* streaming DMA operations (->map_* / ->unmap_* / ->sync_*), and
* optional (if the coherent mask is large enough) also for dma
* allocations. This flag is managed by the dma ops instance from
* ->dma_supported.
* @DEV_FLAG_STATE_SYNCED: The hardware state of this device has been synced to
* match the software state of this device by calling the
* driver/bus sync_state() callback.
* @DEV_FLAG_DMA_COHERENT: This particular device is dma coherent, even if the
* architecture supports non-coherent devices.
* @DEV_FLAG_OF_NODE_REUSED: Set if the device-tree node is shared with an
* ancestor device.
* @DEV_FLAG_OFFLINE_DISABLED: If set, the device is permanently online.
* @DEV_FLAG_OFFLINE: Set after successful invocation of bus type's .offline().
* @DEV_FLAG_COUNT: Number of defined struct_device_flags.
*/
enum struct_device_flags {
DEV_FLAG_READY_TO_PROBE = 0,
DEV_FLAG_CAN_MATCH = 1,
DEV_FLAG_DMA_IOMMU = 2,
DEV_FLAG_DMA_SKIP_SYNC = 3,
DEV_FLAG_DMA_OPS_BYPASS = 4,
DEV_FLAG_STATE_SYNCED = 5,
DEV_FLAG_DMA_COHERENT = 6,
DEV_FLAG_OF_NODE_REUSED = 7,
DEV_FLAG_OFFLINE_DISABLED = 8,
DEV_FLAG_OFFLINE = 9,
DEV_FLAG_COUNT
};
@@ -594,27 +688,6 @@ enum struct_device_flags {
* @removable: Whether the device can be removed from the system. This
* should be set by the subsystem / bus driver that discovered
* the device.
*
* @offline_disabled: If set, the device is permanently online.
* @offline: Set after successful invocation of bus type's .offline().
* @of_node_reused: Set if the device-tree node is shared with an ancestor
* device.
* @state_synced: The hardware state of this device has been synced to match
* the software state of this device by calling the driver/bus
* sync_state() callback.
* @can_match: The device has matched with a driver at least once or it is in
* a bus (like AMBA) which can't check for matching drivers until
* other devices probe successfully.
* @dma_coherent: this particular device is dma coherent, even if the
* architecture supports non-coherent devices.
* @dma_ops_bypass: If set to %true then the dma_ops are bypassed for the
* streaming DMA operations (->map_* / ->unmap_* / ->sync_*),
* and optionall (if the coherent mask is large enough) also
* for dma allocations. This flag is managed by the dma ops
* instance from ->dma_supported.
* @dma_skip_sync: DMA sync operations can be skipped for coherent buffers.
* @dma_iommu: Device is using default IOMMU implementation for DMA and
* doesn't rely on dma_ops structure.
* @flags: DEV_FLAG_XXX flags. Use atomic bitfield operations to modify.
*
* At the lowest level, every device in a Linux system is represented by an
@@ -719,26 +792,6 @@ struct device {
enum device_removable removable;
bool offline_disabled:1;
bool offline:1;
bool of_node_reused:1;
bool state_synced:1;
bool can_match:1;
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
bool dma_coherent:1;
#endif
#ifdef CONFIG_DMA_OPS_BYPASS
bool dma_ops_bypass : 1;
#endif
#ifdef CONFIG_DMA_NEED_SYNC
bool dma_skip_sync:1;
#endif
#ifdef CONFIG_IOMMU_DMA
bool dma_iommu:1;
#endif
DECLARE_BITMAP(flags, DEV_FLAG_COUNT);
};
@@ -765,6 +818,15 @@ static inline bool dev_test_and_set_##accessor_name(struct device *dev) \
}
__create_dev_flag_accessors(ready_to_probe, DEV_FLAG_READY_TO_PROBE);
__create_dev_flag_accessors(can_match, DEV_FLAG_CAN_MATCH);
__create_dev_flag_accessors(dma_iommu, DEV_FLAG_DMA_IOMMU);
__create_dev_flag_accessors(dma_skip_sync, DEV_FLAG_DMA_SKIP_SYNC);
__create_dev_flag_accessors(dma_ops_bypass, DEV_FLAG_DMA_OPS_BYPASS);
__create_dev_flag_accessors(state_synced, DEV_FLAG_STATE_SYNCED);
__create_dev_flag_accessors(dma_coherent, DEV_FLAG_DMA_COHERENT);
__create_dev_flag_accessors(of_node_reused, DEV_FLAG_OF_NODE_REUSED);
__create_dev_flag_accessors(offline_disabled, DEV_FLAG_OFFLINE_DISABLED);
__create_dev_flag_accessors(offline, DEV_FLAG_OFFLINE);
#undef __create_dev_flag_accessors
@@ -1063,17 +1125,6 @@ static inline void device_lock_assert(struct device *dev)
lockdep_assert_held(&dev->mutex);
}
static inline bool dev_has_sync_state(struct device *dev)
{
if (!dev)
return false;
if (dev->driver && dev->driver->sync_state)
return true;
if (dev->bus && dev->bus->sync_state)
return true;
return false;
}
static inline int dev_set_drv_sync_state(struct device *dev,
void (*fn)(struct device *dev))
{

View File

@@ -83,9 +83,9 @@ struct fwnode_handle;
struct bus_type {
const char *name;
const char *dev_name;
const struct attribute_group **bus_groups;
const struct attribute_group **dev_groups;
const struct attribute_group **drv_groups;
const struct attribute_group *const *bus_groups;
const struct attribute_group *const *dev_groups;
const struct attribute_group *const *drv_groups;
int (*match)(struct device *dev, const struct device_driver *drv);
int (*uevent)(const struct device *dev, struct kobj_uevent_env *env);

View File

@@ -34,7 +34,7 @@ struct fwnode_handle;
* @class_release: Called to release this class.
* @dev_release: Called to release the device.
* @shutdown_pre: Called at shut-down time before driver shutdown.
* @ns_type: Callbacks so sysfs can detemine namespaces.
* @ns_type: Callbacks so sysfs can determine namespaces.
* @namespace: Namespace of the device belongs to this class.
* @get_ownership: Allows class to specify uid/gid of the sysfs directories
* for the devices belonging to the class. Usually tied to

View File

@@ -114,8 +114,8 @@ struct device_driver {
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct attribute_group **dev_groups;
const struct attribute_group *const *groups;
const struct attribute_group *const *dev_groups;
const struct dev_pm_ops *pm;
void (*coredump) (struct device *dev);
@@ -123,8 +123,8 @@ struct device_driver {
struct driver_private *p;
struct {
/*
* Called after remove() and after all devres entries have been
* processed. This is a Rust only callback.
* Called after remove() but before devres entries are released.
* This is a Rust only callback.
*/
void (*post_unbind_rust)(struct device *dev);
} p_cb;
@@ -160,8 +160,6 @@ int __must_check driver_create_file(const struct device_driver *driver,
void driver_remove_file(const 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);
int __must_check driver_for_each_device(struct device_driver *drv, struct device *start,
void *data, device_iter_t fn);
struct device *driver_find_device(const struct device_driver *drv,

View File

@@ -225,7 +225,7 @@ int dma_direct_set_offset(struct device *dev, phys_addr_t cpu_start,
extern bool dma_default_coherent;
static inline bool dev_is_dma_coherent(struct device *dev)
{
return dev->dma_coherent;
return dev_dma_coherent(dev);
}
#else
#define dma_default_coherent true
@@ -240,8 +240,8 @@ static inline void dma_reset_need_sync(struct device *dev)
{
#ifdef CONFIG_DMA_NEED_SYNC
/* Reset it only once so that the function can be called on hotpath */
if (unlikely(dev->dma_skip_sync))
dev->dma_skip_sync = false;
if (unlikely(dev_dma_skip_sync(dev)))
dev_clear_dma_skip_sync(dev);
#endif
}

View File

@@ -429,7 +429,7 @@ bool __dma_need_sync(struct device *dev, dma_addr_t dma_addr);
static inline bool dma_dev_need_sync(const struct device *dev)
{
/* Always call DMA sync operations when debugging is enabled */
return !dev->dma_skip_sync || IS_ENABLED(CONFIG_DMA_API_DEBUG);
return !dev_dma_skip_sync(dev) || IS_ENABLED(CONFIG_DMA_API_DEBUG);
}
static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,

View File

@@ -210,8 +210,10 @@ static inline void fwnode_init(struct fwnode_handle *fwnode,
{
fwnode->secondary = NULL;
fwnode->ops = ops;
fwnode->dev = NULL;
INIT_LIST_HEAD(&fwnode->consumers);
INIT_LIST_HEAD(&fwnode->suppliers);
fwnode->flags = 0;
}
static inline void fwnode_set_flag(struct fwnode_handle *fwnode,
@@ -251,6 +253,7 @@ int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup,
u8 flags);
void fwnode_links_purge(struct fwnode_handle *fwnode);
void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode);
void fw_devlink_refresh_fwnode(struct fwnode_handle *fwnode);
bool fw_devlink_is_strict(void);
#endif

View File

@@ -1272,11 +1272,6 @@ struct hv_device {
u16 device_id;
struct device device;
/*
* Driver name to force a match. Do not set directly, because core
* frees it. Use driver_set_override() to set or clear it.
*/
const char *driver_override;
struct vmbus_channel *channel;
struct kset *channels_kset;

View File

@@ -7,12 +7,13 @@
#ifndef _LINUX_IOMMU_DMA_H
#define _LINUX_IOMMU_DMA_H
#include <linux/device.h>
#include <linux/dma-direction.h>
#ifdef CONFIG_IOMMU_DMA
static inline bool use_dma_iommu(struct device *dev)
{
return dev->dma_iommu;
return dev_dma_iommu(dev);
}
#else
static inline bool use_dma_iommu(struct device *dev)

View File

@@ -293,18 +293,19 @@ struct platform_driver {
* use a macro to avoid include chaining to get THIS_MODULE
*/
#define platform_driver_register(drv) \
__platform_driver_register(drv, THIS_MODULE)
__platform_driver_register(drv, THIS_MODULE, KBUILD_MODNAME)
extern int __platform_driver_register(struct platform_driver *,
struct module *);
struct module *, const char *mod_name);
extern void platform_driver_unregister(struct platform_driver *);
/* non-hotpluggable platform devices may use this so that probe() and
* its support may live in __init sections, conserving runtime memory.
*/
#define platform_driver_probe(drv, probe) \
__platform_driver_probe(drv, probe, THIS_MODULE)
__platform_driver_probe(drv, probe, THIS_MODULE, KBUILD_MODNAME)
extern int __platform_driver_probe(struct platform_driver *driver,
int (*probe)(struct platform_device *), struct module *module);
int (*probe)(struct platform_device *), struct module *module,
const char *mod_name);
static inline void *platform_get_drvdata(const struct platform_device *pdev)
{
@@ -368,19 +369,19 @@ static int __init __platform_driver##_init(void) \
device_initcall(__platform_driver##_init); \
#define platform_create_bundle(driver, probe, res, n_res, data, size) \
__platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE)
__platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE, KBUILD_MODNAME)
extern struct platform_device *__platform_create_bundle(
struct platform_driver *driver, int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
const void *data, size_t size, struct module *module);
const void *data, size_t size, struct module *module, const char *mod_name);
int __platform_register_drivers(struct platform_driver * const *drivers,
unsigned int count, struct module *owner);
unsigned int count, struct module *owner, const char *mod_name);
void platform_unregister_drivers(struct platform_driver * const *drivers,
unsigned int count);
#define platform_register_drivers(drivers, count) \
__platform_register_drivers(drivers, count, THIS_MODULE)
__platform_register_drivers(drivers, count, THIS_MODULE, KBUILD_MODNAME)
#ifdef CONFIG_SUSPEND
extern int platform_pm_suspend(struct device *dev);

View File

@@ -471,12 +471,18 @@ struct property_entry {
#define PROPERTY_ENTRY_STRING(_name_, _val_) \
__PROPERTY_ENTRY_ELEMENT(_name_, str, STRING, _val_)
#define __PROPERTY_ENTRY_REF_ARGS(_ref_, ...) \
_Generic(_ref_, \
const struct software_node_ref_args *: _ref_, \
struct software_node_ref_args *: _ref_, \
default: &SOFTWARE_NODE_REFERENCE(_ref_, ##__VA_ARGS__))
#define PROPERTY_ENTRY_REF(_name_, _ref_, ...) \
(struct property_entry) { \
.name = _name_, \
.length = sizeof(struct software_node_ref_args), \
.type = DEV_PROP_REF, \
{ .pointer = &SOFTWARE_NODE_REFERENCE(_ref_, ##__VA_ARGS__), }, \
{ .pointer = __PROPERTY_ENTRY_REF_ARGS(_ref_, ##__VA_ARGS__) }, \
}
#define PROPERTY_ENTRY_BOOL(_name_) \

View File

@@ -41,9 +41,6 @@ struct rpmsg_channel_info {
* rpmsg_device - device that belong to the rpmsg bus
* @dev: the device struct
* @id: device id (used to match between rpmsg drivers and devices)
* @driver_override: driver name to force a match; do not set directly,
* because core frees it; use driver_set_override() to
* set or clear it.
* @src: local address
* @dst: destination address
* @ept: the rpmsg endpoint of this channel
@@ -53,7 +50,6 @@ struct rpmsg_channel_info {
struct rpmsg_device {
struct device dev;
struct rpmsg_device_id id;
const char *driver_override;
u32 src;
u32 dst;
struct rpmsg_endpoint *ept;

View File

@@ -2639,7 +2639,7 @@ static void cpuhp_offline_cpu_device(unsigned int cpu)
{
struct device *dev = get_cpu_device(cpu);
dev->offline = true;
dev_set_offline(dev);
/* Tell user space about the state change */
kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
}
@@ -2648,7 +2648,7 @@ static void cpuhp_online_cpu_device(unsigned int cpu)
{
struct device *dev = get_cpu_device(cpu);
dev->offline = false;
dev_clear_offline(dev);
/* Tell user space about the state change */
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
}

View File

@@ -126,11 +126,9 @@ static bool dma_go_direct(struct device *dev, dma_addr_t mask,
if (likely(!ops))
return true;
#ifdef CONFIG_DMA_OPS_BYPASS
if (dev->dma_ops_bypass)
if (IS_ENABLED(CONFIG_DMA_OPS_BYPASS) && dev_dma_ops_bypass(dev))
return min_not_zero(mask, dev->bus_dma_limit) >=
dma_direct_get_required_mask(dev);
#endif
return false;
}
@@ -472,7 +470,7 @@ bool dma_need_unmap(struct device *dev)
{
if (!dma_map_direct(dev, get_dma_ops(dev)))
return true;
if (!dev->dma_skip_sync)
if (!dev_dma_skip_sync(dev))
return true;
return IS_ENABLED(CONFIG_DMA_API_DEBUG);
}
@@ -488,16 +486,16 @@ static void dma_setup_need_sync(struct device *dev)
* mapping, if any. During the device initialization, it's
* enough to check only for the DMA coherence.
*/
dev->dma_skip_sync = dev_is_dma_coherent(dev);
dev_assign_dma_skip_sync(dev, dev_is_dma_coherent(dev));
else if (!ops->sync_single_for_device && !ops->sync_single_for_cpu &&
!ops->sync_sg_for_device && !ops->sync_sg_for_cpu)
/*
* Synchronization is not possible when none of DMA sync ops
* is set.
*/
dev->dma_skip_sync = true;
dev_set_dma_skip_sync(dev);
else
dev->dma_skip_sync = false;
dev_clear_dma_skip_sync(dev);
}
#else /* !CONFIG_DMA_NEED_SYNC */
static inline void dma_setup_need_sync(struct device *dev) { }

View File

@@ -942,9 +942,9 @@ const struct kobj_type module_ktype = {
/*
* param_sysfs_init - create "module" kset
*
* This must be done before the initramfs is unpacked and
* request_module() thus becomes possible, because otherwise the
* module load would fail in mod_sysfs_init.
* This must be done before any driver registration so that when a driver comes
* from a built-in module, the driver core can add the module under /sys/module
* and create the associated driver symlinks.
*/
static int __init param_sysfs_init(void)
{
@@ -957,7 +957,7 @@ static int __init param_sysfs_init(void)
return 0;
}
subsys_initcall(param_sysfs_init);
pure_initcall(param_sysfs_init);
/*
* param_sysfs_builtin_init - add sysfs version and parameter

View File

@@ -709,7 +709,7 @@ int hmm_dma_map_alloc(struct device *dev, struct hmm_dma_map *map,
* best approximation to ensure no swiotlb buffering happens.
*/
#ifdef CONFIG_DMA_NEED_SYNC
dma_need_sync = !dev->dma_skip_sync;
dma_need_sync = !dev_dma_skip_sync(dev);
#endif /* CONFIG_DMA_NEED_SYNC */
if (dma_need_sync || dma_addressing_limited(dev))
return -EOPNOTSUPP;

View File

@@ -119,6 +119,7 @@ syn-cfgs := \
feature="parsing" \
feature="printing" \
feature="proc-macro" \
feature="visit" \
feature="visit-mut"
syn-flags := \

16
rust/helpers/acpi.c Normal file
View File

@@ -0,0 +1,16 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/acpi.h>
#include <acpi/acpi_bus.h>
__rust_helper bool rust_helper_acpi_of_match_device(const struct acpi_device *adev,
const struct of_device_id *of_match_table,
const struct of_device_id **of_id)
{
return acpi_of_match_device(adev, of_match_table, of_id);
}
__rust_helper struct acpi_device *rust_helper_to_acpi_device_node(struct fwnode_handle *fwnode)
{
return to_acpi_device_node(fwnode);
}

Some files were not shown because too many files have changed in this diff Show More