All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: "Rafael J . Wysocki" <rafael@kernel.org>,
	Mark Gross <markgross@kernel.org>,
	Andy Shevchenko <andy@kernel.org>, Wolfram Sang <wsa@kernel.org>,
	Mika Westerberg <mika.westerberg@linux.intel.com>,
	Rob Herring <robh@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jirislaby@kernel.org>
Cc: Hans de Goede <hdegoede@redhat.com>, Len Brown <lenb@kernel.org>,
	linux-acpi@vger.kernel.org, platform-driver-x86@vger.kernel.org,
	linux-i2c@vger.kernel.org, Stephan Gerhold <stephan@gerhold.net>,
	linux-serial@vger.kernel.org
Subject: [PATCH 07/12] platform/x86: x86-android-tablets: Add support for instantiating serdevs
Date: Thu, 30 Dec 2021 00:14:26 +0100	[thread overview]
Message-ID: <20211229231431.437982-8-hdegoede@redhat.com> (raw)
In-Reply-To: <20211229231431.437982-1-hdegoede@redhat.com>

Add support for instantiating serdevs, this is necessary on some boards
where the serdev info in the DSDT has issues.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/Kconfig               |   2 +-
 drivers/platform/x86/x86-android-tablets.c | 101 +++++++++++++++++++++
 2 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 56efe336a690..8e55529f285c 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1027,7 +1027,7 @@ config TOUCHSCREEN_DMI
 
 config X86_ANDROID_TABLETS
 	tristate "X86 Android tablet support"
-	depends on I2C && ACPI && GPIOLIB
+	depends on I2C && SERIAL_DEV_BUS && ACPI && GPIOLIB
 	help
 	  X86 tablets which ship with Android as (part of) the factory image
 	  typically have various problems with their DSDTs. The factory kernels
diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets.c
index 4bcad05d4039..5267e57c4fea 100644
--- a/drivers/platform/x86/x86-android-tablets.c
+++ b/drivers/platform/x86/x86-android-tablets.c
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
+#include <linux/serdev.h>
 #include <linux/string.h>
 /* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */
 #include "../../gpio/gpiolib.h"
@@ -127,11 +128,26 @@ struct x86_i2c_client_info {
 	struct x86_acpi_irq_data irq_data;
 };
 
+struct x86_serdev_info {
+	const char *ctrl_hid;
+	const char *ctrl_uid;
+	const char *ctrl_devname;
+	/*
+	 * ATM the serdev core only supports of or ACPI matching; and sofar all
+	 * Android x86 tablets DSDTs have usable serdev nodes, but sometimes
+	 * under the wrong controller. So we just tie the existing serdev ACPI
+	 * node to the right controller.
+	 */
+	const char *serdev_hid;
+};
+
 struct x86_dev_info {
 	const struct x86_i2c_client_info *i2c_client_info;
 	const struct platform_device_info *pdev_info;
+	const struct x86_serdev_info *serdev_info;
 	int i2c_client_count;
 	int pdev_count;
+	int serdev_count;
 };
 
 /*
@@ -273,8 +289,10 @@ MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids);
 
 static int i2c_client_count;
 static int pdev_count;
+static int serdev_count;
 static struct i2c_client **i2c_clients;
 static struct platform_device **pdevs;
+static struct serdev_device **serdevs;
 
 static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
 					     int idx)
@@ -310,10 +328,78 @@ static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info
 	return 0;
 }
 
+static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx)
+{
+	struct acpi_device *ctrl_adev, *serdev_adev;
+	struct serdev_device *serdev;
+	struct device *ctrl_dev;
+	int ret = -ENODEV;
+
+	ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1);
+	if (!ctrl_adev) {
+		pr_err("error could not get %s/%s ctrl adev\n",
+		       info->ctrl_hid, info->ctrl_uid);
+		return -ENODEV;
+	}
+
+	serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1);
+	if (!serdev_adev) {
+		pr_err("error could not get %s serdev adev\n", info->serdev_hid);
+		goto put_ctrl_adev;
+	}
+
+	/* get_first_physical_node() returns a weak ref, no need to put() it */
+	ctrl_dev = acpi_get_first_physical_node(ctrl_adev);
+	if (!ctrl_dev)	{
+		pr_err("error could not get %s/%s ctrl physical dev\n",
+		       info->ctrl_hid, info->ctrl_uid);
+		goto put_serdev_adev;
+	}
+
+	/* ctrl_dev now points to the controller's parent, get the controller */
+	ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname);
+	if (!ctrl_dev) {
+		pr_err("error could not get %s/%s %s ctrl dev\n",
+		       info->ctrl_hid, info->ctrl_uid, info->ctrl_devname);
+		goto put_serdev_adev;
+	}
+
+	serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
+	if (!serdev) {
+		ret = -ENOMEM;
+		goto put_serdev_adev;
+	}
+
+	ACPI_COMPANION_SET(&serdev->dev, serdev_adev);
+	acpi_device_set_enumerated(serdev_adev);
+
+	ret = serdev_device_add(serdev);
+	if (ret) {
+		dev_err(&serdev->dev, "error %d adding serdev\n", ret);
+		serdev_device_put(serdev);
+		goto put_serdev_adev;
+	}
+
+	serdevs[idx] = serdev;
+
+put_serdev_adev:
+	acpi_dev_put(serdev_adev);
+put_ctrl_adev:
+	acpi_dev_put(ctrl_adev);
+	return ret;
+}
+
 static void x86_android_tablet_cleanup(void)
 {
 	int i;
 
+	for (i = 0; i < serdev_count; i++) {
+		if (serdevs[i])
+			serdev_device_remove(serdevs[i]);
+	}
+
+	kfree(serdevs);
+
 	for (i = 0; i < pdev_count; i++)
 		platform_device_unregister(pdevs[i]);
 
@@ -365,6 +451,21 @@ static __init int x86_android_tablet_init(void)
 		}
 	}
 
+	serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL);
+	if (!serdevs) {
+		x86_android_tablet_cleanup();
+		return -ENOMEM;
+	}
+
+	serdev_count = dev_info->serdev_count;
+	for (i = 0; i < serdev_count; i++) {
+		ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i);
+		if (ret < 0) {
+			x86_android_tablet_cleanup();
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
-- 
2.33.1


  parent reply	other threads:[~2021-12-29 23:15 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-29 23:14 [PATCH 00/12] ACPI / pdx86: Add support for x86 Android tablets with broken DSDTs Hans de Goede
2021-12-29 23:14 ` [PATCH 01/12] ACPI / x86: Add acpi_quirk_skip_[i2c_client|serdev]_enumeration() helpers Hans de Goede
2021-12-29 23:14 ` [PATCH 02/12] i2c: acpi: Do not instantiate I2C-clients on boards with known bogus DSDT entries Hans de Goede
2021-12-30 12:03   ` Mika Westerberg
2021-12-30 12:21   ` Wolfram Sang
2021-12-30 12:34     ` Hans de Goede
2021-12-29 23:14 ` [PATCH 03/12] serdev: Do not instantiate serdevs " Hans de Goede
2021-12-30 12:44   ` Greg Kroah-Hartman
2021-12-29 23:14 ` [PATCH 04/12] platform/x86: x86-android-tablets: Don't return -EPROBE_DEFER from a non probe() function Hans de Goede
2021-12-29 23:14 ` [PATCH 05/12] platform/x86: x86-android-tablets: Add support for PMIC interrupts Hans de Goede
2021-12-29 23:14 ` [PATCH 06/12] platform/x86: x86-android-tablets: Add support for instantiating platform-devs Hans de Goede
2021-12-29 23:14 ` Hans de Goede [this message]
2021-12-29 23:14 ` [PATCH 08/12] platform/x86: x86-android-tablets: Add support for registering GPIO lookup tables Hans de Goede
2021-12-29 23:14 ` [PATCH 09/12] platform/x86: x86-android-tablets: Add support for preloading modules Hans de Goede
2021-12-29 23:14 ` [PATCH 10/12] platform/x86: x86-android-tablets: Add Asus TF103C data Hans de Goede
2021-12-29 23:14 ` [PATCH 11/12] platform/x86: x86-android-tablets: Add Asus MeMO Pad 7 ME176C data Hans de Goede
2021-12-29 23:14 ` [PATCH 12/12] platform/x86: x86-android-tablets: Add TM800A550L data Hans de Goede
2021-12-30 11:57 ` [PATCH 00/12] ACPI / pdx86: Add support for x86 Android tablets with broken DSDTs Wolfram Sang
2022-01-03 11:42 ` Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211229231431.437982-8-hdegoede@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=andy@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jirislaby@kernel.org \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=markgross@kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=rafael@kernel.org \
    --cc=robh@kernel.org \
    --cc=stephan@gerhold.net \
    --cc=wsa@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.