soc_device_match() interface for matching against soc_bus attributes
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYJDsDAAoJEEgEtLw/Ve77SFEP/1E64/Toxi48RM2e37mtbRRp Dye1FUXxJY67USKx9eBYMGUHaV+QOxiifN7SfU0JgovGYtyAZeerbEbibT2TYN3V c9OP/sKUdAriqv/U4MX+2YiQJJS7zHvVt4yk+ZMU3e9dj8d2ndZKCw1rueGDZekn YjI0yNJdHsd08iZ+zrz/UaGeb0lZOzsQNIH+9rMs3GHfwXzLhh6NoYvQVrneu/Cd 0mDKrFqPVmWNETr2qoyZtrVQefgOKffmw10MfFfeItCMWYpbdjBhR0EuONSMv45q Sk3IHNUU049FnU7ucJHJIIcsPqXUicRDbyonotb8QDx//TCwvPwkiEt2tW/TRgBn J9I+q9sIhLTcHGxuYTaWNvNUo9PGcKHWp+7dHhuPs9R1s8OqpFS/Fu371jQmFxGr 6eSxMED7aGb3qJKKp60vFBnKcivVyRpj0mpwtLDrFLZwl+hT9dH4gto7SBuA6x9U 8XnEyySYsoIETyLhuiladURs9UssbHfAxeoX5zMioZ13PoDnnQQSlhUNnpc7XAtc skTa23JsZAfV+UTvu6A//cGd+Jch72Gf6fIVCNGxkn9+FPA4RAktpGciHTSpKRzF +sAAo8g/usW3q0GQQWZqzJZxbOQ8B8dyMTXtp2LT4HGrZT67fJS2tRVMl9X8t+tk CnCCUJ/FcghiP6/Ou4zM =xyGw -----END PGP SIGNATURE----- Merge tag 'soc-device-match-tag1' into next Merge the immutable soc-device-match-tag1 provided by Geert Uytterhoeven to pull in the new soc_device_match() interface for matching against soc_bus attributes.
This commit is contained in:
Коммит
6ecdf76b8f
|
@ -237,6 +237,7 @@ config GENERIC_CPU_AUTOPROBE
|
|||
|
||||
config SOC_BUS
|
||||
bool
|
||||
select GLOB
|
||||
|
||||
source "drivers/base/regmap/Kconfig"
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/glob.h>
|
||||
|
||||
static DEFINE_IDA(soc_ida);
|
||||
|
||||
|
@ -113,6 +114,12 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr
|
|||
struct soc_device *soc_dev;
|
||||
int ret;
|
||||
|
||||
if (!soc_bus_type.p) {
|
||||
ret = bus_register(&soc_bus_type);
|
||||
if (ret)
|
||||
goto out1;
|
||||
}
|
||||
|
||||
soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL);
|
||||
if (!soc_dev) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -156,6 +163,78 @@ void soc_device_unregister(struct soc_device *soc_dev)
|
|||
|
||||
static int __init soc_bus_register(void)
|
||||
{
|
||||
if (soc_bus_type.p)
|
||||
return 0;
|
||||
|
||||
return bus_register(&soc_bus_type);
|
||||
}
|
||||
core_initcall(soc_bus_register);
|
||||
|
||||
static int soc_device_match_one(struct device *dev, void *arg)
|
||||
{
|
||||
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
|
||||
const struct soc_device_attribute *match = arg;
|
||||
|
||||
if (match->machine &&
|
||||
(!soc_dev->attr->machine ||
|
||||
!glob_match(match->machine, soc_dev->attr->machine)))
|
||||
return 0;
|
||||
|
||||
if (match->family &&
|
||||
(!soc_dev->attr->family ||
|
||||
!glob_match(match->family, soc_dev->attr->family)))
|
||||
return 0;
|
||||
|
||||
if (match->revision &&
|
||||
(!soc_dev->attr->revision ||
|
||||
!glob_match(match->revision, soc_dev->attr->revision)))
|
||||
return 0;
|
||||
|
||||
if (match->soc_id &&
|
||||
(!soc_dev->attr->soc_id ||
|
||||
!glob_match(match->soc_id, soc_dev->attr->soc_id)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* soc_device_match - identify the SoC in the machine
|
||||
* @matches: zero-terminated array of possible matches
|
||||
*
|
||||
* returns the first matching entry of the argument array, or NULL
|
||||
* if none of them match.
|
||||
*
|
||||
* This function is meant as a helper in place of of_match_node()
|
||||
* in cases where either no device tree is available or the information
|
||||
* in a device node is insufficient to identify a particular variant
|
||||
* by its compatible strings or other properties. For new devices,
|
||||
* the DT binding should always provide unique compatible strings
|
||||
* that allow the use of of_match_node() instead.
|
||||
*
|
||||
* The calling function can use the .data entry of the
|
||||
* soc_device_attribute to pass a structure or function pointer for
|
||||
* each entry.
|
||||
*/
|
||||
const struct soc_device_attribute *soc_device_match(
|
||||
const struct soc_device_attribute *matches)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!matches)
|
||||
return NULL;
|
||||
|
||||
while (!ret) {
|
||||
if (!(matches->machine || matches->family ||
|
||||
matches->revision || matches->soc_id))
|
||||
break;
|
||||
ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches,
|
||||
soc_device_match_one);
|
||||
if (!ret)
|
||||
matches++;
|
||||
else
|
||||
return matches;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(soc_device_match);
|
||||
|
|
|
@ -13,6 +13,7 @@ struct soc_device_attribute {
|
|||
const char *family;
|
||||
const char *revision;
|
||||
const char *soc_id;
|
||||
const void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -34,4 +35,12 @@ void soc_device_unregister(struct soc_device *soc_dev);
|
|||
*/
|
||||
struct device *soc_device_to_device(struct soc_device *soc);
|
||||
|
||||
#ifdef CONFIG_SOC_BUS
|
||||
const struct soc_device_attribute *soc_device_match(
|
||||
const struct soc_device_attribute *matches);
|
||||
#else
|
||||
static inline const struct soc_device_attribute *soc_device_match(
|
||||
const struct soc_device_attribute *matches) { return NULL; }
|
||||
#endif
|
||||
|
||||
#endif /* __SOC_BUS_H */
|
||||
|
|
Загрузка…
Ссылка в новой задаче