Skip to contentSkip to conversation

input: simplify key_matrix_decode_fdt()

PATCH In review Stephen Warren 3 participants 5 messages May 23, 2013 – Jun 5, 2013 Input drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 input: simplify key_matrix_decode_fdt()

From: Stephen Warren <[email protected]>

We know the exact property names that the code wants to process. Look these up directly with fdt_get_property(), rather than iterating over all properties within the node, and checking each property's name, in a convoluted fashion, against the expected name.

---
Note: This depends on my previous patch "input: fix unaligned access in key_matrix_decode_fdt()". While to two patches could be squashed together, I'd prefer them to go in separately, since the former is a bug-fix that makes the original code work again on ARMv7 at least, and this patch is an unrelated refactoring.

---
 drivers/input/key_matrix.c |   66 +++++++++++++++++---------------------------
 1 file changed, 26 insertions(+), 40 deletions(-)
drivers/input/key_matrix.c +26 -40
index c8b048e..ea05c77 100644
@@ -154,54 +154,40 @@ static uchar *create_keymap(struct key_matrix *config, u32 *data, int len,
 	return map;
 }
 
-int key_matrix_decode_fdt(struct key_matrix *config, const void *blob,
-			  int node)
+int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, int node)
 {
 	const struct fdt_property *prop;
-	static const char prefix[] = "linux,";
-	int plen = sizeof(prefix) - 1;
-	int offset;
-
-	/* Check each property name for ones that we understand */
-	for (offset = fdt_first_property_offset(blob, node);
-		      offset > 0;
-		      offset = fdt_next_property_offset(blob, offset)) {
-		const char *name;
-		int len;
-
-		prop = fdt_get_property_by_offset(blob, offset, NULL);
-		name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
-		len = strlen(name);
-
-		/* Name needs to match "1,<type>keymap" */
-		debug("%s: property '%s'\n", __func__, name);
-		if (strncmp(name, prefix, plen) ||
-				len < plen + 6 ||
-				strcmp(name + len - 6, "keymap"))
-			continue;
+	int proplen;
+	uchar *plain_keycode;
 
-		len -= plen + 6;
-		if (len == 0) {
-			config->plain_keycode = create_keymap(config,
-				(u32 *)prop->data, fdt32_to_cpu(prop->len),
-				KEY_FN, &config->fn_pos);
-		} else if (0 == strncmp(name + plen, "fn-", len)) {
-			config->fn_keycode = create_keymap(config,
-				(u32 *)prop->data, fdt32_to_cpu(prop->len),
-				-1, NULL);
-		} else {
-			debug("%s: unrecognised property '%s'\n", __func__,
-			      name);
-		}
-	}
-	debug("%s: Decoded key maps %p, %p from fdt\n", __func__,
-	      config->plain_keycode, config->fn_keycode);
+	prop = fdt_get_property(blob, node, "linux,keymap", &proplen);
+	/* Basic keymap is required */
+	if (!prop)
+		return -1;
 
+	plain_keycode = create_keymap(config, (u32 *)prop->data,
+		proplen, KEY_FN, &config->fn_pos);
+	config->plain_keycode = plain_keycode;
+	/* Conversion error -> fail */
+	if (!config->plain_keycode)
+		return -1;
+
+	prop = fdt_get_property(blob, node, "linux,fn-keymap", &proplen);
+	/* fn keymap is optional */
+	if (!prop)
+		goto done;
+
+	config->fn_keycode = create_keymap(config, (u32 *)prop->data,
+		proplen, -1, NULL);
+	/* Conversion error -> fail */
 	if (!config->plain_keycode) {
-		debug("%s: cannot find keycode-plain map\n", __func__);
+		free(plain_keycode);
 		return -1;
 	}
 
+done:
+	debug("%s: Decoded key maps %p, %p from fdt\n", __func__,
+	      config->plain_keycode, config->fn_keycode);
 	return 0;
 }
 
Signature · 1 line
1.7.10.4
#1 lore raw

PATCH 1/1 input: simplify key_matrix_decode_fdt()

Hi Stephen,

Quoted 7 lines · Stephen Warren

From: Stephen Warren <[email protected]>

We know the exact property names that the code wants to process. Look these up directly with fdt_get_property(), rather than iterating over all properties within the node, and checking each property's name, in a convoluted fashion, against the expected name.

The original code dealt with ctrl and shift also - since removed. I think it is good to simplify it.

Quoted 9 lines

---
Note: This depends on my previous patch "input: fix unaligned access in key_matrix_decode_fdt()". While to two patches could be squashed together, I'd prefer them to go in separately, since the former is a bug-fix that makes the original code work again on ARMv7 at least, and this patch is an unrelated refactoring.

Yes.

Quoted 58 lines
---
 drivers/input/key_matrix.c |   66
+++++++++++++++++---------------------------
 1 file changed, 26 insertions(+), 40 deletions(-)
drivers/input/key_matrix.c +3 -37
index c8b048e..ea05c77 100644
@@ -154,54 +154,40 @@ static uchar *create_keymap(struct key_matrix
 *config, u32 *data, int len,
        return map;
 }
 
-int key_matrix_decode_fdt(struct key_matrix *config, const void *blob,
-                         int node)
+int key_matrix_decode_fdt(struct key_matrix *config, const void *blob,
 int node)
 {
        const struct fdt_property *prop;
-       static const char prefix[] = "linux,";
-       int plen = sizeof(prefix) - 1;
-       int offset;
-
-       /* Check each property name for ones that we understand */
-       for (offset = fdt_first_property_offset(blob, node);
-                     offset > 0;
-                     offset = fdt_next_property_offset(blob, offset)) {
-               const char *name;
-               int len;
-
-               prop = fdt_get_property_by_offset(blob, offset, NULL);
-               name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
-               len = strlen(name);
-
-               /* Name needs to match "1,<type>keymap" */
-               debug("%s: property '%s'\n", __func__, name);
-               if (strncmp(name, prefix, plen) ||
-                               len < plen + 6 ||
-                               strcmp(name + len - 6, "keymap"))
-                       continue;
+       int proplen;
+       uchar *plain_keycode;
 
-               len -= plen + 6;
-               if (len == 0) {
-                       config->plain_keycode = create_keymap(config,
-                               (u32 *)prop->data, fdt32_to_cpu(prop->len),
-                               KEY_FN, &config->fn_pos);
-               } else if (0 == strncmp(name + plen, "fn-", len)) {
-                       config->fn_keycode = create_keymap(config,
-                               (u32 *)prop->data, fdt32_to_cpu(prop->len),
-                               -1, NULL);
-               } else {
-                       debug("%s: unrecognised property '%s'\n", __func__,
-                             name);
-               }
-       }

drivers/input/key_matrix.c static uchar *create_keymap(struct key_matrix · line 172

Quoted 10 lines
drivers/input/key_matrix.c +6 -2
-       debug("%s: Decoded key maps %p, %p from fdt\n", __func__,
-             config->plain_keycode, config->fn_keycode);
+       prop = fdt_get_property(blob, node, "linux,keymap", &proplen);
+       /* Basic keymap is required */
+       if (!prop)
+               return -1;
 
+       plain_keycode = create_keymap(config, (u32 *)prop->data,
+               proplen, KEY_FN, &config->fn_pos);
 

Probably don't need plain_keycode variable at all.

drivers/input/key_matrix.c static uchar *create_keymap(struct key_matrix *config, u32 *data, int len, · line 187

Quoted 5 lines
drivers/input/key_matrix.c +4 -0
+       config->plain_keycode = plain_keycode;
+       /* Conversion error -> fail */
+       if (!config->plain_keycode)
+               return -1;
 

Missing debug() here from old code

drivers/input/key_matrix.c static uchar *create_keymap(struct key_matrix *config, u32 *data, int len, · line 187

Quoted 11 lines
drivers/input/key_matrix.c +9 -0
+
+       prop = fdt_get_property(blob, node, "linux,fn-keymap", &proplen);
+       /* fn keymap is optional */
+       if (!prop)
+               goto done;
+
+       config->fn_keycode = create_keymap(config, (u32 *)prop->data,
+               proplen, -1, NULL);
+       /* Conversion error -> fail */
        if (!config->plain_keycode) {
 

Should check config->fn_keycode here.

Quoted 12 lines
drivers/input/key_matrix.c +4 -2
-               debug("%s: cannot find keycode-plain map\n", __func__);
+               free(plain_keycode);
                return -1;
        }
 
+done:
+       debug("%s: Decoded key maps %p, %p from fdt\n", __func__,
+             config->plain_keycode, config->fn_keycode);
        return 0;
 }
 
--
Quoted 3 lines

1.7.10.4

Regards,
Simon

#2 lore raw

PATCH 1/1 input: simplify key_matrix_decode_fdt()

Quoted 7 lines · Simon Glass

Hi Stephen,

On Thu, May 23, 2013 at 3:09 PM, Stephen Warren <[email protected] <mailto:[email protected]>> wrote:

From: Stephen Warren <swarren at nvidia.com <mailto:[email protected]>>

Quoted 8 lines

We know the exact property names that the code wants to process. Look these up directly with fdt_get_property(), rather than iterating over all properties within the node, and checking each property's name, in a convoluted fashion, against the expected name.
+ plain_keycode = create_keymap(config, (u32 *)prop->data,
+ proplen, KEY_FN, &config->fn_pos);

Probably don't need plain_keycode variable at all.

This is required because the variable is passed to free() later, and config->plain_keycode is marked const, whereas free isn't prototyped to take a const. I figured that it was simplest to use a separate variable here rather than cast away the const when calling free(). Now, if C had const_cast<>, then I would have made a different decision:-)

#3 lore raw

PATCH 1/1 input: simplify key_matrix_decode_fdt()

In reply to Stephen Warren
Quoted 6 lines · Stephen Warren

From: Stephen Warren <[email protected]>

We know the exact property names that the code wants to process. Look these up directly with fdt_get_property(), rather than iterating over all properties within the node, and checking each property's name, in a convoluted fashion, against the expected name.

Tom, is this likely to be applied for the upcoming release, or would it be deferred until the next? Thanks.

#4 lore raw
In reply to Stephen Warren
Quoted 8 lines · Stephen Warren

From: Stephen Warren <[email protected]>

We know the exact property names that the code wants to process. Look these up directly with fdt_get_property(), rather than iterating over all properties within the node, and checking each property's name, in a convoluted fashion, against the expected name.

Applied to u-boot/master, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130605/df83088f/attachment.pgp>