[PATCH v2 libinput 13/14] quirks: add the devicetree implementation
Peter Hutterer
peter.hutterer at who-t.net
Fri Jun 8 06:00:20 UTC 2018
Using the compatible string
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/quirks.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 53 insertions(+), 15 deletions(-)
diff --git a/src/quirks.c b/src/quirks.c
index 1a44574a..2fca275a 100644
--- a/src/quirks.c
+++ b/src/quirks.c
@@ -127,7 +127,7 @@ struct match {
/* We can have more than one type set, so this is a bitfield */
uint32_t udev_type;
- char *dt; /* FIXME: clarify */
+ char *dt; /* device tree compatible (first) string */
};
/**
@@ -168,6 +168,7 @@ struct quirks_context {
struct libinput *libinput; /* for logging */
char *dmi;
+ char *dt;
struct list sections;
@@ -367,6 +368,35 @@ init_dmi(void)
return copy;
}
+/**
+ * Return the dt compatible string
+ */
+static inline char *
+init_dt(void)
+{
+ char compatible[1024];
+ char *copy = NULL;
+ const char *syspath = "/sys/firmware/devicetree/base/compatible";
+ FILE *fp;
+
+ if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
+ return safe_strdup("");
+
+ fp = fopen(syspath, "r");
+ if (!fp)
+ return NULL;
+
+ /* devicetree/base/compatible has multiple null-terminated entries
+ but we only care about the first one here, so strdup is enough */
+ if (fgets(compatible, sizeof(compatible), fp)) {
+ copy = safe_strdup(compatible);
+ }
+
+ fclose(fp);
+
+ return copy;
+}
+
static inline struct section *
section_new(const char *path, const char *name)
{
@@ -487,7 +517,8 @@ parse_match(struct quirks_context *ctx,
else
goto out;
} else if (streq(key, "MatchDeviceTree")) {
- /* FIXME */
+ check_set_bit(s, M_DT);
+ s->match.dt = safe_strdup(value);
} else {
qlog_error(ctx, "Unknown match key '%s'\n", key);
goto out;
@@ -966,7 +997,8 @@ quirks_init_subsystem(const char *data_path,
qlog_debug(ctx, "%s is data root\n", data_path);
ctx->dmi = init_dmi();
- if (!ctx->dmi)
+ ctx->dt = init_dt();
+ if (!ctx->dmi && !ctx->dt)
goto error;
if (!parse_files(ctx, data_path))
@@ -1160,32 +1192,37 @@ match_fill_udev_type(struct match *m,
}
static inline void
-match_fill_dmi(struct match *m,
- char *dmi)
+match_fill_dmi_dt(struct match *m, char *dmi, char *dt)
{
- m->dmi = dmi;
- m->bits |= M_DMI;
+ if (dmi) {
+ m->dmi = dmi;
+ m->bits |= M_DMI;
+ }
+
+ if (dt) {
+ m->dt = dt;
+ m->bits |= M_DT;
+ }
}
static struct match *
match_new(struct udev_device *device,
- char *dmi)
+ char *dmi, char *dt)
{
struct match *m = zalloc(sizeof *m);
match_fill_name(m, device);
match_fill_bus_vid_pid(m, device);
- match_fill_dmi(m, dmi);
+ match_fill_dmi_dt(m, dmi, dt);
match_fill_udev_type(m, device);
- /* FIXME: dt */
return m;
}
static void
match_free(struct match *m)
{
+ /* dmi and dt are global */
free(m->name);
- free(m->dt);
free(m);
}
@@ -1262,13 +1299,14 @@ quirk_match_section(struct quirks_context *ctx,
if (fnmatch(s->match.dmi, m->dmi, 0) == 0)
matched_flags |= flag;
break;
+ case M_DT:
+ if (fnmatch(s->match.dt, m->dt, 0) == 0)
+ matched_flags |= flag;
+ break;
case M_UDEV_TYPE:
if (s->match.udev_type & m->udev_type)
matched_flags |= flag;
break;
- case M_DT:
- /* FIXME */
- break;
default:
abort();
}
@@ -1305,7 +1343,7 @@ quirks_fetch_for_device(struct quirks_context *ctx,
q = quirks_new();
- m = match_new(udev_device, ctx->dmi);
+ m = match_new(udev_device, ctx->dmi, ctx->dt);
list_for_each(s, &ctx->sections, link) {
quirk_match_section(ctx, q, s, m, udev_device);
--
2.14.4
More information about the wayland-devel
mailing list