From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH 1/3] driver: add support for device aliases
Date: Wed, 13 Sep 2023 15:24:54 +0200 [thread overview]
Message-ID: <20230913132456.2211919-2-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20230913132456.2211919-1-a.fatoum@pengutronix.de>
Device names can get quite long, which makes them cumbersome to use
on the shell, e.g. firmware:zynqmp-firmware:clock-controller.of.
In addition, the names are prone to change when the device tree nodes
are renamed.
One way we work around this is using aliases, but that is partially at
odds with upstream binding. This commit adds an alternative way of
allowing drivers and board code to set an alias that affects only
device_param_complete.
This provides an easy way of defining device names that should be stable
for use in shell scripts.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/complete.c | 14 ++++++-------
drivers/base/driver.c | 46 +++++++++++++++++++++++++++++++++++++++++++
include/driver.h | 7 +++++++
3 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/common/complete.c b/common/complete.c
index e9f3f8ee033f..4137bb3084fc 100644
--- a/common/complete.c
+++ b/common/complete.c
@@ -154,8 +154,8 @@ int device_complete(struct string_list *sl, char *instr)
}
EXPORT_SYMBOL(device_complete);
-static int device_param_complete(struct device *dev, struct string_list *sl,
- char *instr, int eval)
+static int device_param_complete(struct device *dev, const char *devname,
+ struct string_list *sl, char *instr, int eval)
{
struct param_d *param;
int len;
@@ -167,7 +167,7 @@ static int device_param_complete(struct device *dev, struct string_list *sl,
continue;
string_list_add_asprintf(sl, "%s%s.%s%c",
- eval ? "$" : "", dev_name(dev), param->name,
+ eval ? "$" : "", devname, param->name,
eval ? ' ' : '=');
}
@@ -308,14 +308,12 @@ static int env_param_complete(struct string_list *sl, char *instr, int eval)
char *devname;
devname = xstrndup(instr, dot - instr);
-
-
dev = get_device_by_name(devname);
- free(devname);
if (dev)
- device_param_complete(dev, sl, dot + 1, eval);
+ device_param_complete(dev, devname, sl, dot + 1, eval);
+ free(devname);
pos = dot + 1;
}
@@ -323,7 +321,7 @@ static int env_param_complete(struct string_list *sl, char *instr, int eval)
for_each_device(dev) {
if (!strncmp(instr, dev_name(dev), len))
- device_param_complete(dev, sl, "", eval);
+ device_param_complete(dev, dev_name(dev), sl, "", eval);
}
return 0;
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 10d765e1a213..5811c7a11b75 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -24,6 +24,7 @@
#include <fs.h>
#include <of.h>
#include <linux/list.h>
+#include <linux/overflow.h>
#include <linux/err.h>
#include <complete.h>
#include <pinctrl.h>
@@ -46,6 +47,8 @@ LIST_HEAD(active_device_list);
EXPORT_SYMBOL(active_device_list);
static LIST_HEAD(deferred);
+static LIST_HEAD(device_alias_list);
+
struct device *find_device(const char *str)
{
struct device *dev;
@@ -65,12 +68,18 @@ struct device *find_device(const char *str)
struct device *get_device_by_name(const char *name)
{
struct device *dev;
+ struct device_alias *alias;
for_each_device(dev) {
if(!strcmp(dev_name(dev), name))
return dev;
}
+ list_for_each_entry(alias, &device_alias_list, list) {
+ if(!strcmp(alias->name, name))
+ return alias->dev;
+ }
+
return NULL;
}
@@ -261,6 +270,7 @@ EXPORT_SYMBOL(register_device);
int unregister_device(struct device *old_dev)
{
+ struct device_alias *alias, *at;
struct cdev *cdev, *ct;
struct device *child, *dt;
@@ -271,6 +281,11 @@ int unregister_device(struct device *old_dev)
if (old_dev->driver)
old_dev->bus->remove(old_dev);
+ list_for_each_entry_safe(alias, at, &device_alias_list, list) {
+ if(alias->dev == old_dev)
+ list_del(&alias->list);
+ }
+
list_for_each_entry_safe(child, dt, &old_dev->children, sibling) {
dev_dbg(old_dev, "unregister child %s\n", dev_name(child));
unregister_device(child);
@@ -592,6 +607,37 @@ int dev_set_name(struct device *dev, const char *fmt, ...)
}
EXPORT_SYMBOL_GPL(dev_set_name);
+/**
+ * dev_add_alias - add alias for device
+ * @dev: device
+ * @fmt: format string for the device's alias
+ */
+int dev_add_alias(struct device *dev, const char *fmt, ...)
+{
+ va_list va, va_copy;
+ unsigned int len;
+ struct device_alias *alias;
+
+ va_start(va, fmt);
+ va_copy(va_copy, va);
+ len = vsnprintf(NULL, 0, fmt, va_copy);
+ va_end(va_copy);
+
+ alias = malloc(struct_size(alias, name, len + 1));
+ if (!alias)
+ return -ENOMEM;
+
+ vsnprintf(alias->name, len + 1, fmt, va);
+
+ va_end(va);
+
+ alias->dev = dev;
+ list_add_tail(&alias->list, &device_alias_list);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dev_set_alias);
+
static void devices_shutdown(void)
{
struct device *dev;
diff --git a/include/driver.h b/include/driver.h
index 2651cddecc21..a0234fb6c31b 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -101,6 +101,12 @@ struct device {
char *deferred_probe_reason;
};
+struct device_alias {
+ struct device *dev;
+ struct list_head list;
+ char name[];
+};
+
/** @brief Describes a driver present in the system */
struct driver {
/*! The name of this driver. Used to match to
@@ -216,6 +222,7 @@ static inline const char *dev_name(const struct device *dev)
}
int dev_set_name(struct device *dev, const char *fmt, ...);
+int dev_add_alias(struct device *dev, const char *fmt, ...);
/*
* get resource 'num' for a device
--
2.39.2
next prev parent reply other threads:[~2023-09-13 13:26 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-13 13:24 [PATCH 0/3] firmware-zynqmp: add accessors for ggs/pggs Ahmad Fatoum
2023-09-13 13:24 ` Ahmad Fatoum [this message]
2023-09-13 13:24 ` [PATCH 2/3] firmware-zynqmp: export functions for setting GGS/PGGS Ahmad Fatoum
2023-09-13 13:24 ` [PATCH 3/3] firmware-zynqmp: add device parameters for ggs/pggs Ahmad Fatoum
2023-09-14 7:59 ` [PATCH 0/3] firmware-zynqmp: add accessors " Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230913132456.2211919-2-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox