[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