From 372a67c0c5ef63f55bd1eb480d9555328d8ec0f2 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Wed, 4 Sep 2019 14:11:20 -0700 Subject: driver core: Add fwnode_to_dev() to look up device from fwnode It's often useful to look up a device that corresponds to a fwnode. So add an API to do that irrespective of the bus on which the device has been added to. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20190904211126.47518-2-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- include/linux/fwnode.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index ababd6bc82f3..d8c6d231d577 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -17,6 +17,7 @@ struct device; struct fwnode_handle { struct fwnode_handle *secondary; const struct fwnode_operations *ops; + struct device *dev; }; /** @@ -123,5 +124,6 @@ struct fwnode_operations { if (fwnode_has_op(fwnode, op)) \ (fwnode)->ops->op(fwnode, ## __VA_ARGS__); \ } while (false) +#define get_dev_from_fwnode(fwnode) get_device((fwnode)->dev) #endif -- cgit v1.2.3-59-g8ed1b From e2ae9bcc4aaacda04edb75c4eea93384719efaa5 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Wed, 4 Sep 2019 14:11:21 -0700 Subject: driver core: Add support for linking devices during device addition The firmware corresponding to a device (dev.fwnode) might be able to provide functional dependency information between a device and its supplier and consumer devices. Tracking this functional dependency allows optimizing device probe order and informing a supplier when all its consumers have probed (and thereby actively managing their resources). The existing device links feature allows tracking and using supplier-consumer relationships. So, this patch adds the add_links() fwnode callback to allow firmware to create device links for each device as the device is added. However, when consumer devices are added, they might not have a supplier device to link to despite needing mandatory resources/functionality from one or more suppliers. A waiting_for_suppliers list is created to track such consumers and retry linking them when new devices get added. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20190904211126.47518-3-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/device_link.rst | 3 +- drivers/base/core.c | 88 ++++++++++++++++++++++++++++++++ include/linux/device.h | 2 + include/linux/fwnode.h | 17 ++++++ 4 files changed, 109 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/Documentation/driver-api/device_link.rst b/Documentation/driver-api/device_link.rst index 1b5020ec6517..bc2d89af88ce 100644 --- a/Documentation/driver-api/device_link.rst +++ b/Documentation/driver-api/device_link.rst @@ -281,7 +281,8 @@ State machine :c:func:`driver_bound()`.) * Before a consumer device is probed, presence of supplier drivers is - verified by checking that links to suppliers are in ``DL_STATE_AVAILABLE`` + verified by checking the consumer device is not in the wait_for_suppliers + list and by checking that links to suppliers are in ``DL_STATE_AVAILABLE`` state. The state of the links is updated to ``DL_STATE_CONSUMER_PROBE``. (Call to :c:func:`device_links_check_suppliers()` from :c:func:`really_probe()`.) diff --git a/drivers/base/core.c b/drivers/base/core.c index 510fabf8918c..b3896da73b3d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -44,6 +44,8 @@ early_param("sysfs.deprecated", sysfs_deprecated_setup); #endif /* Device links support. */ +static LIST_HEAD(wait_for_suppliers); +static DEFINE_MUTEX(wfs_lock); #ifdef CONFIG_SRCU static DEFINE_MUTEX(device_links_lock); @@ -430,6 +432,58 @@ struct device_link *device_link_add(struct device *consumer, } EXPORT_SYMBOL_GPL(device_link_add); +/** + * device_link_wait_for_supplier - Add device to wait_for_suppliers list + * @consumer: Consumer device + * + * Marks the @consumer device as waiting for suppliers to become available by + * adding it to the wait_for_suppliers list. The consumer device will never be + * probed until it's removed from the wait_for_suppliers list. + * + * The caller is responsible for adding the links to the supplier devices once + * they are available and removing the @consumer device from the + * wait_for_suppliers list once links to all the suppliers have been created. + * + * This function is NOT meant to be called from the probe function of the + * consumer but rather from code that creates/adds the consumer device. + */ +static void device_link_wait_for_supplier(struct device *consumer) +{ + mutex_lock(&wfs_lock); + list_add_tail(&consumer->links.needs_suppliers, &wait_for_suppliers); + mutex_unlock(&wfs_lock); +} + +/** + * device_link_add_missing_supplier_links - Add links from consumer devices to + * supplier devices, leaving any + * consumer with inactive suppliers on + * the wait_for_suppliers list + * + * Loops through all consumers waiting on suppliers and tries to add all their + * supplier links. If that succeeds, the consumer device is removed from + * wait_for_suppliers list. Otherwise, they are left in the wait_for_suppliers + * list. Devices left on the wait_for_suppliers list will not be probed. + * + * The fwnode add_links callback is expected to return 0 if it has found and + * added all the supplier links for the consumer device. It should return an + * error if it isn't able to do so. + * + * The caller of device_link_wait_for_supplier() is expected to call this once + * it's aware of potential suppliers becoming available. + */ +static void device_link_add_missing_supplier_links(void) +{ + struct device *dev, *tmp; + + mutex_lock(&wfs_lock); + list_for_each_entry_safe(dev, tmp, &wait_for_suppliers, + links.needs_suppliers) + if (!fwnode_call_int_op(dev->fwnode, add_links, dev)) + list_del_init(&dev->links.needs_suppliers); + mutex_unlock(&wfs_lock); +} + static void device_link_free(struct device_link *link) { while (refcount_dec_not_one(&link->rpm_active)) @@ -564,6 +618,17 @@ int device_links_check_suppliers(struct device *dev) struct device_link *link; int ret = 0; + /* + * Device waiting for supplier to become available is not allowed to + * probe. + */ + mutex_lock(&wfs_lock); + if (!list_empty(&dev->links.needs_suppliers)) { + mutex_unlock(&wfs_lock); + return -EPROBE_DEFER; + } + mutex_unlock(&wfs_lock); + device_links_write_lock(); list_for_each_entry(link, &dev->links.suppliers, c_node) { @@ -848,6 +913,10 @@ static void device_links_purge(struct device *dev) { struct device_link *link, *ln; + mutex_lock(&wfs_lock); + list_del(&dev->links.needs_suppliers); + mutex_unlock(&wfs_lock); + /* * Delete all of the remaining links from this device to any other * devices (either consumers or suppliers). @@ -1712,6 +1781,7 @@ void device_initialize(struct device *dev) #endif INIT_LIST_HEAD(&dev->links.consumers); INIT_LIST_HEAD(&dev->links.suppliers); + INIT_LIST_HEAD(&dev->links.needs_suppliers); dev->links.status = DL_DEV_NO_DRIVER; } EXPORT_SYMBOL_GPL(device_initialize); @@ -2202,6 +2272,24 @@ int device_add(struct device *dev) if (dev->fwnode && !dev->fwnode->dev) dev->fwnode->dev = dev; + /* + * Check if any of the other devices (consumers) have been waiting for + * this device (supplier) to be added so that they can create a device + * link to it. + * + * This needs to happen after device_pm_add() because device_link_add() + * requires the supplier be registered before it's called. + * + * But this also needs to happe before bus_probe_device() to make sure + * waiting consumers can link to it before the driver is bound to the + * device and the driver sync_state callback is called for this device. + */ + device_link_add_missing_supplier_links(); + + if (fwnode_has_op(dev->fwnode, add_links) + && fwnode_call_int_op(dev->fwnode, add_links, dev)) + device_link_wait_for_supplier(dev); + bus_probe_device(dev); if (parent) klist_add_tail(&dev->p->knode_parent, diff --git a/include/linux/device.h b/include/linux/device.h index 297239a08bb7..c6fb5b3431b7 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1135,11 +1135,13 @@ enum dl_dev_state { * struct dev_links_info - Device data related to device links. * @suppliers: List of links to supplier devices. * @consumers: List of links to consumer devices. + * @needs_suppliers: Hook to global list of devices waiting for suppliers. * @status: Driver status information. */ struct dev_links_info { struct list_head suppliers; struct list_head consumers; + struct list_head needs_suppliers; enum dl_dev_state status; }; diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index d8c6d231d577..6ae05b9ce359 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -66,6 +66,21 @@ struct fwnode_reference_args { * endpoint node. * @graph_get_port_parent: Return the parent node of a port node. * @graph_parse_endpoint: Parse endpoint for port and endpoint id. + * @add_links: Called after the device corresponding to the fwnode is added + * using device_add(). The function is expected to create device + * links to all the suppliers of the device that are available at + * the time this function is called. The function must NOT stop + * at the first failed device link if other unlinked supplier + * devices are present in the system. If some suppliers are not + * yet available, this function will be called again when other + * devices are added to allow creating device links to any newly + * available suppliers. + * + * Return 0 if device links have been successfully created to all + * the suppliers of this device or if the supplier information is + * not known. Return an error if and only if the supplier + * information is known but some of the suppliers are not yet + * available to create device links to. */ struct fwnode_operations { struct fwnode_handle *(*get)(struct fwnode_handle *fwnode); @@ -103,6 +118,8 @@ struct fwnode_operations { (*graph_get_port_parent)(struct fwnode_handle *fwnode); int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode, struct fwnode_endpoint *endpoint); + int (*add_links)(const struct fwnode_handle *fwnode, + struct device *dev); }; #define fwnode_has_op(fwnode, op) \ -- cgit v1.2.3-59-g8ed1b From fc5a251d0fd7ca9038bab78a8c97932c8c6ca23b Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Wed, 4 Sep 2019 14:11:23 -0700 Subject: driver core: Add sync_state driver/bus callback This sync_state driver/bus callback is called once all the consumers of a supplier have probed successfully. This allows the supplier device's driver/bus to sync the supplier device's state to the software state with the guarantee that all the consumers are actively managing the resources provided by the supplier device. To maintain backwards compatibility and ease transition from existing frameworks and resource cleanup schemes, late_initcall_sync is the earliest when the sync_state callback might be called. There is no upper bound on the time by which the sync_state callback has to be called. This is because if a consumer device never probes, the supplier has to maintain its resources in the state left by the bootloader. For example, if the bootloader leaves the display backlight at a fixed voltage and the backlight driver is never probed, you don't want the backlight to ever be turned off after boot up. Also, when multiple devices are added after kernel init, some suppliers could be added before their consumer devices get added. In these instances, the supplier devices could get their sync_state callback called right after they probe because the consumers devices haven't had a chance to create device links to the suppliers. To handle this correctly, this change also provides APIs to pause/resume sync state callbacks so that when multiple devices are added, their sync_state callback evaluation can be postponed to happen after all of them are added. kbuild test robot reported missing documentation for device.state_synced Reported-by: kbuild test robot Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20190904211126.47518-5-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 24 +++++++++++++++++ 2 files changed, 96 insertions(+) (limited to 'include') diff --git a/drivers/base/core.c b/drivers/base/core.c index b3896da73b3d..acbf0b1414ab 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -46,6 +46,8 @@ early_param("sysfs.deprecated", sysfs_deprecated_setup); /* Device links support. */ static LIST_HEAD(wait_for_suppliers); static DEFINE_MUTEX(wfs_lock); +static LIST_HEAD(deferred_sync); +static unsigned int defer_sync_state_count = 1; #ifdef CONFIG_SRCU static DEFINE_MUTEX(device_links_lock); @@ -648,6 +650,69 @@ int device_links_check_suppliers(struct device *dev) return ret; } +static void __device_links_supplier_sync_state(struct device *dev) +{ + struct device_link *link; + + if (dev->state_synced) + return; + + list_for_each_entry(link, &dev->links.consumers, s_node) { + if (!(link->flags & DL_FLAG_MANAGED)) + continue; + if (link->status != DL_STATE_ACTIVE) + return; + } + + if (dev->bus->sync_state) + dev->bus->sync_state(dev); + else if (dev->driver && dev->driver->sync_state) + dev->driver->sync_state(dev); + + dev->state_synced = true; +} + +void device_links_supplier_sync_state_pause(void) +{ + device_links_write_lock(); + defer_sync_state_count++; + device_links_write_unlock(); +} + +void device_links_supplier_sync_state_resume(void) +{ + struct device *dev, *tmp; + + device_links_write_lock(); + if (!defer_sync_state_count) { + WARN(true, "Unmatched sync_state pause/resume!"); + goto out; + } + defer_sync_state_count--; + if (defer_sync_state_count) + goto out; + + list_for_each_entry_safe(dev, tmp, &deferred_sync, links.defer_sync) { + __device_links_supplier_sync_state(dev); + list_del_init(&dev->links.defer_sync); + } +out: + device_links_write_unlock(); +} + +static int sync_state_resume_initcall(void) +{ + device_links_supplier_sync_state_resume(); + return 0; +} +late_initcall(sync_state_resume_initcall); + +static void __device_links_supplier_defer_sync(struct device *sup) +{ + if (list_empty(&sup->links.defer_sync)) + list_add_tail(&sup->links.defer_sync, &deferred_sync); +} + /** * device_links_driver_bound - Update device links after probing its driver. * @dev: Device to update the links for. @@ -692,6 +757,11 @@ void device_links_driver_bound(struct device *dev) WARN_ON(link->status != DL_STATE_CONSUMER_PROBE); WRITE_ONCE(link->status, DL_STATE_ACTIVE); + + if (defer_sync_state_count) + __device_links_supplier_defer_sync(link->supplier); + else + __device_links_supplier_sync_state(link->supplier); } dev->links.status = DL_DEV_DRIVER_BOUND; @@ -808,6 +878,7 @@ void device_links_driver_cleanup(struct device *dev) WRITE_ONCE(link->status, DL_STATE_DORMANT); } + list_del_init(&dev->links.defer_sync); __device_links_no_driver(dev); device_links_write_unlock(); @@ -1782,6 +1853,7 @@ void device_initialize(struct device *dev) INIT_LIST_HEAD(&dev->links.consumers); INIT_LIST_HEAD(&dev->links.suppliers); INIT_LIST_HEAD(&dev->links.needs_suppliers); + INIT_LIST_HEAD(&dev->links.defer_sync); dev->links.status = DL_DEV_NO_DRIVER; } EXPORT_SYMBOL_GPL(device_initialize); diff --git a/include/linux/device.h b/include/linux/device.h index c6fb5b3431b7..6978bb471567 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -80,6 +80,13 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * that generate uevents to add the environment variables. * @probe: Called when a new device or driver add to this bus, and callback * the specific driver's probe to initial the matched device. + * @sync_state: Called to sync device state to software state after all the + * state tracking consumers linked to this device (present at + * the time of late_initcall) have successfully bound to a + * driver. If the device has no consumers, this function will + * be called at late_initcall_sync level. If the device has + * consumers that are never bound to a driver, this function + * will never get called until they do. * @remove: Called when a device removed from this bus. * @shutdown: Called at shut-down time to quiesce the device. * @@ -123,6 +130,7 @@ struct bus_type { int (*match)(struct device *dev, struct device_driver *drv); int (*uevent)(struct device *dev, struct kobj_uevent_env *env); int (*probe)(struct device *dev); + void (*sync_state)(struct device *dev); int (*remove)(struct device *dev); void (*shutdown)(struct device *dev); @@ -340,6 +348,13 @@ enum probe_type { * @probe: Called to query the existence of a specific device, * whether this driver can work with it, and bind the driver * to a specific device. + * @sync_state: Called to sync device state to software state after all the + * state tracking consumers linked to this device (present at + * the time of late_initcall) have successfully bound to a + * driver. If the device has no consumers, this function will + * be called at late_initcall_sync level. If the device has + * consumers that are never bound to a driver, this function + * will never get called until they do. * @remove: Called when the device is removed from the system to * unbind a device from this driver. * @shutdown: Called at shut-down time to quiesce the device. @@ -379,6 +394,7 @@ struct device_driver { const struct acpi_device_id *acpi_match_table; int (*probe) (struct device *dev); + void (*sync_state)(struct device *dev); int (*remove) (struct device *dev); void (*shutdown) (struct device *dev); int (*suspend) (struct device *dev, pm_message_t state); @@ -1136,12 +1152,14 @@ enum dl_dev_state { * @suppliers: List of links to supplier devices. * @consumers: List of links to consumer devices. * @needs_suppliers: Hook to global list of devices waiting for suppliers. + * @defer_sync: Hook to global list of devices that have deferred sync_state. * @status: Driver status information. */ struct dev_links_info { struct list_head suppliers; struct list_head consumers; struct list_head needs_suppliers; + struct list_head defer_sync; enum dl_dev_state status; }; @@ -1217,6 +1235,9 @@ struct dev_links_info { * @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. * @dma_coherent: this particular device is dma coherent, even if the * architecture supports non-coherent devices. * @@ -1313,6 +1334,7 @@ struct device { bool offline_disabled:1; bool offline:1; bool of_node_reused:1; + bool state_synced: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) @@ -1655,6 +1677,8 @@ struct device_link *device_link_add(struct device *consumer, struct device *supplier, u32 flags); void device_link_del(struct device_link *link); void device_link_remove(void *consumer, struct device *supplier); +void device_links_supplier_sync_state_pause(void); +void device_links_supplier_sync_state_resume(void); #ifndef dev_fmt #define dev_fmt(fmt) fmt -- cgit v1.2.3-59-g8ed1b From 507fd01d5333338753a1cc26322dfc9f856c109f Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 3 Oct 2019 11:29:12 +0200 Subject: drivers: move the early platform device support to arch/sh SuperH is the only user of the current implementation of early platform device support. We want to introduce a more robust approach to early probing. As the first step - move all the current early platform code to arch/sh. In order not to export internal drivers/base functions to arch code for this temporary solution - copy the two needed routines for driver matching from drivers/base/platform.c to arch/sh/drivers/platform_early.c. Also: call early_platform_cleanup() from subsys_initcall() so that it's called after all early devices are probed. Signed-off-by: Bartosz Golaszewski Cc: Rich Felker Link: https://lore.kernel.org/r/20191003092913.10731-2-brgl@bgdev.pl Signed-off-by: Greg Kroah-Hartman --- arch/sh/drivers/Makefile | 2 +- arch/sh/drivers/platform_early.c | 347 +++++++++++++++++++++++++++++++++ arch/sh/include/asm/platform_early.h | 61 ++++++ arch/sh/kernel/cpu/sh2/setup-sh7619.c | 1 + arch/sh/kernel/cpu/sh2a/setup-mxg.c | 1 + arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 1 + arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 1 + arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 1 + arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 1 + arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 1 + arch/sh/kernel/cpu/sh3/setup-sh3.c | 1 + arch/sh/kernel/cpu/sh3/setup-sh7705.c | 1 + arch/sh/kernel/cpu/sh3/setup-sh770x.c | 1 + arch/sh/kernel/cpu/sh3/setup-sh7710.c | 1 + arch/sh/kernel/cpu/sh3/setup-sh7720.c | 1 + arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 1 + arch/sh/kernel/cpu/sh4/setup-sh7750.c | 1 + arch/sh/kernel/cpu/sh4/setup-sh7760.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7734.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 1 + arch/sh/kernel/cpu/sh4a/setup-shx3.c | 1 + arch/sh/kernel/cpu/sh5/setup-sh5.c | 1 + arch/sh/kernel/setup.c | 1 + arch/sh/kernel/time.c | 1 + drivers/base/platform.c | 288 --------------------------- drivers/clocksource/sh_cmt.c | 7 + drivers/clocksource/sh_mtu2.c | 7 + drivers/clocksource/sh_tmu.c | 8 + drivers/tty/serial/sh-sci.c | 7 +- include/linux/platform_device.h | 64 ++---- 40 files changed, 480 insertions(+), 342 deletions(-) create mode 100644 arch/sh/drivers/platform_early.c create mode 100644 arch/sh/include/asm/platform_early.h (limited to 'include') diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile index 3e93b434e604..56b0acace6e7 100644 --- a/arch/sh/drivers/Makefile +++ b/arch/sh/drivers/Makefile @@ -3,7 +3,7 @@ # Makefile for the Linux SuperH-specific device drivers. # -obj-y += dma/ +obj-y += dma/ platform_early.o obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_SUPERHYWAY) += superhyway/ diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c new file mode 100644 index 000000000000..3dfe9f3541bb --- /dev/null +++ b/arch/sh/drivers/platform_early.c @@ -0,0 +1,347 @@ +// SPDX--License-Identifier: GPL-2.0 + +#include +#include +#include + +static __initdata LIST_HEAD(early_platform_driver_list); +static __initdata LIST_HEAD(early_platform_device_list); + +static const struct platform_device_id * +platform_match_id(const struct platform_device_id *id, + struct platform_device *pdev) +{ + while (id->name[0]) { + if (strcmp(pdev->name, id->name) == 0) { + pdev->id_entry = id; + return id; + } + id++; + } + return NULL; +} + +static int platform_match(struct device *dev, struct device_driver *drv) +{ + struct platform_device *pdev = to_platform_device(dev); + struct platform_driver *pdrv = to_platform_driver(drv); + + /* When driver_override is set, only bind to the matching driver */ + if (pdev->driver_override) + return !strcmp(pdev->driver_override, drv->name); + + /* Then try to match against the id table */ + if (pdrv->id_table) + return platform_match_id(pdrv->id_table, pdev) != NULL; + + /* fall-back to driver name match */ + return (strcmp(pdev->name, drv->name) == 0); +} + +#ifdef CONFIG_PM +static void device_pm_init_common(struct device *dev) +{ + if (!dev->power.early_init) { + spin_lock_init(&dev->power.lock); + dev->power.qos = NULL; + dev->power.early_init = true; + } +} + +static void pm_runtime_early_init(struct device *dev) +{ + dev->power.disable_depth = 1; + device_pm_init_common(dev); +} +#else +static void pm_runtime_early_init(struct device *dev) {} +#endif + +/** + * early_platform_driver_register - register early platform driver + * @epdrv: early_platform driver structure + * @buf: string passed from early_param() + * + * Helper function for early_platform_init() / early_platform_init_buffer() + */ +int __init early_platform_driver_register(struct early_platform_driver *epdrv, + char *buf) +{ + char *tmp; + int n; + + /* Simply add the driver to the end of the global list. + * Drivers will by default be put on the list in compiled-in order. + */ + if (!epdrv->list.next) { + INIT_LIST_HEAD(&epdrv->list); + list_add_tail(&epdrv->list, &early_platform_driver_list); + } + + /* If the user has specified device then make sure the driver + * gets prioritized. The driver of the last device specified on + * command line will be put first on the list. + */ + n = strlen(epdrv->pdrv->driver.name); + if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { + list_move(&epdrv->list, &early_platform_driver_list); + + /* Allow passing parameters after device name */ + if (buf[n] == '\0' || buf[n] == ',') + epdrv->requested_id = -1; + else { + epdrv->requested_id = simple_strtoul(&buf[n + 1], + &tmp, 10); + + if (buf[n] != '.' || (tmp == &buf[n + 1])) { + epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; + n = 0; + } else + n += strcspn(&buf[n + 1], ",") + 1; + } + + if (buf[n] == ',') + n++; + + if (epdrv->bufsize) { + memcpy(epdrv->buffer, &buf[n], + min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); + epdrv->buffer[epdrv->bufsize - 1] = '\0'; + } + } + + return 0; +} + +/** + * early_platform_add_devices - adds a number of early platform devices + * @devs: array of early platform devices to add + * @num: number of early platform devices in array + * + * Used by early architecture code to register early platform devices and + * their platform data. + */ +void __init early_platform_add_devices(struct platform_device **devs, int num) +{ + struct device *dev; + int i; + + /* simply add the devices to list */ + for (i = 0; i < num; i++) { + dev = &devs[i]->dev; + + if (!dev->devres_head.next) { + pm_runtime_early_init(dev); + INIT_LIST_HEAD(&dev->devres_head); + list_add_tail(&dev->devres_head, + &early_platform_device_list); + } + } +} + +/** + * early_platform_driver_register_all - register early platform drivers + * @class_str: string to identify early platform driver class + * + * Used by architecture code to register all early platform drivers + * for a certain class. If omitted then only early platform drivers + * with matching kernel command line class parameters will be registered. + */ +void __init early_platform_driver_register_all(char *class_str) +{ + /* The "class_str" parameter may or may not be present on the kernel + * command line. If it is present then there may be more than one + * matching parameter. + * + * Since we register our early platform drivers using early_param() + * we need to make sure that they also get registered in the case + * when the parameter is missing from the kernel command line. + * + * We use parse_early_options() to make sure the early_param() gets + * called at least once. The early_param() may be called more than + * once since the name of the preferred device may be specified on + * the kernel command line. early_platform_driver_register() handles + * this case for us. + */ + parse_early_options(class_str); +} + +/** + * early_platform_match - find early platform device matching driver + * @epdrv: early platform driver structure + * @id: id to match against + */ +static struct platform_device * __init +early_platform_match(struct early_platform_driver *epdrv, int id) +{ + struct platform_device *pd; + + list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) + if (platform_match(&pd->dev, &epdrv->pdrv->driver)) + if (pd->id == id) + return pd; + + return NULL; +} + +/** + * early_platform_left - check if early platform driver has matching devices + * @epdrv: early platform driver structure + * @id: return true if id or above exists + */ +static int __init early_platform_left(struct early_platform_driver *epdrv, + int id) +{ + struct platform_device *pd; + + list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) + if (platform_match(&pd->dev, &epdrv->pdrv->driver)) + if (pd->id >= id) + return 1; + + return 0; +} + +/** + * early_platform_driver_probe_id - probe drivers matching class_str and id + * @class_str: string to identify early platform driver class + * @id: id to match against + * @nr_probe: number of platform devices to successfully probe before exiting + */ +static int __init early_platform_driver_probe_id(char *class_str, + int id, + int nr_probe) +{ + struct early_platform_driver *epdrv; + struct platform_device *match; + int match_id; + int n = 0; + int left = 0; + + list_for_each_entry(epdrv, &early_platform_driver_list, list) { + /* only use drivers matching our class_str */ + if (strcmp(class_str, epdrv->class_str)) + continue; + + if (id == -2) { + match_id = epdrv->requested_id; + left = 1; + + } else { + match_id = id; + left += early_platform_left(epdrv, id); + + /* skip requested id */ + switch (epdrv->requested_id) { + case EARLY_PLATFORM_ID_ERROR: + case EARLY_PLATFORM_ID_UNSET: + break; + default: + if (epdrv->requested_id == id) + match_id = EARLY_PLATFORM_ID_UNSET; + } + } + + switch (match_id) { + case EARLY_PLATFORM_ID_ERROR: + pr_warn("%s: unable to parse %s parameter\n", + class_str, epdrv->pdrv->driver.name); + /* fall-through */ + case EARLY_PLATFORM_ID_UNSET: + match = NULL; + break; + default: + match = early_platform_match(epdrv, match_id); + } + + if (match) { + /* + * Set up a sensible init_name to enable + * dev_name() and others to be used before the + * rest of the driver core is initialized. + */ + if (!match->dev.init_name && slab_is_available()) { + if (match->id != -1) + match->dev.init_name = + kasprintf(GFP_KERNEL, "%s.%d", + match->name, + match->id); + else + match->dev.init_name = + kasprintf(GFP_KERNEL, "%s", + match->name); + + if (!match->dev.init_name) + return -ENOMEM; + } + + if (epdrv->pdrv->probe(match)) + pr_warn("%s: unable to probe %s early.\n", + class_str, match->name); + else + n++; + } + + if (n >= nr_probe) + break; + } + + if (left) + return n; + else + return -ENODEV; +} + +/** + * early_platform_driver_probe - probe a class of registered drivers + * @class_str: string to identify early platform driver class + * @nr_probe: number of platform devices to successfully probe before exiting + * @user_only: only probe user specified early platform devices + * + * Used by architecture code to probe registered early platform drivers + * within a certain class. For probe to happen a registered early platform + * device matching a registered early platform driver is needed. + */ +int __init early_platform_driver_probe(char *class_str, + int nr_probe, + int user_only) +{ + int k, n, i; + + n = 0; + for (i = -2; n < nr_probe; i++) { + k = early_platform_driver_probe_id(class_str, i, nr_probe - n); + + if (k < 0) + break; + + n += k; + + if (user_only) + break; + } + + return n; +} + +/** + * early_platform_cleanup - clean up early platform code + */ +static int __init early_platform_cleanup(void) +{ + struct platform_device *pd, *pd2; + + /* clean up the devres list used to chain devices */ + list_for_each_entry_safe(pd, pd2, &early_platform_device_list, + dev.devres_head) { + list_del(&pd->dev.devres_head); + memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); + } + + return 0; +} +/* + * This must happen once after all early devices are probed but before probing + * real platform devices. + */ +subsys_initcall(early_platform_cleanup); diff --git a/arch/sh/include/asm/platform_early.h b/arch/sh/include/asm/platform_early.h new file mode 100644 index 000000000000..4590ab757d5f --- /dev/null +++ b/arch/sh/include/asm/platform_early.h @@ -0,0 +1,61 @@ +/* SPDX--License-Identifier: GPL-2.0 */ + +#ifndef __PLATFORM_EARLY__ +#define __PLATFORM_EARLY__ + +#include +#include +#include +#include + +struct early_platform_driver { + const char *class_str; + struct platform_driver *pdrv; + struct list_head list; + int requested_id; + char *buffer; + int bufsize; +}; + +#define EARLY_PLATFORM_ID_UNSET -2 +#define EARLY_PLATFORM_ID_ERROR -3 + +extern int early_platform_driver_register(struct early_platform_driver *epdrv, + char *buf); +extern void early_platform_add_devices(struct platform_device **devs, int num); + +static inline int is_early_platform_device(struct platform_device *pdev) +{ + return !pdev->dev.driver; +} + +extern void early_platform_driver_register_all(char *class_str); +extern int early_platform_driver_probe(char *class_str, + int nr_probe, int user_only); + +#define early_platform_init(class_string, platdrv) \ + early_platform_init_buffer(class_string, platdrv, NULL, 0) + +#ifndef MODULE +#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ +static __initdata struct early_platform_driver early_driver = { \ + .class_str = class_string, \ + .buffer = buf, \ + .bufsize = bufsiz, \ + .pdrv = platdrv, \ + .requested_id = EARLY_PLATFORM_ID_UNSET, \ +}; \ +static int __init early_platform_driver_setup_func(char *buffer) \ +{ \ + return early_platform_driver_register(&early_driver, buffer); \ +} \ +early_param(class_string, early_platform_driver_setup_func) +#else /* MODULE */ +#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ +static inline char *early_platform_driver_setup_func(void) \ +{ \ + return bufsiz ? buf : NULL; \ +} +#endif /* MODULE */ + +#endif /* __PLATFORM_EARLY__ */ diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index f5b6841ef7e1..27d459e8a598 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -12,6 +12,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 52350ad0b0a2..8a19c5754978 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -9,6 +9,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index b51ed761ae08..d975e4d404bd 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -11,6 +11,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 89b3e49fc250..318b8cd8d5b7 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -10,6 +10,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 36ff3a3139da..8e6fae60074a 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -11,6 +11,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c index d199618d877c..2d95c9b38330 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c @@ -11,6 +11,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c index 9095c960b455..ef4ff76cbe9e 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c @@ -12,6 +12,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c index 8058c01cf09d..cf2a3f09fee4 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh3.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c @@ -8,6 +8,7 @@ #include #include #include +#include /* All SH3 devices are equipped with IRQ0->5 (except sh7708) */ diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index e19d1ce7b6ad..9b34d1f4e797 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -14,6 +14,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 5c5144bee6bc..39f09504bd96 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -18,6 +18,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 4776e2495738..c006c8fcfa0f 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -13,6 +13,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 1d4c34e7b7db..cf2eec9f6abd 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -19,6 +19,7 @@ #include #include #include +#include #include static struct resource rtc_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index a40ef35d101a..2480ce4a3b1e 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -12,6 +12,7 @@ #include #include #include +#include static struct plat_sci_port scif0_platform_data = { .scscr = SCSCR_REIE, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index b37bda66a532..4592d660b942 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -13,6 +13,7 @@ #include #include #include +#include static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 86845da85997..e64eb96e3589 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -11,6 +11,7 @@ #include #include #include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index a15e25690b5f..0fa56128bdca 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -12,6 +12,7 @@ #include #include #include +#include /* Serial */ static struct plat_sci_port scif0_platform_data = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 7bd2776441ba..9f2f75285ec3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -15,6 +15,7 @@ #include #include #include +#include static struct plat_sci_port scif0_platform_data = { .scscr = SCSCR_REIE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 1ce65f88f060..8e5eaac789a7 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index edb649950662..b4b54aa0c267 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /* Serial */ diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 3e9825031d3d..ec237ab112cf 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c index 06a91569697a..7ea9a8b43955 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c @@ -18,6 +18,7 @@ #include #include #include +#include #include /* SCIF */ diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 2501ce656511..922d9886be18 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -19,6 +19,7 @@ #include #include #include +#include static struct plat_sci_port scif2_platform_data = { .scscr = SCSCR_REIE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 419c5efe4a17..8725d4751baf 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -14,6 +14,7 @@ #include #include #include +#include static struct plat_sci_port scif0_platform_data = { .scscr = SCSCR_REIE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 5fb4cf9b58c6..035a0d4f2a2e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -11,6 +11,7 @@ #include #include #include +#include static struct plat_sci_port scif0_platform_data = { .scscr = SCSCR_REIE | SCSCR_TOIE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index ab7d6b715865..983be87cb7be 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -13,6 +13,7 @@ #include #include #include +#include static struct plat_sci_port scif0_platform_data = { .scscr = SCSCR_REIE | SCSCR_CKE1, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index a438da47285d..bb0cb710c16e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -14,6 +14,7 @@ #include #include #include +#include #include static struct plat_sci_port scif0_platform_data = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index d894165a0ef6..b5d94366eed3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -23,6 +23,7 @@ #include #include #include +#include static struct plat_sci_port scif0_platform_data = { .scscr = SCSCR_REIE | SCSCR_CKE1, diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 14aa4552bc45..e82398d80b74 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -14,6 +14,7 @@ #include #include #include +#include /* * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2 diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index 41c1673afc0b..584a6aeeca26 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -12,6 +12,7 @@ #include #include #include +#include static struct plat_sci_port scif0_platform_data = { .flags = UPF_IOREMAP, diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 2c0e0f37a318..e535507851e1 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -44,6 +44,7 @@ #include #include #include +#include /* * Initialize loops_per_jiffy as 10000000 (1000MIPS). diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index e16b2cd269a3..8ad9fd5c4ff6 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -18,6 +18,7 @@ #include #include #include +#include static void __init sh_late_time_init(void) { diff --git a/drivers/base/platform.c b/drivers/base/platform.c index b6c6c7d97d5b..be1e67ee3af6 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1264,8 +1264,6 @@ int __init platform_bus_init(void) { int error; - early_platform_cleanup(); - error = device_register(&platform_bus); if (error) { put_device(&platform_bus); @@ -1277,289 +1275,3 @@ int __init platform_bus_init(void) of_platform_register_reconfig_notifier(); return error; } - -static __initdata LIST_HEAD(early_platform_driver_list); -static __initdata LIST_HEAD(early_platform_device_list); - -/** - * early_platform_driver_register - register early platform driver - * @epdrv: early_platform driver structure - * @buf: string passed from early_param() - * - * Helper function for early_platform_init() / early_platform_init_buffer() - */ -int __init early_platform_driver_register(struct early_platform_driver *epdrv, - char *buf) -{ - char *tmp; - int n; - - /* Simply add the driver to the end of the global list. - * Drivers will by default be put on the list in compiled-in order. - */ - if (!epdrv->list.next) { - INIT_LIST_HEAD(&epdrv->list); - list_add_tail(&epdrv->list, &early_platform_driver_list); - } - - /* If the user has specified device then make sure the driver - * gets prioritized. The driver of the last device specified on - * command line will be put first on the list. - */ - n = strlen(epdrv->pdrv->driver.name); - if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { - list_move(&epdrv->list, &early_platform_driver_list); - - /* Allow passing parameters after device name */ - if (buf[n] == '\0' || buf[n] == ',') - epdrv->requested_id = -1; - else { - epdrv->requested_id = simple_strtoul(&buf[n + 1], - &tmp, 10); - - if (buf[n] != '.' || (tmp == &buf[n + 1])) { - epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; - n = 0; - } else - n += strcspn(&buf[n + 1], ",") + 1; - } - - if (buf[n] == ',') - n++; - - if (epdrv->bufsize) { - memcpy(epdrv->buffer, &buf[n], - min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); - epdrv->buffer[epdrv->bufsize - 1] = '\0'; - } - } - - return 0; -} - -/** - * early_platform_add_devices - adds a number of early platform devices - * @devs: array of early platform devices to add - * @num: number of early platform devices in array - * - * Used by early architecture code to register early platform devices and - * their platform data. - */ -void __init early_platform_add_devices(struct platform_device **devs, int num) -{ - struct device *dev; - int i; - - /* simply add the devices to list */ - for (i = 0; i < num; i++) { - dev = &devs[i]->dev; - - if (!dev->devres_head.next) { - pm_runtime_early_init(dev); - INIT_LIST_HEAD(&dev->devres_head); - list_add_tail(&dev->devres_head, - &early_platform_device_list); - } - } -} - -/** - * early_platform_driver_register_all - register early platform drivers - * @class_str: string to identify early platform driver class - * - * Used by architecture code to register all early platform drivers - * for a certain class. If omitted then only early platform drivers - * with matching kernel command line class parameters will be registered. - */ -void __init early_platform_driver_register_all(char *class_str) -{ - /* The "class_str" parameter may or may not be present on the kernel - * command line. If it is present then there may be more than one - * matching parameter. - * - * Since we register our early platform drivers using early_param() - * we need to make sure that they also get registered in the case - * when the parameter is missing from the kernel command line. - * - * We use parse_early_options() to make sure the early_param() gets - * called at least once. The early_param() may be called more than - * once since the name of the preferred device may be specified on - * the kernel command line. early_platform_driver_register() handles - * this case for us. - */ - parse_early_options(class_str); -} - -/** - * early_platform_match - find early platform device matching driver - * @epdrv: early platform driver structure - * @id: id to match against - */ -static struct platform_device * __init -early_platform_match(struct early_platform_driver *epdrv, int id) -{ - struct platform_device *pd; - - list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) - if (platform_match(&pd->dev, &epdrv->pdrv->driver)) - if (pd->id == id) - return pd; - - return NULL; -} - -/** - * early_platform_left - check if early platform driver has matching devices - * @epdrv: early platform driver structure - * @id: return true if id or above exists - */ -static int __init early_platform_left(struct early_platform_driver *epdrv, - int id) -{ - struct platform_device *pd; - - list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) - if (platform_match(&pd->dev, &epdrv->pdrv->driver)) - if (pd->id >= id) - return 1; - - return 0; -} - -/** - * early_platform_driver_probe_id - probe drivers matching class_str and id - * @class_str: string to identify early platform driver class - * @id: id to match against - * @nr_probe: number of platform devices to successfully probe before exiting - */ -static int __init early_platform_driver_probe_id(char *class_str, - int id, - int nr_probe) -{ - struct early_platform_driver *epdrv; - struct platform_device *match; - int match_id; - int n = 0; - int left = 0; - - list_for_each_entry(epdrv, &early_platform_driver_list, list) { - /* only use drivers matching our class_str */ - if (strcmp(class_str, epdrv->class_str)) - continue; - - if (id == -2) { - match_id = epdrv->requested_id; - left = 1; - - } else { - match_id = id; - left += early_platform_left(epdrv, id); - - /* skip requested id */ - switch (epdrv->requested_id) { - case EARLY_PLATFORM_ID_ERROR: - case EARLY_PLATFORM_ID_UNSET: - break; - default: - if (epdrv->requested_id == id) - match_id = EARLY_PLATFORM_ID_UNSET; - } - } - - switch (match_id) { - case EARLY_PLATFORM_ID_ERROR: - pr_warn("%s: unable to parse %s parameter\n", - class_str, epdrv->pdrv->driver.name); - /* fall-through */ - case EARLY_PLATFORM_ID_UNSET: - match = NULL; - break; - default: - match = early_platform_match(epdrv, match_id); - } - - if (match) { - /* - * Set up a sensible init_name to enable - * dev_name() and others to be used before the - * rest of the driver core is initialized. - */ - if (!match->dev.init_name && slab_is_available()) { - if (match->id != -1) - match->dev.init_name = - kasprintf(GFP_KERNEL, "%s.%d", - match->name, - match->id); - else - match->dev.init_name = - kasprintf(GFP_KERNEL, "%s", - match->name); - - if (!match->dev.init_name) - return -ENOMEM; - } - - if (epdrv->pdrv->probe(match)) - pr_warn("%s: unable to probe %s early.\n", - class_str, match->name); - else - n++; - } - - if (n >= nr_probe) - break; - } - - if (left) - return n; - else - return -ENODEV; -} - -/** - * early_platform_driver_probe - probe a class of registered drivers - * @class_str: string to identify early platform driver class - * @nr_probe: number of platform devices to successfully probe before exiting - * @user_only: only probe user specified early platform devices - * - * Used by architecture code to probe registered early platform drivers - * within a certain class. For probe to happen a registered early platform - * device matching a registered early platform driver is needed. - */ -int __init early_platform_driver_probe(char *class_str, - int nr_probe, - int user_only) -{ - int k, n, i; - - n = 0; - for (i = -2; n < nr_probe; i++) { - k = early_platform_driver_probe_id(class_str, i, nr_probe - n); - - if (k < 0) - break; - - n += k; - - if (user_only) - break; - } - - return n; -} - -/** - * early_platform_cleanup - clean up early platform code - */ -void __init early_platform_cleanup(void) -{ - struct platform_device *pd, *pd2; - - /* clean up the devres list used to chain devices */ - list_for_each_entry_safe(pd, pd2, &early_platform_device_list, - dev.devres_head) { - list_del(&pd->dev.devres_head); - memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); - } -} - diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index ef773db080e9..3a185485300e 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -25,6 +25,10 @@ #include #include +#ifdef CONFIG_SUPERH +#include +#endif + struct sh_cmt_device; /* @@ -1109,7 +1113,10 @@ static void __exit sh_cmt_exit(void) platform_driver_unregister(&sh_cmt_device_driver); } +#ifdef CONFIG_SUPERH early_platform_init("earlytimer", &sh_cmt_device_driver); +#endif + subsys_initcall(sh_cmt_init); module_exit(sh_cmt_exit); diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 354b27d14a19..d581060d33a2 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -23,6 +23,10 @@ #include #include +#ifdef CONFIG_SUPERH +#include +#endif + struct sh_mtu2_device; struct sh_mtu2_channel { @@ -511,7 +515,10 @@ static void __exit sh_mtu2_exit(void) platform_driver_unregister(&sh_mtu2_device_driver); } +#ifdef CONFIG_SUPERH early_platform_init("earlytimer", &sh_mtu2_device_driver); +#endif + subsys_initcall(sh_mtu2_init); module_exit(sh_mtu2_exit); diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 8c4f3753b36e..50e30ead050e 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -24,6 +24,10 @@ #include #include +#ifdef CONFIG_SUPERH +#include +#endif + enum sh_tmu_model { SH_TMU, SH_TMU_SH3, @@ -615,6 +619,7 @@ static int sh_tmu_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); return ret; } + if (is_early_platform_device(pdev)) return 0; @@ -665,7 +670,10 @@ static void __exit sh_tmu_exit(void) platform_driver_unregister(&sh_tmu_device_driver); } +#ifdef CONFIG_SUPERH early_platform_init("earlytimer", &sh_tmu_device_driver); +#endif + subsys_initcall(sh_tmu_init); module_exit(sh_tmu_exit); diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 4e754a4850e6..2a645fd7f07b 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -54,6 +54,7 @@ #ifdef CONFIG_SUPERH #include +#include #endif #include "serial_mctrl_gpio.h" @@ -3086,6 +3087,7 @@ static struct console serial_console = { .data = &sci_uart_driver, }; +#ifdef CONFIG_SUPERH static struct console early_serial_console = { .name = "early_ttySC", .write = serial_console_write, @@ -3114,6 +3116,7 @@ static int sci_probe_earlyprintk(struct platform_device *pdev) register_console(&early_serial_console); return 0; } +#endif #define SCI_CONSOLE (&serial_console) @@ -3314,8 +3317,10 @@ static int sci_probe(struct platform_device *dev) * the special early probe. We don't have sufficient device state * to make it beyond this yet. */ +#ifdef CONFIG_SUPERH if (is_early_platform_device(dev)) return sci_probe_earlyprintk(dev); +#endif if (dev->dev.of_node) { p = sci_parse_dt(dev, &dev_id); @@ -3410,7 +3415,7 @@ static void __exit sci_exit(void) uart_unregister_driver(&sci_uart_driver); } -#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE +#if defined(CONFIG_SUPERH) && defined(CONFIG_SERIAL_SH_SCI_CONSOLE) early_platform_init_buffer("earlyprintk", &sci_driver, early_serial_buf, ARRAY_SIZE(early_serial_buf)); #endif diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 1b5cec067533..85aa28a041a9 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -292,58 +292,6 @@ void platform_unregister_drivers(struct platform_driver * const *drivers, #define platform_register_drivers(drivers, count) \ __platform_register_drivers(drivers, count, THIS_MODULE) -/* early platform driver interface */ -struct early_platform_driver { - const char *class_str; - struct platform_driver *pdrv; - struct list_head list; - int requested_id; - char *buffer; - int bufsize; -}; - -#define EARLY_PLATFORM_ID_UNSET -2 -#define EARLY_PLATFORM_ID_ERROR -3 - -extern int early_platform_driver_register(struct early_platform_driver *epdrv, - char *buf); -extern void early_platform_add_devices(struct platform_device **devs, int num); - -static inline int is_early_platform_device(struct platform_device *pdev) -{ - return !pdev->dev.driver; -} - -extern void early_platform_driver_register_all(char *class_str); -extern int early_platform_driver_probe(char *class_str, - int nr_probe, int user_only); -extern void early_platform_cleanup(void); - -#define early_platform_init(class_string, platdrv) \ - early_platform_init_buffer(class_string, platdrv, NULL, 0) - -#ifndef MODULE -#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ -static __initdata struct early_platform_driver early_driver = { \ - .class_str = class_string, \ - .buffer = buf, \ - .bufsize = bufsiz, \ - .pdrv = platdrv, \ - .requested_id = EARLY_PLATFORM_ID_UNSET, \ -}; \ -static int __init early_platform_driver_setup_func(char *buffer) \ -{ \ - return early_platform_driver_register(&early_driver, buffer); \ -} \ -early_param(class_string, early_platform_driver_setup_func) -#else /* MODULE */ -#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ -static inline char *early_platform_driver_setup_func(void) \ -{ \ - return bufsiz ? buf : NULL; \ -} -#endif /* MODULE */ - #ifdef CONFIG_SUSPEND extern int platform_pm_suspend(struct device *dev); extern int platform_pm_resume(struct device *dev); @@ -378,4 +326,16 @@ extern int platform_dma_configure(struct device *dev); #define USE_PLATFORM_PM_SLEEP_OPS #endif +#ifndef CONFIG_SUPERH +/* + * REVISIT: This stub is needed for all non-SuperH users of early platform + * drivers. It should go away once we introduce the new platform_device-based + * early driver framework. + */ +static inline int is_early_platform_device(struct platform_device *pdev) +{ + return 0; +} +#endif /* CONFIG_SUPERH */ + #endif /* _PLATFORM_DEVICE_H_ */ -- cgit v1.2.3-59-g8ed1b From 201e91091b1d47047f55580b5474e1239f4d17aa Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 3 Oct 2019 11:29:13 +0200 Subject: sh: add the sh_ prefix to early platform symbols Old early platform device support is now sh-specific. Before moving on to implementing new early platform framework based on real platform devices, prefix all early platform symbols with 'sh_'. Signed-off-by: Bartosz Golaszewski Cc: Rich Felker Link: https://lore.kernel.org/r/20191003092913.10731-3-brgl@bgdev.pl Signed-off-by: Greg Kroah-Hartman --- arch/sh/drivers/platform_early.c | 66 +++++++++++++++++----------------- arch/sh/include/asm/platform_early.h | 30 ++++++++-------- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-mxg.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 8 ++--- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7734.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-shx3.c | 2 +- arch/sh/kernel/cpu/sh5/setup-sh5.c | 2 +- arch/sh/kernel/setup.c | 2 +- arch/sh/kernel/time.c | 4 +-- drivers/clocksource/sh_cmt.c | 6 ++-- drivers/clocksource/sh_mtu2.c | 6 ++-- drivers/clocksource/sh_tmu.c | 6 ++-- drivers/tty/serial/sh-sci.c | 4 +-- include/linux/platform_device.h | 2 +- 37 files changed, 94 insertions(+), 94 deletions(-) (limited to 'include') diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c index 3dfe9f3541bb..f6d148451dfc 100644 --- a/arch/sh/drivers/platform_early.c +++ b/arch/sh/drivers/platform_early.c @@ -4,8 +4,8 @@ #include #include -static __initdata LIST_HEAD(early_platform_driver_list); -static __initdata LIST_HEAD(early_platform_device_list); +static __initdata LIST_HEAD(sh_early_platform_driver_list); +static __initdata LIST_HEAD(sh_early_platform_device_list); static const struct platform_device_id * platform_match_id(const struct platform_device_id *id, @@ -58,13 +58,13 @@ static void pm_runtime_early_init(struct device *dev) {} #endif /** - * early_platform_driver_register - register early platform driver - * @epdrv: early_platform driver structure + * sh_early_platform_driver_register - register early platform driver + * @epdrv: sh_early_platform driver structure * @buf: string passed from early_param() * - * Helper function for early_platform_init() / early_platform_init_buffer() + * Helper function for sh_early_platform_init() / sh_early_platform_init_buffer() */ -int __init early_platform_driver_register(struct early_platform_driver *epdrv, +int __init sh_early_platform_driver_register(struct sh_early_platform_driver *epdrv, char *buf) { char *tmp; @@ -75,7 +75,7 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv, */ if (!epdrv->list.next) { INIT_LIST_HEAD(&epdrv->list); - list_add_tail(&epdrv->list, &early_platform_driver_list); + list_add_tail(&epdrv->list, &sh_early_platform_driver_list); } /* If the user has specified device then make sure the driver @@ -84,7 +84,7 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv, */ n = strlen(epdrv->pdrv->driver.name); if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { - list_move(&epdrv->list, &early_platform_driver_list); + list_move(&epdrv->list, &sh_early_platform_driver_list); /* Allow passing parameters after device name */ if (buf[n] == '\0' || buf[n] == ',') @@ -114,14 +114,14 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv, } /** - * early_platform_add_devices - adds a number of early platform devices + * sh_early_platform_add_devices - adds a number of early platform devices * @devs: array of early platform devices to add * @num: number of early platform devices in array * * Used by early architecture code to register early platform devices and * their platform data. */ -void __init early_platform_add_devices(struct platform_device **devs, int num) +void __init sh_early_platform_add_devices(struct platform_device **devs, int num) { struct device *dev; int i; @@ -134,20 +134,20 @@ void __init early_platform_add_devices(struct platform_device **devs, int num) pm_runtime_early_init(dev); INIT_LIST_HEAD(&dev->devres_head); list_add_tail(&dev->devres_head, - &early_platform_device_list); + &sh_early_platform_device_list); } } } /** - * early_platform_driver_register_all - register early platform drivers + * sh_early_platform_driver_register_all - register early platform drivers * @class_str: string to identify early platform driver class * * Used by architecture code to register all early platform drivers * for a certain class. If omitted then only early platform drivers * with matching kernel command line class parameters will be registered. */ -void __init early_platform_driver_register_all(char *class_str) +void __init sh_early_platform_driver_register_all(char *class_str) { /* The "class_str" parameter may or may not be present on the kernel * command line. If it is present then there may be more than one @@ -160,23 +160,23 @@ void __init early_platform_driver_register_all(char *class_str) * We use parse_early_options() to make sure the early_param() gets * called at least once. The early_param() may be called more than * once since the name of the preferred device may be specified on - * the kernel command line. early_platform_driver_register() handles + * the kernel command line. sh_early_platform_driver_register() handles * this case for us. */ parse_early_options(class_str); } /** - * early_platform_match - find early platform device matching driver + * sh_early_platform_match - find early platform device matching driver * @epdrv: early platform driver structure * @id: id to match against */ static struct platform_device * __init -early_platform_match(struct early_platform_driver *epdrv, int id) +sh_early_platform_match(struct sh_early_platform_driver *epdrv, int id) { struct platform_device *pd; - list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) + list_for_each_entry(pd, &sh_early_platform_device_list, dev.devres_head) if (platform_match(&pd->dev, &epdrv->pdrv->driver)) if (pd->id == id) return pd; @@ -185,16 +185,16 @@ early_platform_match(struct early_platform_driver *epdrv, int id) } /** - * early_platform_left - check if early platform driver has matching devices + * sh_early_platform_left - check if early platform driver has matching devices * @epdrv: early platform driver structure * @id: return true if id or above exists */ -static int __init early_platform_left(struct early_platform_driver *epdrv, +static int __init sh_early_platform_left(struct sh_early_platform_driver *epdrv, int id) { struct platform_device *pd; - list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) + list_for_each_entry(pd, &sh_early_platform_device_list, dev.devres_head) if (platform_match(&pd->dev, &epdrv->pdrv->driver)) if (pd->id >= id) return 1; @@ -203,22 +203,22 @@ static int __init early_platform_left(struct early_platform_driver *epdrv, } /** - * early_platform_driver_probe_id - probe drivers matching class_str and id + * sh_early_platform_driver_probe_id - probe drivers matching class_str and id * @class_str: string to identify early platform driver class * @id: id to match against * @nr_probe: number of platform devices to successfully probe before exiting */ -static int __init early_platform_driver_probe_id(char *class_str, +static int __init sh_early_platform_driver_probe_id(char *class_str, int id, int nr_probe) { - struct early_platform_driver *epdrv; + struct sh_early_platform_driver *epdrv; struct platform_device *match; int match_id; int n = 0; int left = 0; - list_for_each_entry(epdrv, &early_platform_driver_list, list) { + list_for_each_entry(epdrv, &sh_early_platform_driver_list, list) { /* only use drivers matching our class_str */ if (strcmp(class_str, epdrv->class_str)) continue; @@ -229,7 +229,7 @@ static int __init early_platform_driver_probe_id(char *class_str, } else { match_id = id; - left += early_platform_left(epdrv, id); + left += sh_early_platform_left(epdrv, id); /* skip requested id */ switch (epdrv->requested_id) { @@ -251,7 +251,7 @@ static int __init early_platform_driver_probe_id(char *class_str, match = NULL; break; default: - match = early_platform_match(epdrv, match_id); + match = sh_early_platform_match(epdrv, match_id); } if (match) { @@ -293,7 +293,7 @@ static int __init early_platform_driver_probe_id(char *class_str, } /** - * early_platform_driver_probe - probe a class of registered drivers + * sh_early_platform_driver_probe - probe a class of registered drivers * @class_str: string to identify early platform driver class * @nr_probe: number of platform devices to successfully probe before exiting * @user_only: only probe user specified early platform devices @@ -302,7 +302,7 @@ static int __init early_platform_driver_probe_id(char *class_str, * within a certain class. For probe to happen a registered early platform * device matching a registered early platform driver is needed. */ -int __init early_platform_driver_probe(char *class_str, +int __init sh_early_platform_driver_probe(char *class_str, int nr_probe, int user_only) { @@ -310,7 +310,7 @@ int __init early_platform_driver_probe(char *class_str, n = 0; for (i = -2; n < nr_probe; i++) { - k = early_platform_driver_probe_id(class_str, i, nr_probe - n); + k = sh_early_platform_driver_probe_id(class_str, i, nr_probe - n); if (k < 0) break; @@ -325,14 +325,14 @@ int __init early_platform_driver_probe(char *class_str, } /** - * early_platform_cleanup - clean up early platform code + * sh_early_platform_cleanup - clean up early platform code */ -static int __init early_platform_cleanup(void) +static int __init sh_early_platform_cleanup(void) { struct platform_device *pd, *pd2; /* clean up the devres list used to chain devices */ - list_for_each_entry_safe(pd, pd2, &early_platform_device_list, + list_for_each_entry_safe(pd, pd2, &sh_early_platform_device_list, dev.devres_head) { list_del(&pd->dev.devres_head); memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); @@ -344,4 +344,4 @@ static int __init early_platform_cleanup(void) * This must happen once after all early devices are probed but before probing * real platform devices. */ -subsys_initcall(early_platform_cleanup); +subsys_initcall(sh_early_platform_cleanup); diff --git a/arch/sh/include/asm/platform_early.h b/arch/sh/include/asm/platform_early.h index 4590ab757d5f..fc802137c37d 100644 --- a/arch/sh/include/asm/platform_early.h +++ b/arch/sh/include/asm/platform_early.h @@ -8,7 +8,7 @@ #include #include -struct early_platform_driver { +struct sh_early_platform_driver { const char *class_str; struct platform_driver *pdrv; struct list_head list; @@ -20,39 +20,39 @@ struct early_platform_driver { #define EARLY_PLATFORM_ID_UNSET -2 #define EARLY_PLATFORM_ID_ERROR -3 -extern int early_platform_driver_register(struct early_platform_driver *epdrv, +extern int sh_early_platform_driver_register(struct sh_early_platform_driver *epdrv, char *buf); -extern void early_platform_add_devices(struct platform_device **devs, int num); +extern void sh_early_platform_add_devices(struct platform_device **devs, int num); -static inline int is_early_platform_device(struct platform_device *pdev) +static inline int is_sh_early_platform_device(struct platform_device *pdev) { return !pdev->dev.driver; } -extern void early_platform_driver_register_all(char *class_str); -extern int early_platform_driver_probe(char *class_str, +extern void sh_early_platform_driver_register_all(char *class_str); +extern int sh_early_platform_driver_probe(char *class_str, int nr_probe, int user_only); -#define early_platform_init(class_string, platdrv) \ - early_platform_init_buffer(class_string, platdrv, NULL, 0) +#define sh_early_platform_init(class_string, platdrv) \ + sh_early_platform_init_buffer(class_string, platdrv, NULL, 0) #ifndef MODULE -#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ -static __initdata struct early_platform_driver early_driver = { \ +#define sh_early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ +static __initdata struct sh_early_platform_driver early_driver = { \ .class_str = class_string, \ .buffer = buf, \ .bufsize = bufsiz, \ .pdrv = platdrv, \ .requested_id = EARLY_PLATFORM_ID_UNSET, \ }; \ -static int __init early_platform_driver_setup_func(char *buffer) \ +static int __init sh_early_platform_driver_setup_func(char *buffer) \ { \ - return early_platform_driver_register(&early_driver, buffer); \ + return sh_early_platform_driver_register(&early_driver, buffer); \ } \ -early_param(class_string, early_platform_driver_setup_func) +early_param(class_string, sh_early_platform_driver_setup_func) #else /* MODULE */ -#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ -static inline char *early_platform_driver_setup_func(void) \ +#define sh_early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ +static inline char *sh_early_platform_driver_setup_func(void) \ { \ return bufsiz ? buf : NULL; \ } diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 27d459e8a598..b1c877b6a420 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -200,6 +200,6 @@ void __init plat_early_device_setup(void) /* enable CMT clock */ __raw_writeb(__raw_readb(STBCR3) & ~0x10, STBCR3); - early_platform_add_devices(sh7619_early_devices, + sh_early_platform_add_devices(sh7619_early_devices, ARRAY_SIZE(sh7619_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 8a19c5754978..cefa07924c16 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -170,6 +170,6 @@ static struct platform_device *mxg_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(mxg_early_devices, + sh_early_platform_add_devices(mxg_early_devices, ARRAY_SIZE(mxg_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index d975e4d404bd..28f1bebf3405 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -413,6 +413,6 @@ void __init plat_early_device_setup(void) /* enable MTU2 clock */ __raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3); - early_platform_add_devices(sh7201_early_devices, + sh_early_platform_add_devices(sh7201_early_devices, ARRAY_SIZE(sh7201_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 318b8cd8d5b7..4839f3aaeb4c 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -350,6 +350,6 @@ void __init plat_early_device_setup(void) /* enable MTU2 clock */ __raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3); - early_platform_add_devices(sh7203_early_devices, + sh_early_platform_add_devices(sh7203_early_devices, ARRAY_SIZE(sh7203_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 8e6fae60074a..68add5af4cc5 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -286,6 +286,6 @@ void __init plat_early_device_setup(void) /* enable MTU2 clock */ __raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3); - early_platform_add_devices(sh7206_early_devices, + sh_early_platform_add_devices(sh7206_early_devices, ARRAY_SIZE(sh7206_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c index 2d95c9b38330..8a1cb613dd2e 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c @@ -547,6 +547,6 @@ static struct platform_device *sh7264_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7264_early_devices, + sh_early_platform_add_devices(sh7264_early_devices, ARRAY_SIZE(sh7264_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c index ef4ff76cbe9e..8b1ef3028320 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c @@ -563,6 +563,6 @@ static struct platform_device *sh7269_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7269_early_devices, + sh_early_platform_add_devices(sh7269_early_devices, ARRAY_SIZE(sh7269_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 9b34d1f4e797..0544134b3f20 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -179,7 +179,7 @@ static struct platform_device *sh7705_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7705_early_devices, + sh_early_platform_add_devices(sh7705_early_devices, ARRAY_SIZE(sh7705_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 39f09504bd96..4947f57748bc 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -231,7 +231,7 @@ static struct platform_device *sh770x_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh770x_early_devices, + sh_early_platform_add_devices(sh770x_early_devices, ARRAY_SIZE(sh770x_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index c006c8fcfa0f..381910761579 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -178,7 +178,7 @@ static struct platform_device *sh7710_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7710_early_devices, + sh_early_platform_add_devices(sh7710_early_devices, ARRAY_SIZE(sh7710_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index cf2eec9f6abd..425d067dae9b 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -212,7 +212,7 @@ static struct platform_device *sh7720_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7720_early_devices, + sh_early_platform_add_devices(sh7720_early_devices, ARRAY_SIZE(sh7720_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index 2480ce4a3b1e..e6737f3d0df2 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -77,7 +77,7 @@ static struct platform_device *sh4202_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh4202_early_devices, + sh_early_platform_add_devices(sh4202_early_devices, ARRAY_SIZE(sh4202_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 4592d660b942..19c8f1d69071 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -162,15 +162,15 @@ void __init plat_early_device_setup(void) if (mach_is_rts7751r2d()) { scif_platform_data.scscr |= SCSCR_CKE1; dev[0] = &scif_device; - early_platform_add_devices(dev, 1); + sh_early_platform_add_devices(dev, 1); } else { dev[0] = &sci_device; - early_platform_add_devices(dev, 1); + sh_early_platform_add_devices(dev, 1); dev[0] = &scif_device; - early_platform_add_devices(dev, 1); + sh_early_platform_add_devices(dev, 1); } - early_platform_add_devices(sh7750_early_devices, + sh_early_platform_add_devices(sh7750_early_devices, ARRAY_SIZE(sh7750_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index e64eb96e3589..14212f5d803c 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -272,7 +272,7 @@ static struct platform_device *sh7760_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7760_early_devices, + sh_early_platform_add_devices(sh7760_early_devices, ARRAY_SIZE(sh7760_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 0fa56128bdca..b6015188fab1 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -297,7 +297,7 @@ static struct platform_device *sh7343_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7343_early_devices, + sh_early_platform_add_devices(sh7343_early_devices, ARRAY_SIZE(sh7343_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 9f2f75285ec3..6676beef053e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -241,7 +241,7 @@ static struct platform_device *sh7366_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7366_early_devices, + sh_early_platform_add_devices(sh7366_early_devices, ARRAY_SIZE(sh7366_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 8e5eaac789a7..0c6757ef63f4 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -513,7 +513,7 @@ static struct platform_device *sh7722_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7722_early_devices, + sh_early_platform_add_devices(sh7722_early_devices, ARRAY_SIZE(sh7722_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index b4b54aa0c267..83ae1ad4a86e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -411,7 +411,7 @@ static struct platform_device *sh7723_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7723_early_devices, + sh_early_platform_add_devices(sh7723_early_devices, ARRAY_SIZE(sh7723_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index ec237ab112cf..0d990ab1ba2a 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -831,7 +831,7 @@ static struct platform_device *sh7724_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7724_early_devices, + sh_early_platform_add_devices(sh7724_early_devices, ARRAY_SIZE(sh7724_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c index 7ea9a8b43955..9911da794358 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c @@ -281,7 +281,7 @@ static struct platform_device *sh7734_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7734_early_devices, + sh_early_platform_add_devices(sh7734_early_devices, ARRAY_SIZE(sh7734_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 922d9886be18..67e330b7ea46 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -768,7 +768,7 @@ static struct platform_device *sh7757_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7757_early_devices, + sh_early_platform_add_devices(sh7757_early_devices, ARRAY_SIZE(sh7757_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 8725d4751baf..b0608664785f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -222,7 +222,7 @@ static struct platform_device *sh7763_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7763_early_devices, + sh_early_platform_add_devices(sh7763_early_devices, ARRAY_SIZE(sh7763_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 035a0d4f2a2e..5efec6ceb04d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -317,7 +317,7 @@ static struct platform_device *sh7770_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7770_early_devices, + sh_early_platform_add_devices(sh7770_early_devices, ARRAY_SIZE(sh7770_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 983be87cb7be..c818b788ecb0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -286,7 +286,7 @@ void __init plat_early_device_setup(void) scif1_platform_data.scscr &= ~SCSCR_CKE1; } - early_platform_add_devices(sh7780_early_devices, + sh_early_platform_add_devices(sh7780_early_devices, ARRAY_SIZE(sh7780_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index bb0cb710c16e..3b4a414d60a9 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -354,7 +354,7 @@ static struct platform_device *sh7785_early_devices[] __initdata = { void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7785_early_devices, + sh_early_platform_add_devices(sh7785_early_devices, ARRAY_SIZE(sh7785_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index b5d94366eed3..4b0db8259e3d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -835,6 +835,6 @@ arch_initcall(sh7786_devices_setup); void __init plat_early_device_setup(void) { - early_platform_add_devices(sh7786_early_devices, + sh_early_platform_add_devices(sh7786_early_devices, ARRAY_SIZE(sh7786_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index e82398d80b74..7014d6d199b3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -153,7 +153,7 @@ arch_initcall(shx3_devices_setup); void __init plat_early_device_setup(void) { - early_platform_add_devices(shx3_early_devices, + sh_early_platform_add_devices(shx3_early_devices, ARRAY_SIZE(shx3_early_devices)); } diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index 584a6aeeca26..dc8476d67244 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -116,6 +116,6 @@ arch_initcall(sh5_devices_setup); void __init plat_early_device_setup(void) { - early_platform_add_devices(sh5_early_devices, + sh_early_platform_add_devices(sh5_early_devices, ARRAY_SIZE(sh5_early_devices)); } diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index e535507851e1..914174a125a4 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -329,7 +329,7 @@ void __init setup_arch(char **cmdline_p) sh_mv_setup(); /* Let earlyprintk output early console messages */ - early_platform_driver_probe("earlyprintk", 1, 1); + sh_early_platform_driver_probe("earlyprintk", 1, 1); #ifdef CONFIG_OF_FLATTREE #ifdef CONFIG_USE_BUILTIN_DTB diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 8ad9fd5c4ff6..821a09cbd605 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -31,8 +31,8 @@ static void __init sh_late_time_init(void) * clocksource and the jiffies clocksource is used transparently * instead. No error handling is necessary here. */ - early_platform_driver_register_all("earlytimer"); - early_platform_driver_probe("earlytimer", 2, 0); + sh_early_platform_driver_register_all("earlytimer"); + sh_early_platform_driver_probe("earlytimer", 2, 0); } void __init time_init(void) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 3a185485300e..9cde50cb3220 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -1056,7 +1056,7 @@ static int sh_cmt_probe(struct platform_device *pdev) struct sh_cmt_device *cmt = platform_get_drvdata(pdev); int ret; - if (!is_early_platform_device(pdev)) { + if (!is_sh_early_platform_device(pdev)) { pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); } @@ -1076,7 +1076,7 @@ static int sh_cmt_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); return ret; } - if (is_early_platform_device(pdev)) + if (is_sh_early_platform_device(pdev)) return 0; out: @@ -1114,7 +1114,7 @@ static void __exit sh_cmt_exit(void) } #ifdef CONFIG_SUPERH -early_platform_init("earlytimer", &sh_cmt_device_driver); +sh_early_platform_init("earlytimer", &sh_cmt_device_driver); #endif subsys_initcall(sh_cmt_init); diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index d581060d33a2..c40eef091a04 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -446,7 +446,7 @@ static int sh_mtu2_probe(struct platform_device *pdev) struct sh_mtu2_device *mtu = platform_get_drvdata(pdev); int ret; - if (!is_early_platform_device(pdev)) { + if (!is_sh_early_platform_device(pdev)) { pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); } @@ -466,7 +466,7 @@ static int sh_mtu2_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); return ret; } - if (is_early_platform_device(pdev)) + if (is_sh_early_platform_device(pdev)) return 0; out: @@ -516,7 +516,7 @@ static void __exit sh_mtu2_exit(void) } #ifdef CONFIG_SUPERH -early_platform_init("earlytimer", &sh_mtu2_device_driver); +sh_early_platform_init("earlytimer", &sh_mtu2_device_driver); #endif subsys_initcall(sh_mtu2_init); diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 50e30ead050e..d49690d15536 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -599,7 +599,7 @@ static int sh_tmu_probe(struct platform_device *pdev) struct sh_tmu_device *tmu = platform_get_drvdata(pdev); int ret; - if (!is_early_platform_device(pdev)) { + if (!is_sh_early_platform_device(pdev)) { pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); } @@ -620,7 +620,7 @@ static int sh_tmu_probe(struct platform_device *pdev) return ret; } - if (is_early_platform_device(pdev)) + if (is_sh_early_platform_device(pdev)) return 0; out: @@ -671,7 +671,7 @@ static void __exit sh_tmu_exit(void) } #ifdef CONFIG_SUPERH -early_platform_init("earlytimer", &sh_tmu_device_driver); +sh_early_platform_init("earlytimer", &sh_tmu_device_driver); #endif subsys_initcall(sh_tmu_init); diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 2a645fd7f07b..970f1f86b945 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -3318,7 +3318,7 @@ static int sci_probe(struct platform_device *dev) * to make it beyond this yet. */ #ifdef CONFIG_SUPERH - if (is_early_platform_device(dev)) + if (is_sh_early_platform_device(dev)) return sci_probe_earlyprintk(dev); #endif @@ -3416,7 +3416,7 @@ static void __exit sci_exit(void) } #if defined(CONFIG_SUPERH) && defined(CONFIG_SERIAL_SH_SCI_CONSOLE) -early_platform_init_buffer("earlyprintk", &sci_driver, +sh_early_platform_init_buffer("earlyprintk", &sci_driver, early_serial_buf, ARRAY_SIZE(early_serial_buf)); #endif #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 85aa28a041a9..f086b6a1bc6b 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -332,7 +332,7 @@ extern int platform_dma_configure(struct device *dev); * drivers. It should go away once we introduce the new platform_device-based * early driver framework. */ -static inline int is_early_platform_device(struct platform_device *pdev) +static inline int is_sh_early_platform_device(struct platform_device *pdev) { return 0; } -- cgit v1.2.3-59-g8ed1b From c31e73121f4c1ec45a3e523ac6ce3ce6dafdcec1 Mon Sep 17 00:00:00 2001 From: Murali Nalajala Date: Mon, 7 Oct 2019 13:37:42 -0700 Subject: base: soc: Handle custom soc information sysfs entries Soc framework exposed sysfs entries are not sufficient for some of the h/w platforms. Currently there is no interface where soc drivers can expose further information about their SoCs via soc framework. This change address this limitation where clients can pass their custom entries as attribute group and soc framework would expose them as sysfs properties. Signed-off-by: Murali Nalajala Reviewed-by: Bjorn Andersson Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/1570480662-25252-1-git-send-email-mnalajal@codeaurora.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/soc.c | 30 +++++++++++++++++------------- include/linux/sys_soc.h | 1 + 2 files changed, 18 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 7c0c5ca5953d..4af11a423475 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -104,15 +104,12 @@ static const struct attribute_group soc_attr_group = { .is_visible = soc_attribute_mode, }; -static const struct attribute_group *soc_attr_groups[] = { - &soc_attr_group, - NULL, -}; - static void soc_release(struct device *dev) { struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); + kfree(soc_dev->dev.groups); kfree(soc_dev); } @@ -121,6 +118,7 @@ static struct soc_device_attribute *early_soc_dev_attr; struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr) { struct soc_device *soc_dev; + const struct attribute_group **soc_attr_groups; int ret; if (!soc_bus_type.p) { @@ -136,10 +134,18 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr goto out1; } + soc_attr_groups = kcalloc(3, sizeof(*soc_attr_groups), GFP_KERNEL); + if (!soc_attr_groups) { + ret = -ENOMEM; + goto out2; + } + soc_attr_groups[0] = &soc_attr_group; + soc_attr_groups[1] = soc_dev_attr->custom_attr_group; + /* Fetch a unique (reclaimable) SOC ID. */ ret = ida_simple_get(&soc_ida, 0, 0, GFP_KERNEL); if (ret < 0) - goto out2; + goto out3; soc_dev->soc_dev_num = ret; soc_dev->attr = soc_dev_attr; @@ -150,15 +156,15 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr dev_set_name(&soc_dev->dev, "soc%d", soc_dev->soc_dev_num); ret = device_register(&soc_dev->dev); - if (ret) - goto out3; + if (ret) { + put_device(&soc_dev->dev); + return ERR_PTR(ret); + } return soc_dev; out3: - ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); - put_device(&soc_dev->dev); - soc_dev = NULL; + kfree(soc_attr_groups); out2: kfree(soc_dev); out1: @@ -169,8 +175,6 @@ EXPORT_SYMBOL_GPL(soc_device_register); /* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */ void soc_device_unregister(struct soc_device *soc_dev) { - ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); - device_unregister(&soc_dev->dev); early_soc_dev_attr = NULL; } diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index 48ceea867dd6..d9b3cf0f410c 100644 --- a/include/linux/sys_soc.h +++ b/include/linux/sys_soc.h @@ -15,6 +15,7 @@ struct soc_device_attribute { const char *serial_number; const char *soc_id; const void *data; + const struct attribute_group *custom_attr_group; }; /** -- cgit v1.2.3-59-g8ed1b From 9655ac4aca20d654769b8f0d6a5be34b7ce7bad1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Oct 2019 15:29:24 +0200 Subject: debugfs: remove return value of debugfs_create_u8() No one checks the return value of debugfs_create_u8(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20191011132931.1186197-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 4 ++-- fs/debugfs/file.c | 15 +++------------ include/linux/debugfs.h | 12 ++++-------- 3 files changed, 9 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 9e27c843d00e..c146f18eb8ac 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -68,8 +68,8 @@ actually necessary; the debugfs code provides a number of helper functions for simple situations. Files containing a single integer value can be created with any of: - struct dentry *debugfs_create_u8(const char *name, umode_t mode, - struct dentry *parent, u8 *value); + void debugfs_create_u8(const char *name, umode_t mode, + struct dentry *parent, u8 *value); struct dentry *debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 87846aad594b..2d5d9a0a6f57 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -420,20 +420,11 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%llu\n"); * This function creates a file in debugfs with the given name that * contains the value of the variable @value. If the @mode variable is so * set, it can be read from, and written to. - * - * This function will return a pointer to a dentry if it succeeds. This - * pointer must be passed to the debugfs_remove() function when the file is - * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be - * returned. - * - * If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will - * be returned. */ -struct dentry *debugfs_create_u8(const char *name, umode_t mode, - struct dentry *parent, u8 *value) +void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, + u8 *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u8, + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u8, &fops_u8_ro, &fops_u8_wo); } EXPORT_SYMBOL_GPL(debugfs_create_u8); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 58424eb3b329..8e071f599245 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -97,8 +97,8 @@ ssize_t debugfs_attr_write(struct file *file, const char __user *buf, struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, struct dentry *new_dir, const char *new_name); -struct dentry *debugfs_create_u8(const char *name, umode_t mode, - struct dentry *parent, u8 *value); +void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, + u8 *value); struct dentry *debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, @@ -244,12 +244,8 @@ static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentr return ERR_PTR(-ENODEV); } -static inline struct dentry *debugfs_create_u8(const char *name, umode_t mode, - struct dentry *parent, - u8 *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_u8(const char *name, umode_t mode, + struct dentry *parent, u8 *value) { } static inline struct dentry *debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, -- cgit v1.2.3-59-g8ed1b From 313f5dbba41d905d59c820bb2d91ee6c661aff99 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Oct 2019 15:29:25 +0200 Subject: debugfs: remove return value of debugfs_create_u16() No one checks the return value of debugfs_create_u16(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20191011132931.1186197-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 4 ++-- fs/debugfs/file.c | 15 +++------------ include/linux/debugfs.h | 12 ++++-------- 3 files changed, 9 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index c146f18eb8ac..6abcf41fbd37 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -70,8 +70,8 @@ created with any of: void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value); - struct dentry *debugfs_create_u16(const char *name, umode_t mode, - struct dentry *parent, u16 *value); + void debugfs_create_u16(const char *name, umode_t mode, + struct dentry *parent, u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value); struct dentry *debugfs_create_u64(const char *name, umode_t mode, diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 2d5d9a0a6f57..8091a7ef3589 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -456,20 +456,11 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%llu\n"); * This function creates a file in debugfs with the given name that * contains the value of the variable @value. If the @mode variable is so * set, it can be read from, and written to. - * - * This function will return a pointer to a dentry if it succeeds. This - * pointer must be passed to the debugfs_remove() function when the file is - * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be - * returned. - * - * If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will - * be returned. */ -struct dentry *debugfs_create_u16(const char *name, umode_t mode, - struct dentry *parent, u16 *value) +void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, + u16 *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u16, + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u16, &fops_u16_ro, &fops_u16_wo); } EXPORT_SYMBOL_GPL(debugfs_create_u16); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 8e071f599245..c83a33a76b6c 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -99,8 +99,8 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value); -struct dentry *debugfs_create_u16(const char *name, umode_t mode, - struct dentry *parent, u16 *value); +void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, + u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value); struct dentry *debugfs_create_u64(const char *name, umode_t mode, @@ -247,12 +247,8 @@ static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentr static inline void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value) { } -static inline struct dentry *debugfs_create_u16(const char *name, umode_t mode, - struct dentry *parent, - u16 *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_u16(const char *name, umode_t mode, + struct dentry *parent, u16 *value) { } static inline struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, -- cgit v1.2.3-59-g8ed1b From ad26221fb9e64e69e32a2caf58dba067ca4e815e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Oct 2019 15:29:26 +0200 Subject: debugfs: remove return value of debugfs_create_u64() No one checks the return value of debugfs_create_u64(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20191011132931.1186197-3-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 4 ++-- fs/debugfs/file.c | 15 +++------------ include/linux/debugfs.h | 12 ++++-------- 3 files changed, 9 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 6abcf41fbd37..1b299ae4904d 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -74,8 +74,8 @@ created with any of: struct dentry *parent, u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value); - struct dentry *debugfs_create_u64(const char *name, umode_t mode, - struct dentry *parent, u64 *value); + void debugfs_create_u64(const char *name, umode_t mode, + struct dentry *parent, u64 *value); These files support both reading and writing the given value; if a specific file should not be written to, simply set the mode bits accordingly. The diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 8091a7ef3589..4c8912d7d34c 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -538,20 +538,11 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); * This function creates a file in debugfs with the given name that * contains the value of the variable @value. If the @mode variable is so * set, it can be read from, and written to. - * - * This function will return a pointer to a dentry if it succeeds. This - * pointer must be passed to the debugfs_remove() function when the file is - * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be - * returned. - * - * If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will - * be returned. */ -struct dentry *debugfs_create_u64(const char *name, umode_t mode, - struct dentry *parent, u64 *value) +void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, + u64 *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u64, + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u64, &fops_u64_ro, &fops_u64_wo); } EXPORT_SYMBOL_GPL(debugfs_create_u64); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index c83a33a76b6c..b3bed4d61733 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -103,8 +103,8 @@ void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value); -struct dentry *debugfs_create_u64(const char *name, umode_t mode, - struct dentry *parent, u64 *value); +void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, + u64 *value); struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); struct dentry *debugfs_create_x8(const char *name, umode_t mode, @@ -257,12 +257,8 @@ static inline struct dentry *debugfs_create_u32(const char *name, umode_t mode, return ERR_PTR(-ENODEV); } -static inline struct dentry *debugfs_create_u64(const char *name, umode_t mode, - struct dentry *parent, - u64 *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_u64(const char *name, umode_t mode, + struct dentry *parent, u64 *value) { } static inline struct dentry *debugfs_create_ulong(const char *name, umode_t mode, -- cgit v1.2.3-59-g8ed1b From 8e5802635f0f9f7329ec8ffdec15479946c99fb1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Oct 2019 15:29:27 +0200 Subject: debugfs: remove return value of debugfs_create_size_t() No one checks the return value of debugfs_create_size_t(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20191011132931.1186197-4-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 5 ++--- fs/debugfs/file.c | 9 ++++----- include/linux/debugfs.h | 13 +++++-------- 3 files changed, 11 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 1b299ae4904d..55a5da08c71c 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -96,9 +96,8 @@ value to be exported. Some types can have different widths on different architectures, though, complicating the situation somewhat. There is a function meant to help out in one special case: - struct dentry *debugfs_create_size_t(const char *name, umode_t mode, - struct dentry *parent, - size_t *value); + void debugfs_create_size_t(const char *name, umode_t mode, + struct dentry *parent, size_t *value); As might be expected, this function will create a debugfs file to represent a variable of type size_t. diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 4c8912d7d34c..dfeda13023b3 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -721,12 +721,11 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_size_t_wo, NULL, debugfs_size_t_set, "%llu\n"); * @value: a pointer to the variable that the file should read to and write * from. */ -struct dentry *debugfs_create_size_t(const char *name, umode_t mode, - struct dentry *parent, size_t *value) +void debugfs_create_size_t(const char *name, umode_t mode, + struct dentry *parent, size_t *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, - &fops_size_t, &fops_size_t_ro, - &fops_size_t_wo); + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_size_t, + &fops_size_t_ro, &fops_size_t_wo); } EXPORT_SYMBOL_GPL(debugfs_create_size_t); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index b3bed4d61733..1d859bc657bd 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -115,8 +115,8 @@ struct dentry *debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); struct dentry *debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value); -struct dentry *debugfs_create_size_t(const char *name, umode_t mode, - struct dentry *parent, size_t *value); +void debugfs_create_size_t(const char *name, umode_t mode, + struct dentry *parent, size_t *value); struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value); struct dentry *debugfs_create_bool(const char *name, umode_t mode, @@ -296,12 +296,9 @@ static inline struct dentry *debugfs_create_x64(const char *name, umode_t mode, return ERR_PTR(-ENODEV); } -static inline struct dentry *debugfs_create_size_t(const char *name, umode_t mode, - struct dentry *parent, - size_t *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_size_t(const char *name, umode_t mode, + struct dentry *parent, size_t *value) +{ } static inline struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value) -- cgit v1.2.3-59-g8ed1b From e40d38f28c10e3010b2828f2c737b50fb81bda8f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Oct 2019 15:29:29 +0200 Subject: debugfs: remove return value of debugfs_create_x16() No one checks the return value of debugfs_create_x16(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Link: https://lore.kernel.org/r/20191011132931.1186197-6-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 4 ++-- fs/debugfs/file.c | 6 +++--- include/linux/debugfs.h | 12 ++++-------- 3 files changed, 9 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 55a5da08c71c..4967f77a62a0 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -84,8 +84,8 @@ the following functions can be used instead: struct dentry *debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); - struct dentry *debugfs_create_x16(const char *name, umode_t mode, - struct dentry *parent, u16 *value); + void debugfs_create_x16(const char *name, umode_t mode, + struct dentry *parent, u16 *value); struct dentry *debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); struct dentry *debugfs_create_x64(const char *name, umode_t mode, diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index dfeda13023b3..cc6c76702e65 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -651,10 +651,10 @@ EXPORT_SYMBOL_GPL(debugfs_create_x8); * @value: a pointer to the variable that the file should read to and write * from. */ -struct dentry *debugfs_create_x16(const char *name, umode_t mode, - struct dentry *parent, u16 *value) +void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, + u16 *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x16, + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x16, &fops_x16_ro, &fops_x16_wo); } EXPORT_SYMBOL_GPL(debugfs_create_x16); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 1d859bc657bd..e742081c6844 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -109,8 +109,8 @@ struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); struct dentry *debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); -struct dentry *debugfs_create_x16(const char *name, umode_t mode, - struct dentry *parent, u16 *value); +void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, + u16 *value); struct dentry *debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); struct dentry *debugfs_create_x64(const char *name, umode_t mode, @@ -275,12 +275,8 @@ static inline struct dentry *debugfs_create_x8(const char *name, umode_t mode, return ERR_PTR(-ENODEV); } -static inline struct dentry *debugfs_create_x16(const char *name, umode_t mode, - struct dentry *parent, - u16 *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_x16(const char *name, umode_t mode, + struct dentry *parent, u16 *value) { } static inline struct dentry *debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, -- cgit v1.2.3-59-g8ed1b From f5cb0a7e64f41b6f1c5cacc64a476962f5e97f91 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Oct 2019 15:29:30 +0200 Subject: debugfs: remove return value of debugfs_create_x32() No one checks the return value of debugfs_create_x32(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Link: https://lore.kernel.org/r/20191011132931.1186197-7-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 4 ++-- fs/debugfs/file.c | 6 +++--- include/linux/debugfs.h | 12 ++++-------- 3 files changed, 9 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 4967f77a62a0..94b8f9a0cb5e 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -86,8 +86,8 @@ the following functions can be used instead: struct dentry *parent, u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); - struct dentry *debugfs_create_x32(const char *name, umode_t mode, - struct dentry *parent, u32 *value); + void debugfs_create_x32(const char *name, umode_t mode, + struct dentry *parent, u32 *value); struct dentry *debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value); diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index cc6c76702e65..9c906251b3c6 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -669,10 +669,10 @@ EXPORT_SYMBOL_GPL(debugfs_create_x16); * @value: a pointer to the variable that the file should read to and write * from. */ -struct dentry *debugfs_create_x32(const char *name, umode_t mode, - struct dentry *parent, u32 *value) +void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, + u32 *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x32, + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x32, &fops_x32_ro, &fops_x32_wo); } EXPORT_SYMBOL_GPL(debugfs_create_x32); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index e742081c6844..89d0b02f82f5 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -111,8 +111,8 @@ struct dentry *debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); -struct dentry *debugfs_create_x32(const char *name, umode_t mode, - struct dentry *parent, u32 *value); +void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, + u32 *value); struct dentry *debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value); void debugfs_create_size_t(const char *name, umode_t mode, @@ -278,12 +278,8 @@ static inline struct dentry *debugfs_create_x8(const char *name, umode_t mode, static inline void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value) { } -static inline struct dentry *debugfs_create_x32(const char *name, umode_t mode, - struct dentry *parent, - u32 *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_x32(const char *name, umode_t mode, + struct dentry *parent, u32 *value) { } static inline struct dentry *debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, -- cgit v1.2.3-59-g8ed1b From 0864c408fb1e5b02d817cc8cd5b794d4cb491d50 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Oct 2019 15:29:31 +0200 Subject: debugfs: remove return value of debugfs_create_x64() No one checks the return value of debugfs_create_x64(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Link: https://lore.kernel.org/r/20191011132931.1186197-8-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 4 ++-- fs/debugfs/file.c | 6 +++--- include/linux/debugfs.h | 12 ++++-------- 3 files changed, 9 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 94b8f9a0cb5e..9e705026ac10 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -88,8 +88,8 @@ the following functions can be used instead: struct dentry *parent, u16 *value); void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); - struct dentry *debugfs_create_x64(const char *name, umode_t mode, - struct dentry *parent, u64 *value); + void debugfs_create_x64(const char *name, umode_t mode, + struct dentry *parent, u64 *value); These functions are useful as long as the developer knows the size of the value to be exported. Some types can have different widths on different diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 9c906251b3c6..3ff736f22eb6 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -687,10 +687,10 @@ EXPORT_SYMBOL_GPL(debugfs_create_x32); * @value: a pointer to the variable that the file should read to and write * from. */ -struct dentry *debugfs_create_x64(const char *name, umode_t mode, - struct dentry *parent, u64 *value) +void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, + u64 *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x64, + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x64, &fops_x64_ro, &fops_x64_wo); } EXPORT_SYMBOL_GPL(debugfs_create_x64); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 89d0b02f82f5..33690949b45d 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -113,8 +113,8 @@ void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); -struct dentry *debugfs_create_x64(const char *name, umode_t mode, - struct dentry *parent, u64 *value); +void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, + u64 *value); void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value); struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, @@ -281,12 +281,8 @@ static inline void debugfs_create_x16(const char *name, umode_t mode, static inline void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value) { } -static inline struct dentry *debugfs_create_x64(const char *name, umode_t mode, - struct dentry *parent, - u64 *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_x64(const char *name, umode_t mode, + struct dentry *parent, u64 *value) { } static inline void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value) -- cgit v1.2.3-59-g8ed1b From 92df01e3601fe29eb3727a82705eafa6209053f5 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Fri, 11 Oct 2019 12:15:20 -0700 Subject: driver: core: Improve documentation for fwnode_operations.add_links() The add_links() ops shouldn't return on the first failed device link add. It needs to continue trying to add device links to other suppliers that are available. The documentation didn't explain WHY this behavior is necessary. So, update the documentation with an example that explains why this is necessary. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20191011191521.179614-3-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- include/linux/fwnode.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 6ae05b9ce359..97223e2410bd 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -71,8 +71,25 @@ struct fwnode_reference_args { * links to all the suppliers of the device that are available at * the time this function is called. The function must NOT stop * at the first failed device link if other unlinked supplier - * devices are present in the system. If some suppliers are not - * yet available, this function will be called again when other + * devices are present in the system. This is necessary for the + * driver/bus sync_state() callbacks to work correctly. + * + * For example, say Device-C depends on suppliers Device-S1 and + * Device-S2 and the dependency is listed in that order in the + * firmware. Say, S1 gets populated from the firmware after + * late_initcall_sync(). Say S2 is populated and probed way + * before that in device_initcall(). When C is populated, if this + * add_links() function doesn't continue past a "failed linking to + * S1" and continue linking C to S2, then S2 will get a + * sync_state() callback before C is probed. This is because from + * the perspective of S2, C was never a consumer when its + * sync_state() evaluation is done. To avoid this, the add_links() + * function has to go through all available suppliers of the + * device (that corresponds to this fwnode) and link to them + * before returning. + * + * If some suppliers are not yet available (indicated by an error + * return value), this function will be called again when other * devices are added to allow creating device links to any newly * available suppliers. * -- cgit v1.2.3-59-g8ed1b From 05ef983e0d65a31b370a4e1b93c1efd490ae778f Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Mon, 28 Oct 2019 15:00:22 -0700 Subject: driver core: Add device link support for SYNC_STATE_ONLY flag Parent devices might need to create "proxy" device links from themselves to supplier devices to make sure the supplier devices don't get a sync_state() before the child consumer devices get a chance to add device links to the supplier devices. However, the parent device has no real dependency on the supplier device and probing, suspend/resume or runtime PM don't need to be affected by the supplier device. To capture these cases, create a SYNC_STATE_ONLY device link flag that only affects sync_state() behavior and doesn't affect probing, suspend/resume or runtime PM. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20191028220027.251605-2-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 50 +++++++++++++++++++++++++++++++++++++++++--------- include/linux/device.h | 2 ++ 2 files changed, 43 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/drivers/base/core.c b/drivers/base/core.c index 7ea665a97da2..17ed054c4132 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -131,6 +131,9 @@ static int device_is_dependent(struct device *dev, void *target) return ret; list_for_each_entry(link, &dev->links.consumers, s_node) { + if (link->flags == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) + continue; + if (link->consumer == target) return 1; @@ -200,8 +203,11 @@ static int device_reorder_to_tail(struct device *dev, void *not_used) device_pm_move_last(dev); device_for_each_child(dev, NULL, device_reorder_to_tail); - list_for_each_entry(link, &dev->links.consumers, s_node) + list_for_each_entry(link, &dev->links.consumers, s_node) { + if (link->flags == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) + continue; device_reorder_to_tail(link->consumer, NULL); + } return 0; } @@ -228,7 +234,8 @@ void device_pm_move_to_tail(struct device *dev) #define DL_MANAGED_LINK_FLAGS (DL_FLAG_AUTOREMOVE_CONSUMER | \ DL_FLAG_AUTOREMOVE_SUPPLIER | \ - DL_FLAG_AUTOPROBE_CONSUMER) + DL_FLAG_AUTOPROBE_CONSUMER | \ + DL_FLAG_SYNC_STATE_ONLY) #define DL_ADD_VALID_FLAGS (DL_MANAGED_LINK_FLAGS | DL_FLAG_STATELESS | \ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE) @@ -296,6 +303,8 @@ struct device_link *device_link_add(struct device *consumer, if (!consumer || !supplier || flags & ~DL_ADD_VALID_FLAGS || (flags & DL_FLAG_STATELESS && flags & DL_MANAGED_LINK_FLAGS) || + (flags & DL_FLAG_SYNC_STATE_ONLY && + flags != DL_FLAG_SYNC_STATE_ONLY) || (flags & DL_FLAG_AUTOPROBE_CONSUMER && flags & (DL_FLAG_AUTOREMOVE_CONSUMER | DL_FLAG_AUTOREMOVE_SUPPLIER))) @@ -316,11 +325,14 @@ struct device_link *device_link_add(struct device *consumer, /* * If the supplier has not been fully registered yet or there is a - * reverse dependency between the consumer and the supplier already in - * the graph, return NULL. + * reverse (non-SYNC_STATE_ONLY) dependency between the consumer and + * the supplier already in the graph, return NULL. If the link is a + * SYNC_STATE_ONLY link, we don't check for reverse dependencies + * because it only affects sync_state() callbacks. */ if (!device_pm_initialized(supplier) - || device_is_dependent(consumer, supplier)) { + || (!(flags & DL_FLAG_SYNC_STATE_ONLY) && + device_is_dependent(consumer, supplier))) { link = NULL; goto out; } @@ -347,9 +359,14 @@ struct device_link *device_link_add(struct device *consumer, } if (flags & DL_FLAG_STATELESS) { - link->flags |= DL_FLAG_STATELESS; kref_get(&link->kref); - goto out; + if (link->flags & DL_FLAG_SYNC_STATE_ONLY && + !(link->flags & DL_FLAG_STATELESS)) { + link->flags |= DL_FLAG_STATELESS; + goto reorder; + } else { + goto out; + } } /* @@ -371,6 +388,12 @@ struct device_link *device_link_add(struct device *consumer, link->flags |= DL_FLAG_MANAGED; device_link_init_status(link, consumer, supplier); } + if (link->flags & DL_FLAG_SYNC_STATE_ONLY && + !(flags & DL_FLAG_SYNC_STATE_ONLY)) { + link->flags &= ~DL_FLAG_SYNC_STATE_ONLY; + goto reorder; + } + goto out; } @@ -410,6 +433,13 @@ struct device_link *device_link_add(struct device *consumer, flags & DL_FLAG_PM_RUNTIME) pm_runtime_resume(supplier); + if (flags & DL_FLAG_SYNC_STATE_ONLY) { + dev_dbg(consumer, + "Linked as a sync state only consumer to %s\n", + dev_name(supplier)); + goto out; + } +reorder: /* * Move the consumer and all of the devices depending on it to the end * of dpm_list and the devices_kset list. @@ -635,7 +665,8 @@ int device_links_check_suppliers(struct device *dev) device_links_write_lock(); list_for_each_entry(link, &dev->links.suppliers, c_node) { - if (!(link->flags & DL_FLAG_MANAGED)) + if (!(link->flags & DL_FLAG_MANAGED) || + link->flags & DL_FLAG_SYNC_STATE_ONLY) continue; if (link->status != DL_STATE_AVAILABLE) { @@ -949,7 +980,8 @@ void device_links_unbind_consumers(struct device *dev) list_for_each_entry(link, &dev->links.consumers, s_node) { enum device_link_state status; - if (!(link->flags & DL_FLAG_MANAGED)) + if (!(link->flags & DL_FLAG_MANAGED) || + link->flags & DL_FLAG_SYNC_STATE_ONLY) continue; status = link->status; diff --git a/include/linux/device.h b/include/linux/device.h index 6978bb471567..82890e1b8f08 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1096,6 +1096,7 @@ enum device_link_state { * AUTOREMOVE_SUPPLIER: Remove the link automatically on supplier driver unbind. * AUTOPROBE_CONSUMER: Probe consumer driver automatically after supplier binds. * MANAGED: The core tracks presence of supplier/consumer drivers (internal). + * SYNC_STATE_ONLY: Link only affects sync_state() behavior. */ #define DL_FLAG_STATELESS BIT(0) #define DL_FLAG_AUTOREMOVE_CONSUMER BIT(1) @@ -1104,6 +1105,7 @@ enum device_link_state { #define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4) #define DL_FLAG_AUTOPROBE_CONSUMER BIT(5) #define DL_FLAG_MANAGED BIT(6) +#define DL_FLAG_SYNC_STATE_ONLY BIT(7) /** * struct device_link - Device link representation. -- cgit v1.2.3-59-g8ed1b From bcbbcfd57247f4c2976055995e5760fb576aae1e Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Mon, 28 Oct 2019 15:00:23 -0700 Subject: driver core: Allow a device to wait on optional suppliers Before this change, if a device is waiting on suppliers, it's assumed that all those suppliers are needed for the device to probe successfully. This change allows marking a devices as waiting only on optional suppliers. This allows a device to wait on suppliers (and link to them as soon as they are available) without preventing the device from being probed. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20191028220027.251605-3-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 28 +++++++++++++++++++++++++--- include/linux/device.h | 3 +++ 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/base/core.c b/drivers/base/core.c index 17ed054c4132..48cd43a91ce6 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -480,13 +480,25 @@ EXPORT_SYMBOL_GPL(device_link_add); * This function is NOT meant to be called from the probe function of the * consumer but rather from code that creates/adds the consumer device. */ -static void device_link_wait_for_supplier(struct device *consumer) +static void device_link_wait_for_supplier(struct device *consumer, + bool need_for_probe) { mutex_lock(&wfs_lock); list_add_tail(&consumer->links.needs_suppliers, &wait_for_suppliers); + consumer->links.need_for_probe = need_for_probe; mutex_unlock(&wfs_lock); } +static void device_link_wait_for_mandatory_supplier(struct device *consumer) +{ + device_link_wait_for_supplier(consumer, true); +} + +static void device_link_wait_for_optional_supplier(struct device *consumer) +{ + device_link_wait_for_supplier(consumer, false); +} + /** * device_link_add_missing_supplier_links - Add links from consumer devices to * supplier devices, leaving any @@ -656,7 +668,8 @@ int device_links_check_suppliers(struct device *dev) * probe. */ mutex_lock(&wfs_lock); - if (!list_empty(&dev->links.needs_suppliers)) { + if (!list_empty(&dev->links.needs_suppliers) && + dev->links.need_for_probe) { mutex_unlock(&wfs_lock); return -EPROBE_DEFER; } @@ -760,6 +773,15 @@ void device_links_driver_bound(struct device *dev) { struct device_link *link; + /* + * If a device probes successfully, it's expected to have created all + * the device links it needs to or make new device links as it needs + * them. So, it no longer needs to wait on any suppliers. + */ + mutex_lock(&wfs_lock); + list_del_init(&dev->links.needs_suppliers); + mutex_unlock(&wfs_lock); + device_links_write_lock(); list_for_each_entry(link, &dev->links.consumers, s_node) { @@ -2393,7 +2415,7 @@ int device_add(struct device *dev) if (fwnode_has_op(dev->fwnode, add_links) && fwnode_call_int_op(dev->fwnode, add_links, dev)) - device_link_wait_for_supplier(dev); + device_link_wait_for_mandatory_supplier(dev, true); bus_probe_device(dev); if (parent) diff --git a/include/linux/device.h b/include/linux/device.h index 82890e1b8f08..d1bcc8f122f6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1155,6 +1155,8 @@ enum dl_dev_state { * @consumers: List of links to consumer devices. * @needs_suppliers: Hook to global list of devices waiting for suppliers. * @defer_sync: Hook to global list of devices that have deferred sync_state. + * @need_for_probe: If needs_suppliers is on a list, this indicates if the + * suppliers are needed for probe or not. * @status: Driver status information. */ struct dev_links_info { @@ -1162,6 +1164,7 @@ struct dev_links_info { struct list_head consumers; struct list_head needs_suppliers; struct list_head defer_sync; + bool need_for_probe; enum dl_dev_state status; }; -- cgit v1.2.3-59-g8ed1b From 03324507e66c7664c754b1ef92c5c3be24c78aa2 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Mon, 28 Oct 2019 15:00:24 -0700 Subject: driver core: Allow fwnode_operations.add_links to differentiate errors When add_links() still has suppliers that it needs to link to in the future, this patch allows it to differentiate between suppliers that are needed for probing vs suppliers that are needed for sync_state() correctness. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20191028220027.251605-4-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 12 ++++++++---- include/linux/fwnode.h | 13 +++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/drivers/base/core.c b/drivers/base/core.c index 48cd43a91ce6..e6d3e6d485da 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2297,7 +2297,7 @@ int device_add(struct device *dev) struct device *parent; struct kobject *kobj; struct class_interface *class_intf; - int error = -EINVAL; + int error = -EINVAL, fw_ret; struct kobject *glue_dir = NULL; dev = get_device(dev); @@ -2413,9 +2413,13 @@ int device_add(struct device *dev) */ device_link_add_missing_supplier_links(); - if (fwnode_has_op(dev->fwnode, add_links) - && fwnode_call_int_op(dev->fwnode, add_links, dev)) - device_link_wait_for_mandatory_supplier(dev, true); + if (fwnode_has_op(dev->fwnode, add_links)) { + fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev); + if (fw_ret == -ENODEV) + device_link_wait_for_mandatory_supplier(dev); + else if (fw_ret) + device_link_wait_for_optional_supplier(dev); + } bus_probe_device(dev); if (parent) diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 97223e2410bd..766ff9bb5876 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -94,10 +94,15 @@ struct fwnode_reference_args { * available suppliers. * * Return 0 if device links have been successfully created to all - * the suppliers of this device or if the supplier information is - * not known. Return an error if and only if the supplier - * information is known but some of the suppliers are not yet - * available to create device links to. + * the suppliers this device needs to create device links to or if + * the supplier information is not known. + * + * Return -ENODEV if and only if the suppliers needed for probing + * the device are not yet available to create device links to. + * + * Return -EAGAIN if there are suppliers that need to be linked to + * that are not yet available but none of those suppliers are + * necessary for probing this device. */ struct fwnode_operations { struct fwnode_handle *(*get)(struct fwnode_handle *fwnode); -- cgit v1.2.3-59-g8ed1b From c7c1168909410e692be6df17d0092363a00f33a9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Oct 2019 15:29:28 +0200 Subject: debugfs: remove return value of debugfs_create_x8() No one checks the return value of debugfs_create_x8(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Link: https://lore.kernel.org/r/20191011132931.1186197-5-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 4 ++-- fs/debugfs/file.c | 6 +++--- include/linux/debugfs.h | 12 ++++-------- 3 files changed, 9 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 9e705026ac10..1ec4a94b6e93 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -82,8 +82,8 @@ file should not be written to, simply set the mode bits accordingly. The values in these files are in decimal; if hexadecimal is more appropriate, the following functions can be used instead: - struct dentry *debugfs_create_x8(const char *name, umode_t mode, - struct dentry *parent, u8 *value); + void debugfs_create_x8(const char *name, umode_t mode, + struct dentry *parent, u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); void debugfs_create_x32(const char *name, umode_t mode, diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 3ff736f22eb6..8aac1a9007c9 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -633,10 +633,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_wo, NULL, debugfs_u64_set, "0x%016llx\n"); * @value: a pointer to the variable that the file should read to and write * from. */ -struct dentry *debugfs_create_x8(const char *name, umode_t mode, - struct dentry *parent, u8 *value) +void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, + u8 *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x8, + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x8, &fops_x8_ro, &fops_x8_wo); } EXPORT_SYMBOL_GPL(debugfs_create_x8); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 33690949b45d..c127c159d10a 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -107,8 +107,8 @@ void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, u64 *value); struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); -struct dentry *debugfs_create_x8(const char *name, umode_t mode, - struct dentry *parent, u8 *value); +void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, + u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, @@ -268,12 +268,8 @@ static inline struct dentry *debugfs_create_ulong(const char *name, return ERR_PTR(-ENODEV); } -static inline struct dentry *debugfs_create_x8(const char *name, umode_t mode, - struct dentry *parent, - u8 *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_x8(const char *name, umode_t mode, + struct dentry *parent, u8 *value) { } static inline void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value) { } -- cgit v1.2.3-59-g8ed1b From 9927c6fa3e1d941c9b89f807f5d0480390eb0471 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 16 Oct 2019 06:03:32 -0700 Subject: debugfs: remove return value of debugfs_create_atomic_t() No one checks the return value of debugfs_create_atomic_t(), as it's not needed, so make the return value void, so that no one tries to do so in the future. Link: https://lore.kernel.org/r/20191016130332.GA28240@kroah.com Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 4 ++-- fs/debugfs/file.c | 9 ++++----- include/linux/debugfs.h | 13 ++++++------- 3 files changed, 12 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 1ec4a94b6e93..ac6067a02f74 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -113,8 +113,8 @@ lower-case values, or 1 or 0. Any other input will be silently ignored. Also, atomic_t values can be placed in debugfs with: - struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, - struct dentry *parent, atomic_t *value) + void debugfs_create_atomic_t(const char *name, umode_t mode, + struct dentry *parent, atomic_t *value) A read of this file will get atomic_t values, and a write of this file will set atomic_t values. diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 8aac1a9007c9..dede25247b81 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -757,12 +757,11 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, * @value: a pointer to the variable that the file should read to and write * from. */ -struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, - struct dentry *parent, atomic_t *value) +void debugfs_create_atomic_t(const char *name, umode_t mode, + struct dentry *parent, atomic_t *value) { - return debugfs_create_mode_unsafe(name, mode, parent, value, - &fops_atomic_t, &fops_atomic_t_ro, - &fops_atomic_t_wo); + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_atomic_t, + &fops_atomic_t_ro, &fops_atomic_t_wo); } EXPORT_SYMBOL_GPL(debugfs_create_atomic_t); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index c127c159d10a..19231e618c16 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -117,8 +117,8 @@ void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value); void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value); -struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, - struct dentry *parent, atomic_t *value); +void debugfs_create_atomic_t(const char *name, umode_t mode, + struct dentry *parent, atomic_t *value); struct dentry *debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, bool *value); @@ -284,11 +284,10 @@ static inline void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value) { } -static inline struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, - struct dentry *parent, atomic_t *value) -{ - return ERR_PTR(-ENODEV); -} +static inline void debugfs_create_atomic_t(const char *name, umode_t mode, + struct dentry *parent, + atomic_t *value) +{ } static inline struct dentry *debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, -- cgit v1.2.3-59-g8ed1b From d3504757f3f049b553ba0eda8bd17cd1f2651285 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 25 Oct 2019 11:41:24 +0200 Subject: debugfs: Add debugfs_create_xul() for hexadecimal unsigned long The existing debugfs_create_ulong() function supports objects of type "unsigned long", which are 32-bit or 64-bit depending on the platform, in decimal form. To format objects in hexadecimal, various debugfs_create_x*() functions exist, but all of them take fixed-size types. Add a debugfs helper for "unsigned long" objects in hexadecimal format. This avoids the need for users to open-code the same, or introduce bugs when casting the value pointer to "u32 *" or "u64 *" to call debugfs_create_x{32,64}(). Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20191025094130.26033-2-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/debugfs.txt | 5 ++++- include/linux/debugfs.h | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 36dac49e859f..dc497b96fa4f 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -102,11 +102,14 @@ functions meant to help out in such special cases: As might be expected, this function will create a debugfs file to represent a variable of type size_t. -Similarly, there is a helper for variables of type unsigned long: +Similarly, there are helpers for variables of type unsigned long, in decimal +and hexadecimal: struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); + void debugfs_create_xul(const char *name, umode_t mode, + struct dentry *parent, unsigned long *value); Boolean values can be placed in debugfs with: diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 19231e618c16..0e8f2e0cb91f 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -351,4 +351,25 @@ static inline ssize_t debugfs_write_file_bool(struct file *file, #endif +/** + * debugfs_create_xul - create a debugfs file that is used to read and write an + * unsigned long value, formatted in hexadecimal + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is %NULL, then the + * file will be created in the root of the debugfs filesystem. + * @value: a pointer to the variable that the file should read to and write + * from. + */ +static inline void debugfs_create_xul(const char *name, umode_t mode, + struct dentry *parent, + unsigned long *value) +{ + if (sizeof(*value) == sizeof(u32)) + debugfs_create_x32(name, mode, parent, (u32 *)value); + else + debugfs_create_x64(name, mode, parent, (u64 *)value); +} + #endif -- cgit v1.2.3-59-g8ed1b From b873af620e58863b70ae9cf97f6fab4cf4c544af Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 22 Oct 2019 10:43:13 +0200 Subject: lib: devres: provide devm_ioremap_resource_wc() Provide a variant of devm_ioremap_resource() for write-combined ioremap. Signed-off-by: Bartosz Golaszewski Reviewed-by: Arnd Bergmann Link: https://lore.kernel.org/r/20191022084318.22256-4-brgl@bgdev.pl Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/driver-model/devres.rst | 1 + include/linux/device.h | 2 ++ lib/devres.c | 15 +++++++++++++++ 3 files changed, 18 insertions(+) (limited to 'include') diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 8e3087662daf..e605bb9df6e1 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -316,6 +316,7 @@ IOMAP devm_ioremap_nocache() devm_ioremap_wc() devm_ioremap_resource() : checks resource, requests memory region, ioremaps + devm_ioremap_resource_wc() devm_platform_ioremap_resource() : calls devm_ioremap_resource() for platform device devm_iounmap() pcim_iomap() diff --git a/include/linux/device.h b/include/linux/device.h index d1bcc8f122f6..f05c5b92e61f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -962,6 +962,8 @@ extern void devm_free_pages(struct device *dev, unsigned long addr); void __iomem *devm_ioremap_resource(struct device *dev, const struct resource *res); +void __iomem *devm_ioremap_resource_wc(struct device *dev, + const struct resource *res); void __iomem *devm_of_iomap(struct device *dev, struct device_node *node, int index, diff --git a/lib/devres.c b/lib/devres.c index a14c727128c1..97fb44e5b4d6 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -169,6 +169,21 @@ void __iomem *devm_ioremap_resource(struct device *dev, } EXPORT_SYMBOL(devm_ioremap_resource); +/** + * devm_ioremap_resource_wc() - write-combined variant of + * devm_ioremap_resource() + * @dev: generic device to handle the resource for + * @res: resource to be handled + * + * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code + * on failure. Usage example: + */ +void __iomem *devm_ioremap_resource_wc(struct device *dev, + const struct resource *res) +{ + return __devm_ioremap_resource(dev, res, DEVM_IOREMAP_WC); +} + /* * devm_of_iomap - Requests a resource and maps the memory mapped IO * for a given device_node managed by a given device -- cgit v1.2.3-59-g8ed1b From bb6243b4f73d29f8c8faf8f805a2042ac3973b71 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 22 Oct 2019 10:43:14 +0200 Subject: drivers: platform: provide devm_platform_ioremap_resource_wc() Provide a write-combined variant of devm_platform_ioremap_resource(). Signed-off-by: Bartosz Golaszewski Reviewed-by: Arnd Bergmann Link: https://lore.kernel.org/r/20191022084318.22256-5-brgl@bgdev.pl Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/driver-model/devres.rst | 1 + drivers/base/platform.c | 19 ++++++++++++++++++- include/linux/platform_device.h | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index e605bb9df6e1..480b78ca3871 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -318,6 +318,7 @@ IOMAP devm_ioremap_resource() : checks resource, requests memory region, ioremaps devm_ioremap_resource_wc() devm_platform_ioremap_resource() : calls devm_ioremap_resource() for platform device + devm_platform_ioremap_resource_wc() devm_iounmap() pcim_iomap() pcim_iomap_regions() : do request_region() and iomap() on multiple BARs diff --git a/drivers/base/platform.c b/drivers/base/platform.c index e0ca682a756d..28eb71967f17 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -60,6 +60,7 @@ struct resource *platform_get_resource(struct platform_device *dev, } EXPORT_SYMBOL_GPL(platform_get_resource); +#ifdef CONFIG_HAS_IOMEM /** * devm_platform_ioremap_resource - call devm_ioremap_resource() for a platform * device @@ -68,7 +69,6 @@ EXPORT_SYMBOL_GPL(platform_get_resource); * resource management * @index: resource index */ -#ifdef CONFIG_HAS_IOMEM void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev, unsigned int index) { @@ -78,6 +78,23 @@ void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev, return devm_ioremap_resource(&pdev->dev, res); } EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource); + +/** + * devm_platform_ioremap_resource_wc - write-combined variant of + * devm_platform_ioremap_resource() + * + * @pdev: platform device to use both for memory resource lookup as well as + * resource management + * @index: resource index + */ +void __iomem *devm_platform_ioremap_resource_wc(struct platform_device *pdev, + unsigned int index) +{ + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, index); + return devm_ioremap_resource_wc(&pdev->dev, res); +} #endif /* CONFIG_HAS_IOMEM */ /** diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 51fb7fc28587..91fcdbbae89d 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -57,6 +57,9 @@ platform_find_device_by_driver(struct device *start, extern void __iomem * devm_platform_ioremap_resource(struct platform_device *pdev, unsigned int index); +extern void __iomem * +devm_platform_ioremap_resource_wc(struct platform_device *pdev, + unsigned int index); extern int platform_get_irq(struct platform_device *, unsigned int); extern int platform_get_irq_optional(struct platform_device *, unsigned int); extern int platform_irq_count(struct platform_device *); -- cgit v1.2.3-59-g8ed1b From c9c8641d3ebd79274af75f7df3e6a9c6cc8a66e9 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 22 Oct 2019 10:43:16 +0200 Subject: drivers: provide devm_platform_ioremap_resource_byname() Provide a variant of devm_platform_ioremap_resource() that allows to lookup resources from platform devices by name rather than by index. Signed-off-by: Bartosz Golaszewski Reviewed-by: Arnd Bergmann Link: https://lore.kernel.org/r/20191022084318.22256-7-brgl@bgdev.pl Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/driver-model/devres.rst | 1 + drivers/base/platform.c | 20 ++++++++++++++++++++ include/linux/platform_device.h | 3 +++ 3 files changed, 24 insertions(+) (limited to 'include') diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 480b78ca3871..4ab193319d8c 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -319,6 +319,7 @@ IOMAP devm_ioremap_resource_wc() devm_platform_ioremap_resource() : calls devm_ioremap_resource() for platform device devm_platform_ioremap_resource_wc() + devm_platform_ioremap_resource_byname() devm_iounmap() pcim_iomap() pcim_iomap_regions() : do request_region() and iomap() on multiple BARs diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 28eb71967f17..1b8a20466eef 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -95,6 +95,26 @@ void __iomem *devm_platform_ioremap_resource_wc(struct platform_device *pdev, res = platform_get_resource(pdev, IORESOURCE_MEM, index); return devm_ioremap_resource_wc(&pdev->dev, res); } + +/** + * devm_platform_ioremap_resource_byname - call devm_ioremap_resource for + * a platform device, retrieve the + * resource by name + * + * @pdev: platform device to use both for memory resource lookup as well as + * resource management + * @name: name of the resource + */ +void __iomem * +devm_platform_ioremap_resource_byname(struct platform_device *pdev, + const char *name) +{ + struct resource *res; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + return devm_ioremap_resource(&pdev->dev, res); +} +EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname); #endif /* CONFIG_HAS_IOMEM */ /** diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 91fcdbbae89d..276a03c24691 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -60,6 +60,9 @@ devm_platform_ioremap_resource(struct platform_device *pdev, extern void __iomem * devm_platform_ioremap_resource_wc(struct platform_device *pdev, unsigned int index); +extern void __iomem * +devm_platform_ioremap_resource_byname(struct platform_device *pdev, + const char *name); extern int platform_get_irq(struct platform_device *, unsigned int); extern int platform_get_irq_optional(struct platform_device *, unsigned int); extern int platform_irq_count(struct platform_device *); -- cgit v1.2.3-59-g8ed1b From bee3bbe616a2c8de641a64d874f9206835bd4401 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Tue, 12 Nov 2019 18:35:59 -0800 Subject: driver core: Clarify documentation for fwnode_operations.add_links() The wording was a bit ambiguous. So update it to make it clear. Signed-off-by: Saravana Kannan Reviewed-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20191113023559.62295-2-saravanak@google.com Signed-off-by: Greg Kroah-Hartman --- include/linux/fwnode.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 766ff9bb5876..23df37f85398 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -94,15 +94,16 @@ struct fwnode_reference_args { * available suppliers. * * Return 0 if device links have been successfully created to all - * the suppliers this device needs to create device links to or if - * the supplier information is not known. + * the known suppliers of this device or if the supplier + * information is not known. * - * Return -ENODEV if and only if the suppliers needed for probing - * the device are not yet available to create device links to. + * Return -ENODEV if the suppliers needed for probing this device + * have not been registered yet (because device links can only be + * created to devices registered with the driver core). * - * Return -EAGAIN if there are suppliers that need to be linked to - * that are not yet available but none of those suppliers are - * necessary for probing this device. + * Return -EAGAIN if some of the suppliers of this device have not + * been registered yet, but none of those suppliers are necessary + * for probing the device. */ struct fwnode_operations { struct fwnode_handle *(*get)(struct fwnode_handle *fwnode); -- cgit v1.2.3-59-g8ed1b From edb44e8461cfb9da8fd7a60d1ded2912a01100be Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Tue, 22 Oct 2019 09:43:23 +0100 Subject: cpu-topology: declare parse_acpi_topology in The parse_acpi_topology() is not declared anywhere which causes the following sparse warning: drivers/base/arch_topology.c:522:19: warning: symbol 'parse_acpi_topology' was not declared. Should it be static? Signed-off-by: Ben Dooks (Codethink) Acked-by: Sudeep Holla Link: https://lore.kernel.org/r/20191022084323.13594-1-ben.dooks@codethink.co.uk Signed-off-by: Greg Kroah-Hartman --- include/linux/arch_topology.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h index 42f2b5126094..3015ecbb90b1 100644 --- a/include/linux/arch_topology.h +++ b/include/linux/arch_topology.h @@ -57,6 +57,7 @@ const struct cpumask *cpu_coregroup_mask(int cpu); void update_siblings_masks(unsigned int cpu); void remove_cpu_topology(unsigned int cpuid); void reset_cpu_topology(void); +int parse_acpi_topology(void); #endif #endif /* _LINUX_ARCH_TOPOLOGY_H_ */ -- cgit v1.2.3-59-g8ed1b From 4250b047039d324e0ff65267c8beb5bad5052a86 Mon Sep 17 00:00:00 2001 From: Kusanagi Kouichi Date: Thu, 21 Nov 2019 19:20:21 +0900 Subject: debugfs: Fix !DEBUG_FS debugfs_create_automount If DEBUG_FS=n, compile fails with the following error: kernel/trace/trace.c: In function 'tracing_init_dentry': kernel/trace/trace.c:8658:9: error: passing argument 3 of 'debugfs_create_automount' from incompatible pointer type [-Werror=incompatible-pointer-types] 8658 | trace_automount, NULL); | ^~~~~~~~~~~~~~~ | | | struct vfsmount * (*)(struct dentry *, void *) In file included from kernel/trace/trace.c:24: ./include/linux/debugfs.h:206:25: note: expected 'struct vfsmount * (*)(void *)' but argument is of type 'struct vfsmount * (*)(struct dentry *, void *)' 206 | struct vfsmount *(*f)(void *), | ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~ Signed-off-by: Kusanagi Kouichi Link: https://lore.kernel.org/r/20191121102021787.MLMY.25002.ppp.dion.ne.jp@dmta0003.auone-net.jp Signed-off-by: Greg Kroah-Hartman --- include/linux/debugfs.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 0e8f2e0cb91f..bf9b6cafa4c2 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -54,6 +54,8 @@ static const struct file_operations __fops = { \ .llseek = no_llseek, \ } +typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *); + #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_lookup(const char *name, struct dentry *parent); @@ -75,7 +77,6 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, const char *dest); -typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *); struct dentry *debugfs_create_automount(const char *name, struct dentry *parent, debugfs_automount_t f, @@ -203,7 +204,7 @@ static inline struct dentry *debugfs_create_symlink(const char *name, static inline struct dentry *debugfs_create_automount(const char *name, struct dentry *parent, - struct vfsmount *(*f)(void *), + debugfs_automount_t f, void *data) { return ERR_PTR(-ENODEV); -- cgit v1.2.3-59-g8ed1b