All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Input: i8042 - Add PNP checking hook for Loongson
@ 2022-08-18  4:04 Huacai Chen
  2022-09-16  9:53 ` Huacai Chen
  0 siblings, 1 reply; 4+ messages in thread
From: Huacai Chen @ 2022-08-18  4:04 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen, Dmitry Torokhov
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-input, linux-kernel, Huacai Chen, Jianmin Lv

Add PNP checking related functions for Loongson, so that i8042 driver
can work well under the ACPI firmware with PNP typed keyboard and mouse
configured in DSDT.

Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 drivers/input/serio/i8042-loongsonio.h | 330 +++++++++++++++++++++++++
 drivers/input/serio/i8042.h            |   2 +
 2 files changed, 332 insertions(+)
 create mode 100644 drivers/input/serio/i8042-loongsonio.h

diff --git a/drivers/input/serio/i8042-loongsonio.h b/drivers/input/serio/i8042-loongsonio.h
new file mode 100644
index 000000000000..2ea83b14f13d
--- /dev/null
+++ b/drivers/input/serio/i8042-loongsonio.h
@@ -0,0 +1,330 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * i8042-loongsonio.h
+ *
+ * Copyright (C) 2020 Loongson Technology Corporation Limited
+ * Author: Jianmin Lv <lvjianmin@loongson.cn>
+ *         Huacai Chen <chenhuacai@loongson.cn>
+ */
+
+#ifndef _I8042_LOONGSONIO_H
+#define _I8042_LOONGSONIO_H
+
+/*
+ * Names.
+ */
+
+#define I8042_KBD_PHYS_DESC "isa0060/serio0"
+#define I8042_AUX_PHYS_DESC "isa0060/serio1"
+#define I8042_MUX_PHYS_DESC "isa0060/serio%d"
+
+/*
+ * IRQs.
+ */
+#define I8042_MAP_IRQ(x)	(x)
+
+#define I8042_KBD_IRQ	i8042_kbd_irq
+#define I8042_AUX_IRQ	i8042_aux_irq
+
+static int i8042_kbd_irq;
+static int i8042_aux_irq;
+
+/*
+ * Register numbers.
+ */
+
+#define I8042_COMMAND_REG	i8042_command_reg
+#define I8042_STATUS_REG	i8042_command_reg
+#define I8042_DATA_REG		i8042_data_reg
+
+static int i8042_command_reg = 0x64;
+static int i8042_data_reg = 0x60;
+
+
+static inline int i8042_read_data(void)
+{
+	return inb(I8042_DATA_REG);
+}
+
+static inline int i8042_read_status(void)
+{
+	return inb(I8042_STATUS_REG);
+}
+
+static inline void i8042_write_data(int val)
+{
+	outb(val, I8042_DATA_REG);
+}
+
+static inline void i8042_write_command(int val)
+{
+	outb(val, I8042_COMMAND_REG);
+}
+
+#ifdef CONFIG_PNP
+#include <linux/pnp.h>
+
+static bool i8042_pnp_kbd_registered;
+static unsigned int i8042_pnp_kbd_devices;
+static bool i8042_pnp_aux_registered;
+static unsigned int i8042_pnp_aux_devices;
+
+static int i8042_pnp_command_reg;
+static int i8042_pnp_data_reg;
+static int i8042_pnp_kbd_irq;
+static int i8042_pnp_aux_irq;
+
+static char i8042_pnp_kbd_name[32];
+static char i8042_pnp_aux_name[32];
+
+static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size)
+{
+	strlcpy(dst, "PNP:", dst_size);
+
+	while (id) {
+		strlcat(dst, " ", dst_size);
+		strlcat(dst, id->id, dst_size);
+		id = id->next;
+	}
+}
+
+static int i8042_pnp_kbd_probe(struct pnp_dev *dev,
+		const struct pnp_device_id *did)
+{
+	if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
+		i8042_pnp_data_reg = pnp_port_start(dev, 0);
+
+	if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
+		i8042_pnp_command_reg = pnp_port_start(dev, 1);
+
+	if (pnp_irq_valid(dev, 0))
+		i8042_pnp_kbd_irq = pnp_irq(dev, 0);
+
+	strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name));
+	if (strlen(pnp_dev_name(dev))) {
+		strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
+		strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev),
+				sizeof(i8042_pnp_kbd_name));
+	}
+	i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id,
+			       sizeof(i8042_kbd_firmware_id));
+
+	/* Keyboard ports are always supposed to be wakeup-enabled */
+	device_set_wakeup_enable(&dev->dev, true);
+
+	i8042_pnp_kbd_devices++;
+	return 0;
+}
+
+static int i8042_pnp_aux_probe(struct pnp_dev *dev,
+		const struct pnp_device_id *did)
+{
+	if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
+		i8042_pnp_data_reg = pnp_port_start(dev, 0);
+
+	if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
+		i8042_pnp_command_reg = pnp_port_start(dev, 1);
+
+	if (pnp_irq_valid(dev, 0))
+		i8042_pnp_aux_irq = pnp_irq(dev, 0);
+
+	strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name));
+	if (strlen(pnp_dev_name(dev))) {
+		strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
+		strlcat(i8042_pnp_aux_name, pnp_dev_name(dev),
+				sizeof(i8042_pnp_aux_name));
+	}
+	i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id,
+			       sizeof(i8042_aux_firmware_id));
+
+	i8042_pnp_aux_devices++;
+	return 0;
+}
+
+static const struct pnp_device_id pnp_kbd_devids[] = {
+	{ .id = "PNP0300", .driver_data = 0 },
+	{ .id = "PNP0301", .driver_data = 0 },
+	{ .id = "PNP0302", .driver_data = 0 },
+	{ .id = "PNP0303", .driver_data = 0 },
+	{ .id = "PNP0304", .driver_data = 0 },
+	{ .id = "PNP0305", .driver_data = 0 },
+	{ .id = "PNP0306", .driver_data = 0 },
+	{ .id = "PNP0309", .driver_data = 0 },
+	{ .id = "PNP030a", .driver_data = 0 },
+	{ .id = "PNP030b", .driver_data = 0 },
+	{ .id = "PNP0320", .driver_data = 0 },
+	{ .id = "PNP0343", .driver_data = 0 },
+	{ .id = "PNP0344", .driver_data = 0 },
+	{ .id = "PNP0345", .driver_data = 0 },
+	{ .id = "CPQA0D7", .driver_data = 0 },
+	{ .id = "", },
+};
+MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids);
+
+static struct pnp_driver i8042_pnp_kbd_driver = {
+	.name           = "i8042 kbd",
+	.id_table       = pnp_kbd_devids,
+	.probe          = i8042_pnp_kbd_probe,
+	.driver         = {
+		.probe_type = PROBE_FORCE_SYNCHRONOUS,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static const struct pnp_device_id pnp_aux_devids[] = {
+	{ .id = "AUI0200", .driver_data = 0 },
+	{ .id = "FJC6000", .driver_data = 0 },
+	{ .id = "FJC6001", .driver_data = 0 },
+	{ .id = "PNP0f03", .driver_data = 0 },
+	{ .id = "PNP0f0b", .driver_data = 0 },
+	{ .id = "PNP0f0e", .driver_data = 0 },
+	{ .id = "PNP0f12", .driver_data = 0 },
+	{ .id = "PNP0f13", .driver_data = 0 },
+	{ .id = "PNP0f19", .driver_data = 0 },
+	{ .id = "PNP0f1c", .driver_data = 0 },
+	{ .id = "SYN0801", .driver_data = 0 },
+	{ .id = "", },
+};
+MODULE_DEVICE_TABLE(pnp, pnp_aux_devids);
+
+static struct pnp_driver i8042_pnp_aux_driver = {
+	.name           = "i8042 aux",
+	.id_table       = pnp_aux_devids,
+	.probe          = i8042_pnp_aux_probe,
+	.driver         = {
+		.probe_type = PROBE_FORCE_SYNCHRONOUS,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static void i8042_pnp_exit(void)
+{
+	if (i8042_pnp_kbd_registered) {
+		i8042_pnp_kbd_registered = false;
+		pnp_unregister_driver(&i8042_pnp_kbd_driver);
+	}
+
+	if (i8042_pnp_aux_registered) {
+		i8042_pnp_aux_registered = false;
+		pnp_unregister_driver(&i8042_pnp_aux_driver);
+	}
+}
+#ifdef CONFIG_ACPI
+#include <linux/acpi.h>
+#endif
+static int __init i8042_pnp_init(void)
+{
+	char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
+	bool pnp_data_busted = false;
+	int err;
+
+	if (i8042_nopnp) {
+		pr_info("PNP detection disabled\n");
+		return 0;
+	}
+
+	err = pnp_register_driver(&i8042_pnp_kbd_driver);
+	if (!err)
+		i8042_pnp_kbd_registered = true;
+
+	err = pnp_register_driver(&i8042_pnp_aux_driver);
+	if (!err)
+		i8042_pnp_aux_registered = true;
+
+	if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) {
+		i8042_pnp_exit();
+		pr_info("PNP: No PS/2 controller found.\n");
+#ifdef CONFIG_ACPI
+		if (acpi_disabled == 0)
+			return -ENODEV;
+#endif
+		pr_info("Probing ports directly.\n");
+		return 0;
+	}
+
+	if (i8042_pnp_kbd_devices)
+		snprintf(kbd_irq_str, sizeof(kbd_irq_str),
+			"%d", i8042_pnp_kbd_irq);
+	if (i8042_pnp_aux_devices)
+		snprintf(aux_irq_str, sizeof(aux_irq_str),
+			"%d", i8042_pnp_aux_irq);
+
+	pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
+		i8042_pnp_kbd_name,
+		(i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
+		i8042_pnp_aux_name,
+		i8042_pnp_data_reg, i8042_pnp_command_reg,
+		kbd_irq_str,
+		(i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
+		aux_irq_str);
+
+	if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
+	      i8042_pnp_data_reg != i8042_data_reg) ||
+	    !i8042_pnp_data_reg) {
+		pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
+			i8042_pnp_data_reg, i8042_data_reg);
+		i8042_pnp_data_reg = i8042_data_reg;
+		pnp_data_busted = true;
+	}
+
+	if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
+	      i8042_pnp_command_reg != i8042_command_reg) ||
+	    !i8042_pnp_command_reg) {
+		pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n",
+			i8042_pnp_command_reg, i8042_command_reg);
+		i8042_pnp_command_reg = i8042_command_reg;
+		pnp_data_busted = true;
+	}
+
+	if (!i8042_nokbd && !i8042_pnp_kbd_irq) {
+		pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n",
+			i8042_kbd_irq);
+		i8042_pnp_kbd_irq = i8042_kbd_irq;
+		pnp_data_busted = true;
+	}
+
+	if (!i8042_noaux && !i8042_pnp_aux_irq) {
+		if (!pnp_data_busted && i8042_pnp_kbd_irq) {
+			pr_warn("PNP: PS/2 appears to have AUX port disabled, "
+				"if this is incorrect please boot with i8042.nopnp\n");
+			i8042_noaux = true;
+		} else {
+			pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n",
+				i8042_aux_irq);
+			i8042_pnp_aux_irq = i8042_aux_irq;
+		}
+	}
+
+	i8042_data_reg = i8042_pnp_data_reg;
+	i8042_command_reg = i8042_pnp_command_reg;
+	i8042_kbd_irq = i8042_pnp_kbd_irq;
+	i8042_aux_irq = i8042_pnp_aux_irq;
+
+	return 0;
+}
+
+#else  /* !CONFIG_PNP */
+static inline int i8042_pnp_init(void) { return 0; }
+static inline void i8042_pnp_exit(void) { }
+#endif /* CONFIG_PNP */
+
+static int __init i8042_platform_init(void)
+{
+	int retval;
+
+	i8042_kbd_irq = I8042_MAP_IRQ(1);
+	i8042_aux_irq = I8042_MAP_IRQ(12);
+
+	retval = i8042_pnp_init();
+	if (retval)
+		return retval;
+
+	return retval;
+}
+
+static inline void i8042_platform_exit(void)
+{
+	i8042_pnp_exit();
+}
+
+#endif /* _I8042_LOONGSONIO_H */
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index 55381783dc82..166bd69841cf 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -19,6 +19,8 @@
 #include "i8042-snirm.h"
 #elif defined(CONFIG_SPARC)
 #include "i8042-sparcio.h"
+#elif defined(CONFIG_MACH_LOONGSON64)
+#include "i8042-loongsonio.h"
 #elif defined(CONFIG_X86) || defined(CONFIG_IA64)
 #include "i8042-x86ia64io.h"
 #else
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] Input: i8042 - Add PNP checking hook for Loongson
  2022-08-18  4:04 [PATCH] Input: i8042 - Add PNP checking hook for Loongson Huacai Chen
@ 2022-09-16  9:53 ` Huacai Chen
  2022-09-16 10:16   ` Arnd Bergmann
  0 siblings, 1 reply; 4+ messages in thread
From: Huacai Chen @ 2022-09-16  9:53 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Arnd Bergmann, Dmitry Torokhov, loongarch, linux-arch,
	Xuefeng Li, Guo Ren, Xuerui Wang, Jiaxun Yang, linux-input, LKML,
	Jianmin Lv

Ping?

On Thu, Aug 18, 2022 at 12:04 PM Huacai Chen <chenhuacai@loongson.cn> wrote:
>
> Add PNP checking related functions for Loongson, so that i8042 driver
> can work well under the ACPI firmware with PNP typed keyboard and mouse
> configured in DSDT.
>
> Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> ---
>  drivers/input/serio/i8042-loongsonio.h | 330 +++++++++++++++++++++++++
>  drivers/input/serio/i8042.h            |   2 +
>  2 files changed, 332 insertions(+)
>  create mode 100644 drivers/input/serio/i8042-loongsonio.h
>
> diff --git a/drivers/input/serio/i8042-loongsonio.h b/drivers/input/serio/i8042-loongsonio.h
> new file mode 100644
> index 000000000000..2ea83b14f13d
> --- /dev/null
> +++ b/drivers/input/serio/i8042-loongsonio.h
> @@ -0,0 +1,330 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * i8042-loongsonio.h
> + *
> + * Copyright (C) 2020 Loongson Technology Corporation Limited
> + * Author: Jianmin Lv <lvjianmin@loongson.cn>
> + *         Huacai Chen <chenhuacai@loongson.cn>
> + */
> +
> +#ifndef _I8042_LOONGSONIO_H
> +#define _I8042_LOONGSONIO_H
> +
> +/*
> + * Names.
> + */
> +
> +#define I8042_KBD_PHYS_DESC "isa0060/serio0"
> +#define I8042_AUX_PHYS_DESC "isa0060/serio1"
> +#define I8042_MUX_PHYS_DESC "isa0060/serio%d"
> +
> +/*
> + * IRQs.
> + */
> +#define I8042_MAP_IRQ(x)       (x)
> +
> +#define I8042_KBD_IRQ  i8042_kbd_irq
> +#define I8042_AUX_IRQ  i8042_aux_irq
> +
> +static int i8042_kbd_irq;
> +static int i8042_aux_irq;
> +
> +/*
> + * Register numbers.
> + */
> +
> +#define I8042_COMMAND_REG      i8042_command_reg
> +#define I8042_STATUS_REG       i8042_command_reg
> +#define I8042_DATA_REG         i8042_data_reg
> +
> +static int i8042_command_reg = 0x64;
> +static int i8042_data_reg = 0x60;
> +
> +
> +static inline int i8042_read_data(void)
> +{
> +       return inb(I8042_DATA_REG);
> +}
> +
> +static inline int i8042_read_status(void)
> +{
> +       return inb(I8042_STATUS_REG);
> +}
> +
> +static inline void i8042_write_data(int val)
> +{
> +       outb(val, I8042_DATA_REG);
> +}
> +
> +static inline void i8042_write_command(int val)
> +{
> +       outb(val, I8042_COMMAND_REG);
> +}
> +
> +#ifdef CONFIG_PNP
> +#include <linux/pnp.h>
> +
> +static bool i8042_pnp_kbd_registered;
> +static unsigned int i8042_pnp_kbd_devices;
> +static bool i8042_pnp_aux_registered;
> +static unsigned int i8042_pnp_aux_devices;
> +
> +static int i8042_pnp_command_reg;
> +static int i8042_pnp_data_reg;
> +static int i8042_pnp_kbd_irq;
> +static int i8042_pnp_aux_irq;
> +
> +static char i8042_pnp_kbd_name[32];
> +static char i8042_pnp_aux_name[32];
> +
> +static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size)
> +{
> +       strlcpy(dst, "PNP:", dst_size);
> +
> +       while (id) {
> +               strlcat(dst, " ", dst_size);
> +               strlcat(dst, id->id, dst_size);
> +               id = id->next;
> +       }
> +}
> +
> +static int i8042_pnp_kbd_probe(struct pnp_dev *dev,
> +               const struct pnp_device_id *did)
> +{
> +       if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
> +               i8042_pnp_data_reg = pnp_port_start(dev, 0);
> +
> +       if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
> +               i8042_pnp_command_reg = pnp_port_start(dev, 1);
> +
> +       if (pnp_irq_valid(dev, 0))
> +               i8042_pnp_kbd_irq = pnp_irq(dev, 0);
> +
> +       strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name));
> +       if (strlen(pnp_dev_name(dev))) {
> +               strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
> +               strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev),
> +                               sizeof(i8042_pnp_kbd_name));
> +       }
> +       i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id,
> +                              sizeof(i8042_kbd_firmware_id));
> +
> +       /* Keyboard ports are always supposed to be wakeup-enabled */
> +       device_set_wakeup_enable(&dev->dev, true);
> +
> +       i8042_pnp_kbd_devices++;
> +       return 0;
> +}
> +
> +static int i8042_pnp_aux_probe(struct pnp_dev *dev,
> +               const struct pnp_device_id *did)
> +{
> +       if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
> +               i8042_pnp_data_reg = pnp_port_start(dev, 0);
> +
> +       if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
> +               i8042_pnp_command_reg = pnp_port_start(dev, 1);
> +
> +       if (pnp_irq_valid(dev, 0))
> +               i8042_pnp_aux_irq = pnp_irq(dev, 0);
> +
> +       strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name));
> +       if (strlen(pnp_dev_name(dev))) {
> +               strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
> +               strlcat(i8042_pnp_aux_name, pnp_dev_name(dev),
> +                               sizeof(i8042_pnp_aux_name));
> +       }
> +       i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id,
> +                              sizeof(i8042_aux_firmware_id));
> +
> +       i8042_pnp_aux_devices++;
> +       return 0;
> +}
> +
> +static const struct pnp_device_id pnp_kbd_devids[] = {
> +       { .id = "PNP0300", .driver_data = 0 },
> +       { .id = "PNP0301", .driver_data = 0 },
> +       { .id = "PNP0302", .driver_data = 0 },
> +       { .id = "PNP0303", .driver_data = 0 },
> +       { .id = "PNP0304", .driver_data = 0 },
> +       { .id = "PNP0305", .driver_data = 0 },
> +       { .id = "PNP0306", .driver_data = 0 },
> +       { .id = "PNP0309", .driver_data = 0 },
> +       { .id = "PNP030a", .driver_data = 0 },
> +       { .id = "PNP030b", .driver_data = 0 },
> +       { .id = "PNP0320", .driver_data = 0 },
> +       { .id = "PNP0343", .driver_data = 0 },
> +       { .id = "PNP0344", .driver_data = 0 },
> +       { .id = "PNP0345", .driver_data = 0 },
> +       { .id = "CPQA0D7", .driver_data = 0 },
> +       { .id = "", },
> +};
> +MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids);
> +
> +static struct pnp_driver i8042_pnp_kbd_driver = {
> +       .name           = "i8042 kbd",
> +       .id_table       = pnp_kbd_devids,
> +       .probe          = i8042_pnp_kbd_probe,
> +       .driver         = {
> +               .probe_type = PROBE_FORCE_SYNCHRONOUS,
> +               .suppress_bind_attrs = true,
> +       },
> +};
> +
> +static const struct pnp_device_id pnp_aux_devids[] = {
> +       { .id = "AUI0200", .driver_data = 0 },
> +       { .id = "FJC6000", .driver_data = 0 },
> +       { .id = "FJC6001", .driver_data = 0 },
> +       { .id = "PNP0f03", .driver_data = 0 },
> +       { .id = "PNP0f0b", .driver_data = 0 },
> +       { .id = "PNP0f0e", .driver_data = 0 },
> +       { .id = "PNP0f12", .driver_data = 0 },
> +       { .id = "PNP0f13", .driver_data = 0 },
> +       { .id = "PNP0f19", .driver_data = 0 },
> +       { .id = "PNP0f1c", .driver_data = 0 },
> +       { .id = "SYN0801", .driver_data = 0 },
> +       { .id = "", },
> +};
> +MODULE_DEVICE_TABLE(pnp, pnp_aux_devids);
> +
> +static struct pnp_driver i8042_pnp_aux_driver = {
> +       .name           = "i8042 aux",
> +       .id_table       = pnp_aux_devids,
> +       .probe          = i8042_pnp_aux_probe,
> +       .driver         = {
> +               .probe_type = PROBE_FORCE_SYNCHRONOUS,
> +               .suppress_bind_attrs = true,
> +       },
> +};
> +
> +static void i8042_pnp_exit(void)
> +{
> +       if (i8042_pnp_kbd_registered) {
> +               i8042_pnp_kbd_registered = false;
> +               pnp_unregister_driver(&i8042_pnp_kbd_driver);
> +       }
> +
> +       if (i8042_pnp_aux_registered) {
> +               i8042_pnp_aux_registered = false;
> +               pnp_unregister_driver(&i8042_pnp_aux_driver);
> +       }
> +}
> +#ifdef CONFIG_ACPI
> +#include <linux/acpi.h>
> +#endif
> +static int __init i8042_pnp_init(void)
> +{
> +       char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
> +       bool pnp_data_busted = false;
> +       int err;
> +
> +       if (i8042_nopnp) {
> +               pr_info("PNP detection disabled\n");
> +               return 0;
> +       }
> +
> +       err = pnp_register_driver(&i8042_pnp_kbd_driver);
> +       if (!err)
> +               i8042_pnp_kbd_registered = true;
> +
> +       err = pnp_register_driver(&i8042_pnp_aux_driver);
> +       if (!err)
> +               i8042_pnp_aux_registered = true;
> +
> +       if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) {
> +               i8042_pnp_exit();
> +               pr_info("PNP: No PS/2 controller found.\n");
> +#ifdef CONFIG_ACPI
> +               if (acpi_disabled == 0)
> +                       return -ENODEV;
> +#endif
> +               pr_info("Probing ports directly.\n");
> +               return 0;
> +       }
> +
> +       if (i8042_pnp_kbd_devices)
> +               snprintf(kbd_irq_str, sizeof(kbd_irq_str),
> +                       "%d", i8042_pnp_kbd_irq);
> +       if (i8042_pnp_aux_devices)
> +               snprintf(aux_irq_str, sizeof(aux_irq_str),
> +                       "%d", i8042_pnp_aux_irq);
> +
> +       pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
> +               i8042_pnp_kbd_name,
> +               (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
> +               i8042_pnp_aux_name,
> +               i8042_pnp_data_reg, i8042_pnp_command_reg,
> +               kbd_irq_str,
> +               (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
> +               aux_irq_str);
> +
> +       if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
> +             i8042_pnp_data_reg != i8042_data_reg) ||
> +           !i8042_pnp_data_reg) {
> +               pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
> +                       i8042_pnp_data_reg, i8042_data_reg);
> +               i8042_pnp_data_reg = i8042_data_reg;
> +               pnp_data_busted = true;
> +       }
> +
> +       if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
> +             i8042_pnp_command_reg != i8042_command_reg) ||
> +           !i8042_pnp_command_reg) {
> +               pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n",
> +                       i8042_pnp_command_reg, i8042_command_reg);
> +               i8042_pnp_command_reg = i8042_command_reg;
> +               pnp_data_busted = true;
> +       }
> +
> +       if (!i8042_nokbd && !i8042_pnp_kbd_irq) {
> +               pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n",
> +                       i8042_kbd_irq);
> +               i8042_pnp_kbd_irq = i8042_kbd_irq;
> +               pnp_data_busted = true;
> +       }
> +
> +       if (!i8042_noaux && !i8042_pnp_aux_irq) {
> +               if (!pnp_data_busted && i8042_pnp_kbd_irq) {
> +                       pr_warn("PNP: PS/2 appears to have AUX port disabled, "
> +                               "if this is incorrect please boot with i8042.nopnp\n");
> +                       i8042_noaux = true;
> +               } else {
> +                       pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n",
> +                               i8042_aux_irq);
> +                       i8042_pnp_aux_irq = i8042_aux_irq;
> +               }
> +       }
> +
> +       i8042_data_reg = i8042_pnp_data_reg;
> +       i8042_command_reg = i8042_pnp_command_reg;
> +       i8042_kbd_irq = i8042_pnp_kbd_irq;
> +       i8042_aux_irq = i8042_pnp_aux_irq;
> +
> +       return 0;
> +}
> +
> +#else  /* !CONFIG_PNP */
> +static inline int i8042_pnp_init(void) { return 0; }
> +static inline void i8042_pnp_exit(void) { }
> +#endif /* CONFIG_PNP */
> +
> +static int __init i8042_platform_init(void)
> +{
> +       int retval;
> +
> +       i8042_kbd_irq = I8042_MAP_IRQ(1);
> +       i8042_aux_irq = I8042_MAP_IRQ(12);
> +
> +       retval = i8042_pnp_init();
> +       if (retval)
> +               return retval;
> +
> +       return retval;
> +}
> +
> +static inline void i8042_platform_exit(void)
> +{
> +       i8042_pnp_exit();
> +}
> +
> +#endif /* _I8042_LOONGSONIO_H */
> diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
> index 55381783dc82..166bd69841cf 100644
> --- a/drivers/input/serio/i8042.h
> +++ b/drivers/input/serio/i8042.h
> @@ -19,6 +19,8 @@
>  #include "i8042-snirm.h"
>  #elif defined(CONFIG_SPARC)
>  #include "i8042-sparcio.h"
> +#elif defined(CONFIG_MACH_LOONGSON64)
> +#include "i8042-loongsonio.h"
>  #elif defined(CONFIG_X86) || defined(CONFIG_IA64)
>  #include "i8042-x86ia64io.h"
>  #else
> --
> 2.31.1
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Input: i8042 - Add PNP checking hook for Loongson
  2022-09-16  9:53 ` Huacai Chen
@ 2022-09-16 10:16   ` Arnd Bergmann
  2022-09-16 15:04     ` Huacai Chen
  0 siblings, 1 reply; 4+ messages in thread
From: Arnd Bergmann @ 2022-09-16 10:16 UTC (permalink / raw)
  To: Huacai Chen, Huacai Chen
  Cc: Dmitry Torokhov, loongarch, Linux-Arch, Xuefeng Li, guoren,
	WANG Xuerui, Jiaxun Yang, linux-input, LKML, Jianmin Lv

On Fri, Sep 16, 2022, at 11:53 AM, Huacai Chen wrote:
> Ping?
>
> On Thu, Aug 18, 2022 at 12:04 PM Huacai Chen <chenhuacai@loongson.cn> wrote:
>>
>> Add PNP checking related functions for Loongson, so that i8042 driver
>> can work well under the ACPI firmware with PNP typed keyboard and mouse
>> configured in DSDT.
>>
>> Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
>> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
>> ---
>>  drivers/input/serio/i8042-loongsonio.h | 330 +++++++++++++++++++++++++
>>  drivers/input/serio/i8042.h            |   2 +
>>  2 files changed, 332 insertions(+)

This looks like you are just duplicating code from
i8042-x86ia64io.h. Can't you just use that version
directly?

      Arnd

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Input: i8042 - Add PNP checking hook for Loongson
  2022-09-16 10:16   ` Arnd Bergmann
@ 2022-09-16 15:04     ` Huacai Chen
  0 siblings, 0 replies; 4+ messages in thread
From: Huacai Chen @ 2022-09-16 15:04 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Huacai Chen, Dmitry Torokhov, loongarch, Linux-Arch, Xuefeng Li,
	guoren, WANG Xuerui, Jiaxun Yang, linux-input, LKML, Jianmin Lv

Hi, Arnd,

On Fri, Sep 16, 2022 at 6:16 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Fri, Sep 16, 2022, at 11:53 AM, Huacai Chen wrote:
> > Ping?
> >
> > On Thu, Aug 18, 2022 at 12:04 PM Huacai Chen <chenhuacai@loongson.cn> wrote:
> >>
> >> Add PNP checking related functions for Loongson, so that i8042 driver
> >> can work well under the ACPI firmware with PNP typed keyboard and mouse
> >> configured in DSDT.
> >>
> >> Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
> >> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> >> ---
> >>  drivers/input/serio/i8042-loongsonio.h | 330 +++++++++++++++++++++++++
> >>  drivers/input/serio/i8042.h            |   2 +
> >>  2 files changed, 332 insertions(+)
>
> This looks like you are just duplicating code from
> i8042-x86ia64io.h. Can't you just use that version
> directly?
OK, I will rename i8042-x86ia64io.h to i8042-acpiio.h and use it for LoongArch.

Huacai
>
>       Arnd

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-09-16 15:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-18  4:04 [PATCH] Input: i8042 - Add PNP checking hook for Loongson Huacai Chen
2022-09-16  9:53 ` Huacai Chen
2022-09-16 10:16   ` Arnd Bergmann
2022-09-16 15:04     ` Huacai Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.