[053/108] dm: core: Add a way of overriding the ACPI device path

Message ID 20200126220508.53.I05c1764b12b8c4770c5a0aa9d149c551f9a8fe70@changeid
State New
Headers show
Series
  • RFC: dm: Add programatic generation of ACPI tables
Related show

Commit Message

Simon Glass Jan. 27, 2020, 5:06 a.m.
Some devices such as GPIO need to override the normal path that would be
generated by driver model. Add a device-tree property for this.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 doc/device-tree-bindings/device.txt | 23 +++++++++++++++++++++++
 drivers/core/acpi.c                 | 19 +++++++++++++++++++
 include/dm/acpi.h                   | 13 +++++++++++++
 3 files changed, 55 insertions(+)

Patch

diff --git a/doc/device-tree-bindings/device.txt b/doc/device-tree-bindings/device.txt
index 61ebd7a942..107b17589c 100644
--- a/doc/device-tree-bindings/device.txt
+++ b/doc/device-tree-bindings/device.txt
@@ -16,6 +16,8 @@  U-Boot provides for some optional properties which are documented here.
  - acpi,hid : Contains the string to use as the HID (Human Interface Device)
     identifier _HID
  - acpi,hid-desc-reg-offset : HID register offset (for Human Interface Devices)
+ - acpi,path : Specifies the full ACPI path for a device. This overrides the
+    normal path built from the driver-model hierarchy
  - acpi,probed : Tells U-Boot to add 'linux,probed' to the ACPI tables so that
     Linux will not re-init the device
  - acpi,name : Provides the ACPI name for a device, which is a string consisting
@@ -48,3 +50,24 @@  pcie-a0 at 14,0 {
 		interrupts-extended = <&acpi_gpe 0x3c 0>;
 	};
 };
+
+p2sb: p2sb at d,0 {
+	u-boot,dm-pre-reloc;
+	reg = <0x02006810 0 0 0 0>;
+	compatible = "intel,apl-p2sb";
+	early-regs = <IOMAP_P2SB_BAR 0x100000>;
+	pci,no-autoconfig;
+
+	n {
+		compatible = "intel,apl-pinctrl";
+		u-boot,dm-pre-reloc;
+		intel,p2sb-port-id = <PID_GPIO_N>;
+		acpi,path = "\\_SB.GPO0";
+		gpio_n: gpio-n {
+			compatible = "intel,gpio";
+			u-boot,dm-pre-reloc;
+			gpio-controller;
+			#gpio-cells = <2>;
+			linux-name = "INT3452:00";
+		};
+	};
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
index 762cc40511..65c1fed132 100644
--- a/drivers/core/acpi.c
+++ b/drivers/core/acpi.c
@@ -68,6 +68,25 @@  int acpi_get_name(const struct udevice *dev, char *out_name)
 	return 0;
 }
 
+int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen)
+{
+	const char *path;
+	int ret;
+
+	path = dev_read_string(dev, "acpi,path");
+	if (path) {
+		if (strlen(path) >= maxlen)
+			return -E2BIG;
+		strcpy(out_path, path);
+		return 0;
+	}
+	ret = acpi_device_path(dev, out_path, maxlen);
+	if (ret)
+		return log_msg_ret("dev", ret);
+
+	return 0;
+}
+
 /**
  * acpi_add_item() - Add a new item to the list of data collected
  *
diff --git a/include/dm/acpi.h b/include/dm/acpi.h
index ea3a615f60..2b4e8d7e87 100644
--- a/include/dm/acpi.h
+++ b/include/dm/acpi.h
@@ -172,6 +172,19 @@  int acpi_inject_dsdt(struct acpi_ctx *ctx);
  */
 void acpi_dump_items(bool dump_contents);
 
+/**
+ * acpi_get_path() - Get the full ACPI path for a device
+ *
+ * This checks for any override in the device tree and calls acpi_device_path()
+ * if not
+ *
+ * @dev: Device to check
+ * @out_path: Buffer to place the path in (should be ACPI_PATH_MAX long)
+ * @maxlen: Size of buffer (typically ACPI_PATH_MAX)
+ * @return 0 if OK, -ve on error
+ */
+int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen);
+
 #endif /* __ACPI__ */
 
 #endif