* [PATCH HID v2 13/16] HID: bpf: error on warnings when compiling bpf objects
From: Benjamin Tissoires @ 2024-06-07 15:28 UTC (permalink / raw)
To: Shuah Khan, Jiri Kosina, Jonathan Corbet, Alexei Starovoitov
Cc: linux-kselftest, linux-kernel, bpf, linux-input, linux-doc,
Benjamin Tissoires
In-Reply-To: <20240607-hid_bpf_struct_ops-v2-0-3f95f4d02292@kernel.org>
There is no real reasons to paper over warnings for such small programs.
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
no changes in v2
---
drivers/hid/bpf/progs/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/bpf/progs/Makefile b/drivers/hid/bpf/progs/Makefile
index 63ed7e02adf1..ec1fc642fd63 100644
--- a/drivers/hid/bpf/progs/Makefile
+++ b/drivers/hid/bpf/progs/Makefile
@@ -56,7 +56,7 @@ clean:
%.bpf.o: %.bpf.c vmlinux.h $(BPFOBJ) | $(OUTPUT)
$(call msg,BPF,$@)
- $(Q)$(CLANG) -g -O2 --target=bpf $(INCLUDES) \
+ $(Q)$(CLANG) -g -O2 --target=bpf -Wall -Werror $(INCLUDES) \
-c $(filter %.c,$^) -o $@ && \
$(LLVM_STRIP) -g $@
--
2.44.0
^ permalink raw reply related
* [PATCH HID v2 14/16] bpf: allow bpf helpers to be used into HID-BPF struct_ops
From: Benjamin Tissoires @ 2024-06-07 15:28 UTC (permalink / raw)
To: Shuah Khan, Jiri Kosina, Jonathan Corbet, Alexei Starovoitov
Cc: linux-kselftest, linux-kernel, bpf, linux-input, linux-doc,
Benjamin Tissoires
In-Reply-To: <20240607-hid_bpf_struct_ops-v2-0-3f95f4d02292@kernel.org>
Without this helpers like bpf_printk() or bpf_map_update() are not
available, making anything but change of bytes impossible to do.
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
new in v2
---
drivers/hid/bpf/hid_bpf_struct_ops.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c
index 9192c66cde20..056d05d96962 100644
--- a/drivers/hid/bpf/hid_bpf_struct_ops.c
+++ b/drivers/hid/bpf/hid_bpf_struct_ops.c
@@ -89,6 +89,7 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log,
}
static const struct bpf_verifier_ops hid_bpf_verifier_ops = {
+ .get_func_proto = bpf_base_func_proto,
.is_valid_access = hid_bpf_ops_is_valid_access,
.btf_struct_access = hid_bpf_ops_btf_struct_access,
};
--
2.44.0
^ permalink raw reply related
* [PATCH HID v2 15/16] HID: bpf: rework hid_bpf_ops_btf_struct_access
From: Benjamin Tissoires @ 2024-06-07 15:28 UTC (permalink / raw)
To: Shuah Khan, Jiri Kosina, Jonathan Corbet, Alexei Starovoitov
Cc: linux-kselftest, linux-kernel, bpf, linux-input, linux-doc,
Benjamin Tissoires
In-Reply-To: <20240607-hid_bpf_struct_ops-v2-0-3f95f4d02292@kernel.org>
The idea is to provide a list of stucts and their editable fields.
Currently no functional changes are introduced here, we will add some
more writeable fields in the next patch.
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
new in v2
---
drivers/hid/bpf/hid_bpf_struct_ops.c | 91 +++++++++++++++++++++++++++---------
1 file changed, 69 insertions(+), 22 deletions(-)
diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c
index 056d05d96962..944e6d91a36b 100644
--- a/drivers/hid/bpf/hid_bpf_struct_ops.c
+++ b/drivers/hid/bpf/hid_bpf_struct_ops.c
@@ -16,6 +16,7 @@
#include <linux/hid_bpf.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/stddef.h>
#include <linux/workqueue.h>
#include "hid_bpf_dispatch.h"
@@ -52,40 +53,86 @@ static int hid_bpf_ops_check_member(const struct btf_type *t,
return 0;
}
+struct hid_bpf_offset_write_range {
+ const char *struct_name;
+ u32 struct_length;
+ u32 start;
+ u32 end;
+};
+
static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log,
const struct bpf_reg_state *reg,
int off, int size)
{
- const struct btf_type *state;
- const struct btf_type *t;
- s32 type_id;
+#define WRITE_RANGE(_name, _field, _start_offset, _end_offset) \
+ { \
+ .struct_name = #_name, \
+ .struct_length = sizeof(struct _name), \
+ .start = offsetof(struct _name, _field) + _start_offset, \
+ .end = offsetofend(struct _name, _field) + _end_offset, \
+ }
- type_id = btf_find_by_name_kind(reg->btf, "hid_bpf_ctx",
- BTF_KIND_STRUCT);
- if (type_id < 0)
- return -EINVAL;
+ const struct hid_bpf_offset_write_range write_ranges[] = {
+ WRITE_RANGE(hid_bpf_ctx, retval, 0, 0),
+ };
+#undef WRITE_RANGE
+ const struct btf_type *state = NULL;
+ const struct btf_type *t;
+ const char *cur = NULL;
+ int i;
t = btf_type_by_id(reg->btf, reg->btf_id);
- state = btf_type_by_id(reg->btf, type_id);
- if (t != state) {
- bpf_log(log, "only access to hid_bpf_ctx is supported\n");
- return -EACCES;
- }
- /* out-of-bound access in hid_bpf_ctx */
- if (off + size > sizeof(struct hid_bpf_ctx)) {
- bpf_log(log, "write access at off %d with size %d\n", off, size);
- return -EACCES;
+ for (i = 0; i < ARRAY_SIZE(write_ranges); i++) {
+ const struct hid_bpf_offset_write_range *write_range = &write_ranges[i];
+ s32 type_id;
+
+ /* we already found a writeable struct, but there is a
+ * new one, let's break the loop.
+ */
+ if (t == state && write_range->struct_name != cur)
+ break;
+
+ /* new struct to look for */
+ if (write_range->struct_name != cur) {
+ type_id = btf_find_by_name_kind(reg->btf, write_range->struct_name,
+ BTF_KIND_STRUCT);
+ if (type_id < 0)
+ return -EINVAL;
+
+ state = btf_type_by_id(reg->btf, type_id);
+ }
+
+ /* this is not the struct we are looking for */
+ if (t != state) {
+ cur = write_range->struct_name;
+ continue;
+ }
+
+ /* first time we see this struct, check for out of bounds */
+ if (cur != write_range->struct_name &&
+ off + size > write_range->struct_length) {
+ bpf_log(log, "write access for struct %s at off %d with size %d\n",
+ write_range->struct_name, off, size);
+ return -EACCES;
+ }
+
+ /* now check if we are in our boundaries */
+ if (off >= write_range->start && off + size <= write_range->end)
+ return NOT_INIT;
+
+ cur = write_range->struct_name;
}
- if (off < offsetof(struct hid_bpf_ctx, retval)) {
+
+ if (t != state)
+ bpf_log(log, "write access to this struct is not supported\n");
+ else
bpf_log(log,
- "write access at off %d with size %d on read-only part of hid_bpf_ctx\n",
- off, size);
- return -EACCES;
- }
+ "write access at off %d with size %d on read-only part of %s\n",
+ off, size, cur);
- return NOT_INIT;
+ return -EACCES;
}
static const struct bpf_verifier_ops hid_bpf_verifier_ops = {
--
2.44.0
^ permalink raw reply related
* [PATCH HID v2 16/16] HID: bpf: make part of struct hid_device writable
From: Benjamin Tissoires @ 2024-06-07 15:28 UTC (permalink / raw)
To: Shuah Khan, Jiri Kosina, Jonathan Corbet, Alexei Starovoitov
Cc: linux-kselftest, linux-kernel, bpf, linux-input, linux-doc,
Benjamin Tissoires
In-Reply-To: <20240607-hid_bpf_struct_ops-v2-0-3f95f4d02292@kernel.org>
It is useful to change the name, the phys and/or the uniq of a
struct hid_device during .rdesc_fixup().
For example, hid-uclogic.ko changes the uniq to store the firmware version
to differentiate between 2 devices sharing the same PID. In the same
way, changing the device name is useful when the device export 3 nodes,
all with the same name.
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
new in v2
---
drivers/hid/bpf/hid_bpf_struct_ops.c | 3 +++
include/linux/hid_bpf.h | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c
index 944e6d91a36b..14a4c64ae242 100644
--- a/drivers/hid/bpf/hid_bpf_struct_ops.c
+++ b/drivers/hid/bpf/hid_bpf_struct_ops.c
@@ -74,6 +74,9 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log,
const struct hid_bpf_offset_write_range write_ranges[] = {
WRITE_RANGE(hid_bpf_ctx, retval, 0, 0),
+ WRITE_RANGE(hid_device, name, 0, -1), /* minus 1 to ensure \0 at the end */
+ WRITE_RANGE(hid_device, uniq, 0, -1), /* minus 1 to ensure \0 at the end */
+ WRITE_RANGE(hid_device, phys, 0, -1), /* minus 1 to ensure \0 at the end */
};
#undef WRITE_RANGE
const struct btf_type *state = NULL;
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index 88ab4925bdaa..ff30cbc0a090 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -43,7 +43,7 @@ struct hid_device;
* ``hid`` and ``allocated_size`` are read-only, ``size`` and ``retval`` are read-write.
*/
struct hid_bpf_ctx {
- const struct hid_device *hid;
+ struct hid_device *hid;
__u32 allocated_size;
union {
__s32 retval;
--
2.44.0
^ permalink raw reply related
* Re: [PATCH HID v2 03/16] HID: bpf: implement HID-BPF through bpf_struct_ops
From: Alexei Starovoitov @ 2024-06-07 16:51 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Shuah Khan, Jiri Kosina, Jonathan Corbet, Alexei Starovoitov,
open list:KERNEL SELFTEST FRAMEWORK, LKML, bpf,
open list:HID CORE LAYER, open list:DOCUMENTATION
In-Reply-To: <20240607-hid_bpf_struct_ops-v2-3-3f95f4d02292@kernel.org>
On Fri, Jun 7, 2024 at 8:28 AM Benjamin Tissoires <bentiss@kernel.org> wrote:
> +struct hid_bpf_ops {
> + /* hid_id needs to stay first so we can easily change it
> + * from userspace.
> + */
> + int hid_id;
> + u32 flags;
> +
> + /* private: internal use only */
> + struct list_head list;
> +
> + /* public: rest is public */
Didn't notice it before, but the above comments are misleading.
The whole struct is private to the kernel and bpf prog, while
registering, can only touch a handful.
I'd drop "internal use" and "is public". It's not an uapi.
> +
> +/* fast path fields are put first to fill one cache line */
Also misleading. The whole struct fits one cache line.
> +
> + /**
> + * @hid_device_event: called whenever an event is coming in from the device
> + *
> + * It has the following arguments:
> + *
> + * ``ctx``: The HID-BPF context as &struct hid_bpf_ctx
> + *
> + * Return: %0 on success and keep processing; a positive
> + * value to change the incoming size buffer; a negative
> + * error code to interrupt the processing of this event
> + *
> + * Context: Interrupt context.
> + */
> + int (*hid_device_event)(struct hid_bpf_ctx *ctx, enum hid_report_type report_type);
> +
> +/* control/slow paths put last */
> +
> + /**
> + * @hid_rdesc_fixup: called when the probe function parses the report descriptor
> + * of the HID device
> + *
> + * It has the following arguments:
> + *
> + * ``ctx``: The HID-BPF context as &struct hid_bpf_ctx
> + *
> + * Return: %0 on success and keep processing; a positive
> + * value to change the incoming size buffer; a negative
> + * error code to interrupt the processing of this device
> + */
> + int (*hid_rdesc_fixup)(struct hid_bpf_ctx *ctx);
> +
> + /* private: internal use only */
> + struct hid_device *hdev;
> +} ____cacheline_aligned_in_smp;
Such alignment is an overkill.
I don't think you can measure the difference.
> +
> struct hid_bpf_prog_list {
> u16 prog_idx[HID_BPF_MAX_PROGS_PER_DEV];
> u8 prog_cnt;
> @@ -129,6 +188,10 @@ struct hid_bpf {
> bool destroyed; /* prevents the assignment of any progs */
>
> spinlock_t progs_lock; /* protects RCU update of progs */
> +
> + struct hid_bpf_ops *rdesc_ops;
> + struct list_head prog_list;
> + struct mutex prog_list_lock; /* protects RCU update of prog_list */
mutex protects rcu update... sounds very odd.
Just say that mutex protects prog_list update, because "RCU update"
has a different meaning. RCU logic itself is what protects Update part of rcU.
The rest looks good.
^ permalink raw reply
* Re: [PATCH HID v2 15/16] HID: bpf: rework hid_bpf_ops_btf_struct_access
From: Alexei Starovoitov @ 2024-06-07 16:57 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Shuah Khan, Jiri Kosina, Jonathan Corbet, Alexei Starovoitov,
open list:KERNEL SELFTEST FRAMEWORK, LKML, bpf,
open list:HID CORE LAYER, open list:DOCUMENTATION
In-Reply-To: <20240607-hid_bpf_struct_ops-v2-15-3f95f4d02292@kernel.org>
On Fri, Jun 7, 2024 at 8:29 AM Benjamin Tissoires <bentiss@kernel.org> wrote:
>
> The idea is to provide a list of stucts and their editable fields.
>
> Currently no functional changes are introduced here, we will add some
> more writeable fields in the next patch.
>
> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
>
> ---
>
> new in v2
> ---
> drivers/hid/bpf/hid_bpf_struct_ops.c | 91 +++++++++++++++++++++++++++---------
> 1 file changed, 69 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c
> index 056d05d96962..944e6d91a36b 100644
> --- a/drivers/hid/bpf/hid_bpf_struct_ops.c
> +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c
> @@ -16,6 +16,7 @@
> #include <linux/hid_bpf.h>
> #include <linux/init.h>
> #include <linux/module.h>
> +#include <linux/stddef.h>
> #include <linux/workqueue.h>
> #include "hid_bpf_dispatch.h"
>
> @@ -52,40 +53,86 @@ static int hid_bpf_ops_check_member(const struct btf_type *t,
> return 0;
> }
>
> +struct hid_bpf_offset_write_range {
> + const char *struct_name;
> + u32 struct_length;
> + u32 start;
> + u32 end;
> +};
> +
> static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log,
> const struct bpf_reg_state *reg,
> int off, int size)
> {
> - const struct btf_type *state;
> - const struct btf_type *t;
> - s32 type_id;
> +#define WRITE_RANGE(_name, _field, _start_offset, _end_offset) \
> + { \
> + .struct_name = #_name, \
> + .struct_length = sizeof(struct _name), \
> + .start = offsetof(struct _name, _field) + _start_offset, \
> + .end = offsetofend(struct _name, _field) + _end_offset, \
> + }
reading comment /* minus 1 to ensure \0 at the end */
in the next patch...
I don't see this logic below.
In general the manual byte offset adjustment
looks like a footgun. Maybe add a flag for \0 and avoid
messing with offsets?
>
> - type_id = btf_find_by_name_kind(reg->btf, "hid_bpf_ctx",
> - BTF_KIND_STRUCT);
> - if (type_id < 0)
> - return -EINVAL;
> + const struct hid_bpf_offset_write_range write_ranges[] = {
> + WRITE_RANGE(hid_bpf_ctx, retval, 0, 0),
> + };
> +#undef WRITE_RANGE
> + const struct btf_type *state = NULL;
> + const struct btf_type *t;
> + const char *cur = NULL;
> + int i;
>
> t = btf_type_by_id(reg->btf, reg->btf_id);
> - state = btf_type_by_id(reg->btf, type_id);
> - if (t != state) {
> - bpf_log(log, "only access to hid_bpf_ctx is supported\n");
> - return -EACCES;
> - }
>
> - /* out-of-bound access in hid_bpf_ctx */
> - if (off + size > sizeof(struct hid_bpf_ctx)) {
> - bpf_log(log, "write access at off %d with size %d\n", off, size);
> - return -EACCES;
> + for (i = 0; i < ARRAY_SIZE(write_ranges); i++) {
> + const struct hid_bpf_offset_write_range *write_range = &write_ranges[i];
> + s32 type_id;
> +
> + /* we already found a writeable struct, but there is a
> + * new one, let's break the loop.
> + */
> + if (t == state && write_range->struct_name != cur)
> + break;
> +
> + /* new struct to look for */
> + if (write_range->struct_name != cur) {
> + type_id = btf_find_by_name_kind(reg->btf, write_range->struct_name,
> + BTF_KIND_STRUCT);
> + if (type_id < 0)
> + return -EINVAL;
> +
> + state = btf_type_by_id(reg->btf, type_id);
> + }
> +
> + /* this is not the struct we are looking for */
> + if (t != state) {
> + cur = write_range->struct_name;
> + continue;
> + }
> +
> + /* first time we see this struct, check for out of bounds */
> + if (cur != write_range->struct_name &&
> + off + size > write_range->struct_length) {
> + bpf_log(log, "write access for struct %s at off %d with size %d\n",
> + write_range->struct_name, off, size);
> + return -EACCES;
> + }
> +
> + /* now check if we are in our boundaries */
> + if (off >= write_range->start && off + size <= write_range->end)
> + return NOT_INIT;
> +
> + cur = write_range->struct_name;
> }
>
> - if (off < offsetof(struct hid_bpf_ctx, retval)) {
> +
> + if (t != state)
> + bpf_log(log, "write access to this struct is not supported\n");
> + else
> bpf_log(log,
> - "write access at off %d with size %d on read-only part of hid_bpf_ctx\n",
> - off, size);
> - return -EACCES;
> - }
> + "write access at off %d with size %d on read-only part of %s\n",
> + off, size, cur);
>
> - return NOT_INIT;
> + return -EACCES;
> }
>
> static const struct bpf_verifier_ops hid_bpf_verifier_ops = {
>
> --
> 2.44.0
>
^ permalink raw reply
* [PATCH v4 0/3] Add cros-ec-keyboard v3.0
From: Daisuke Nojiri @ 2024-06-07 17:02 UTC (permalink / raw)
Cc: Benson Leung, Tzung-Bi Shih, Guenter Roeck, Dmitry Torokhov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Reka Norman,
Hans Verkuil, Pavan Holla, Gwendal Grignou, Lukasz Majczak,
Daisuke Nojiri, Ching-Kang Yen, Stephen Boyd, Prashant Malani,
chrome-platform, linux-kernel, linux-input, devicetree
This patch series adds a support for cros-ec-keyboard v3.0, which uses a
reorganized and larger keyboard matrix thus also requires a protocol update.
---
Changes in v4:
- Change subject line: ARM:... to dt-bindings:...
- Add description about keyboard matrix v3.0.
- Add cover letter.
---
Changes in v3:
- Remove CROS_KBD_V30 in Kconfig and macros conditionally set in
cros-ec-keyboard.dtsi.
---
Changes in v2:
- Separate cros_ec_commands.h from cros_ec_proto.{c.h}.
- Remove Change-Id, TEST=, BUG= lines.
---
Daisuke Nojiri (3):
platform/chrome: Add struct ec_response_get_next_event_v3
platform/chrome: cros_ec_proto: Upgrade get_next_event to v3
dt-bindings: cros-ec-keyboard: Add keyboard matrix v3.0
drivers/platform/chrome/cros_ec_proto.c | 27 +++--
include/dt-bindings/input/cros-ec-keyboard.h | 104 ++++++++++++++++++
.../linux/platform_data/cros_ec_commands.h | 34 ++++++
include/linux/platform_data/cros_ec_proto.h | 2 +-
4 files changed, 157 insertions(+), 10 deletions(-)
--
2.45.2.505.gda0bf45e8d-goog
^ permalink raw reply
* [PATCH v4 1/3] platform/chrome: Add struct ec_response_get_next_event_v3
From: Daisuke Nojiri @ 2024-06-07 17:02 UTC (permalink / raw)
Cc: Benson Leung, Tzung-Bi Shih, Guenter Roeck, Dmitry Torokhov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Reka Norman,
Hans Verkuil, Pavan Holla, Gwendal Grignou, Lukasz Majczak,
Daisuke Nojiri, Ching-Kang Yen, Stephen Boyd, Prashant Malani,
chrome-platform, linux-kernel, linux-input, devicetree
In-Reply-To: <cover.1717779167.git.dnojiri@chromium.org>
Add struct ec_response_get_next_event_v3 to upgrade
EC_CMD_GET_NEXT_EVENT to version 3.
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
---
.../linux/platform_data/cros_ec_commands.h | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h
index 070e49c5381e..fff191a8d413 100644
--- a/include/linux/platform_data/cros_ec_commands.h
+++ b/include/linux/platform_data/cros_ec_commands.h
@@ -3527,6 +3527,34 @@ union __ec_align_offset1 ec_response_get_next_data_v1 {
};
BUILD_ASSERT(sizeof(union ec_response_get_next_data_v1) == 16);
+union __ec_align_offset1 ec_response_get_next_data_v3 {
+ uint8_t key_matrix[18];
+
+ /* Unaligned */
+ uint32_t host_event;
+ uint64_t host_event64;
+
+ struct __ec_todo_unpacked {
+ /* For aligning the fifo_info */
+ uint8_t reserved[3];
+ struct ec_response_motion_sense_fifo_info info;
+ } sensor_fifo;
+
+ uint32_t buttons;
+
+ uint32_t switches;
+
+ uint32_t fp_events;
+
+ uint32_t sysrq;
+
+ /* CEC events from enum mkbp_cec_event */
+ uint32_t cec_events;
+
+ uint8_t cec_message[16];
+};
+BUILD_ASSERT(sizeof(union ec_response_get_next_data_v3) == 18);
+
struct ec_response_get_next_event {
uint8_t event_type;
/* Followed by event data if any */
@@ -3539,6 +3567,12 @@ struct ec_response_get_next_event_v1 {
union ec_response_get_next_data_v1 data;
} __ec_align1;
+struct ec_response_get_next_event_v3 {
+ uint8_t event_type;
+ /* Followed by event data if any */
+ union ec_response_get_next_data_v3 data;
+} __ec_align1;
+
/* Bit indices for buttons and switches.*/
/* Buttons */
#define EC_MKBP_POWER_BUTTON 0
--
2.45.2.505.gda0bf45e8d-goog
^ permalink raw reply related
* [PATCH v4 2/3] platform/chrome: cros_ec_proto: Upgrade get_next_event to v3
From: Daisuke Nojiri @ 2024-06-07 17:02 UTC (permalink / raw)
Cc: Benson Leung, Tzung-Bi Shih, Guenter Roeck, Dmitry Torokhov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Reka Norman,
Hans Verkuil, Pavan Holla, Gwendal Grignou, Lukasz Majczak,
Daisuke Nojiri, Ching-Kang Yen, Stephen Boyd, Prashant Malani,
chrome-platform, linux-kernel, linux-input, devicetree
In-Reply-To: <cover.1717779167.git.dnojiri@chromium.org>
Upgrade EC_CMD_GET_NEXT_EVENT to version 3.
The max supported version will be v3. So, we speak v3 even if the EC
says it supports v4+.
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
---
drivers/platform/chrome/cros_ec_proto.c | 27 ++++++++++++++-------
include/linux/platform_data/cros_ec_proto.h | 2 +-
2 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index 945b1b15a04c..df257ab12968 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -686,7 +686,7 @@ EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
static int get_next_event_xfer(struct cros_ec_device *ec_dev,
struct cros_ec_command *msg,
- struct ec_response_get_next_event_v1 *event,
+ struct ec_response_get_next_event_v3 *event,
int version, uint32_t size)
{
int ret;
@@ -709,11 +709,12 @@ static int get_next_event(struct cros_ec_device *ec_dev)
{
struct {
struct cros_ec_command msg;
- struct ec_response_get_next_event_v1 event;
+ struct ec_response_get_next_event_v3 event;
} __packed buf;
struct cros_ec_command *msg = &buf.msg;
- struct ec_response_get_next_event_v1 *event = &buf.event;
- const int cmd_version = ec_dev->mkbp_event_supported - 1;
+ struct ec_response_get_next_event_v3 *event = &buf.event;
+ int cmd_version = ec_dev->mkbp_event_supported - 1;
+ uint32_t size;
memset(msg, 0, sizeof(*msg));
if (ec_dev->suspended) {
@@ -721,12 +722,20 @@ static int get_next_event(struct cros_ec_device *ec_dev)
return -EHOSTDOWN;
}
- if (cmd_version == 0)
- return get_next_event_xfer(ec_dev, msg, event, 0,
- sizeof(struct ec_response_get_next_event));
+ if (cmd_version == 0) {
+ size = sizeof(struct ec_response_get_next_event);
+ } else if (cmd_version < 3) {
+ size = sizeof(struct ec_response_get_next_event_v1);
+ } else {
+ /*
+ * The max version we support is v3. So, we speak v3 even if the
+ * EC says it supports v4+.
+ */
+ cmd_version = 3;
+ size = sizeof(struct ec_response_get_next_event_v3);
+ }
- return get_next_event_xfer(ec_dev, msg, event, cmd_version,
- sizeof(struct ec_response_get_next_event_v1));
+ return get_next_event_xfer(ec_dev, msg, event, cmd_version, size);
}
static int get_keyboard_state_event(struct cros_ec_device *ec_dev)
diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h
index 8865e350c12a..dbfd38b3becd 100644
--- a/include/linux/platform_data/cros_ec_proto.h
+++ b/include/linux/platform_data/cros_ec_proto.h
@@ -185,7 +185,7 @@ struct cros_ec_device {
bool host_sleep_v1;
struct blocking_notifier_head event_notifier;
- struct ec_response_get_next_event_v1 event_data;
+ struct ec_response_get_next_event_v3 event_data;
int event_size;
u32 host_event_wake_mask;
u32 last_resume_result;
--
2.45.2.505.gda0bf45e8d-goog
^ permalink raw reply related
* [PATCH v4 3/3] dt-bindings: cros-ec-keyboard: Add keyboard matrix v3.0
From: Daisuke Nojiri @ 2024-06-07 17:02 UTC (permalink / raw)
Cc: Benson Leung, Tzung-Bi Shih, Guenter Roeck, Dmitry Torokhov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Reka Norman,
Hans Verkuil, Pavan Holla, Gwendal Grignou, Lukasz Majczak,
Daisuke Nojiri, Ching-Kang Yen, Stephen Boyd, Prashant Malani,
chrome-platform, linux-kernel, linux-input, devicetree
In-Reply-To: <cover.1717779167.git.dnojiri@chromium.org>
Add support for keyboard matrix version 3.0, which reduces keyboard
ghosting.
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
---
include/dt-bindings/input/cros-ec-keyboard.h | 104 +++++++++++++++++++
1 file changed, 104 insertions(+)
diff --git a/include/dt-bindings/input/cros-ec-keyboard.h b/include/dt-bindings/input/cros-ec-keyboard.h
index f0ae03634a96..afc12f6aa642 100644
--- a/include/dt-bindings/input/cros-ec-keyboard.h
+++ b/include/dt-bindings/input/cros-ec-keyboard.h
@@ -100,4 +100,108 @@
MATRIX_KEY(0x07, 0x0b, KEY_UP) \
MATRIX_KEY(0x07, 0x0c, KEY_LEFT)
+/* No numpad */
+#define CROS_TOP_ROW_KEYMAP_V30 \
+ MATRIX_KEY(0x00, 0x01, KEY_F11) /* T11 */ \
+ MATRIX_KEY(0x00, 0x02, KEY_F1) /* T1 */ \
+ MATRIX_KEY(0x00, 0x04, KEY_F10) /* T10 */ \
+ MATRIX_KEY(0x00, 0x0b, KEY_F14) /* T14 */ \
+ MATRIX_KEY(0x00, 0x0c, KEY_F15) /* T15 */ \
+ MATRIX_KEY(0x01, 0x02, KEY_F4) /* T4 */ \
+ MATRIX_KEY(0x01, 0x04, KEY_F7) /* T7 */ \
+ MATRIX_KEY(0x01, 0x05, KEY_F12) /* T12 */ \
+ MATRIX_KEY(0x01, 0x09, KEY_F9) /* T9 */ \
+ MATRIX_KEY(0x02, 0x02, KEY_F3) /* T3 */ \
+ MATRIX_KEY(0x02, 0x04, KEY_F6) /* T6 */ \
+ MATRIX_KEY(0x02, 0x0b, KEY_F8) /* T8 */ \
+ MATRIX_KEY(0x03, 0x02, KEY_F2) /* T2 */ \
+ MATRIX_KEY(0x03, 0x05, KEY_F13) /* T13 */ \
+ MATRIX_KEY(0x04, 0x04, KEY_F5) /* T5 */
+
+#define CROS_MAIN_KEYMAP_V30 /* Keycode */ \
+ MATRIX_KEY(0x00, 0x03, KEY_B) /* 50 */ \
+ MATRIX_KEY(0x00, 0x05, KEY_N) /* 51 */ \
+ MATRIX_KEY(0x00, 0x06, KEY_RO) /* 56 (JIS) */ \
+ MATRIX_KEY(0x00, 0x08, KEY_EQUAL) /* 13 */ \
+ MATRIX_KEY(0x00, 0x09, KEY_HOME) /* 80 (Numpad) */ \
+ MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT) /* 62 */ \
+ MATRIX_KEY(0x00, 0x10, KEY_FN) /* 127 */ \
+ \
+ MATRIX_KEY(0x01, 0x01, KEY_ESC) /* 110 */ \
+ MATRIX_KEY(0x01, 0x03, KEY_G) /* 35 */ \
+ MATRIX_KEY(0x01, 0x06, KEY_H) /* 36 */ \
+ MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE) /* 41 */ \
+ MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE) /* 15 */ \
+ MATRIX_KEY(0x01, 0x0c, KEY_HENKAN) /* 65 (JIS) */ \
+ MATRIX_KEY(0x01, 0x0e, KEY_LEFTCTRL) /* 58 */ \
+ \
+ MATRIX_KEY(0x02, 0x01, KEY_TAB) /* 16 */ \
+ MATRIX_KEY(0x02, 0x03, KEY_T) /* 21 */ \
+ MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE) /* 28 */ \
+ MATRIX_KEY(0x02, 0x06, KEY_Y) /* 22 */ \
+ MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE) /* 27 */ \
+ MATRIX_KEY(0x02, 0x09, KEY_DELETE) /* 76 (Numpad) */ \
+ MATRIX_KEY(0x02, 0x0c, KEY_PAGEUP) /* 85 (Numpad) */ \
+ MATRIX_KEY(0x02, 0x011, KEY_YEN) /* 14 (JIS) */ \
+ \
+ MATRIX_KEY(0x03, 0x00, KEY_LEFTMETA) /* Launcher */ \
+ MATRIX_KEY(0x03, 0x01, KEY_GRAVE) /* 1 */ \
+ MATRIX_KEY(0x03, 0x03, KEY_5) /* 6 */ \
+ MATRIX_KEY(0x03, 0x04, KEY_S) /* 32 */ \
+ MATRIX_KEY(0x03, 0x06, KEY_MINUS) /* 12 */ \
+ MATRIX_KEY(0x03, 0x08, KEY_6) /* 7 */ \
+ MATRIX_KEY(0x03, 0x09, KEY_SLEEP) /* Lock */ \
+ MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH) /* 29 */ \
+ MATRIX_KEY(0x03, 0x0c, KEY_MUHENKAN) /* 63 (JIS) */ \
+ MATRIX_KEY(0x03, 0x0e, KEY_RIGHTCTRL) /* 64 */ \
+ \
+ MATRIX_KEY(0x04, 0x01, KEY_A) /* 31 */ \
+ MATRIX_KEY(0x04, 0x02, KEY_D) /* 33 */ \
+ MATRIX_KEY(0x04, 0x03, KEY_F) /* 34 */ \
+ MATRIX_KEY(0x04, 0x05, KEY_K) /* 38 */ \
+ MATRIX_KEY(0x04, 0x06, KEY_J) /* 37 */ \
+ MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON) /* 40 */ \
+ MATRIX_KEY(0x04, 0x09, KEY_L) /* 39 */ \
+ MATRIX_KEY(0x04, 0x0b, KEY_ENTER) /* 43 */ \
+ MATRIX_KEY(0x04, 0x0c, KEY_END) /* 81 (Numpad) */ \
+ \
+ MATRIX_KEY(0x05, 0x01, KEY_1) /* 2 */ \
+ MATRIX_KEY(0x05, 0x02, KEY_COMMA) /* 53 */ \
+ MATRIX_KEY(0x05, 0x03, KEY_DOT) /* 54 */ \
+ MATRIX_KEY(0x05, 0x04, KEY_SLASH) /* 55 */ \
+ MATRIX_KEY(0x05, 0x05, KEY_C) /* 48 */ \
+ MATRIX_KEY(0x05, 0x06, KEY_SPACE) /* 61 */ \
+ MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT) /* 44 */ \
+ MATRIX_KEY(0x05, 0x08, KEY_X) /* 47 */ \
+ MATRIX_KEY(0x05, 0x09, KEY_V) /* 49 */ \
+ MATRIX_KEY(0x05, 0x0b, KEY_M) /* 52 */ \
+ MATRIX_KEY(0x05, 0x0c, KEY_PAGEDOWN) /* 86 (Numpad) */ \
+ \
+ MATRIX_KEY(0x06, 0x01, KEY_Z) /* 46 */ \
+ MATRIX_KEY(0x06, 0x02, KEY_3) /* 4 */ \
+ MATRIX_KEY(0x06, 0x03, KEY_4) /* 5 */ \
+ MATRIX_KEY(0x06, 0x04, KEY_2) /* 3 */ \
+ MATRIX_KEY(0x06, 0x05, KEY_8) /* 9 */ \
+ MATRIX_KEY(0x06, 0x06, KEY_0) /* 11 */ \
+ MATRIX_KEY(0x06, 0x08, KEY_7) /* 8 */ \
+ MATRIX_KEY(0x06, 0x09, KEY_9) /* 10 */ \
+ MATRIX_KEY(0x06, 0x0b, KEY_DOWN) /* 84 */ \
+ MATRIX_KEY(0x06, 0x0c, KEY_RIGHT) /* 89 */ \
+ MATRIX_KEY(0x06, 0x0d, KEY_LEFTALT) /* 60 */ \
+ MATRIX_KEY(0x06, 0x0f, KEY_ASSISTANT) /* 128 */ \
+ MATRIX_KEY(0x06, 0x11, KEY_BACKSLASH) /* 42 (JIS, ISO) */ \
+ \
+ MATRIX_KEY(0x07, 0x01, KEY_U) /* 23 */ \
+ MATRIX_KEY(0x07, 0x02, KEY_I) /* 24 */ \
+ MATRIX_KEY(0x07, 0x03, KEY_O) /* 25 */ \
+ MATRIX_KEY(0x07, 0x04, KEY_P) /* 26 */ \
+ MATRIX_KEY(0x07, 0x05, KEY_Q) /* 17 */ \
+ MATRIX_KEY(0x07, 0x06, KEY_W) /* 18 */ \
+ MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT) /* 57 */ \
+ MATRIX_KEY(0x07, 0x08, KEY_E) /* 19 */ \
+ MATRIX_KEY(0x07, 0x09, KEY_R) /* 20 */ \
+ MATRIX_KEY(0x07, 0x0b, KEY_UP) /* 83 */ \
+ MATRIX_KEY(0x07, 0x0c, KEY_LEFT) /* 79 */ \
+ MATRIX_KEY(0x07, 0x11, KEY_102ND) /* 45 (ISO) */
+
#endif /* _CROS_EC_KEYBOARD_H */
--
2.45.2.505.gda0bf45e8d-goog
^ permalink raw reply related
* [PATCH] Input: serio - use sizeof(*pointer) instead of sizeof(type)
From: Erick Archer @ 2024-06-07 17:04 UTC (permalink / raw)
To: Dmitry Torokhov, Russell King, James E.J. Bottomley, Helge Deller,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Stephen Chandler Paul, Michal Simek, Uwe Kleine-König,
Russell King (Oracle), Suzuki K Poulose, Krzysztof Kozlowski,
Rob Herring, Ruan Jinjie, Ricardo B. Marliere, Greg Kroah-Hartman,
Jiri Slaby (SUSE), Mark Brown, Yang Li, Kees Cook,
Gustavo A. R. Silva, Justin Stitt
Cc: Erick Archer, linux-input, linux-kernel, linux-parisc,
linux-hyperv, linux-arm-kernel, linux-sunxi, linux-hardening
It is preferred to use sizeof(*pointer) instead of sizeof(type)
due to the type of the variable can change and one needs not
change the former (unlike the latter). This patch has no effect
on runtime behavior.
Signed-off-by: Erick Archer <erick.archer@outlook.com>
---
drivers/input/serio/altera_ps2.c | 2 +-
drivers/input/serio/ambakmi.c | 4 ++--
drivers/input/serio/apbps2.c | 2 +-
drivers/input/serio/arc_ps2.c | 2 +-
drivers/input/serio/ct82c710.c | 2 +-
drivers/input/serio/gscps2.c | 4 ++--
drivers/input/serio/hyperv-keyboard.c | 4 ++--
drivers/input/serio/i8042.c | 4 ++--
drivers/input/serio/maceps2.c | 2 +-
drivers/input/serio/olpc_apsp.c | 4 ++--
drivers/input/serio/parkbd.c | 2 +-
drivers/input/serio/pcips2.c | 4 ++--
drivers/input/serio/ps2-gpio.c | 4 ++--
drivers/input/serio/ps2mult.c | 2 +-
drivers/input/serio/q40kbd.c | 4 ++--
drivers/input/serio/rpckbd.c | 2 +-
drivers/input/serio/sa1111ps2.c | 4 ++--
drivers/input/serio/serio.c | 2 +-
drivers/input/serio/serio_raw.c | 4 ++--
drivers/input/serio/serport.c | 4 ++--
drivers/input/serio/sun4i-ps2.c | 4 ++--
drivers/input/serio/userio.c | 4 ++--
drivers/input/serio/xilinx_ps2.c | 4 ++--
23 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
index c5b634940cfc..611eb9fe2d04 100644
--- a/drivers/input/serio/altera_ps2.c
+++ b/drivers/input/serio/altera_ps2.c
@@ -100,7 +100,7 @@ static int altera_ps2_probe(struct platform_device *pdev)
return error;
}
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index 496bb7a312d2..de4b3915c37d 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -114,8 +114,8 @@ static int amba_kmi_probe(struct amba_device *dev,
if (ret)
return ret;
- kmi = kzalloc(sizeof(struct amba_kmi_port), GFP_KERNEL);
- io = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ kmi = kzalloc(sizeof(*kmi), GFP_KERNEL);
+ io = kzalloc(sizeof(*io), GFP_KERNEL);
if (!kmi || !io) {
ret = -ENOMEM;
goto out;
diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c
index dbbb10251520..4015e75fcb90 100644
--- a/drivers/input/serio/apbps2.c
+++ b/drivers/input/serio/apbps2.c
@@ -165,7 +165,7 @@ static int apbps2_of_probe(struct platform_device *ofdev)
/* Set reload register to core freq in kHz/10 */
iowrite32be(freq_hz / 10000, &priv->regs->reload);
- priv->io = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ priv->io = kzalloc(sizeof(*priv->io), GFP_KERNEL);
if (!priv->io)
return -ENOMEM;
diff --git a/drivers/input/serio/arc_ps2.c b/drivers/input/serio/arc_ps2.c
index 9d8726830140..a9180a005872 100644
--- a/drivers/input/serio/arc_ps2.c
+++ b/drivers/input/serio/arc_ps2.c
@@ -155,7 +155,7 @@ static int arc_ps2_create_port(struct platform_device *pdev,
struct arc_ps2_port *port = &arc_ps2->port[index];
struct serio *io;
- io = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ io = kzalloc(sizeof(*io), GFP_KERNEL);
if (!io)
return -ENOMEM;
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index d5c9bb3d0103..6834440b37f6 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -158,7 +158,7 @@ static int __init ct82c710_detect(void)
static int ct82c710_probe(struct platform_device *dev)
{
- ct82c710_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ ct82c710_port = kzalloc(sizeof(*ct82c710_port), GFP_KERNEL);
if (!ct82c710_port)
return -ENOMEM;
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 633c7de49d67..d94c01eb3fc9 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -338,8 +338,8 @@ static int __init gscps2_probe(struct parisc_device *dev)
if (dev->id.sversion == 0x96)
hpa += GSC_DINO_OFFSET;
- ps2port = kzalloc(sizeof(struct gscps2port), GFP_KERNEL);
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ ps2port = kzalloc(sizeof(*ps2port), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!ps2port || !serio) {
ret = -ENOMEM;
goto fail_nomem;
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c
index 31def6ce5157..31d9dacd2fd1 100644
--- a/drivers/input/serio/hyperv-keyboard.c
+++ b/drivers/input/serio/hyperv-keyboard.c
@@ -318,8 +318,8 @@ static int hv_kbd_probe(struct hv_device *hv_dev,
struct serio *hv_serio;
int error;
- kbd_dev = kzalloc(sizeof(struct hv_kbd_dev), GFP_KERNEL);
- hv_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ kbd_dev = kzalloc(sizeof(*kbd_dev), GFP_KERNEL);
+ hv_serio = kzalloc(sizeof(*hv_serio), GFP_KERNEL);
if (!kbd_dev || !hv_serio) {
error = -ENOMEM;
goto err_free_mem;
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 9fbb8d31575a..e0fb1db653b7 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -1329,7 +1329,7 @@ static int i8042_create_kbd_port(void)
struct serio *serio;
struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!serio)
return -ENOMEM;
@@ -1359,7 +1359,7 @@ static int i8042_create_aux_port(int idx)
int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
struct i8042_port *port = &i8042_ports[port_no];
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
index 5ccfb82759b3..42ac1eb94866 100644
--- a/drivers/input/serio/maceps2.c
+++ b/drivers/input/serio/maceps2.c
@@ -117,7 +117,7 @@ static struct serio *maceps2_allocate_port(int idx)
{
struct serio *serio;
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (serio) {
serio->id.type = SERIO_8042;
serio->write = maceps2_write;
diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c
index 240a714f7081..0ad95e880cc2 100644
--- a/drivers/input/serio/olpc_apsp.c
+++ b/drivers/input/serio/olpc_apsp.c
@@ -188,7 +188,7 @@ static int olpc_apsp_probe(struct platform_device *pdev)
return priv->irq;
/* KEYBOARD */
- kb_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ kb_serio = kzalloc(sizeof(*kb_serio), GFP_KERNEL);
if (!kb_serio)
return -ENOMEM;
kb_serio->id.type = SERIO_8042_XL;
@@ -203,7 +203,7 @@ static int olpc_apsp_probe(struct platform_device *pdev)
serio_register_port(kb_serio);
/* TOUCHPAD */
- pad_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ pad_serio = kzalloc(sizeof(*pad_serio), GFP_KERNEL);
if (!pad_serio) {
error = -ENOMEM;
goto err_pad;
diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
index 0d54895428f5..328932297aad 100644
--- a/drivers/input/serio/parkbd.c
+++ b/drivers/input/serio/parkbd.c
@@ -165,7 +165,7 @@ static struct serio *parkbd_allocate_serio(void)
{
struct serio *serio;
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (serio) {
serio->id.type = parkbd_mode;
serio->write = parkbd_write;
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
index 05878750f2c2..6b9abb2e18c9 100644
--- a/drivers/input/serio/pcips2.c
+++ b/drivers/input/serio/pcips2.c
@@ -137,8 +137,8 @@ static int pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (ret)
goto disable;
- ps2if = kzalloc(sizeof(struct pcips2_data), GFP_KERNEL);
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ ps2if = kzalloc(sizeof(*ps2if), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!ps2if || !serio) {
ret = -ENOMEM;
goto release;
diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c
index c3ff60859a03..0c8b390b8b4f 100644
--- a/drivers/input/serio/ps2-gpio.c
+++ b/drivers/input/serio/ps2-gpio.c
@@ -404,8 +404,8 @@ static int ps2_gpio_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int error;
- drvdata = devm_kzalloc(dev, sizeof(struct ps2_gpio_data), GFP_KERNEL);
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!drvdata || !serio) {
error = -ENOMEM;
goto err_free_serio;
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c
index 902e81826fbf..937ecdea491d 100644
--- a/drivers/input/serio/ps2mult.c
+++ b/drivers/input/serio/ps2mult.c
@@ -127,7 +127,7 @@ static int ps2mult_create_port(struct ps2mult *psm, int i)
struct serio *mx_serio = psm->mx_serio;
struct serio *serio;
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index 3f81f8749cd5..cd4d5be946a3 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -108,8 +108,8 @@ static int q40kbd_probe(struct platform_device *pdev)
struct serio *port;
int error;
- q40kbd = kzalloc(sizeof(struct q40kbd), GFP_KERNEL);
- port = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ q40kbd = kzalloc(sizeof(*q40kbd), GFP_KERNEL);
+ port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!q40kbd || !port) {
error = -ENOMEM;
goto err_free_mem;
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index 9bbfefd092c0..e236bb7e1014 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -108,7 +108,7 @@ static int rpckbd_probe(struct platform_device *dev)
if (tx_irq < 0)
return tx_irq;
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
if (!serio || !rpckbd) {
kfree(rpckbd);
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 2724c3aa512c..1311caf7dba4 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -256,8 +256,8 @@ static int ps2_probe(struct sa1111_dev *dev)
struct serio *serio;
int ret;
- ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL);
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ ps2if = kzalloc(sizeof(*ps2if), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!ps2if || !serio) {
ret = -ENOMEM;
goto free;
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index a8838b522627..04967494eeb6 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -258,7 +258,7 @@ static int serio_queue_event(void *object, struct module *owner,
}
}
- event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
+ event = kmalloc(sizeof(*event), GFP_ATOMIC);
if (!event) {
pr_err("Not enough memory to queue event %d\n", event_type);
retval = -ENOMEM;
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 1e4770094415..0186d1b38f49 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -92,7 +92,7 @@ static int serio_raw_open(struct inode *inode, struct file *file)
goto out;
}
- client = kzalloc(sizeof(struct serio_raw_client), GFP_KERNEL);
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
retval = -ENOMEM;
goto out;
@@ -293,7 +293,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
struct serio_raw *serio_raw;
int err;
- serio_raw = kzalloc(sizeof(struct serio_raw), GFP_KERNEL);
+ serio_raw = kzalloc(sizeof(*serio_raw), GFP_KERNEL);
if (!serio_raw) {
dev_dbg(&serio->dev, "can't allocate memory for a device\n");
return -ENOMEM;
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 1db3f30011c4..5a2b5404ffc2 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -82,7 +82,7 @@ static int serport_ldisc_open(struct tty_struct *tty)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- serport = kzalloc(sizeof(struct serport), GFP_KERNEL);
+ serport = kzalloc(sizeof(*serport), GFP_KERNEL);
if (!serport)
return -ENOMEM;
@@ -167,7 +167,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file,
if (test_and_set_bit(SERPORT_BUSY, &serport->flags))
return -EBUSY;
- serport->serio = serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serport->serio = serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/sun4i-ps2.c b/drivers/input/serio/sun4i-ps2.c
index aec66d9f5176..95cd8aaee65d 100644
--- a/drivers/input/serio/sun4i-ps2.c
+++ b/drivers/input/serio/sun4i-ps2.c
@@ -213,8 +213,8 @@ static int sun4i_ps2_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int error;
- drvdata = kzalloc(sizeof(struct sun4i_ps2data), GFP_KERNEL);
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!drvdata || !serio) {
error = -ENOMEM;
goto err_free_mem;
diff --git a/drivers/input/serio/userio.c b/drivers/input/serio/userio.c
index 9ab5c45c3a9f..a88e2eee55c3 100644
--- a/drivers/input/serio/userio.c
+++ b/drivers/input/serio/userio.c
@@ -77,7 +77,7 @@ static int userio_char_open(struct inode *inode, struct file *file)
{
struct userio_device *userio;
- userio = kzalloc(sizeof(struct userio_device), GFP_KERNEL);
+ userio = kzalloc(sizeof(*userio), GFP_KERNEL);
if (!userio)
return -ENOMEM;
@@ -85,7 +85,7 @@ static int userio_char_open(struct inode *inode, struct file *file)
spin_lock_init(&userio->buf_lock);
init_waitqueue_head(&userio->waitq);
- userio->serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ userio->serio = kzalloc(sizeof(*userio->serio), GFP_KERNEL);
if (!userio->serio) {
kfree(userio);
return -ENOMEM;
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index bb758346a33d..1543267d02ac 100644
--- a/drivers/input/serio/xilinx_ps2.c
+++ b/drivers/input/serio/xilinx_ps2.c
@@ -252,8 +252,8 @@ static int xps2_of_probe(struct platform_device *ofdev)
return -ENODEV;
}
- drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+ serio = kzalloc(sizeof(*serio), GFP_KERNEL);
if (!drvdata || !serio) {
error = -ENOMEM;
goto failed1;
--
2.25.1
^ permalink raw reply related
* Re: [PATCH v13 3/3] Input: Add TouchNetix axiom i2c touchscreen driver
From: Dmitry Torokhov @ 2024-06-07 17:05 UTC (permalink / raw)
To: Gregory CLEMENT
Cc: Kamel BOUHARA, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Henrik Rydberg, linux-input, linux-kernel, devicetree,
Marco Felsch, Jeff LaBundy, catalin.popescu, mark.satterthwaite,
Thomas Petazzoni, bsp-development.geo
In-Reply-To: <87bk4dfc7b.fsf@BLaptop.bootlin.com>
Hi Gregory,
On Fri, Jun 07, 2024 at 09:23:36AM +0200, Gregory CLEMENT wrote:
> Hello Dmitry,
>
> > On Wed, Jun 05, 2024 at 03:48:20PM +0200, Kamel BOUHARA wrote:
> >> [...]
> >>
> >> > > > +
> >> > > > + error = devm_request_threaded_irq(dev, client->irq, NULL,
> >> > > > + axiom_irq, IRQF_ONESHOT, dev_name(dev), ts);
> >> > > > + if (error) {
> >> > > > + dev_info(dev, "Request irq failed, falling back to polling mode");
> >> > >
> >> > > I do not think you should fall back to polling mode if you fail to get
> >> > > interrupt. If it was not specified (client->irq) then I can see that
> >> > > we
> >> > > might want to fall back, but if the system configured for using
> >> > > interrupt and you can not get it you should bail out.
> >> > >
> >> >
> >> > Yes, clear, the polling mode can be decorrelated to the irq not provided
> >> > case.
> >>
> >> Just to make sure I understood, is this what you propose ?
> >>
> >> if (client->irq) {
> >> error = devm_request_threaded_irq(...)
> >> if (error) {
> >> dev_warn(dev, "failed to request IRQ\n");
> >> client->irq = 0;
> >> }
> >> }
> >>
> >> if(!client->irq) {
> >> // setup polling stuff
> >> ...
> >> }
> >
> > No, if you fail to acquire interrupt that was described in ACPI/DT it
> > should be treated as an error, like this:
> >
> > if (client->irq) {
> > error = devm_request_threaded_irq(...)
> > if (error)
> > return dev_err_probe(...);
> > } else {
> > .. set up polling ..
> > }
> >
> > This also makes sure that if interrupt controller is not ready and
> > requests probe deferral we will not end up with device in polling
> > mode.
>
> In the case of probe deferral, I see the benefit of treating it as an
> error. However, in the other case, I find it better to fall back to
> polling mode with a big error message than just exiting in error. As a
> user, I think we prefer having a degraded feature over not having the
> feature at all.
No, this is not how the drivers work, we do not simply ignore errors and
hope for the best. If resources are described in platform definition (be
it ACPI or device tree) they need to be there and they need to work. It
is true for regulators and reset gpios (you do not ignore errors if you
fail to obtain a them in the hope that the device is operable), and you
should not ignore errors when trying to set up interrupt.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH] Input: gameport - use sizeof(*pointer) instead of sizeof(type)
From: Erick Archer @ 2024-06-07 17:17 UTC (permalink / raw)
To: Dmitry Torokhov, Niklas Schnelle, Greg Kroah-Hartman,
Arnd Bergmann, Ricardo B. Marliere, Kees Cook,
Gustavo A. R. Silva, Justin Stitt
Cc: Erick Archer, linux-input, linux-kernel, linux-hardening
It is preferred to use sizeof(*pointer) instead of sizeof(type)
due to the type of the variable can change and one needs not
change the former (unlike the latter). This patch has no effect
on runtime behavior.
Signed-off-by: Erick Archer <erick.archer@outlook.com>
---
drivers/input/gameport/emu10k1-gp.c | 2 +-
drivers/input/gameport/fm801-gp.c | 2 +-
drivers/input/gameport/gameport.c | 2 +-
drivers/input/gameport/ns558.c | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c
index 76ce41e58df0..4f4583048f24 100644
--- a/drivers/input/gameport/emu10k1-gp.c
+++ b/drivers/input/gameport/emu10k1-gp.c
@@ -43,7 +43,7 @@ static int emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct gameport *port;
int error;
- emu = kzalloc(sizeof(struct emu), GFP_KERNEL);
+ emu = kzalloc(sizeof(*emu), GFP_KERNEL);
port = gameport_allocate_port();
if (!emu || !port) {
printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n");
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c
index e785d36b1926..7ae5009385cc 100644
--- a/drivers/input/gameport/fm801-gp.c
+++ b/drivers/input/gameport/fm801-gp.c
@@ -68,7 +68,7 @@ static int fm801_gp_probe(struct pci_dev *pci, const struct pci_device_id *id)
struct gameport *port;
int error;
- gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL);
+ gp = kzalloc(sizeof(*gp), GFP_KERNEL);
port = gameport_allocate_port();
if (!gp || !port) {
printk(KERN_ERR "fm801-gp: Memory allocation failed\n");
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index cfcc81c47b50..ad39ac6fa96d 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -372,7 +372,7 @@ static int gameport_queue_event(void *object, struct module *owner,
}
}
- event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
+ event = kmalloc(sizeof(*event), GFP_ATOMIC);
if (!event) {
pr_err("Not enough memory to queue event %d\n", event_type);
retval = -ENOMEM;
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
index 91a8cd346e9b..880e714b49bc 100644
--- a/drivers/input/gameport/ns558.c
+++ b/drivers/input/gameport/ns558.c
@@ -120,7 +120,7 @@ static int ns558_isa_probe(int io)
return -EBUSY;
}
- ns558 = kzalloc(sizeof(struct ns558), GFP_KERNEL);
+ ns558 = kzalloc(sizeof(*ns558), GFP_KERNEL);
port = gameport_allocate_port();
if (!ns558 || !port) {
printk(KERN_ERR "ns558: Memory allocation failed.\n");
@@ -192,7 +192,7 @@ static int ns558_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
if (!request_region(ioport, iolen, "ns558-pnp"))
return -EBUSY;
- ns558 = kzalloc(sizeof(struct ns558), GFP_KERNEL);
+ ns558 = kzalloc(sizeof(*ns558), GFP_KERNEL);
port = gameport_allocate_port();
if (!ns558 || !port) {
printk(KERN_ERR "ns558: Memory allocation failed\n");
--
2.25.1
^ permalink raw reply related
* Re: [PATCH v11 0/4] Firmware Support for USB-HID Devices and CP2112
From: Danny Kaehn @ 2024-06-07 17:20 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Rob Herring, Krzysztof Kozlowski, Benjamin Tissoires, Jiri Kosina,
devicetree, linux-input, Dmitry Torokhov, Bartosz Golaszewski,
Ethan Twardy
In-Reply-To: <ZmISaEIGlxZVK_jf@smile.fi.intel.com>
On Thu, Jun 06, 2024 at 10:47:52PM +0300, Andy Shevchenko wrote:
> On Thu, Jun 06, 2024 at 10:54:53AM -0500, Danny Kaehn wrote:
> > On Thu, Jun 06, 2024 at 02:42:42AM +0300, Andy Shevchenko wrote:
> > > On Wed, Jun 05, 2024 at 06:12:43PM -0500, Danny Kaehn wrote:
>
> ...
>
> > > > Changes in v11:
> > > > - Eliminate 'gpio' subnode for DT and ACPI for the CP2112 per comment
> > > > from Rob H.
> > >
> > > Hmm... I don't know much about DT, but how is this supposed to work in ACPI?
> > > I mean if we want to refer to the GPIO in GpioIo() or GpioInt() resources,
> > > what should we put there as ACPI path?
> >
> > What I tested was essentially taking what Benjamin had done in [1], just
> > removing the "GPIO" device and combining it with the parent device (the
> > CP2112 itself). So for the example below, I believe the path would be
> > "\_SB_.PCI0.SE9_.RHUB.CP2_". If I get the chance (and can figure out how
> > to do it using ACPI) I'll try to add a "gpio-keys" or something to the
> > system using this path and make sure that works.
>
> This is counter intuitive and doesn't follow other (ACPI) devices with GPIO.
> So whatever you do for DT I don't care much, but let's not remove subnode
> for ACPI case.
>
Fair enough, will let this sit for a moment to see if there are comments
from Rob/Krzysztof, and otherwise will rework the driver to support the
different models for DT and ACPI. For what it's worth, combining the
GPIO chip and CP2112 nodes in DT also seems unintuitive to me, and it
seems there's other bindings for multi-function devices which define a
separate child "gpio" node, so I'm not sure why it's not desired here.
Thanks,
Danny Kaehn
^ permalink raw reply
* Re: [PATCH v11 1/4] dt-bindings: i2c: Add CP2112 HID USB to SMBus Bridge
From: Danny Kaehn @ 2024-06-07 18:38 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Rob Herring, Krzysztof Kozlowski, Benjamin Tissoires, Jiri Kosina,
devicetree, linux-input, Dmitry Torokhov, Bartosz Golaszewski,
Ethan Twardy
In-Reply-To: <ZmISrFrUVadRS1Do@smile.fi.intel.com>
On Thu, Jun 06, 2024 at 10:49:00PM +0300, Andy Shevchenko wrote:
> On Thu, Jun 06, 2024 at 11:24:38AM -0500, Danny Kaehn wrote:
> > On Thu, Jun 06, 2024 at 09:18:59AM -0600, Rob Herring wrote:
> > > On Wed, Jun 05, 2024 at 06:12:44PM -0500, Danny Kaehn wrote:
>
> ...
>
> > > > + i2c:
> > > > + description: The SMBus/I2C controller node for the CP2112
> > > > + $ref: /schemas/i2c/i2c-controller.yaml#
> > > > + unevaluatedProperties: false
> > > > +
> > > > + properties:
> > > > + sda-gpios:
> > > > + maxItems: 1
> > > > +
> > > > + scl-gpios:
> > > > + maxItems: 1
> > >
> > > These are because I2C can be on any of the pins? It's a bit odd if they
> > > aren't used as gpios. Probably should be pinmux, but that's overkill for
> > > 2 pins.
> > >
> >
> > I'm beginning to realize now that this may be a bit non-standard, but it
> > did solve a stuck bus issue under some conditions.
> >
> > The CP2112's I2C controller is self-contained and can only be on the
> > specific pins it is attached to (no pinmux, etc..).
> >
> > In this case, these properties are ment to specify additional gpio pins
> > which are connected to the SCL and SDA lines (this then also assumes those
> > are configured to be open drain / inputs to not interfere with the bus
> > during normal operation). This was inspired by what is done ini2c-imx.yaml,
> > but I realize this is a bit different due to using external pins rather
> > than pinmuxing to the GPIOs.
> >
> > How I used this was to actually connect some of the CP2112's own GPIO pins
> > to the SDA and SCL lines to be able to use those pins to recover the
> > bus. This was able to solve a stuck bus under some real-world cases with
> > the v2 of the CP2112 containing an errata which caused this
> > semi-frequently.
>
> Aren't they just for I²C recovery?
Not sure if you were looking for my reply here, but yes. I guess the
only "non-standard" thing really here is the idea of using
external/separate GPIO pins to do the recovery, rather than pinmuxing the
I2C pins to GPIO which most current implementations seem to do.
Thanks,
Danny Kaehn
^ permalink raw reply
* Re: (subset) [PATCH v2 0/7] HID/arm64: dts: qcom: sc8280xp-x13s: fix touchscreen power on
From: Bjorn Andersson @ 2024-06-07 18:48 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, Johan Hovold
Cc: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Konrad Dybcio, Linus Walleij, Douglas Anderson, linux-input,
devicetree, linux-arm-msm, linux-kernel
In-Reply-To: <20240507144821.12275-1-johan+linaro@kernel.org>
On Tue, 07 May 2024 16:48:14 +0200, Johan Hovold wrote:
> The Elan eKTH5015M touch controller on the X13s requires a 300 ms delay
> before sending commands after having deasserted reset during power on.
>
> This series switches the X13s devicetree to use the Elan specific
> binding so that the OS can determine the required power-on sequence and
> make sure that the controller is always detected during boot. [1]
>
> [...]
Applied, thanks!
[7/7] arm64: defconfig: enable Elan i2c-hid driver
commit: e706474d8428f420bba11f2c49c3083fd1b31d88
Best regards,
--
Bjorn Andersson <andersson@kernel.org>
^ permalink raw reply
* Re: [PATCH v3] HID: hid-goodix: Add Goodix HID-over-SPI driver
From: Dmitry Torokhov @ 2024-06-07 18:59 UTC (permalink / raw)
To: Charles Wang; +Cc: jikos, bentiss, hbarnor, dianders, linux-input, linux-kernel
In-Reply-To: <20240607133709.3518-1-charles.goodix@gmail.com>
Hi Charles,
On Fri, Jun 07, 2024 at 09:36:02PM +0800, Charles Wang wrote:
> This patch introduces a new driver to support the Goodix GT7986U
> touch controller. This device is not compatible with Microsoft's
> HID-over-SPI protocol and therefore needs to implement its own
> flavor. The data reported is packaged according to the HID
> protocol but uses SPI for communication to improve speed. This
> enables the device to transmit not only coordinate data but also
> corresponding raw data that can be accessed by user-space programs
> through the hidraw interface. The raw data can be utilized for
> functions like palm rejection, thereby improving the touch experience.
>
> Key features:
> - Device connection confirmation and initialization
> - IRQ-based event reporting to the input subsystem
> - Support for HIDRAW operations (GET_REPORT and SET_REPORT)
>
> Signed-off-by: Charles Wang <charles.goodix@gmail.com>
> ---
> Changes in v3:
> - Renamed the driver file to hid-goodix-spi.c.
> - Mentioned in the commit message that this implementation is not compatible with
> Microsoft's HID-over-SPI protocol.
> - Modified the driver to fetch the GOODIX_HID_REPORT_ADDR from device properties.
> - Add a lock to prevent concurrent hid feature request operations.
> - Optimized the SPI read/write functions by reducing the number of malloc calls.
Thank you for making the changes. A few more comments below.
>
> Changes in v2:
> - Fixed build warnings reported by kernel test robot
> ---
> drivers/hid/Kconfig | 6 +
> drivers/hid/Makefile | 1 +
> drivers/hid/hid-goodix-spi.c | 687 +++++++++++++++++++++++++++++++++++
> 3 files changed, 694 insertions(+)
> create mode 100644 drivers/hid/hid-goodix-spi.c
>
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index 4c682c650..03e750e04 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -404,6 +404,12 @@ config HID_VIVALDI_COMMON
> option so that drivers can use common code to parse the HID
> descriptors for vivaldi function row keymap.
>
> +config HID_GOODIX_SPI
> + tristate "Goodix GT7986U SPI HID touchscreen"
> + depends on SPI_MASTER
> + help
> + Support for Goodix GT7986U SPI HID touchscreen device.
> +
> config HID_GOOGLE_HAMMER
> tristate "Google Hammer Keyboard"
> select HID_VIVALDI_COMMON
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index 082a728ea..56e3ed4c1 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -54,6 +54,7 @@ obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o
> obj-$(CONFIG_HID_GFRM) += hid-gfrm.o
> obj-$(CONFIG_HID_GLORIOUS) += hid-glorious.o
> obj-$(CONFIG_HID_VIVALDI_COMMON) += hid-vivaldi-common.o
> +obj-$(CONFIG_HID_GOODIX_SPI) += hid-goodix-spi.o
> obj-$(CONFIG_HID_GOOGLE_HAMMER) += hid-google-hammer.o
> obj-$(CONFIG_HID_GOOGLE_STADIA_FF) += hid-google-stadiaff.o
> obj-$(CONFIG_HID_VIVALDI) += hid-vivaldi.o
> diff --git a/drivers/hid/hid-goodix-spi.c b/drivers/hid/hid-goodix-spi.c
> new file mode 100644
> index 000000000..7ba7016e1
> --- /dev/null
> +++ b/drivers/hid/hid-goodix-spi.c
> @@ -0,0 +1,687 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Goodix GT7986U SPI Driver Code for HID.
> + *
> + * Copyright (C) 2024 Godix, Inc.
> + */
> +#include <asm/unaligned.h>
> +#include <linux/delay.h>
> +#include <linux/hid.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/sizes.h>
> +#include <linux/spi/spi.h>
> +
> +#define GOODIX_DEV_CONFIRM_ADDR 0x10000
> +#define GOODIX_HID_DESC_ADDR 0x1058C
> +#define GOODIX_HID_REPORT_DESC_ADDR 0x105AA
> +#define GOODIX_HID_SIGN_ADDR 0x10D32
> +
> +#define GOODIX_HID_GET_REPORT_CMD 0x02
> +#define GOODIX_HID_SET_REPORT_CMD 0x03
> +
> +#define GOODIX_HID_MAX_INBUF_SIZE 128
> +#define GOODIX_HID_ACK_READY_FLAG 0x01
> +#define GOODIX_HID_REPORT_READY_FLAG 0x80
> +
> +#define GOODIX_DEV_CONFIRM_VAL 0xAA
> +
> +#define GOODIX_SPI_WRITE_FLAG 0xF0
> +#define GOODIX_SPI_READ_FLAG 0xF1
> +#define GOODIX_SPI_TRANS_PREFIX_LEN 1
> +#define GOODIX_REGISTER_WIDTH 4
> +#define GOODIX_SPI_READ_DUMMY_LEN 3
> +#define GOODIX_SPI_READ_PREFIX_LEN (GOODIX_SPI_TRANS_PREFIX_LEN + \
> + GOODIX_REGISTER_WIDTH + \
> + GOODIX_SPI_READ_DUMMY_LEN)
> +#define GOODIX_SPI_WRITE_PREFIX_LEN (GOODIX_SPI_TRANS_PREFIX_LEN + \
> + GOODIX_REGISTER_WIDTH)
> +
> +#define GOODIX_CHECKSUM_SIZE sizeof(u16)
> +#define GOODIX_NORMAL_RESET_DELAY_MS 150
> +
> +struct goodix_hid_report_header {
> + u8 flag;
> + __le16 size;
> +} __packed;
> +#define GOODIX_HID_ACK_HEADER_SIZE sizeof(struct goodix_hid_report_header)
> +
> +struct goodix_hid_report_package {
> + __le16 size;
> + u8 data[];
> +};
> +
> +#define GOODIX_HID_PKG_LEN_SIZE sizeof(u16)
> +#define GOODIX_HID_COOR_DATA_LEN 82
> +#define GOODIX_HID_COOR_PKG_LEN (GOODIX_HID_PKG_LEN_SIZE + \
> + GOODIX_HID_COOR_DATA_LEN)
> +
> +#define GOODIX_HID_MAX_PKG_SIZE (GOODIX_HID_COOR_PKG_LEN + SZ_4K)
> +
> +struct goodix_hid_report_event {
> + struct goodix_hid_report_header hdr;
> + u8 data[GOODIX_HID_COOR_PKG_LEN];
> +} __packed;
> +
> +struct goodix_hid_desc {
> + __le16 desc_length;
> + __le16 bcd_version;
> + __le16 report_desc_lenght;
> + __le16 report_desc_register;
> + __le16 input_register;
> + __le16 max_input_length;
> + __le16 output_register;
> + __le16 max_output_length;
> + __le16 cmd_register;
> + __le16 data_register;
> + __le16 vendor_id;
> + __le16 product_id;
> + __le16 version_id;
> + __le32 reserved;
> +} __packed;
> +
> +struct goodix_ts_data {
> + struct device *dev;
> + struct spi_device *spi;
> + struct hid_device *hid;
> + struct goodix_hid_desc hid_desc;
> +
> + struct gpio_desc *reset_gpio;
> + u32 hid_report_addr;
> +
> + /* lock for hid raw request operation */
> + struct mutex hid_request_lock;
> + /* lock for reg read write operations */
> + struct mutex reg_rw_lock;
> + u32 spi_xfer_max_sz;
> + /* buffer used to store hid report event */
> + u8 event_buf[SZ_4K] ____cacheline_aligned;
Why does this have to be cacheline aligned? I do not think it is
directly involved in the transfers.
Also, 4K is quite a bit of data. How often does the device send more
than 1 report? Maybe you should do what i2c-hid does and scan reports
for the maximum report size and use it to allocate sufficiently sized
buffer(s)? See drivers/hid/i2c-hid/i2c-hid-core.c::i2c_hid_start().
> + /* buffer used to do spi data transfer */
> + u8 xfer_buf[GOODIX_HID_MAX_PKG_SIZE] ____cacheline_aligned;
> +};
> +
> +static int goodix_spi_read(struct goodix_ts_data *ts, u32 addr,
> + u8 *data, unsigned int len)
Maybe make data void * so callers do not need to cast? Also maybe size_t
for len?
> +{
> + struct spi_device *spi = to_spi_device(&ts->spi->dev);
> + struct spi_transfer xfers;
> + struct spi_message spi_msg;
> + int error;
> +
> + if (GOODIX_SPI_READ_PREFIX_LEN + len > ts->spi_xfer_max_sz) {
> + dev_err(ts->dev, "read data len exceed limit %d",
> + ts->spi_xfer_max_sz - GOODIX_SPI_READ_PREFIX_LEN);
> + return -EINVAL;
> + }
> +
> + mutex_lock(&ts->reg_rw_lock);
This can be written as
guard(mutex)(&ts->reg_rw_lock);
and you do not need to explicitly unlock the mutex at the end of the
function. You can also safely return early and the mutex will be
unlocked.
> + /* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
> + ts->xfer_buf[0] = GOODIX_SPI_READ_FLAG;
> + put_unaligned_be32(addr, ts->xfer_buf + GOODIX_SPI_TRANS_PREFIX_LEN);
> +
> + spi_message_init(&spi_msg);
> + memset(&xfers, 0, sizeof(xfers));
> + xfers.tx_buf = ts->xfer_buf;
> + xfers.rx_buf = ts->xfer_buf;
> + xfers.len = GOODIX_SPI_READ_PREFIX_LEN + len;
> + spi_message_add_tail(&xfers, &spi_msg);
> +
> + error = spi_sync(spi, &spi_msg);
> + if (error)
> + dev_err(ts->dev, "spi transfer error:%d", error);
"error: %d"
> + else
> + memcpy(data, ts->xfer_buf + GOODIX_SPI_READ_PREFIX_LEN, len);
> +
> + mutex_unlock(&ts->reg_rw_lock);
> + return error;
> +}
> +
> +static int goodix_spi_write(struct goodix_ts_data *ts, u32 addr,
> + u8 *data, unsigned int len)
const void *data
> +{
> + struct spi_device *spi = to_spi_device(&ts->spi->dev);
> + struct spi_transfer xfers;
> + struct spi_message spi_msg;
> + int error;
> +
> + if (GOODIX_SPI_WRITE_PREFIX_LEN + len > ts->spi_xfer_max_sz) {
> + dev_err(ts->dev, "write data len exceed limit %d",
> + ts->spi_xfer_max_sz - GOODIX_SPI_WRITE_PREFIX_LEN);
> + return -EINVAL;
> + }
> +
> + mutex_lock(&ts->reg_rw_lock);
guard(mutex)(&ts->reg_rw_lock);
> + /* buffer format: 0xF0 + addr(4bytes) + data */
> + ts->xfer_buf[0] = GOODIX_SPI_WRITE_FLAG;
> + put_unaligned_be32(addr, ts->xfer_buf + GOODIX_SPI_TRANS_PREFIX_LEN);
> + memcpy(ts->xfer_buf + GOODIX_SPI_WRITE_PREFIX_LEN, data, len);
> +
> + spi_message_init(&spi_msg);
> + memset(&xfers, 0, sizeof(xfers));
> + xfers.tx_buf = ts->xfer_buf;
> + xfers.len = GOODIX_SPI_WRITE_PREFIX_LEN + len;
> + spi_message_add_tail(&xfers, &spi_msg);
> +
> + error = spi_sync(spi, &spi_msg);
> + if (error)
> + dev_err(ts->dev, "spi transfer error:%d", error);
> +
> + mutex_unlock(&ts->reg_rw_lock);
> + return error;
> +}
> +
> +static int goodix_dev_confirm(struct goodix_ts_data *ts)
> +{
> + u8 tx_buf[8], rx_buf[8];
> + int retry = 3;
> + int error;
> +
> + gpiod_set_value_cansleep(ts->reset_gpio, 0);
> + usleep_range(4000, 4100);
> +
> + memset(tx_buf, GOODIX_DEV_CONFIRM_VAL, sizeof(tx_buf));
> + while (retry--) {
> + error = goodix_spi_write(ts, GOODIX_DEV_CONFIRM_ADDR,
> + tx_buf, sizeof(tx_buf));
> + if (error)
> + return error;
> +
> + error = goodix_spi_read(ts, GOODIX_DEV_CONFIRM_ADDR,
> + rx_buf, sizeof(rx_buf));
> + if (error)
> + return error;
> +
> + if (!memcmp(tx_buf, rx_buf, sizeof(tx_buf)))
> + return 0;
> +
> + usleep_range(5000, 5100);
> + }
> +
> + dev_err(ts->dev, "device confirm failed, rx_buf:%*ph", 8, rx_buf);
> + return -EINVAL;
> +}
> +
> +/**
> + * goodix_hid_parse() - hid-core .parse() callback
> + * @hid: hid device instance
> + *
> + * This function gets called during call to hid_add_device
> + *
> + * Return: 0 on success and non zero on error
> + */
> +static int goodix_hid_parse(struct hid_device *hid)
> +{
> + struct goodix_ts_data *ts = hid->driver_data;
> + u8 *rdesc __free(kfree);
This is not proper use of this. rdesc will contain garbage (not NULL),
so if rsize check below failed we'll get a nasty surprise.
> + u16 rsize;
> + int error;
> +
> + rsize = le16_to_cpu(ts->hid_desc.report_desc_lenght);
> + if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
> + dev_err(ts->dev, "invalid report desc size %d", rsize);
> + return -EINVAL;
> + }
> +
> + rdesc = kzalloc(rsize, GFP_KERNEL);
> + if (!rdesc)
> + return -ENOMEM;
Linus said that for pointers annotated with __free() he prefers
combining declaration with allocation, like this:
u8 *rdesc __free(kfree) = kzalloc(rsize, GFP_KERNEL);
if (!rdesc)
return -ENOMEM;
> +
> + error = goodix_spi_read(ts, GOODIX_HID_REPORT_DESC_ADDR, rdesc, rsize);
> + if (error) {
> + dev_err(ts->dev, "failed get report desc, %d", error);
> + return error;
> + }
> +
> + error = hid_parse_report(hid, rdesc, rsize);
> + if (error)
> + dev_err(ts->dev, "failed parse report, %d", error);
> +
> + return error;
I am not sure what Benjamin and Jiri prefer, but my preference is to
explicitly return error or 0 instead of returning "error" in both
success and failure cases, especially when there are multiple failure
points in a function. So:
error = hid_parse_report(hid, rdesc, rsize);
if (error) {
dev_err(ts->dev, "failed parse report, %d", error);
return error;
}
return 0;
> +}
> +
> +/* Empty callbacks with success return code */
> +static int goodix_hid_start(struct hid_device *hid)
> +{
> + return 0;
> +}
> +
> +static void goodix_hid_stop(struct hid_device *hid)
> +{
> +}
> +
> +static int goodix_hid_open(struct hid_device *hid)
> +{
> + return 0;
> +}
> +
> +static void goodix_hid_close(struct hid_device *hid)
> +{
> +}
> +
> +/* Return date length of response data */
> +static int goodix_hid_check_ack_status(struct goodix_ts_data *ts)
> +{
> + struct goodix_hid_report_header hdr;
> + int retry = 20;
> + int error;
> +
> + while (retry--) {
> + /*
> + * 3 bytes of hid request response data
> + * - byte 0: Ack flag, value of 1 for data ready
> + * - bytes 1-2: Response data length
> + */
> + error = goodix_spi_read(ts, ts->hid_report_addr,
> + (u8 *)&hdr, sizeof(hdr));
> + if (!error && (hdr.flag & GOODIX_HID_ACK_READY_FLAG))
> + return le16_to_cpu(hdr.size);
> +
> + /* Wait 10ms for another try */
> + usleep_range(10000, 11000);
> + }
> +
> + return -EINVAL;
> +}
> +
> +/**
> + * goodix_hid_get_raw_report() - Process hidraw GET REPORT operation
> + * @hid: hid device instance
> + * @reportnum: Report ID
> + * @buf: Buffer for store the reprot date
> + * @len: Length fo reprot data
> + * @report_type: Report type
> + *
> + * The function for hid_ll_driver.get_raw_report to handle the HIDRAW ioctl
> + * get report request. The transmitted data follows the standard i2c-hid
> + * protocol with a specified header.
> + *
> + * Return: The length of the data in the buf on success, negative error code
> + */
> +static int goodix_hid_get_raw_report(struct hid_device *hid,
> + unsigned char reportnum,
> + __u8 *buf, size_t len,
> + unsigned char report_type)
I think u8 for report type is better. It is not a character but a
number.
> +{
> + struct goodix_ts_data *ts = hid->driver_data;
> + u16 data_register = le16_to_cpu(ts->hid_desc.data_register);
> + u16 cmd_register = le16_to_cpu(ts->hid_desc.cmd_register);
> + u8 tmp_buf[GOODIX_HID_MAX_INBUF_SIZE];
> + int tx_len = 0, args_len = 0;
> + int response_data_len;
> + u8 args[3];
> + int error;
> +
> + if (report_type == HID_OUTPUT_REPORT)
> + return -EINVAL;
> +
> + if (reportnum == 3) {
> + /* Get win8 signature data */
> + error = goodix_spi_read(ts, GOODIX_HID_SIGN_ADDR, buf, len);
> + if (error) {
> + dev_err(ts->dev, "failed get win8 sign:%d", error);
> + return -EINVAL;
> + }
> + return len;
> + }
> +
> + if (reportnum >= 0x0F)
> + args[args_len++] = reportnum;
> +
> + put_unaligned_le16(data_register, args + args_len);
> + args_len += sizeof(data_register);
> +
> + /* Clean 3 bytes of hid ack header data */
> + memset(tmp_buf, 0, GOODIX_HID_ACK_HEADER_SIZE);
> + tx_len += GOODIX_HID_ACK_HEADER_SIZE;
> +
> + put_unaligned_le16(cmd_register, tmp_buf + tx_len);
> + tx_len += sizeof(cmd_register);
> +
> + tmp_buf[tx_len] = (report_type == HID_FEATURE_REPORT ? 0x03 : 0x01) << 4;
> + tmp_buf[tx_len] |= reportnum >= 0x0F ? 0x0F : reportnum;
> + tx_len++;
> +
> + tmp_buf[tx_len++] = GOODIX_HID_GET_REPORT_CMD;
> +
> + memcpy(tmp_buf + tx_len, args, args_len);
> + tx_len += args_len;
> +
> + /* Step1: write report request info */
> + error = goodix_spi_write(ts, ts->hid_report_addr, tmp_buf, tx_len);
> + if (error) {
> + dev_err(ts->dev, "failed send read feature cmd, %d", error);
> + return error;
> + }
> +
> + /* No need read response data */
> + if (!len)
> + return 0;
> +
> + /* Step2: check response data status */
> + response_data_len = goodix_hid_check_ack_status(ts);
> + if (response_data_len <= GOODIX_HID_PKG_LEN_SIZE)
> + return -EINVAL;
> +
> + len = min(len, response_data_len - GOODIX_HID_PKG_LEN_SIZE);
> + /* Step3: read response data(skip 2bytes of hid pkg length) */
> + error = goodix_spi_read(ts, ts->hid_report_addr +
> + GOODIX_HID_ACK_HEADER_SIZE +
> + GOODIX_HID_PKG_LEN_SIZE, buf, len);
> + if (error) {
> + dev_err(ts->dev, "failed read hid response data, %d", error);
> + return error;
> + }
> +
> + if (buf[0] != reportnum) {
> + dev_err(ts->dev, "incorrect reprot (%d vs %d expected)",
s/reprot/report/
> + buf[0], reportnum);
> + return -EINVAL;
> + }
> + return len;
> +}
> +
> +/**
> + * goodix_hid_set_raw_report() - process hidraw SET REPORT operation
> + * @hid: HID device
> + * @reportnum: Report ID
> + * @buf: Buffer for communication
> + * @len: Length of data in the buffer
> + * @report_type: Report type
> + *
> + * The function for hid_ll_driver.get_raw_report to handle the HIDRAW ioctl
> + * set report request. The transmitted data follows the standard i2c-hid
> + * protocol with a specified header.
> + *
> + * Return: The length of the data sent, negative error code on failure
> + */
> +static int goodix_hid_set_raw_report(struct hid_device *hid,
> + unsigned char reportnum,
> + __u8 *buf, size_t len,
> + unsigned char report_type)
> +{
> + struct goodix_ts_data *ts = hid->driver_data;
> + u16 data_register = le16_to_cpu(ts->hid_desc.data_register);
> + u16 cmd_register = le16_to_cpu(ts->hid_desc.cmd_register);
> + int tx_len = 0, args_len = 0;
> + u8 tmp_buf[GOODIX_HID_MAX_INBUF_SIZE];
> + u8 args[5];
> + int error;
> +
> + if (reportnum >= 0x0F) {
> + args[args_len++] = reportnum;
> + reportnum = 0x0F;
> + }
> +
> + put_unaligned_le16(data_register, args + args_len);
> + args_len += sizeof(data_register);
> +
> + put_unaligned_le16(GOODIX_HID_PKG_LEN_SIZE + len, args + args_len);
> + args_len += GOODIX_HID_PKG_LEN_SIZE;
> +
> + /* Clean 3 bytes of hid ack header data */
> + memset(tmp_buf, 0, GOODIX_HID_ACK_HEADER_SIZE);
> + tx_len += GOODIX_HID_ACK_HEADER_SIZE;
> +
> + put_unaligned_le16(cmd_register, tmp_buf + tx_len);
> + tx_len += sizeof(cmd_register);
> +
> + tmp_buf[tx_len++] = ((report_type == HID_FEATURE_REPORT ? 0x03 : 0x02) << 4) | reportnum;
> + tmp_buf[tx_len++] = GOODIX_HID_SET_REPORT_CMD;
> +
> + memcpy(tmp_buf + tx_len, args, args_len);
> + tx_len += args_len;
> +
> + memcpy(tmp_buf + tx_len, buf, len);
> + tx_len += len;
> +
> + error = goodix_spi_write(ts, ts->hid_report_addr, tmp_buf, tx_len);
> + if (error) {
> + dev_err(ts->dev, "failed send report %*ph", tx_len, tmp_buf);
> + return error;
> + }
> + return len;
> +}
> +
> +static int goodix_hid_raw_request(struct hid_device *hid,
> + unsigned char reportnum,
> + __u8 *buf, size_t len,
> + unsigned char rtype, int reqtype)
> +{
> + struct goodix_ts_data *ts = hid->driver_data;
> + int error = -EINVAL;
> +
> + mutex_lock(&ts->hid_request_lock);
guard(mutex)(&ts->hid_request_lock);
> + switch (reqtype) {
> + case HID_REQ_GET_REPORT:
> + error = goodix_hid_get_raw_report(hid, reportnum, buf,
> + len, rtype);
> + break;
> + case HID_REQ_SET_REPORT:
> + if (buf[0] == reportnum)
> + error = goodix_hid_set_raw_report(hid, reportnum,
> + buf, len, rtype);
> + break;
> + default:
> + break;
> + }
> + mutex_unlock(&ts->hid_request_lock);
> +
> + return error;
> +}
> +
> +static struct hid_ll_driver goodix_hid_ll_driver = {
> + .parse = goodix_hid_parse,
> + .start = goodix_hid_start,
> + .stop = goodix_hid_stop,
> + .open = goodix_hid_open,
> + .close = goodix_hid_close,
> + .raw_request = goodix_hid_raw_request
> +};
> +
> +static irqreturn_t goodix_hid_irq(int irq, void *data)
> +{
> + struct goodix_ts_data *ts = data;
> + struct goodix_hid_report_event event;
> + struct goodix_hid_report_package *pkg;
> + u16 report_size;
> + int error;
> +
> + /*
> + * First, read buffer with space for header and coordinate package:
> + * - event header = 3 bytes
> + * - coordinate event = GOODIX_HID_COOR_PKG_LEN bytes
> + *
> + * If the data size info in the event header exceeds
> + * GOODIX_HID_COOR_PKG_LEN, it means that there are other packages
> + * besides the coordinate package.
> + */
> + error = goodix_spi_read(ts, ts->hid_report_addr, (u8 *)&event,
Drop cast.
> + sizeof(event));
> + if (error) {
> + dev_err(ts->dev, "failed get coordinate data, %d", error);
> + return IRQ_HANDLED;
> + }
> +
> + /* Check coordinate data valid falg */
> + if (event.hdr.flag != GOODIX_HID_REPORT_READY_FLAG) {
> + dev_err(ts->dev, "invalid event flag 0x%x", event.hdr.flag);
> + return IRQ_HANDLED;
> + }
> +
> + pkg = (struct goodix_hid_report_package *)event.data;
> + hid_input_report(ts->hid, HID_INPUT_REPORT, pkg->data,
> + le16_to_cpu(pkg->size) - GOODIX_HID_PKG_LEN_SIZE, 1);
> +
> + report_size = le16_to_cpu(event.hdr.size);
> + /* Check if there are other packages */
> + if (report_size <= GOODIX_HID_COOR_PKG_LEN)
> + return IRQ_HANDLED;
> +
> + if (report_size - GOODIX_HID_COOR_PKG_LEN > sizeof(ts->event_buf)) {
> + dev_err(ts->dev, "invalid package size, %d", report_size);
> + return IRQ_HANDLED;
> + }
> +
> + /* Read the package behind the coordinate data */
> + error = goodix_spi_read(ts, ts->hid_report_addr + sizeof(event),
> + ts->event_buf,
> + report_size - GOODIX_HID_COOR_PKG_LEN);
> + if (error) {
> + dev_err(ts->dev, "failed read data, %d", error);
> + return IRQ_HANDLED;
> + }
> +
> + pkg = (struct goodix_hid_report_package *)ts->event_buf;
> + hid_input_report(ts->hid, HID_INPUT_REPORT, pkg->data,
> + le16_to_cpu(pkg->size) - GOODIX_HID_PKG_LEN_SIZE, 1);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int goodix_hid_init(struct goodix_ts_data *ts)
> +{
> + struct hid_device *hid;
> + int error;
> +
> + /* Get hid descriptor */
> + error = goodix_spi_read(ts, GOODIX_HID_DESC_ADDR, (u8 *)&ts->hid_desc,
Drop cast.
> + sizeof(ts->hid_desc));
> + if (error) {
> + dev_err(ts->dev, "failed get hid desc, %d", error);
> + return error;
> + }
> +
> + hid = hid_allocate_device();
> + if (IS_ERR(hid))
> + return PTR_ERR(hid);
> +
> + hid->driver_data = ts;
> + hid->ll_driver = &goodix_hid_ll_driver;
> + hid->bus = BUS_SPI;
> + hid->dev.parent = &ts->spi->dev;
> +
> + hid->version = le16_to_cpu(ts->hid_desc.bcd_version);
> + hid->vendor = le16_to_cpu(ts->hid_desc.vendor_id);
> + hid->product = le16_to_cpu(ts->hid_desc.product_id);
> + snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-gdix",
> + hid->vendor, hid->product);
> +
> + error = hid_add_device(hid);
> + if (error) {
> + dev_err(ts->dev, "failed add hid device, %d", error);
> + hid_destroy_device(hid);
> + return error;
> + }
> +
> + ts->hid = hid;
> + return 0;
> +}
> +
> +static int goodix_spi_probe(struct spi_device *spi)
> +{
> + struct device *dev = &spi->dev;
> + struct goodix_ts_data *ts;
> + int error;
> +
> + /* init spi_device */
> + spi->mode = SPI_MODE_0;
> + spi->bits_per_word = 8;
> + error = spi_setup(spi);
> + if (error)
> + return error;
> +
> + ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
> + if (!ts)
> + return -ENOMEM;
> +
> + mutex_init(&ts->hid_request_lock);
> + mutex_init(&ts->reg_rw_lock);
> + spi_set_drvdata(spi, ts);
> + if (spi->controller->max_transfer_size)
> + ts->spi_xfer_max_sz = spi->controller->max_transfer_size(spi);
> + else
> + ts->spi_xfer_max_sz = GOODIX_HID_MAX_PKG_SIZE;
> +
> + ts->spi_xfer_max_sz = min(GOODIX_HID_MAX_PKG_SIZE, ts->spi_xfer_max_sz);
> + ts->spi = spi;
> + ts->dev = dev;
> + ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
> + if (IS_ERR(ts->reset_gpio))
> + return dev_err_probe(dev, PTR_ERR(ts->reset_gpio),
> + "failed to request reset gpio\n");
> +
> + error = device_property_read_u32(dev, "hid-report-addr",
> + &ts->hid_report_addr);
This will require device binding document. Well, we needed it anyway to
describe the reset GPIO. You should add regulator handling as well.
> + if (error)
> + return dev_err_probe(dev, error,
> + "failed get hid report addr\n");
> +
> + error = goodix_dev_confirm(ts);
> + if (error)
> + return error;
> +
> + /* Waits 150ms for firmware to fully boot */
> + msleep(GOODIX_NORMAL_RESET_DELAY_MS);
> +
> + error = goodix_hid_init(ts);
> + if (error) {
> + dev_err(dev, "failed init hid device");
> + return error;
> + }
> +
> + error = devm_request_threaded_irq(&ts->spi->dev, ts->spi->irq,
> + NULL, goodix_hid_irq, IRQF_ONESHOT,
> + "goodix_spi_hid", ts);
I think we still have an issue. The hid device is "added" to hid bus in
goodix_hid_init(). Immediately HID bus will attempt to match the HID
device and HID driver, start the low level transport (i.e. us), and try
to interrogate and initiate the device. That means that interrupts need
to be working already. However we only request IRQ after returning from
goodix_hid_init(), which is too late.
Please take a look at how i2c-hid driver allocates HID device, requests
IRQ, and then calls to hid_add_device(). Also see how it checks for
I2C_HID_STARTED flags in the interrupt routine to see of the data needs
to be reported to the HID subsystem.
> + if (error < 0) {
if (error)
> + dev_err(ts->dev, "could not register interrupt, irq = %d, %d",
> + ts->spi->irq, error);
> + goto err_destroy_hid;
> + }
> +
> + return 0;
> +
> +err_destroy_hid:
> + hid_destroy_device(ts->hid);
> + return error;
> +}
> +
> +static void goodix_spi_remove(struct spi_device *spi)
> +{
> + struct goodix_ts_data *ts = spi_get_drvdata(spi);
> +
> + disable_irq(spi->irq);
> + hid_destroy_device(ts->hid);
Here we again need to make sure interrupts are working while the device
is being used but the HID subsystem, but make sure we are not trying to
service interrupts once device is fully gone.
> +}
> +
> +static void goodix_spi_shutdown(struct spi_device *spi)
> +{
> + struct goodix_ts_data *ts = spi_get_drvdata(spi);
> +
> + disable_irq(spi->irq);
> + hid_destroy_device(ts->hid);
Same as above.
> +}
> +
> +#ifdef CONFIG_ACPI
> +static const struct acpi_device_id goodix_spi_acpi_match[] = {
> + { "GXTS7986" },
> + { },
> +};
> +MODULE_DEVICE_TABLE(acpi, goodix_spi_acpi_match);
> +#endif
> +
> +static struct spi_driver goodix_spi_driver = {
> + .driver = {
> + .name = "goodix-spi-hid",
> + .acpi_match_table = ACPI_PTR(goodix_spi_acpi_match),
> + },
> + .probe = goodix_spi_probe,
> + .remove = goodix_spi_remove,
> + .shutdown = goodix_spi_shutdown,
> +};
> +module_spi_driver(goodix_spi_driver);
> +
> +MODULE_DESCRIPTION("Goodix SPI driver for HID touchscreen");
> +MODULE_AUTHOR("Goodix, Inc.");
> +MODULE_LICENSE("GPL");
> --
> 2.43.0
>
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: serio - use sizeof(*pointer) instead of sizeof(type)
From: Dmitry Torokhov @ 2024-06-07 19:17 UTC (permalink / raw)
To: Erick Archer
Cc: Russell King, James E.J. Bottomley, Helge Deller,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Stephen Chandler Paul, Michal Simek, Uwe Kleine-König,
Russell King (Oracle), Suzuki K Poulose, Krzysztof Kozlowski,
Rob Herring, Ruan Jinjie, Ricardo B. Marliere, Greg Kroah-Hartman,
Jiri Slaby (SUSE), Mark Brown, Yang Li, Kees Cook,
Gustavo A. R. Silva, Justin Stitt, linux-input, linux-kernel,
linux-parisc, linux-hyperv, linux-arm-kernel, linux-sunxi,
linux-hardening
In-Reply-To: <AS8PR02MB7237D3D898CCC9C50C18DE078BFB2@AS8PR02MB7237.eurprd02.prod.outlook.com>
On Fri, Jun 07, 2024 at 07:04:23PM +0200, Erick Archer wrote:
> It is preferred to use sizeof(*pointer) instead of sizeof(type)
> due to the type of the variable can change and one needs not
> change the former (unlike the latter). This patch has no effect
> on runtime behavior.
>
> Signed-off-by: Erick Archer <erick.archer@outlook.com>
Applied, thank you.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: gameport - use sizeof(*pointer) instead of sizeof(type)
From: Dmitry Torokhov @ 2024-06-07 19:17 UTC (permalink / raw)
To: Erick Archer
Cc: Niklas Schnelle, Greg Kroah-Hartman, Arnd Bergmann,
Ricardo B. Marliere, Kees Cook, Gustavo A. R. Silva, Justin Stitt,
linux-input, linux-kernel, linux-hardening
In-Reply-To: <PAXPR02MB72483F512F863C74A4AECA2B8BFB2@PAXPR02MB7248.eurprd02.prod.outlook.com>
On Fri, Jun 07, 2024 at 07:17:55PM +0200, Erick Archer wrote:
> It is preferred to use sizeof(*pointer) instead of sizeof(type)
> due to the type of the variable can change and one needs not
> change the former (unlike the latter). This patch has no effect
> on runtime behavior.
>
> Signed-off-by: Erick Archer <erick.archer@outlook.com>
Applied, thank you.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v3] Input: adc-joystick: Handle inverted axes
From: Dmitry Torokhov @ 2024-06-07 19:31 UTC (permalink / raw)
To: Chris Morgan
Cc: linux-input, contact, hdegoede, paul, peter.hutterer, svv,
biswarupp, Chris Morgan
In-Reply-To: <ZauN-gBsIPO0AyGE@google.com>
On Sat, Jan 20, 2024 at 01:10:18AM -0800, Dmitry Torokhov wrote:
> On Fri, Jan 19, 2024 at 12:29:54AM -0800, Dmitry Torokhov wrote:
> > Hi Chris,
> >
> > On Mon, Jan 15, 2024 at 01:27:52PM -0600, Chris Morgan wrote:
> > >
> > > +static int adc_joystick_invert(struct input_dev *dev,
> > > + unsigned int axis, int val)
> > > +{
> > > + int min = dev->absinfo[axis].minimum;
> > > + int max = dev->absinfo[axis].maximum;
> >
> > I changed this to input_abs_get_[min|max](dev, axis) to avoid peeking
> > into absinfo and applied.
>
> Apparently min_array() and max_array() are a bit too new. Also I am not
> sure if they are actually needed. Can we do it like this:
>
> diff --git a/drivers/input/joystick/adc-joystick.c b/drivers/input/joystick/adc-joystick.c
> index 10ee13465cfe..916e78e4dc9f 100644
> --- a/drivers/input/joystick/adc-joystick.c
> +++ b/drivers/input/joystick/adc-joystick.c
> @@ -185,14 +185,14 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
> if (axes[i].range[0] > axes[i].range[1]) {
> dev_dbg(dev, "abs-axis %d inverted\n", i);
> axes[i].inverted = true;
> + swap(axes[i].range[0], axes[i].range[1]);
> }
>
> fwnode_property_read_u32(child, "abs-fuzz", &axes[i].fuzz);
> fwnode_property_read_u32(child, "abs-flat", &axes[i].flat);
>
> input_set_abs_params(joy->input, axes[i].code,
> - min_array(axes[i].range, 2),
> - max_array(axes[i].range, 2),
> + axes[i].range[0], axes[i].range[1],
> axes[i].fuzz, axes[i].flat);
> input_set_capability(joy->input, EV_ABS, axes[i].code);
> }
OK, I went ahead and folded this into the original patch and applied.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH] Input: xpad - add support for ASUS ROG RAIKIRI PRO
From: Luke D. Jones @ 2024-06-07 22:37 UTC (permalink / raw)
To: linux-input
Cc: dmitry.torokhov, vi, maxwell.nguyen, appsforartists, carl.ng,
christophe.jaillet, matt.git, linux-kernel, Luke D. Jones
Add the VID/PID for ASUS ROG RAIKIRI PRO to
xpad_device and the VID to xpad_table.
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
drivers/hid/hid-ids.h | 1 +
drivers/input/joystick/xpad.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 61d2a21affa2..31c522fa4e87 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -209,6 +209,7 @@
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30
#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6
+#define USB_DEVICE_ID_ASUSTEK_ROG_RAIKIRI_PAD 0x1abb
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe
#define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
#define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 6fadaddb2b90..3a5af0909233 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -209,6 +209,7 @@ static const struct xpad_device {
{ 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 },
{ 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 },
{ 0x0b05, 0x1a38, "ASUS ROG RAIKIRI", 0, XTYPE_XBOXONE },
+ { 0x0b05, 0x1abb, "ASUS ROG RAIKIRI PRO", 0, XTYPE_XBOXONE },
{ 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX },
{ 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX },
{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
--
2.45.2
^ permalink raw reply related
* Re: [PATCH v2 1/1] hid-asus: use hid for brightness control on keyboard
From: Luke Jones @ 2024-06-07 23:24 UTC (permalink / raw)
To: Jiri Kosina; +Cc: Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20240607040532.1074379-2-luke@ljones.dev>
I thought this was finalised but I'm still getting conflicting reports.
Please don't merge until I confirm the fix.
On Fri, 7 Jun 2024, at 4:05 PM, Luke D. Jones wrote:
> On almost all ASUS ROG series laptops the MCU used for the USB keyboard
> also has a HID packet used for setting the brightness. This is usually
> the same as the WMI method. But in some laptops the WMI method either
> is missing or doesn't work, so we should default to the HID control.
>
> Signed-off-by: Luke D. Jones <luke@ljones.dev>
> ---
> drivers/hid/hid-asus.c | 7 ++++
> drivers/platform/x86/asus-wmi.c | 3 +-
> include/linux/platform_data/x86/asus-wmi.h | 45 ++++++++++++++++++++++
> 3 files changed, 54 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index 02de2bf4f790..0ed3708ef7e2 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c
> @@ -492,12 +492,19 @@ static void asus_kbd_backlight_work(struct work_struct *work)
> */
> static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
> {
> + struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
> u32 value;
> int ret;
>
> if (!IS_ENABLED(CONFIG_ASUS_WMI))
> return false;
>
> + if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
> + dmi_check_system(asus_use_hid_led_dmi_ids)) {
> + hid_info(hdev, "using HID for asus::kbd_backlight\n");
> + return false;
> + }
> +
> ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
> ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
> hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 3f9b6285c9a6..799d928c7d3d 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -1681,7 +1681,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
> goto error;
> }
>
> - if (!kbd_led_read(asus, &led_val, NULL)) {
> + if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
> + pr_info("using asus-wmi for asus::kbd_backlight\n");
> asus->kbd_led_wk = led_val;
> asus->kbd_led.name = "asus::kbd_backlight";
> asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
> diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
> index 3eb5cd6773ad..6ba0015e4386 100644
> --- a/include/linux/platform_data/x86/asus-wmi.h
> +++ b/include/linux/platform_data/x86/asus-wmi.h
> @@ -4,6 +4,7 @@
>
> #include <linux/errno.h>
> #include <linux/types.h>
> +#include <linux/dmi.h>
>
> /* WMI Methods */
> #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
> @@ -160,4 +161,48 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
> }
> #endif
>
> +/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */
> +#if IS_ENABLED(CONFIG_ASUS_WMI)
> +bool asus_use_hid_led(void);
> +#else
> +static inline bool asus_use_hid_led(void)
> +{
> + return true;
> +}
> +#endif
> +
> +static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = {
> + {
> + .matches = {
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_BOARD_NAME, "GA403"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_BOARD_NAME, "GU605"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
> + },
> + },
> + NULL,
> +};
> +
> #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */
> --
> 2.45.1
>
>
^ permalink raw reply
* Re: [PATCH v2] Input: ili210x - fix ili251x_read_touch_data() return value
From: Dmitry Torokhov @ 2024-06-07 23:35 UTC (permalink / raw)
To: John Keeping; +Cc: linux-input, linux-kernel
In-Reply-To: <20240523085624.2295988-1-jkeeping@inmusicbrands.com>
On Thu, May 23, 2024 at 09:56:24AM +0100, John Keeping wrote:
> The caller of this function treats all non-zero values as an error, so
> the return value of i2c_master_recv() cannot be returned directly.
>
> This fixes touch reporting when there are more than 6 active touches.
>
> Fixes: ef536abd3afd1 ("Input: ili210x - define and use chip operations structure")
> Signed-off-by: John Keeping <jkeeping@inmusicbrands.com>
Applied, thank you.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: xpad - add support for ASUS ROG RAIKIRI PRO
From: Dmitry Torokhov @ 2024-06-07 23:41 UTC (permalink / raw)
To: Luke D. Jones
Cc: linux-input, vi, maxwell.nguyen, appsforartists, carl.ng,
christophe.jaillet, matt.git, linux-kernel
In-Reply-To: <20240607223722.1170776-1-luke@ljones.dev>
Hi Luke,
On Sat, Jun 08, 2024 at 10:37:22AM +1200, Luke D. Jones wrote:
> Add the VID/PID for ASUS ROG RAIKIRI PRO to
> xpad_device and the VID to xpad_table.
>
> Signed-off-by: Luke D. Jones <luke@ljones.dev>
> ---
> drivers/hid/hid-ids.h | 1 +
> drivers/input/joystick/xpad.c | 1 +
> 2 files changed, 2 insertions(+)
>
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 61d2a21affa2..31c522fa4e87 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -209,6 +209,7 @@
> #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6
> #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30
> #define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6
> +#define USB_DEVICE_ID_ASUSTEK_ROG_RAIKIRI_PAD 0x1abb
> #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe
> #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
> #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
This chunk is not needed, I dropped it and applied the rest.
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index 6fadaddb2b90..3a5af0909233 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
> @@ -209,6 +209,7 @@ static const struct xpad_device {
> { 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 },
> { 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 },
> { 0x0b05, 0x1a38, "ASUS ROG RAIKIRI", 0, XTYPE_XBOXONE },
> + { 0x0b05, 0x1abb, "ASUS ROG RAIKIRI PRO", 0, XTYPE_XBOXONE },
> { 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX },
> { 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX },
> { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
> --
> 2.45.2
>
Thanks.
--
Dmitry
^ permalink raw reply
* [dtor-input:ib/6.9-disable-irq-guard] BUILD SUCCESS c76494768761aef7630e7e0db820ba7b375964da
From: kernel test robot @ 2024-06-08 0:18 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git ib/6.9-disable-irq-guard
branch HEAD: c76494768761aef7630e7e0db820ba7b375964da linux/interrupt.h: allow "guard" notation to disable and reenable IRQ
elapsed time: 1513m
configs tested: 61
configs skipped: 3
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc
alpha allyesconfig gcc
alpha defconfig gcc
arc allnoconfig gcc
arc defconfig gcc
arc randconfig-001-20240608 gcc
arc randconfig-002-20240608 gcc
arm allnoconfig clang
arm defconfig clang
arm randconfig-001-20240608 gcc
arm randconfig-002-20240608 clang
arm64 allnoconfig gcc
arm64 defconfig gcc
csky allnoconfig gcc
csky defconfig gcc
hexagon allmodconfig clang
hexagon allnoconfig clang
hexagon allyesconfig clang
hexagon defconfig clang
i386 allmodconfig gcc
i386 allnoconfig gcc
i386 allyesconfig gcc
i386 defconfig clang
loongarch allnoconfig gcc
loongarch defconfig gcc
m68k allnoconfig gcc
m68k defconfig gcc
microblaze allnoconfig gcc
microblaze defconfig gcc
mips allnoconfig gcc
nios2 allnoconfig gcc
nios2 defconfig gcc
openrisc allnoconfig gcc
openrisc defconfig gcc
parisc allnoconfig gcc
parisc defconfig gcc
parisc64 defconfig gcc
powerpc allnoconfig gcc
riscv allnoconfig gcc
riscv defconfig clang
s390 allnoconfig clang
s390 defconfig clang
sh allmodconfig gcc
sh allnoconfig gcc
sh allyesconfig gcc
sh defconfig gcc
sparc allnoconfig gcc
sparc defconfig gcc
sparc64 defconfig gcc
um allmodconfig clang
um allnoconfig clang
um allyesconfig gcc
um defconfig clang
um i386_defconfig gcc
um x86_64_defconfig clang
x86_64 allnoconfig clang
x86_64 allyesconfig clang
x86_64 defconfig gcc
x86_64 kexec clang
x86_64 rhel-8.3-rust clang
xtensa allnoconfig gcc
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox