Driver core patches for 4.19-rc1
Here are all of the driver core and related patches for 4.19-rc1. Nothing huge here, just a number of small cleanups and the ability to now stop the deferred probing after init happens. All of these have been in linux-next for a while with only a merge issue reported. That merge issue is in fs/sysfs/group.c and Stephen has posted the diff of what it should be to resolve this. I'll follow up with that diff to this pull request. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCW3g86Q8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ynyXQCePaZSW8wft4b7nLN8RdZ98ATBru0Ani10lrJa HQeQJRNbWU1AZ0ym7695 =tOaH -----END PGP SIGNATURE----- Merge tag 'driver-core-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core updates from Greg KH: "Here are all of the driver core and related patches for 4.19-rc1. Nothing huge here, just a number of small cleanups and the ability to now stop the deferred probing after init happens. All of these have been in linux-next for a while with only a merge issue reported" * tag 'driver-core-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (21 commits) base: core: Remove WARN_ON from link dependencies check drivers/base: stop new probing during shutdown drivers: core: Remove glue dirs from sysfs earlier driver core: remove unnecessary function extern declare sysfs.h: fix non-kernel-doc comment PM / Domains: Stop deferring probe at the end of initcall iommu: Remove IOMMU_OF_DECLARE iommu: Stop deferring probe at end of initcalls pinctrl: Support stopping deferred probe after initcalls dt-bindings: pinctrl: add a 'pinctrl-use-default' property driver core: allow stopping deferred probe after init driver core: add a debugfs entry to show deferred devices sysfs: Fix internal_create_group() for named group updates base: fix order of OF initialization linux/device.h: fix kernel-doc notation warning Documentation: update firmware loader fallback reference kobject: Replace strncpy with memcpy drivers: base: cacheinfo: use OF property_read_u32 instead of get_property,read_number kernfs: Replace strncpy with memcpy device: Add #define dev_fmt similar to #define pr_fmt ...hifive-unleashed-5.1
commit
a18d783fed
|
@ -812,6 +812,15 @@
|
||||||
Defaults to the default architecture's huge page size
|
Defaults to the default architecture's huge page size
|
||||||
if not specified.
|
if not specified.
|
||||||
|
|
||||||
|
deferred_probe_timeout=
|
||||||
|
[KNL] Debugging option to set a timeout in seconds for
|
||||||
|
deferred probe to give up waiting on dependencies to
|
||||||
|
probe. Only specific dependencies (subsystems or
|
||||||
|
drivers) that have opted in will be ignored. A timeout of 0
|
||||||
|
will timeout at the end of initcalls. This option will also
|
||||||
|
dump out devices still on the deferred probe list after
|
||||||
|
retrying.
|
||||||
|
|
||||||
dhash_entries= [KNL]
|
dhash_entries= [KNL]
|
||||||
Set number of hash buckets for dentry cache.
|
Set number of hash buckets for dentry cache.
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,12 @@ Optional properties:
|
||||||
#pinctrl-cells: Number of pin control cells in addition to the index within the
|
#pinctrl-cells: Number of pin control cells in addition to the index within the
|
||||||
pin controller device instance
|
pin controller device instance
|
||||||
|
|
||||||
|
pinctrl-use-default: Boolean. Indicates that the OS can use the boot default
|
||||||
|
pin configuration. This allows using an OS that does not have a
|
||||||
|
driver for the pin controller. This property can be set either
|
||||||
|
globally for the pin controller or in child nodes for individual
|
||||||
|
pin group control.
|
||||||
|
|
||||||
Pin controller devices should contain the pin configuration nodes that client
|
Pin controller devices should contain the pin configuration nodes that client
|
||||||
devices reference.
|
devices reference.
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ the loading file.
|
||||||
|
|
||||||
The firmware device used to help load firmware using sysfs is only created if
|
The firmware device used to help load firmware using sysfs is only created if
|
||||||
direct firmware loading fails and if the fallback mechanism is enabled for your
|
direct firmware loading fails and if the fallback mechanism is enabled for your
|
||||||
firmware request, this is set up with fw_load_from_user_helper(). It is
|
firmware request, this is set up with :c:func:`firmware_fallback_sysfs`. It is
|
||||||
important to re-iterate that no device is created if a direct filesystem lookup
|
important to re-iterate that no device is created if a direct filesystem lookup
|
||||||
succeeded.
|
succeeded.
|
||||||
|
|
||||||
|
@ -108,6 +108,11 @@ firmware_data_read() and firmware_loading_show() are just provided for the
|
||||||
test_firmware driver for testing, they are not called in normal use or
|
test_firmware driver for testing, they are not called in normal use or
|
||||||
expected to be used regularly by userspace.
|
expected to be used regularly by userspace.
|
||||||
|
|
||||||
|
firmware_fallback_sysfs
|
||||||
|
-----------------------
|
||||||
|
.. kernel-doc:: drivers/base/firmware_loader/fallback.c
|
||||||
|
:functions: firmware_fallback_sysfs
|
||||||
|
|
||||||
Firmware kobject uevent fallback mechanism
|
Firmware kobject uevent fallback mechanism
|
||||||
==========================================
|
==========================================
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,6 @@ struct device_private {
|
||||||
#define to_device_private_bus(obj) \
|
#define to_device_private_bus(obj) \
|
||||||
container_of(obj, struct device_private, knode_bus)
|
container_of(obj, struct device_private, knode_bus)
|
||||||
|
|
||||||
extern int device_private_init(struct device *dev);
|
|
||||||
|
|
||||||
/* initialisation functions */
|
/* initialisation functions */
|
||||||
extern int devices_init(void);
|
extern int devices_init(void);
|
||||||
extern int buses_init(void);
|
extern int buses_init(void);
|
||||||
|
|
|
@ -74,52 +74,48 @@ static inline int get_cacheinfo_idx(enum cache_type type)
|
||||||
static void cache_size(struct cacheinfo *this_leaf, struct device_node *np)
|
static void cache_size(struct cacheinfo *this_leaf, struct device_node *np)
|
||||||
{
|
{
|
||||||
const char *propname;
|
const char *propname;
|
||||||
const __be32 *cache_size;
|
|
||||||
int ct_idx;
|
int ct_idx;
|
||||||
|
|
||||||
ct_idx = get_cacheinfo_idx(this_leaf->type);
|
ct_idx = get_cacheinfo_idx(this_leaf->type);
|
||||||
propname = cache_type_info[ct_idx].size_prop;
|
propname = cache_type_info[ct_idx].size_prop;
|
||||||
|
|
||||||
cache_size = of_get_property(np, propname, NULL);
|
if (of_property_read_u32(np, propname, &this_leaf->size))
|
||||||
if (cache_size)
|
this_leaf->size = 0;
|
||||||
this_leaf->size = of_read_number(cache_size, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* not cache_line_size() because that's a macro in include/linux/cache.h */
|
/* not cache_line_size() because that's a macro in include/linux/cache.h */
|
||||||
static void cache_get_line_size(struct cacheinfo *this_leaf,
|
static void cache_get_line_size(struct cacheinfo *this_leaf,
|
||||||
struct device_node *np)
|
struct device_node *np)
|
||||||
{
|
{
|
||||||
const __be32 *line_size;
|
|
||||||
int i, lim, ct_idx;
|
int i, lim, ct_idx;
|
||||||
|
|
||||||
ct_idx = get_cacheinfo_idx(this_leaf->type);
|
ct_idx = get_cacheinfo_idx(this_leaf->type);
|
||||||
lim = ARRAY_SIZE(cache_type_info[ct_idx].line_size_props);
|
lim = ARRAY_SIZE(cache_type_info[ct_idx].line_size_props);
|
||||||
|
|
||||||
for (i = 0; i < lim; i++) {
|
for (i = 0; i < lim; i++) {
|
||||||
|
int ret;
|
||||||
|
u32 line_size;
|
||||||
const char *propname;
|
const char *propname;
|
||||||
|
|
||||||
propname = cache_type_info[ct_idx].line_size_props[i];
|
propname = cache_type_info[ct_idx].line_size_props[i];
|
||||||
line_size = of_get_property(np, propname, NULL);
|
ret = of_property_read_u32(np, propname, &line_size);
|
||||||
if (line_size)
|
if (!ret) {
|
||||||
|
this_leaf->coherency_line_size = line_size;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (line_size)
|
|
||||||
this_leaf->coherency_line_size = of_read_number(line_size, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cache_nr_sets(struct cacheinfo *this_leaf, struct device_node *np)
|
static void cache_nr_sets(struct cacheinfo *this_leaf, struct device_node *np)
|
||||||
{
|
{
|
||||||
const char *propname;
|
const char *propname;
|
||||||
const __be32 *nr_sets;
|
|
||||||
int ct_idx;
|
int ct_idx;
|
||||||
|
|
||||||
ct_idx = get_cacheinfo_idx(this_leaf->type);
|
ct_idx = get_cacheinfo_idx(this_leaf->type);
|
||||||
propname = cache_type_info[ct_idx].nr_sets_prop;
|
propname = cache_type_info[ct_idx].nr_sets_prop;
|
||||||
|
|
||||||
nr_sets = of_get_property(np, propname, NULL);
|
if (of_property_read_u32(np, propname, &this_leaf->number_of_sets))
|
||||||
if (nr_sets)
|
this_leaf->number_of_sets = 0;
|
||||||
this_leaf->number_of_sets = of_read_number(nr_sets, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cache_associativity(struct cacheinfo *this_leaf)
|
static void cache_associativity(struct cacheinfo *this_leaf)
|
||||||
|
|
|
@ -105,7 +105,7 @@ static int device_is_dependent(struct device *dev, void *target)
|
||||||
struct device_link *link;
|
struct device_link *link;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (WARN_ON(dev == target))
|
if (dev == target)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ret = device_for_each_child(dev, target, device_is_dependent);
|
ret = device_for_each_child(dev, target, device_is_dependent);
|
||||||
|
@ -113,7 +113,7 @@ static int device_is_dependent(struct device *dev, void *target)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
list_for_each_entry(link, &dev->links.consumers, s_node) {
|
list_for_each_entry(link, &dev->links.consumers, s_node) {
|
||||||
if (WARN_ON(link->consumer == target))
|
if (link->consumer == target)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ret = device_is_dependent(link->consumer, target);
|
ret = device_is_dependent(link->consumer, target);
|
||||||
|
@ -1647,6 +1647,8 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&gdp_mutex);
|
mutex_lock(&gdp_mutex);
|
||||||
|
if (!kobject_has_children(glue_dir))
|
||||||
|
kobject_del(glue_dir);
|
||||||
kobject_put(glue_dir);
|
kobject_put(glue_dir);
|
||||||
mutex_unlock(&gdp_mutex);
|
mutex_unlock(&gdp_mutex);
|
||||||
}
|
}
|
||||||
|
@ -1786,7 +1788,7 @@ static void device_remove_sys_dev_entry(struct device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_private_init(struct device *dev)
|
static int device_private_init(struct device *dev)
|
||||||
{
|
{
|
||||||
dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
|
dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
|
||||||
if (!dev->p)
|
if (!dev->p)
|
||||||
|
@ -2859,6 +2861,9 @@ void device_shutdown(void)
|
||||||
{
|
{
|
||||||
struct device *dev, *parent;
|
struct device *dev, *parent;
|
||||||
|
|
||||||
|
wait_for_device_probe();
|
||||||
|
device_block_probing();
|
||||||
|
|
||||||
spin_lock(&devices_kset->list_lock);
|
spin_lock(&devices_kset->list_lock);
|
||||||
/*
|
/*
|
||||||
* Walk the devices list backward, shutting down each in turn.
|
* Walk the devices list backward, shutting down each in turn.
|
||||||
|
@ -3052,12 +3057,12 @@ void func(const struct device *dev, const char *fmt, ...) \
|
||||||
} \
|
} \
|
||||||
EXPORT_SYMBOL(func);
|
EXPORT_SYMBOL(func);
|
||||||
|
|
||||||
define_dev_printk_level(dev_emerg, KERN_EMERG);
|
define_dev_printk_level(_dev_emerg, KERN_EMERG);
|
||||||
define_dev_printk_level(dev_alert, KERN_ALERT);
|
define_dev_printk_level(_dev_alert, KERN_ALERT);
|
||||||
define_dev_printk_level(dev_crit, KERN_CRIT);
|
define_dev_printk_level(_dev_crit, KERN_CRIT);
|
||||||
define_dev_printk_level(dev_err, KERN_ERR);
|
define_dev_printk_level(_dev_err, KERN_ERR);
|
||||||
define_dev_printk_level(dev_warn, KERN_WARNING);
|
define_dev_printk_level(_dev_warn, KERN_WARNING);
|
||||||
define_dev_printk_level(dev_notice, KERN_NOTICE);
|
define_dev_printk_level(_dev_notice, KERN_NOTICE);
|
||||||
define_dev_printk_level(_dev_info, KERN_INFO);
|
define_dev_printk_level(_dev_info, KERN_INFO);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
* Copyright (c) 2007-2009 Novell Inc.
|
* Copyright (c) 2007-2009 Novell Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/debugfs.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
@ -53,6 +54,7 @@ static DEFINE_MUTEX(deferred_probe_mutex);
|
||||||
static LIST_HEAD(deferred_probe_pending_list);
|
static LIST_HEAD(deferred_probe_pending_list);
|
||||||
static LIST_HEAD(deferred_probe_active_list);
|
static LIST_HEAD(deferred_probe_active_list);
|
||||||
static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
|
static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
|
||||||
|
static struct dentry *deferred_devices;
|
||||||
static bool initcalls_done;
|
static bool initcalls_done;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -62,26 +64,6 @@ static bool initcalls_done;
|
||||||
*/
|
*/
|
||||||
static bool defer_all_probes;
|
static bool defer_all_probes;
|
||||||
|
|
||||||
/*
|
|
||||||
* For initcall_debug, show the deferred probes executed in late_initcall
|
|
||||||
* processing.
|
|
||||||
*/
|
|
||||||
static void deferred_probe_debug(struct device *dev)
|
|
||||||
{
|
|
||||||
ktime_t calltime, delta, rettime;
|
|
||||||
unsigned long long duration;
|
|
||||||
|
|
||||||
printk(KERN_DEBUG "deferred probe %s @ %i\n", dev_name(dev),
|
|
||||||
task_pid_nr(current));
|
|
||||||
calltime = ktime_get();
|
|
||||||
bus_probe_device(dev);
|
|
||||||
rettime = ktime_get();
|
|
||||||
delta = ktime_sub(rettime, calltime);
|
|
||||||
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
|
|
||||||
printk(KERN_DEBUG "deferred probe %s returned after %lld usecs\n",
|
|
||||||
dev_name(dev), duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* deferred_probe_work_func() - Retry probing devices in the active list.
|
* deferred_probe_work_func() - Retry probing devices in the active list.
|
||||||
*/
|
*/
|
||||||
|
@ -125,11 +107,7 @@ static void deferred_probe_work_func(struct work_struct *work)
|
||||||
device_pm_move_to_tail(dev);
|
device_pm_move_to_tail(dev);
|
||||||
|
|
||||||
dev_dbg(dev, "Retrying from deferred list\n");
|
dev_dbg(dev, "Retrying from deferred list\n");
|
||||||
if (initcall_debug && !initcalls_done)
|
|
||||||
deferred_probe_debug(dev);
|
|
||||||
else
|
|
||||||
bus_probe_device(dev);
|
bus_probe_device(dev);
|
||||||
|
|
||||||
mutex_lock(&deferred_probe_mutex);
|
mutex_lock(&deferred_probe_mutex);
|
||||||
|
|
||||||
put_device(dev);
|
put_device(dev);
|
||||||
|
@ -224,6 +202,69 @@ void device_unblock_probing(void)
|
||||||
driver_deferred_probe_trigger();
|
driver_deferred_probe_trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* deferred_devs_show() - Show the devices in the deferred probe pending list.
|
||||||
|
*/
|
||||||
|
static int deferred_devs_show(struct seq_file *s, void *data)
|
||||||
|
{
|
||||||
|
struct device_private *curr;
|
||||||
|
|
||||||
|
mutex_lock(&deferred_probe_mutex);
|
||||||
|
|
||||||
|
list_for_each_entry(curr, &deferred_probe_pending_list, deferred_probe)
|
||||||
|
seq_printf(s, "%s\n", dev_name(curr->device));
|
||||||
|
|
||||||
|
mutex_unlock(&deferred_probe_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DEFINE_SHOW_ATTRIBUTE(deferred_devs);
|
||||||
|
|
||||||
|
static int deferred_probe_timeout = -1;
|
||||||
|
static int __init deferred_probe_timeout_setup(char *str)
|
||||||
|
{
|
||||||
|
deferred_probe_timeout = simple_strtol(str, NULL, 10);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
__setup("deferred_probe_timeout=", deferred_probe_timeout_setup);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* driver_deferred_probe_check_state() - Check deferred probe state
|
||||||
|
* @dev: device to check
|
||||||
|
*
|
||||||
|
* Returns -ENODEV if init is done and all built-in drivers have had a chance
|
||||||
|
* to probe (i.e. initcalls are done), -ETIMEDOUT if deferred probe debug
|
||||||
|
* timeout has expired, or -EPROBE_DEFER if none of those conditions are met.
|
||||||
|
*
|
||||||
|
* Drivers or subsystems can opt-in to calling this function instead of directly
|
||||||
|
* returning -EPROBE_DEFER.
|
||||||
|
*/
|
||||||
|
int driver_deferred_probe_check_state(struct device *dev)
|
||||||
|
{
|
||||||
|
if (initcalls_done) {
|
||||||
|
if (!deferred_probe_timeout) {
|
||||||
|
dev_WARN(dev, "deferred probe timeout, ignoring dependency");
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
dev_warn(dev, "ignoring dependency for device, assuming no driver");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deferred_probe_timeout_work_func(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct device_private *private, *p;
|
||||||
|
|
||||||
|
deferred_probe_timeout = 0;
|
||||||
|
driver_deferred_probe_trigger();
|
||||||
|
flush_work(&deferred_probe_work);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe)
|
||||||
|
dev_info(private->device, "deferred probe pending");
|
||||||
|
}
|
||||||
|
static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deferred_probe_initcall() - Enable probing of deferred devices
|
* deferred_probe_initcall() - Enable probing of deferred devices
|
||||||
*
|
*
|
||||||
|
@ -233,15 +274,36 @@ void device_unblock_probing(void)
|
||||||
*/
|
*/
|
||||||
static int deferred_probe_initcall(void)
|
static int deferred_probe_initcall(void)
|
||||||
{
|
{
|
||||||
|
deferred_devices = debugfs_create_file("devices_deferred", 0444, NULL,
|
||||||
|
NULL, &deferred_devs_fops);
|
||||||
|
|
||||||
driver_deferred_probe_enable = true;
|
driver_deferred_probe_enable = true;
|
||||||
driver_deferred_probe_trigger();
|
driver_deferred_probe_trigger();
|
||||||
/* Sort as many dependencies as possible before exiting initcalls */
|
/* Sort as many dependencies as possible before exiting initcalls */
|
||||||
flush_work(&deferred_probe_work);
|
flush_work(&deferred_probe_work);
|
||||||
initcalls_done = true;
|
initcalls_done = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trigger deferred probe again, this time we won't defer anything
|
||||||
|
* that is optional
|
||||||
|
*/
|
||||||
|
driver_deferred_probe_trigger();
|
||||||
|
flush_work(&deferred_probe_work);
|
||||||
|
|
||||||
|
if (deferred_probe_timeout > 0) {
|
||||||
|
schedule_delayed_work(&deferred_probe_timeout_work,
|
||||||
|
deferred_probe_timeout * HZ);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
late_initcall(deferred_probe_initcall);
|
late_initcall(deferred_probe_initcall);
|
||||||
|
|
||||||
|
static void __exit deferred_probe_exit(void)
|
||||||
|
{
|
||||||
|
debugfs_remove_recursive(deferred_devices);
|
||||||
|
}
|
||||||
|
__exitcall(deferred_probe_exit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* device_is_bound() - Check if device is bound to a driver
|
* device_is_bound() - Check if device is bound to a driver
|
||||||
* @dev: device to check
|
* @dev: device to check
|
||||||
|
@ -519,6 +581,23 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For initcall_debug, show the driver probe time.
|
||||||
|
*/
|
||||||
|
static int really_probe_debug(struct device *dev, struct device_driver *drv)
|
||||||
|
{
|
||||||
|
ktime_t calltime, delta, rettime;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
calltime = ktime_get();
|
||||||
|
ret = really_probe(dev, drv);
|
||||||
|
rettime = ktime_get();
|
||||||
|
delta = ktime_sub(rettime, calltime);
|
||||||
|
printk(KERN_DEBUG "probe of %s returned %d after %lld usecs\n",
|
||||||
|
dev_name(dev), ret, (s64) ktime_to_us(delta));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* driver_probe_done
|
* driver_probe_done
|
||||||
* Determine if the probe sequence is finished or not.
|
* Determine if the probe sequence is finished or not.
|
||||||
|
@ -577,6 +656,9 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
|
||||||
pm_runtime_get_sync(dev->parent);
|
pm_runtime_get_sync(dev->parent);
|
||||||
|
|
||||||
pm_runtime_barrier(dev);
|
pm_runtime_barrier(dev);
|
||||||
|
if (initcall_debug)
|
||||||
|
ret = really_probe_debug(dev, drv);
|
||||||
|
else
|
||||||
ret = really_probe(dev, drv);
|
ret = really_probe(dev, drv);
|
||||||
pm_request_idle(dev);
|
pm_request_idle(dev);
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ void __init driver_init(void)
|
||||||
/* These are also core pieces, but must come after the
|
/* These are also core pieces, but must come after the
|
||||||
* core core pieces.
|
* core core pieces.
|
||||||
*/
|
*/
|
||||||
|
of_core_init();
|
||||||
platform_bus_init();
|
platform_bus_init();
|
||||||
cpu_dev_init();
|
cpu_dev_init();
|
||||||
memory_dev_init();
|
memory_dev_init();
|
||||||
container_dev_init();
|
container_dev_init();
|
||||||
of_core_init();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2253,7 +2253,7 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device_node *np,
|
||||||
mutex_unlock(&gpd_list_lock);
|
mutex_unlock(&gpd_list_lock);
|
||||||
dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
|
dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
|
||||||
__func__, PTR_ERR(pd));
|
__func__, PTR_ERR(pd));
|
||||||
return -EPROBE_DEFER;
|
return driver_deferred_probe_check_state(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(dev, "adding to PM domain %s\n", pd->name);
|
dev_dbg(dev, "adding to PM domain %s\n", pd->name);
|
||||||
|
|
|
@ -2915,8 +2915,6 @@ static struct platform_driver arm_smmu_driver = {
|
||||||
};
|
};
|
||||||
module_platform_driver(arm_smmu_driver);
|
module_platform_driver(arm_smmu_driver);
|
||||||
|
|
||||||
IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3");
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
|
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
|
||||||
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
|
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
|
@ -2211,13 +2211,6 @@ static struct platform_driver arm_smmu_driver = {
|
||||||
};
|
};
|
||||||
module_platform_driver(arm_smmu_driver);
|
module_platform_driver(arm_smmu_driver);
|
||||||
|
|
||||||
IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1");
|
|
||||||
IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2");
|
|
||||||
IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400");
|
|
||||||
IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401");
|
|
||||||
IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500");
|
|
||||||
IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2");
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
|
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
|
||||||
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
|
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
|
@ -1390,5 +1390,3 @@ err_reg_driver:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
core_initcall(exynos_iommu_init);
|
core_initcall(exynos_iommu_init);
|
||||||
|
|
||||||
IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu");
|
|
||||||
|
|
|
@ -1108,9 +1108,6 @@ static void __exit ipmmu_exit(void)
|
||||||
subsys_initcall(ipmmu_init);
|
subsys_initcall(ipmmu_init);
|
||||||
module_exit(ipmmu_exit);
|
module_exit(ipmmu_exit);
|
||||||
|
|
||||||
IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa");
|
|
||||||
IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795");
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
|
MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
|
||||||
MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
|
MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
|
@ -877,7 +877,5 @@ static void __exit msm_iommu_driver_exit(void)
|
||||||
subsys_initcall(msm_iommu_driver_init);
|
subsys_initcall(msm_iommu_driver_init);
|
||||||
module_exit(msm_iommu_driver_exit);
|
module_exit(msm_iommu_driver_exit);
|
||||||
|
|
||||||
IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu");
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
|
MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
|
||||||
|
|
|
@ -27,9 +27,6 @@
|
||||||
|
|
||||||
#define NO_IOMMU 1
|
#define NO_IOMMU 1
|
||||||
|
|
||||||
static const struct of_device_id __iommu_of_table_sentinel
|
|
||||||
__used __section(__iommu_of_table_end);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* of_get_dma_window - Parse *dma-window property and returns 0 if found.
|
* of_get_dma_window - Parse *dma-window property and returns 0 if found.
|
||||||
*
|
*
|
||||||
|
@ -98,19 +95,6 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(of_get_dma_window);
|
EXPORT_SYMBOL_GPL(of_get_dma_window);
|
||||||
|
|
||||||
static bool of_iommu_driver_present(struct device_node *np)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If the IOMMU still isn't ready by the time we reach init, assume
|
|
||||||
* it never will be. We don't want to defer indefinitely, nor attempt
|
|
||||||
* to dereference __iommu_of_table after it's been freed.
|
|
||||||
*/
|
|
||||||
if (system_state >= SYSTEM_RUNNING)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return of_match_node(&__iommu_of_table, np);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int of_iommu_xlate(struct device *dev,
|
static int of_iommu_xlate(struct device *dev,
|
||||||
struct of_phandle_args *iommu_spec)
|
struct of_phandle_args *iommu_spec)
|
||||||
{
|
{
|
||||||
|
@ -120,8 +104,7 @@ static int of_iommu_xlate(struct device *dev,
|
||||||
|
|
||||||
ops = iommu_ops_from_fwnode(fwnode);
|
ops = iommu_ops_from_fwnode(fwnode);
|
||||||
if ((ops && !ops->of_xlate) ||
|
if ((ops && !ops->of_xlate) ||
|
||||||
!of_device_is_available(iommu_spec->np) ||
|
!of_device_is_available(iommu_spec->np))
|
||||||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
|
|
||||||
return NO_IOMMU;
|
return NO_IOMMU;
|
||||||
|
|
||||||
err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
|
err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
|
||||||
|
@ -133,7 +116,7 @@ static int of_iommu_xlate(struct device *dev,
|
||||||
* a proper probe-ordering dependency mechanism in future.
|
* a proper probe-ordering dependency mechanism in future.
|
||||||
*/
|
*/
|
||||||
if (!ops)
|
if (!ops)
|
||||||
return -EPROBE_DEFER;
|
return driver_deferred_probe_check_state(dev);
|
||||||
|
|
||||||
return ops->of_xlate(dev, iommu_spec);
|
return ops->of_xlate(dev, iommu_spec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -945,7 +945,5 @@ static void __exit qcom_iommu_exit(void)
|
||||||
module_init(qcom_iommu_init);
|
module_init(qcom_iommu_init);
|
||||||
module_exit(qcom_iommu_exit);
|
module_exit(qcom_iommu_exit);
|
||||||
|
|
||||||
IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1");
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
|
MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
|
@ -1284,8 +1284,6 @@ static int __init rk_iommu_init(void)
|
||||||
}
|
}
|
||||||
subsys_initcall(rk_iommu_init);
|
subsys_initcall(rk_iommu_init);
|
||||||
|
|
||||||
IOMMU_OF_DECLARE(rk_iommu_of, "rockchip,iommu");
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("IOMMU API for Rockchip");
|
MODULE_DESCRIPTION("IOMMU API for Rockchip");
|
||||||
MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <djkurtz@chromium.org>");
|
MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <djkurtz@chromium.org>");
|
||||||
MODULE_ALIAS("platform:rockchip-iommu");
|
MODULE_ALIAS("platform:rockchip-iommu");
|
||||||
|
|
|
@ -111,17 +111,24 @@ static int dt_to_map_one_config(struct pinctrl *p,
|
||||||
int ret;
|
int ret;
|
||||||
struct pinctrl_map *map;
|
struct pinctrl_map *map;
|
||||||
unsigned num_maps;
|
unsigned num_maps;
|
||||||
|
bool allow_default = false;
|
||||||
|
|
||||||
/* Find the pin controller containing np_config */
|
/* Find the pin controller containing np_config */
|
||||||
np_pctldev = of_node_get(np_config);
|
np_pctldev = of_node_get(np_config);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
if (!allow_default)
|
||||||
|
allow_default = of_property_read_bool(np_pctldev,
|
||||||
|
"pinctrl-use-default");
|
||||||
|
|
||||||
np_pctldev = of_get_next_parent(np_pctldev);
|
np_pctldev = of_get_next_parent(np_pctldev);
|
||||||
if (!np_pctldev || of_node_is_root(np_pctldev)) {
|
if (!np_pctldev || of_node_is_root(np_pctldev)) {
|
||||||
dev_info(p->dev, "could not find pctldev for node %pOF, deferring probe\n",
|
|
||||||
np_config);
|
|
||||||
of_node_put(np_pctldev);
|
of_node_put(np_pctldev);
|
||||||
/* OK let's just assume this will appear later then */
|
ret = driver_deferred_probe_check_state(p->dev);
|
||||||
return -EPROBE_DEFER;
|
/* keep deferring if modules are enabled unless we've timed out */
|
||||||
|
if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret == -ENODEV)
|
||||||
|
ret = -EPROBE_DEFER;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
/* If we're creating a hog we can use the passed pctldev */
|
/* If we're creating a hog we can use the passed pctldev */
|
||||||
if (hog_pctldev && (np_pctldev == p->dev->of_node)) {
|
if (hog_pctldev && (np_pctldev == p->dev->of_node)) {
|
||||||
|
|
|
@ -97,7 +97,7 @@ static int kernfs_get_target_path(struct kernfs_node *parent,
|
||||||
int slen = strlen(kn->name);
|
int slen = strlen(kn->name);
|
||||||
|
|
||||||
len -= slen;
|
len -= slen;
|
||||||
strncpy(s + len, kn->name, slen);
|
memcpy(s + len, kn->name, slen);
|
||||||
if (len)
|
if (len)
|
||||||
s[--len] = '/';
|
s[--len] = '/';
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,14 @@ static int internal_create_group(struct kobject *kobj, int update,
|
||||||
}
|
}
|
||||||
kobject_get_ownership(kobj, &uid, &gid);
|
kobject_get_ownership(kobj, &uid, &gid);
|
||||||
if (grp->name) {
|
if (grp->name) {
|
||||||
|
if (update) {
|
||||||
|
kn = kernfs_find_and_get(kobj->sd, grp->name);
|
||||||
|
if (!kn) {
|
||||||
|
pr_warn("Can't update unknown attr grp name: %s/%s\n",
|
||||||
|
kobj->name, grp->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
kn = kernfs_create_dir_ns(kobj->sd, grp->name,
|
kn = kernfs_create_dir_ns(kobj->sd, grp->name,
|
||||||
S_IRWXU | S_IRUGO | S_IXUGO,
|
S_IRWXU | S_IRUGO | S_IXUGO,
|
||||||
uid, gid, kobj, NULL);
|
uid, gid, kobj, NULL);
|
||||||
|
@ -132,6 +140,7 @@ static int internal_create_group(struct kobject *kobj, int update,
|
||||||
sysfs_warn_dup(kobj->sd, grp->name);
|
sysfs_warn_dup(kobj->sd, grp->name);
|
||||||
return PTR_ERR(kn);
|
return PTR_ERR(kn);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
kn = kobj->sd;
|
kn = kobj->sd;
|
||||||
kernfs_get(kn);
|
kernfs_get(kn);
|
||||||
|
@ -141,6 +150,10 @@ static int internal_create_group(struct kobject *kobj, int update,
|
||||||
kernfs_remove(kn);
|
kernfs_remove(kn);
|
||||||
}
|
}
|
||||||
kernfs_put(kn);
|
kernfs_put(kn);
|
||||||
|
|
||||||
|
if (grp->name && update)
|
||||||
|
kernfs_put(kn);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +218,8 @@ EXPORT_SYMBOL_GPL(sysfs_create_groups);
|
||||||
* of the attribute files being created already exist. Furthermore,
|
* of the attribute files being created already exist. Furthermore,
|
||||||
* if the visibility of the files has changed through the is_visible()
|
* if the visibility of the files has changed through the is_visible()
|
||||||
* callback, it will update the permissions and add or remove the
|
* callback, it will update the permissions and add or remove the
|
||||||
* relevant files.
|
* relevant files. Changing a group's name (subdirectory name under
|
||||||
|
* kobj's directory in sysfs) is not allowed.
|
||||||
*
|
*
|
||||||
* The primary use for this function is to call it after making a change
|
* The primary use for this function is to call it after making a change
|
||||||
* that affects group visibility.
|
* that affects group visibility.
|
||||||
|
|
|
@ -218,7 +218,6 @@
|
||||||
#define TIMER_OF_TABLES() OF_TABLE(CONFIG_TIMER_OF, timer)
|
#define TIMER_OF_TABLES() OF_TABLE(CONFIG_TIMER_OF, timer)
|
||||||
#define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip)
|
#define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip)
|
||||||
#define CLK_OF_TABLES() OF_TABLE(CONFIG_COMMON_CLK, clk)
|
#define CLK_OF_TABLES() OF_TABLE(CONFIG_COMMON_CLK, clk)
|
||||||
#define IOMMU_OF_TABLES() OF_TABLE(CONFIG_OF_IOMMU, iommu)
|
|
||||||
#define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem)
|
#define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem)
|
||||||
#define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method)
|
#define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method)
|
||||||
#define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
|
#define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
|
||||||
|
@ -601,7 +600,6 @@
|
||||||
CLK_OF_TABLES() \
|
CLK_OF_TABLES() \
|
||||||
RESERVEDMEM_OF_TABLES() \
|
RESERVEDMEM_OF_TABLES() \
|
||||||
TIMER_OF_TABLES() \
|
TIMER_OF_TABLES() \
|
||||||
IOMMU_OF_TABLES() \
|
|
||||||
CPU_METHOD_OF_TABLES() \
|
CPU_METHOD_OF_TABLES() \
|
||||||
CPUIDLE_METHOD_OF_TABLES() \
|
CPUIDLE_METHOD_OF_TABLES() \
|
||||||
KERNEL_DTB() \
|
KERNEL_DTB() \
|
||||||
|
|
|
@ -339,6 +339,8 @@ struct device *driver_find_device(struct device_driver *drv,
|
||||||
struct device *start, void *data,
|
struct device *start, void *data,
|
||||||
int (*match)(struct device *dev, void *data));
|
int (*match)(struct device *dev, void *data));
|
||||||
|
|
||||||
|
int driver_deferred_probe_check_state(struct device *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct subsys_interface - interfaces to device functions
|
* struct subsys_interface - interfaces to device functions
|
||||||
* @name: name of the device function
|
* @name: name of the device function
|
||||||
|
@ -1329,30 +1331,34 @@ struct device_link *device_link_add(struct device *consumer,
|
||||||
void device_link_del(struct device_link *link);
|
void device_link_del(struct device_link *link);
|
||||||
void device_link_remove(void *consumer, struct device *supplier);
|
void device_link_remove(void *consumer, struct device *supplier);
|
||||||
|
|
||||||
|
#ifndef dev_fmt
|
||||||
|
#define dev_fmt(fmt) fmt
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PRINTK
|
#ifdef CONFIG_PRINTK
|
||||||
|
|
||||||
extern __printf(3, 0)
|
__printf(3, 0)
|
||||||
int dev_vprintk_emit(int level, const struct device *dev,
|
int dev_vprintk_emit(int level, const struct device *dev,
|
||||||
const char *fmt, va_list args);
|
const char *fmt, va_list args);
|
||||||
extern __printf(3, 4)
|
__printf(3, 4)
|
||||||
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
|
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
|
||||||
|
|
||||||
extern __printf(3, 4)
|
__printf(3, 4)
|
||||||
void dev_printk(const char *level, const struct device *dev,
|
void dev_printk(const char *level, const struct device *dev,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
extern __printf(2, 3)
|
__printf(2, 3)
|
||||||
void dev_emerg(const struct device *dev, const char *fmt, ...);
|
void _dev_emerg(const struct device *dev, const char *fmt, ...);
|
||||||
extern __printf(2, 3)
|
__printf(2, 3)
|
||||||
void dev_alert(const struct device *dev, const char *fmt, ...);
|
void _dev_alert(const struct device *dev, const char *fmt, ...);
|
||||||
extern __printf(2, 3)
|
__printf(2, 3)
|
||||||
void dev_crit(const struct device *dev, const char *fmt, ...);
|
void _dev_crit(const struct device *dev, const char *fmt, ...);
|
||||||
extern __printf(2, 3)
|
__printf(2, 3)
|
||||||
void dev_err(const struct device *dev, const char *fmt, ...);
|
void _dev_err(const struct device *dev, const char *fmt, ...);
|
||||||
extern __printf(2, 3)
|
__printf(2, 3)
|
||||||
void dev_warn(const struct device *dev, const char *fmt, ...);
|
void _dev_warn(const struct device *dev, const char *fmt, ...);
|
||||||
extern __printf(2, 3)
|
__printf(2, 3)
|
||||||
void dev_notice(const struct device *dev, const char *fmt, ...);
|
void _dev_notice(const struct device *dev, const char *fmt, ...);
|
||||||
extern __printf(2, 3)
|
__printf(2, 3)
|
||||||
void _dev_info(const struct device *dev, const char *fmt, ...);
|
void _dev_info(const struct device *dev, const char *fmt, ...);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -1374,22 +1380,22 @@ void dev_printk(const char *level, const struct device *dev,
|
||||||
{}
|
{}
|
||||||
|
|
||||||
static inline __printf(2, 3)
|
static inline __printf(2, 3)
|
||||||
void dev_emerg(const struct device *dev, const char *fmt, ...)
|
void _dev_emerg(const struct device *dev, const char *fmt, ...)
|
||||||
{}
|
{}
|
||||||
static inline __printf(2, 3)
|
static inline __printf(2, 3)
|
||||||
void dev_crit(const struct device *dev, const char *fmt, ...)
|
void _dev_crit(const struct device *dev, const char *fmt, ...)
|
||||||
{}
|
{}
|
||||||
static inline __printf(2, 3)
|
static inline __printf(2, 3)
|
||||||
void dev_alert(const struct device *dev, const char *fmt, ...)
|
void _dev_alert(const struct device *dev, const char *fmt, ...)
|
||||||
{}
|
{}
|
||||||
static inline __printf(2, 3)
|
static inline __printf(2, 3)
|
||||||
void dev_err(const struct device *dev, const char *fmt, ...)
|
void _dev_err(const struct device *dev, const char *fmt, ...)
|
||||||
{}
|
{}
|
||||||
static inline __printf(2, 3)
|
static inline __printf(2, 3)
|
||||||
void dev_warn(const struct device *dev, const char *fmt, ...)
|
void _dev_warn(const struct device *dev, const char *fmt, ...)
|
||||||
{}
|
{}
|
||||||
static inline __printf(2, 3)
|
static inline __printf(2, 3)
|
||||||
void dev_notice(const struct device *dev, const char *fmt, ...)
|
void _dev_notice(const struct device *dev, const char *fmt, ...)
|
||||||
{}
|
{}
|
||||||
static inline __printf(2, 3)
|
static inline __printf(2, 3)
|
||||||
void _dev_info(const struct device *dev, const char *fmt, ...)
|
void _dev_info(const struct device *dev, const char *fmt, ...)
|
||||||
|
@ -1398,27 +1404,36 @@ void _dev_info(const struct device *dev, const char *fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stupid hackaround for existing uses of non-printk uses dev_info
|
* #defines for all the dev_<level> macros to prefix with whatever
|
||||||
*
|
* possible use of #define dev_fmt(fmt) ...
|
||||||
* Note that the definition of dev_info below is actually _dev_info
|
|
||||||
* and a macro is used to avoid redefining dev_info
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define dev_info(dev, fmt, arg...) _dev_info(dev, fmt, ##arg)
|
#define dev_emerg(dev, fmt, ...) \
|
||||||
|
_dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
#define dev_crit(dev, fmt, ...) \
|
||||||
|
_dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
#define dev_alert(dev, fmt, ...) \
|
||||||
|
_dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
#define dev_err(dev, fmt, ...) \
|
||||||
|
_dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
#define dev_warn(dev, fmt, ...) \
|
||||||
|
_dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
#define dev_notice(dev, fmt, ...) \
|
||||||
|
_dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
#define dev_info(dev, fmt, ...) \
|
||||||
|
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
|
||||||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||||
#define dev_dbg(dev, format, ...) \
|
#define dev_dbg(dev, fmt, ...) \
|
||||||
do { \
|
dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
|
|
||||||
} while (0)
|
|
||||||
#elif defined(DEBUG)
|
#elif defined(DEBUG)
|
||||||
#define dev_dbg(dev, format, arg...) \
|
#define dev_dbg(dev, fmt, ...) \
|
||||||
dev_printk(KERN_DEBUG, dev, format, ##arg)
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define dev_dbg(dev, format, arg...) \
|
#define dev_dbg(dev, fmt, ...) \
|
||||||
({ \
|
({ \
|
||||||
if (0) \
|
if (0) \
|
||||||
dev_printk(KERN_DEBUG, dev, format, ##arg); \
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
|
||||||
})
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1490,7 +1505,7 @@ do { \
|
||||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||||
if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
|
if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
|
||||||
__ratelimit(&_rs)) \
|
__ratelimit(&_rs)) \
|
||||||
__dynamic_dev_dbg(&descriptor, dev, fmt, \
|
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
|
||||||
##__VA_ARGS__); \
|
##__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#elif defined(DEBUG)
|
#elif defined(DEBUG)
|
||||||
|
@ -1500,23 +1515,23 @@ do { \
|
||||||
DEFAULT_RATELIMIT_INTERVAL, \
|
DEFAULT_RATELIMIT_INTERVAL, \
|
||||||
DEFAULT_RATELIMIT_BURST); \
|
DEFAULT_RATELIMIT_BURST); \
|
||||||
if (__ratelimit(&_rs)) \
|
if (__ratelimit(&_rs)) \
|
||||||
dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define dev_dbg_ratelimited(dev, fmt, ...) \
|
#define dev_dbg_ratelimited(dev, fmt, ...) \
|
||||||
do { \
|
do { \
|
||||||
if (0) \
|
if (0) \
|
||||||
dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VERBOSE_DEBUG
|
#ifdef VERBOSE_DEBUG
|
||||||
#define dev_vdbg dev_dbg
|
#define dev_vdbg dev_dbg
|
||||||
#else
|
#else
|
||||||
#define dev_vdbg(dev, format, arg...) \
|
#define dev_vdbg(dev, fmt, ...) \
|
||||||
({ \
|
({ \
|
||||||
if (0) \
|
if (0) \
|
||||||
dev_printk(KERN_DEBUG, dev, format, ##arg); \
|
dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
|
||||||
})
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,23 @@ extern void kobject_get_ownership(struct kobject *kobj,
|
||||||
kuid_t *uid, kgid_t *gid);
|
kuid_t *uid, kgid_t *gid);
|
||||||
extern char *kobject_get_path(struct kobject *kobj, gfp_t flag);
|
extern char *kobject_get_path(struct kobject *kobj, gfp_t flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kobject_has_children - Returns whether a kobject has children.
|
||||||
|
* @kobj: the object to test
|
||||||
|
*
|
||||||
|
* This will return whether a kobject has other kobjects as children.
|
||||||
|
*
|
||||||
|
* It does NOT account for the presence of attribute files, only sub
|
||||||
|
* directories. It also assumes there is no concurrent addition or
|
||||||
|
* removal of such children, and thus relies on external locking.
|
||||||
|
*/
|
||||||
|
static inline bool kobject_has_children(struct kobject *kobj)
|
||||||
|
{
|
||||||
|
WARN_ON_ONCE(kref_read(&kobj->kref) == 0);
|
||||||
|
|
||||||
|
return kobj->sd && kobj->sd->dir.subdirs;
|
||||||
|
}
|
||||||
|
|
||||||
struct kobj_type {
|
struct kobj_type {
|
||||||
void (*release)(struct kobject *kobj);
|
void (*release)(struct kobject *kobj);
|
||||||
const struct sysfs_ops *sysfs_ops;
|
const struct sysfs_ops *sysfs_ops;
|
||||||
|
|
|
@ -32,8 +32,4 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
|
||||||
|
|
||||||
#endif /* CONFIG_OF_IOMMU */
|
#endif /* CONFIG_OF_IOMMU */
|
||||||
|
|
||||||
extern struct of_device_id __iommu_of_table;
|
|
||||||
|
|
||||||
#define IOMMU_OF_DECLARE(name, compat) OF_DECLARE_1(iommu, name, compat, NULL)
|
|
||||||
|
|
||||||
#endif /* __OF_IOMMU_H */
|
#endif /* __OF_IOMMU_H */
|
||||||
|
|
|
@ -91,9 +91,9 @@ struct attribute_group {
|
||||||
struct bin_attribute **bin_attrs;
|
struct bin_attribute **bin_attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Use these macros to make defining attributes easier. See include/linux/device.h
|
* Use these macros to make defining attributes easier.
|
||||||
* for examples..
|
* See include/linux/device.h for examples..
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SYSFS_PREALLOC 010000
|
#define SYSFS_PREALLOC 010000
|
||||||
|
|
|
@ -144,7 +144,7 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length)
|
||||||
int cur = strlen(kobject_name(parent));
|
int cur = strlen(kobject_name(parent));
|
||||||
/* back up enough to print this name with '/' */
|
/* back up enough to print this name with '/' */
|
||||||
length -= cur;
|
length -= cur;
|
||||||
strncpy(path + length, kobject_name(parent), cur);
|
memcpy(path + length, kobject_name(parent), cur);
|
||||||
*(path + --length) = '/';
|
*(path + --length) = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue