Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH 4/5] HID: intel-ish-hid: Implement loading firmware from host feature
From: Zhang Lixu @ 2024-05-06  1:30 UTC (permalink / raw)
  To: linux-input, srinivas.pandruvada, jikos, benjamin.tissoires; +Cc: lixu.zhang
In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com>

Starting from the Lunar Lake generation, the ISH firmware has been
divided into two components for better space optimization and increased
flexibility. These components include a bootloader that is integrated
into the BIOS, and a main firmware that is stored within the operating
system's file system.

Introduce support for loading ISH main firmware from host. This feature is
applicable for Lunar Lake and later generation.

Current intel-ishtp-loader, is designed for Chrome OS based systems which
uses core boot and has different firmware loading method. For non chrome
systems the ISH firmware loading uses different method.

Key differences include:
1. The new method utilizes ISHTP capability/fixed client to enumerate the
firmware loader function. It does not require a connection or flow control,
unlike the method used in Chrome OS, which is enumerated as an ISHTP
dynamic client driver, necessitating connect/disconnect operations and flow
control.

2. The new method employs a table to describe firmware fragments, which are
sent to ISH in a single operation. Conversely, the Chrome OS method sends
firmware fragments in multiple operations within a loop, sending only one
fragment at a time.

Additionally, address potential error scenarios to ensure graceful failure
handling.
- Firmware Not Found: Triggers if request_firmware() fails, leaving ISH in
  a waiting state.
  Recovery: Re-insmod the ISH drivers to retry.

- DMA Buffer Allocation Failure: Occurs during prepare_dma_bufs(), leading
  to ISH waiting state. Allocated resources are released.
  Recovery: Re-insmod the ISH drivers to retry.

- Incorrect Firmware Image: Causes ISH to refuse loading after three failed
  attempts.
  Recovery: A platform reset is required.

Please refer to the [Documentation](Documentation/hid/intel-ish-hid.rst)
for the details on flows.

Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 drivers/hid/intel-ish-hid/Makefile          |   1 +
 drivers/hid/intel-ish-hid/ishtp/hbm.c       |  21 ++
 drivers/hid/intel-ish-hid/ishtp/init.c      |   8 +
 drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h |  11 +
 drivers/hid/intel-ish-hid/ishtp/loader.c    | 275 ++++++++++++++++++++
 drivers/hid/intel-ish-hid/ishtp/loader.h    | 226 ++++++++++++++++
 6 files changed, 542 insertions(+)
 create mode 100644 drivers/hid/intel-ish-hid/ishtp/loader.c
 create mode 100644 drivers/hid/intel-ish-hid/ishtp/loader.h

diff --git a/drivers/hid/intel-ish-hid/Makefile b/drivers/hid/intel-ish-hid/Makefile
index f0a82b1c7cb9..a927b224cd44 100644
--- a/drivers/hid/intel-ish-hid/Makefile
+++ b/drivers/hid/intel-ish-hid/Makefile
@@ -11,6 +11,7 @@ intel-ishtp-objs += ishtp/client.o
 intel-ishtp-objs += ishtp/bus.o
 intel-ishtp-objs += ishtp/dma-if.o
 intel-ishtp-objs += ishtp/client-buffers.o
+intel-ishtp-objs += ishtp/loader.o
 
 obj-$(CONFIG_INTEL_ISH_HID) += intel-ish-ipc.o
 intel-ish-ipc-objs := ipc/ipc.o
diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.c b/drivers/hid/intel-ish-hid/ishtp/hbm.c
index 9c031a06e4c4..8ee5467127d8 100644
--- a/drivers/hid/intel-ish-hid/ishtp/hbm.c
+++ b/drivers/hid/intel-ish-hid/ishtp/hbm.c
@@ -13,6 +13,7 @@
 #include "ishtp-dev.h"
 #include "hbm.h"
 #include "client.h"
+#include "loader.h"
 
 /**
  * ishtp_hbm_fw_cl_allocate() - Allocate FW clients
@@ -570,6 +571,10 @@ void ishtp_hbm_dispatch(struct ishtp_device *dev,
 			return;
 		}
 
+		/* Start firmware loading process if it has loader capability */
+		if (version_res->host_version_supported & ISHTP_SUPPORT_CAP_LOADER)
+			schedule_work(&dev->work_fw_loader);
+
 		dev->version.major_version = HBM_MAJOR_VERSION;
 		dev->version.minor_version = HBM_MINOR_VERSION;
 		if (dev->dev_state == ISHTP_DEV_INIT_CLIENTS &&
@@ -864,6 +869,20 @@ void	recv_hbm(struct ishtp_device *dev, struct ishtp_msg_hdr *ishtp_hdr)
 	return;
 }
 
+/**
+ * ishtp_loader_recv_msg() - Receive a message from the ISHTP device
+ * @dev: The ISHTP device
+ * @buf: The buffer containing the message
+ */
+static void ishtp_loader_recv_msg(struct ishtp_device *dev, void *buf)
+{
+	if (dev->fw_loader_rx_buf)
+		memcpy(dev->fw_loader_rx_buf, buf, dev->fw_loader_rx_size);
+
+	dev->fw_loader_received = true;
+	wake_up_interruptible(&dev->wait_loader_recvd_msg);
+}
+
 /**
  * recv_fixed_cl_msg() - Receive fixed client message
  * @dev: ISHTP device instance
@@ -890,6 +909,8 @@ void recv_fixed_cl_msg(struct ishtp_device *dev,
 		else
 			dev_err(dev->devc, "unknown fixed client msg [%02X]\n",
 				msg_hdr->cmd);
+	} else if (ishtp_hdr->fw_addr == ISHTP_LOADER_CLIENT_ADDR) {
+		ishtp_loader_recv_msg(dev, rd_msg_buf);
 	}
 }
 
diff --git a/drivers/hid/intel-ish-hid/ishtp/init.c b/drivers/hid/intel-ish-hid/ishtp/init.c
index 02a00cc2dd11..07fdd52e4c5e 100644
--- a/drivers/hid/intel-ish-hid/ishtp/init.c
+++ b/drivers/hid/intel-ish-hid/ishtp/init.c
@@ -5,12 +5,14 @@
  * Copyright (c) 2003-2016, Intel Corporation.
  */
 
+#include <linux/devm-helpers.h>
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include "ishtp-dev.h"
 #include "hbm.h"
 #include "client.h"
+#include "loader.h"
 
 /**
  * ishtp_dev_state_str() -Convert to string format
@@ -51,6 +53,8 @@ const char *ishtp_dev_state_str(int state)
  */
 void ishtp_device_init(struct ishtp_device *dev)
 {
+	int ret;
+
 	dev->dev_state = ISHTP_DEV_INITIALIZING;
 	INIT_LIST_HEAD(&dev->cl_list);
 	INIT_LIST_HEAD(&dev->device_list);
@@ -59,6 +63,7 @@ void ishtp_device_init(struct ishtp_device *dev)
 	spin_lock_init(&dev->rd_msg_spinlock);
 
 	init_waitqueue_head(&dev->wait_hbm_recvd_msg);
+	init_waitqueue_head(&dev->wait_loader_recvd_msg);
 	spin_lock_init(&dev->read_list_spinlock);
 	spin_lock_init(&dev->device_lock);
 	spin_lock_init(&dev->device_list_lock);
@@ -76,6 +81,9 @@ void ishtp_device_init(struct ishtp_device *dev)
 
 	INIT_LIST_HEAD(&dev->read_list.list);
 
+	ret = devm_work_autocancel(dev->devc, &dev->work_fw_loader, ishtp_loader_work);
+	if (ret)
+		dev_err_probe(dev->devc, ret, "Failed to initialise FW loader work\n");
 }
 EXPORT_SYMBOL(ishtp_device_init);
 
diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
index ed294bf0bc8f..181838c3d7ac 100644
--- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
+++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
@@ -164,6 +164,17 @@ struct ishtp_device {
 	struct hbm_version version;
 	int transfer_path; /* Choice of transfer path: IPC or DMA */
 
+	/* work structure for scheduling firmware loading tasks */
+	struct work_struct work_fw_loader;
+	/* waitq for waiting for command response from the firmware loader */
+	wait_queue_head_t wait_loader_recvd_msg;
+	/* indicating whether a message from the firmware loader has been received */
+	bool fw_loader_received;
+	/* pointer to a buffer for receiving messages from the firmware loader */
+	void *fw_loader_rx_buf;
+	/* size of the buffer pointed to by fw_loader_rx_buf */
+	int fw_loader_rx_size;
+
 	/* ishtp device states */
 	enum ishtp_dev_state dev_state;
 	enum ishtp_hbm_state hbm_state;
diff --git a/drivers/hid/intel-ish-hid/ishtp/loader.c b/drivers/hid/intel-ish-hid/ishtp/loader.c
new file mode 100644
index 000000000000..993f8b390e57
--- /dev/null
+++ b/drivers/hid/intel-ish-hid/ishtp/loader.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ISHTP firmware loader function
+ *
+ * Copyright (c) 2024, Intel Corporation.
+ *
+ * This module implements the functionality to load the main ISH firmware from the host, starting
+ * with the Lunar Lake generation. It leverages a new method that enhances space optimization and
+ * flexibility by dividing the ISH firmware into a bootloader and main firmware.
+ *
+ * Please refer to the [Documentation](Documentation/hid/intel-ish-hid.rst) for the details on
+ * flows.
+ *
+ * Additionally, address potential error scenarios to ensure graceful failure handling.
+ * - Firmware Image Not Found:
+ *   Occurs when `request_firmware()` cannot locate the firmware image. The ISH firmware will
+ *   remain in a state awaiting firmware loading from the host, with no further action from
+ *   the ISHTP driver.
+ *   Recovery: Re-insmod the ISH drivers allows for a retry of the firmware loading from the host.
+ *
+ * - DMA Buffer Allocation Failure:
+ *   This happens if allocating a DMA buffer during `prepare_dma_bufs()` fails. The ISH firmware
+ *   will stay in a waiting state, and the ISHTP driver will release any allocated DMA buffers and
+ *   firmware without further actions.
+ *   Recovery: Re-insmod the ISH drivers allows for a retry of the firmware loading from the host.
+ *
+ * - Incorrect Firmware Image:
+ *   Using an incorrect firmware image will initiate the firmware loading process but will
+ *   eventually be refused by the ISH firmware after three unsuccessful attempts, indicated by
+ *   returning an error code. The ISHTP driver will stop attempting after three tries.
+ *   Recovery: A platform reset is required to retry firmware loading from the host.
+ */
+
+#define dev_fmt(fmt) "ISH loader: " fmt
+
+#include <linux/cacheflush.h>
+#include <linux/container_of.h>
+#include <linux/dev_printk.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/firmware.h>
+#include <linux/gfp_types.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/pfn.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+
+#include "hbm.h"
+#include "loader.h"
+
+/**
+ * loader_write_message() - Write a message to the ISHTP device
+ * @dev: The ISHTP device
+ * @buf: The buffer containing the message
+ * @len: The length of the message
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+static int loader_write_message(struct ishtp_device *dev, void *buf, int len)
+{
+	struct ishtp_msg_hdr ishtp_hdr = {
+		.fw_addr = ISHTP_LOADER_CLIENT_ADDR,
+		.length = len,
+		.msg_complete = 1,
+	};
+
+	dev->fw_loader_received = false;
+
+	return ishtp_write_message(dev, &ishtp_hdr, buf);
+}
+
+/**
+ * loader_xfer_cmd() - Transfer a command to the ISHTP device
+ * @dev: The ISHTP device
+ * @req: The request buffer
+ * @req_len: The length of the request
+ * @resp: The response buffer
+ * @resp_len: The length of the response
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+static int loader_xfer_cmd(struct ishtp_device *dev, void *req, int req_len,
+			   void *resp, int resp_len)
+{
+	struct loader_msg_header *req_hdr = req;
+	struct loader_msg_header *resp_hdr = resp;
+	struct device *devc = dev->devc;
+	int rv;
+
+	dev->fw_loader_rx_buf = resp;
+	dev->fw_loader_rx_size = resp_len;
+
+	rv = loader_write_message(dev, req, req_len);
+	if (rv < 0) {
+		dev_err(devc, "write cmd %u failed:%d\n", req_hdr->command, rv);
+		return rv;
+	}
+
+	/* Wait the ACK */
+	wait_event_interruptible_timeout(dev->wait_loader_recvd_msg, dev->fw_loader_received,
+					 ISHTP_LOADER_TIMEOUT);
+	dev->fw_loader_rx_size = 0;
+	dev->fw_loader_rx_buf = NULL;
+	if (!dev->fw_loader_received) {
+		dev_err(devc, "wait response of cmd %u timeout\n", req_hdr->command);
+		return -ETIMEDOUT;
+	}
+
+	if (!resp_hdr->is_response) {
+		dev_err(devc, "not a response for %u\n", req_hdr->command);
+		return -EBADMSG;
+	}
+
+	if (req_hdr->command != resp_hdr->command) {
+		dev_err(devc, "unexpected cmd response %u:%u\n", req_hdr->command,
+			resp_hdr->command);
+		return -EBADMSG;
+	}
+
+	if (resp_hdr->status) {
+		dev_err(devc, "cmd %u failed %u\n", req_hdr->command, resp_hdr->status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * release_dma_bufs() - Release the DMA buffer for transferring firmware fragments
+ * @dev: The ISHTP device
+ * @fragment: The ISHTP firmware fragment descriptor
+ * @dma_bufs: The array of DMA fragment buffers
+ * @fragment_size: The size of a single DMA fragment
+ */
+static void release_dma_bufs(struct ishtp_device *dev,
+			     struct loader_xfer_dma_fragment *fragment,
+			     void **dma_bufs, u32 fragment_size)
+{
+	int i;
+
+	for (i = 0; i < FRAGMENT_MAX_NUM; i++) {
+		if (dma_bufs[i]) {
+			dma_free_coherent(dev->devc, fragment_size, dma_bufs[i],
+					  fragment->fragment_tbl[i].ddr_adrs);
+			dma_bufs[i] = NULL;
+		}
+	}
+}
+
+/**
+ * prepare_dma_bufs() - Prepare the DMA buffer for transferring firmware fragments
+ * @dev: The ISHTP device
+ * @ish_fw: The ISH firmware
+ * @fragment: The ISHTP firmware fragment descriptor
+ * @dma_bufs: The array of DMA fragment buffers
+ * @fragment_size: The size of a single DMA fragment
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+static int prepare_dma_bufs(struct ishtp_device *dev,
+			    const struct firmware *ish_fw,
+			    struct loader_xfer_dma_fragment *fragment,
+			    void **dma_bufs, u32 fragment_size)
+{
+	u32 offset = 0;
+	int i;
+
+	for (i = 0; i < fragment->fragment_cnt && offset < ish_fw->size; i++) {
+		dma_bufs[i] = dma_alloc_coherent(dev->devc, fragment_size,
+						 &fragment->fragment_tbl[i].ddr_adrs, GFP_KERNEL);
+		if (!dma_bufs[i])
+			return -ENOMEM;
+
+		fragment->fragment_tbl[i].length = clamp(ish_fw->size - offset, 0, fragment_size);
+		fragment->fragment_tbl[i].fw_off = offset;
+		memcpy(dma_bufs[i], ish_fw->data + offset, fragment->fragment_tbl[i].length);
+		clflush_cache_range(dma_bufs[i], fragment_size);
+
+		offset += fragment->fragment_tbl[i].length;
+	}
+
+	return 0;
+}
+
+/**
+ * ishtp_loader_work() - Load the ISHTP firmware
+ * @work: The work structure
+ *
+ * The ISH Loader attempts to load firmware by sending a series of commands
+ * to the ISH device. If a command fails to be acknowledged by the ISH device,
+ * the loader will retry sending the command, up to a maximum of
+ * ISHTP_LOADER_RETRY_TIMES.
+ *
+ * After the maximum number of retries has been reached without success, the
+ * ISH bootloader will return an error status code and will no longer respond
+ * to the driver's commands. This behavior indicates that the ISH Loader has
+ * encountered a critical error during the firmware loading process.
+ *
+ * In such a case, where the ISH bootloader is unresponsive after all retries
+ * have been exhausted, a platform reset is required to restore communication
+ * with the ISH device and to recover from this error state.
+ */
+void ishtp_loader_work(struct work_struct *work)
+{
+	DEFINE_RAW_FLEX(struct loader_xfer_dma_fragment, fragment, fragment_tbl, FRAGMENT_MAX_NUM);
+	struct ishtp_device *dev = container_of(work, struct ishtp_device, work_fw_loader);
+	struct loader_xfer_query query = {
+		.header.command = LOADER_CMD_XFER_QUERY,
+	};
+	struct loader_start start = {
+		.header.command = LOADER_CMD_START,
+	};
+	union loader_recv_message recv_msg;
+	char *filename = dev->driver_data->fw_filename;
+	const struct firmware *ish_fw;
+	void *dma_bufs[FRAGMENT_MAX_NUM] = {};
+	u32 fragment_size;
+	int retry = ISHTP_LOADER_RETRY_TIMES;
+	int rv;
+
+	rv = request_firmware(&ish_fw, filename, dev->devc);
+	if (rv < 0) {
+		dev_err(dev->devc, "request firmware %s failed:%d\n", filename, rv);
+		return;
+	}
+
+	fragment->fragment.header.command = LOADER_CMD_XFER_FRAGMENT;
+	fragment->fragment.xfer_mode = LOADER_XFER_MODE_DMA;
+	fragment->fragment.is_last = 1;
+	fragment->fragment.size = ish_fw->size;
+	/* Calculate the size of a single DMA fragment */
+	fragment_size = PFN_ALIGN(DIV_ROUND_UP(ish_fw->size, FRAGMENT_MAX_NUM));
+	/* Calculate the count of DMA fragments */
+	fragment->fragment_cnt = DIV_ROUND_UP(ish_fw->size, fragment_size);
+
+	rv = prepare_dma_bufs(dev, ish_fw, fragment, dma_bufs, fragment_size);
+	if (rv) {
+		dev_err(dev->devc, "prepare DMA buffer failed.\n");
+		goto out;
+	}
+
+	do {
+		query.image_size = ish_fw->size;
+		rv = loader_xfer_cmd(dev, &query, sizeof(query), recv_msg.raw_data,
+				     sizeof(struct loader_xfer_query_ack));
+		if (rv)
+			continue; /* try again if failed */
+
+		dev_dbg(dev->devc, "ISH Version %u.%u.%u.%u\n",
+			recv_msg.query_ack.version_major,
+			recv_msg.query_ack.version_minor,
+			recv_msg.query_ack.version_hotfix,
+			recv_msg.query_ack.version_build);
+
+		rv = loader_xfer_cmd(dev, fragment,
+				     struct_size(fragment, fragment_tbl, fragment->fragment_cnt),
+				     recv_msg.raw_data, sizeof(struct loader_xfer_fragment_ack));
+		if (rv)
+			continue; /* try again if failed */
+
+		rv = loader_xfer_cmd(dev, &start, sizeof(start), recv_msg.raw_data,
+				     sizeof(struct loader_start_ack));
+		if (rv)
+			continue; /* try again if failed */
+
+		dev_info(dev->devc, "firmware loaded. size:%zu\n", ish_fw->size);
+		break;
+	} while (--retry);
+
+out:
+	release_dma_bufs(dev, fragment, dma_bufs, fragment_size);
+	release_firmware(ish_fw);
+}
diff --git a/drivers/hid/intel-ish-hid/ishtp/loader.h b/drivers/hid/intel-ish-hid/ishtp/loader.h
new file mode 100644
index 000000000000..7aa45ebc3f7b
--- /dev/null
+++ b/drivers/hid/intel-ish-hid/ishtp/loader.h
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * ISHTP firmware loader header
+ *
+ * Copyright (c) 2024, Intel Corporation.
+ */
+
+#ifndef _ISHTP_LOADER_H_
+#define _ISHTP_LOADER_H_
+
+#include <linux/bits.h>
+#include <linux/jiffies.h>
+#include <linux/types.h>
+
+#include "ishtp-dev.h"
+
+struct work_struct;
+
+#define LOADER_MSG_SIZE \
+	(IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr))
+
+/*
+ * ISHTP firmware loader protocol definition
+ */
+#define LOADER_CMD_XFER_QUERY		0	/* SW -> FW */
+#define LOADER_CMD_XFER_FRAGMENT	1	/* SW -> FW */
+#define LOADER_CMD_START		2	/* SW -> FW */
+
+/* Only support DMA mode */
+#define LOADER_XFER_MODE_DMA BIT(0)
+
+/**
+ * struct loader_msg_header - ISHTP firmware loader message header
+ * @command: Command type
+ * @is_response: Indicates if the message is a response
+ * @has_next: Indicates if there is a next message
+ * @reserved: Reserved for future use
+ * @status: Status of the message
+ */
+struct loader_msg_header {
+	__le32 command:7;
+	__le32 is_response:1;
+	__le32 has_next:1;
+	__le32 reserved:15;
+	__le32 status:8;
+};
+
+/**
+ * struct loader_xfer_query - ISHTP firmware loader transfer query packet
+ * @header: Header of the message
+ * @image_size: Size of the image
+ */
+struct loader_xfer_query {
+	struct loader_msg_header header;
+	__le32 image_size;
+};
+
+/**
+ * struct loader_version - ISHTP firmware loader version
+ * @value: Value of the version
+ * @major: Major version
+ * @minor: Minor version
+ * @hotfix: Hotfix version
+ * @build: Build version
+ */
+struct loader_version {
+	union {
+		__le32 value;
+		struct {
+			__u8 major;
+			__u8 minor;
+			__u8 hotfix;
+			__u8 build;
+		};
+	};
+};
+
+/**
+ * struct loader_capability - ISHTP firmware loader capability
+ * @max_fw_image_size: Maximum firmware image size
+ * @support_mode: Support mode
+ * @reserved: Reserved for future use
+ * @platform: Platform
+ * @max_dma_buf_size: Maximum DMA buffer size, multiples of 4096
+ */
+struct loader_capability {
+	__le32 max_fw_image_size;
+	__le16 support_mode;
+	__u8 reserved;
+	__u8 platform;
+	__le32 max_dma_buf_size;
+};
+
+/**
+ * struct loader_xfer_query_ack - ISHTP firmware loader transfer query acknowledgment
+ * @header: Header of the message
+ * @version_major: ISH Major version
+ * @version_minor: ISH Minor version
+ * @version_hotfix: ISH Hotfix version
+ * @version_build: ISH Build version
+ * @protocol_version: Protocol version
+ * @loader_version: Loader version
+ * @capability: Loader capability
+ */
+struct loader_xfer_query_ack {
+	struct loader_msg_header header;
+	__le16 version_major;
+	__le16 version_minor;
+	__le16 version_hotfix;
+	__le16 version_build;
+	__le32 protocol_version;
+	struct loader_version loader_version;
+	struct loader_capability capability;
+};
+
+/**
+ * struct loader_xfer_fragment - ISHTP firmware loader transfer fragment
+ * @header: Header of the message
+ * @xfer_mode: Transfer mode
+ * @offset: Offset
+ * @size: Size
+ * @is_last: Is last
+ */
+struct loader_xfer_fragment {
+	struct loader_msg_header header;
+	__le32 xfer_mode;
+	__le32 offset;
+	__le32 size;
+	__le32 is_last;
+};
+
+/**
+ * struct loader_xfer_fragment_ack - ISHTP firmware loader transfer fragment acknowledgment
+ * @header: Header of the message
+ */
+struct loader_xfer_fragment_ack {
+	struct loader_msg_header header;
+};
+
+/**
+ * struct fragment_dscrpt - ISHTP firmware loader fragment descriptor
+ * @ddr_adrs: The address in host DDR
+ * @fw_off: The offset of the fragment in the fw image
+ * @length: The length of the fragment
+ */
+struct fragment_dscrpt {
+	__le64 ddr_adrs;
+	__le32 fw_off;
+	__le32 length;
+};
+
+#define FRAGMENT_MAX_NUM \
+	((LOADER_MSG_SIZE - sizeof(struct loader_xfer_dma_fragment)) / \
+	 sizeof(struct fragment_dscrpt))
+
+/**
+ * struct loader_xfer_dma_fragment - ISHTP firmware loader transfer DMA fragment
+ * @fragment: Fragment
+ * @fragment_cnt: How many descriptors in the fragment_tbl
+ * @fragment_tbl: Fragment table
+ */
+struct loader_xfer_dma_fragment {
+	struct loader_xfer_fragment fragment;
+	__le32 fragment_cnt;
+	struct fragment_dscrpt fragment_tbl[] __counted_by(fragment_cnt);
+};
+
+/**
+ * struct loader_start - ISHTP firmware loader start
+ * @header: Header of the message
+ */
+struct loader_start {
+	struct loader_msg_header header;
+};
+
+/**
+ * struct loader_start_ack - ISHTP firmware loader start acknowledgment
+ * @header: Header of the message
+ */
+struct loader_start_ack {
+	struct loader_msg_header header;
+};
+
+union loader_recv_message {
+	struct loader_xfer_query_ack query_ack;
+	struct loader_xfer_fragment_ack fragment_ack;
+	struct loader_start_ack start_ack;
+	__u8 raw_data[LOADER_MSG_SIZE];
+};
+
+/*
+ * ISHTP firmware loader internal use
+ */
+/* ISHTP firmware loader command timeout */
+#define ISHTP_LOADER_TIMEOUT msecs_to_jiffies(100)
+
+/* ISHTP firmware loader retry times */
+#define ISHTP_LOADER_RETRY_TIMES 3
+
+/**
+ * struct ish_firmware_variant - ISH firmware variant
+ * @device: PCI Device ID
+ * @filename: The firmware file name
+ */
+struct ish_firmware_variant {
+	unsigned short device;
+	const char *filename;
+};
+
+/*
+ * ISHTP firmware loader API for ISHTP hbm
+ */
+
+/* ISHTP capability bit for firmware loader */
+#define ISHTP_SUPPORT_CAP_LOADER BIT(4)
+
+/* Firmware loader address */
+#define ISHTP_LOADER_CLIENT_ADDR 16
+
+/**
+ * ishtp_loader_work - The work function to start the firmware loading process
+ * @work: The work structure
+ */
+void ishtp_loader_work(struct work_struct *work);
+
+#endif /* _ISHTP_LOADER_H_ */
-- 
2.34.1


^ permalink raw reply related

* [PATCH 3/5] HID: intel-ish-hid: Add driver_data for specifying the firmware filename
From: Zhang Lixu @ 2024-05-06  1:30 UTC (permalink / raw)
  To: linux-input, srinivas.pandruvada, jikos, benjamin.tissoires; +Cc: lixu.zhang
In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com>

Introduces a new structure, ishtp_driver_data, to hold driver-specific
data, including the firmware filename for different hardware variants of
the Intel Integrated Sensor Hub (ISH).

Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 drivers/hid/intel-ish-hid/ipc/pci-ish.c     | 18 +++++++++++++++++-
 drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h | 17 +++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
index e79d72f7db2a..d487227085b2 100644
--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
@@ -23,6 +23,19 @@
 #include "ishtp-dev.h"
 #include "hw-ish.h"
 
+enum ishtp_driver_data_index {
+	ISHTP_DRIVER_DATA_NONE,
+	ISHTP_DRIVER_DATA_LNL_M,
+};
+
+#define ISH_FW_FILENAME_LNL_M "intel/ish/ish_lnlm.bin"
+
+static struct ishtp_driver_data ishtp_driver_data[] = {
+	[ISHTP_DRIVER_DATA_LNL_M] = {
+		.fw_filename = ISH_FW_FILENAME_LNL_M,
+	},
+};
+
 static const struct pci_device_id ish_pci_tbl[] = {
 	{PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_CHV)},
 	{PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_BXT_Ax)},
@@ -46,7 +59,7 @@ static const struct pci_device_id ish_pci_tbl[] = {
 	{PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_MTL_P)},
 	{PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_ARL_H)},
 	{PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_ARL_S)},
-	{PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_LNL_M)},
+	{PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_LNL_M), .driver_data = ISHTP_DRIVER_DATA_LNL_M},
 	{}
 };
 MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
@@ -167,6 +180,7 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 	hw = to_ish_hw(ishtp);
 	ishtp->print_log = ish_event_tracer;
+	ishtp->driver_data = &ishtp_driver_data[ent->driver_data];
 
 	/* mapping IO device memory */
 	hw->mem_addr = pcim_iomap_table(pdev)[0];
@@ -377,3 +391,5 @@ MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
 
 MODULE_DESCRIPTION("Intel(R) Integrated Sensor Hub PCI Device Driver");
 MODULE_LICENSE("GPL");
+
+MODULE_FIRMWARE(ISH_FW_FILENAME_LNL_M);
diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
index 32142c7d9a04..ed294bf0bc8f 100644
--- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
+++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
@@ -122,12 +122,29 @@ struct ishtp_hw_ops {
 	bool	(*dma_no_cache_snooping)(struct ishtp_device *dev);
 };
 
+/**
+ * struct ishtp_driver_data - Driver-specific data for ISHTP devices
+ *
+ * This structure holds driver-specific data that can be associated with each
+ * ISHTP device instance. It allows for the storage of data that is unique to
+ * a particular driver or hardware variant.
+ *
+ * @fw_filename: The firmware filename associated with a specific hardware
+ *               variant of the Intel Integrated Sensor Hub (ISH). This allows
+ *               the driver to load the correct firmware based on the device's
+ *               hardware variant.
+ */
+struct ishtp_driver_data {
+	char *fw_filename;
+};
+
 /**
  * struct ishtp_device - ISHTP private device struct
  */
 struct ishtp_device {
 	struct device *devc;	/* pointer to lowest device */
 	struct pci_dev *pdev;	/* PCI device to get device ids */
+	struct ishtp_driver_data *driver_data; /* pointer to driver-specific data */
 
 	/* waitq for waiting for suspend response */
 	wait_queue_head_t suspend_wait;
-- 
2.34.1


^ permalink raw reply related

* [PATCH 2/5] Documentation: hid: intel-ish-hid: add section for firmware loading
From: Zhang Lixu @ 2024-05-06  1:30 UTC (permalink / raw)
  To: linux-input, srinivas.pandruvada, jikos, benjamin.tissoires; +Cc: lixu.zhang
In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com>

From: Qianru Huang <qianru.huang@intel.com>

Add a section to describe the ISH firmware loading process for Lunar Lake
and later generations.

Signed-off-by: Qianru Huang <qianru.huang@intel.com>
Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 Documentation/hid/intel-ish-hid.rst | 65 +++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/Documentation/hid/intel-ish-hid.rst b/Documentation/hid/intel-ish-hid.rst
index 12613cb2be43..55cbaa719a79 100644
--- a/Documentation/hid/intel-ish-hid.rst
+++ b/Documentation/hid/intel-ish-hid.rst
@@ -339,6 +339,71 @@ End to End HID transport Sequence Diagram
           |                        |                       |                               |
 
 
+ISH Firmware Loading from Host Flow
+-----------------------------------
+
+Starting from the Lunar Lake generation, the ISH firmware has been divided into two components for better space optimization and increased flexibility. These components include a bootloader that is integrated into the BIOS, and a main firmware that is stored within the operating system's file system.
+
+The process works as follows:
+
+- Initially, the ISHTP driver sends a command, HOST_START_REQ_CMD, to the ISH bootloader. In response, the bootloader sends back a HOST_START_RES_CMD. This response includes the ISHTP_SUPPORT_CAP_LOADER bit. Subsequently, the ISHTP driver checks if this bit is set. If it is, the firmware loading process from the host begins.
+
+- During this process, the ISHTP driver first invokes the request_firmware() function, followed by sending a LOADER_CMD_XFER_QUERY command. Upon receiving a response from the bootloader, the ISHTP driver sends a LOADER_CMD_XFER_FRAGMENT command. After receiving another response, the ISHTP driver sends a LOADER_CMD_START command. The bootloader responds and then proceeds to the Main Firmware.
+
+- After the process concludes, the ISHTP driver calls the release_firmware() function.
+
+For more detailed information, please refer to the flow descriptions provided below:
+
+::
+
+  +---------------+                                                    +-----------------+
+  | ISHTP Driver  |                                                    | ISH Bootloader  |
+  +---------------+                                                    +-----------------+
+          |                                                                     |
+          |~~~Send HOST_START_REQ_CMD~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
+          |                                                                     |
+          |<--Send HOST_START_RES_CMD(Includes ISHTP_SUPPORT_CAP_LOADER bit)----|
+          |                                                                     |
+  ****************************************************************************************
+  * if ISHTP_SUPPORT_CAP_LOADER bit is set                                               *
+  ****************************************************************************************
+          |                                                                     |
+          |~~~start loading firmware from host process~~~+                      |
+          |                                              |                      |
+          |<---------------------------------------------+                      |
+          |                                                                     |
+  ---------------------------                                                   |
+  | Call request_firmware() |                                                   |
+  ---------------------------                                                   |
+          |                                                                     |
+          |~~~Send LOADER_CMD_XFER_QUERY~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
+          |                                                                     |
+          |<--Send response-----------------------------------------------------|
+          |                                                                     |
+          |~~~Send LOADER_CMD_XFER_FRAGMENT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
+          |                                                                     |
+          |<--Send response-----------------------------------------------------|
+          |                                                                     |
+          |~~~Send LOADER_CMD_START~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
+          |                                                                     |
+          |<--Send response-----------------------------------------------------|
+          |                                                                     |
+          |                                                                     |~~~Jump to Main Firmware~~~+
+          |                                                                     |                           |
+          |                                                                     |<--------------------------+
+          |                                                                     |
+  ---------------------------                                                   |
+  | Call release_firmware() |                                                   |
+  ---------------------------                                                   |
+          |                                                                     |
+  ****************************************************************************************
+  * end if                                                                               *
+  ****************************************************************************************
+          |                                                                     |
+  +---------------+                                                    +-----------------+
+  | ISHTP Driver  |                                                    | ISH Bootloader  |
+  +---------------+                                                    +-----------------+
+
 ISH Debugging
 -------------
 
-- 
2.34.1


^ permalink raw reply related

* [PATCH 1/5] Documentation: hid: intel-ish-hid: remove section numbering
From: Zhang Lixu @ 2024-05-06  1:30 UTC (permalink / raw)
  To: linux-input, srinivas.pandruvada, jikos, benjamin.tissoires; +Cc: lixu.zhang
In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com>

From: Qianru Huang <qianru.huang@intel.com>

Remove section numbering from the Intel Integrated Sensor Hub (ISH)
documentation to simplify the structure, making it easier to maintain
and update in the future.

Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Qianru Huang <qianru.huang@intel.com>
Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 Documentation/hid/intel-ish-hid.rst | 72 ++++++++++++++---------------
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/Documentation/hid/intel-ish-hid.rst b/Documentation/hid/intel-ish-hid.rst
index 42dc77b7b10f..12613cb2be43 100644
--- a/Documentation/hid/intel-ish-hid.rst
+++ b/Documentation/hid/intel-ish-hid.rst
@@ -18,8 +18,8 @@ These ISH also comply to HID sensor specification, but the difference is the
 transport protocol used for communication. The current external sensor hubs
 mainly use HID over I2C or USB. But ISH doesn't use either I2C or USB.
 
-1. Overview
-===========
+Overview
+========
 
 Using a analogy with a usbhid implementation, the ISH follows a similar model
 for a very high speed communication::
@@ -58,8 +58,8 @@ implemented as a bus. Each client application executing in the ISH processor
 is registered as a device on this bus. The driver, which binds each device
 (ISH HID driver) identifies the device type and registers with the HID core.
 
-2. ISH Implementation: Block Diagram
-====================================
+ISH Implementation: Block Diagram
+=================================
 
 ::
 
@@ -96,27 +96,27 @@ is registered as a device on this bus. The driver, which binds each device
 	| ISH Hardware/Firmware(FW) |
 	 ----------------------------
 
-3. High level processing in above blocks
-========================================
+High level processing in above blocks
+=====================================
 
-3.1 Hardware Interface
-----------------------
+Hardware Interface
+------------------
 
 The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
 product and vendor IDs are changed from different generations of processors. So
 the source code which enumerates drivers needs to update from generation to
 generation.
 
-3.2 Inter Processor Communication (IPC) driver
-----------------------------------------------
+Inter Processor Communication (IPC) driver
+------------------------------------------
 
 Location: drivers/hid/intel-ish-hid/ipc
 
 The IPC message uses memory mapped I/O. The registers are defined in
 hw-ish-regs.h.
 
-3.2.1 IPC/FW message types
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+IPC/FW message types
+^^^^^^^^^^^^^^^^^^^^
 
 There are two types of messages, one for management of link and another for
 messages to and from transport layers.
@@ -142,20 +142,20 @@ register has the following format::
   Bit 31: doorbell trigger (signal H/W interrupt to the other side)
   Other bits are reserved, should be 0.
 
-3.2.2 Transport layer interface
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Transport layer interface
+^^^^^^^^^^^^^^^^^^^^^^^^^
 
 To abstract HW level IPC communication, a set of callbacks is registered.
 The transport layer uses them to send and receive messages.
 Refer to struct ishtp_hw_ops for callbacks.
 
-3.3 ISH Transport layer
------------------------
+ISH Transport layer
+-------------------
 
 Location: drivers/hid/intel-ish-hid/ishtp/
 
-3.3.1 A Generic Transport Layer
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+A Generic Transport Layer
+^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The transport layer is a bi-directional protocol, which defines:
 - Set of commands to start, stop, connect, disconnect and flow control
@@ -166,8 +166,8 @@ This protocol resembles bus messages described in the following document:
 http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
 specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
 
-3.3.2 Connection and Flow Control Mechanism
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Connection and Flow Control Mechanism
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Each FW client and a protocol is identified by a UUID. In order to communicate
 to a FW client, a connection must be established using connect request and
@@ -181,8 +181,8 @@ before receiving the next flow control credit.
 Either side can send disconnect request bus message to end communication. Also
 the link will be dropped if major FW reset occurs.
 
-3.3.3 Peer to Peer data transfer
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Peer to Peer data transfer
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Peer to Peer data transfer can happen with or without using DMA. Depending on
 the sensor bandwidth requirement DMA can be enabled by using module parameter
@@ -217,8 +217,8 @@ In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
 Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
 fragments and via IPC otherwise.
 
-3.3.4 Ring Buffers
-^^^^^^^^^^^^^^^^^^
+Ring Buffers
+^^^^^^^^^^^^
 
 When a client initiates a connection, a ring of RX and TX buffers is allocated.
 The size of ring can be specified by the client. HID client sets 16 and 32 for
@@ -228,8 +228,8 @@ bus message protocol. These buffers are required because the FW may have not
 have processed the last message and may not have enough flow control credits
 to send. Same thing holds true on receive side and flow control is required.
 
-3.3.5 Host Enumeration
-^^^^^^^^^^^^^^^^^^^^^^
+Host Enumeration
+^^^^^^^^^^^^^^^^
 
 The host enumeration bus command allows discovery of clients present in the FW.
 There can be multiple sensor clients and clients for calibration function.
@@ -252,8 +252,8 @@ Enumeration sequence of messages:
 - Once host received properties for that last discovered client, it considers
   ISHTP device fully functional (and allocates DMA buffers)
 
-3.4 HID over ISH Client
------------------------
+HID over ISH Client
+-------------------
 
 Location: drivers/hid/intel-ish-hid
 
@@ -265,16 +265,16 @@ The ISHTP client driver is responsible for:
 - Process Get/Set feature request
 - Get input reports
 
-3.5 HID Sensor Hub MFD and IIO sensor drivers
----------------------------------------------
+HID Sensor Hub MFD and IIO sensor drivers
+-----------------------------------------
 
 The functionality in these drivers is the same as an external sensor hub.
 Refer to
 Documentation/hid/hid-sensor.rst for HID sensor
 Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space.
 
-3.6 End to End HID transport Sequence Diagram
----------------------------------------------
+End to End HID transport Sequence Diagram
+-----------------------------------------
 
 ::
 
@@ -339,16 +339,16 @@ Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space.
           |                        |                       |                               |
 
 
-3.7 ISH Debugging
------------------
+ISH Debugging
+-------------
 
 To debug ISH, event tracing mechanism is used. To enable debug logs::
 
   echo 1 > /sys/kernel/tracing/events/intel_ish/enable
   cat /sys/kernel/tracing/trace
 
-3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
------------------------------------------------------
+ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
+-------------------------------------------------
 
 ::
 
-- 
2.34.1


^ permalink raw reply related

* [PATCH 0/5] HID: intel-ish-hid: Implement loading firmware from host feature
From: Zhang Lixu @ 2024-05-06  1:30 UTC (permalink / raw)
  To: linux-input, srinivas.pandruvada, jikos, benjamin.tissoires; +Cc: lixu.zhang

This patch series is comprised of 5 patches. The first two patches are to add documentation
for firmware loading. The third and fourth patches introduce support for the 'Load Main
Firmware from Host' feature in the ISHTP driver, applicable to Lunar Lake and subsequent
platforms. The last patch enhances the firmware reset handler in the ISH driver. This
addresses an issue where the driver receives two MNG_RESET_NOTIFY messages upon implementing
the 'Load Main Firmware from Host' feature.

This patch series is based on the following 3 commits, which have already been included in the linux-next/master branch.
- HID: intel-ish-hid: ipc: Fix dev_err usage with uninitialized dev->devc
- HID: intel-ish-hid: Use PCI_VDEVICE() and rename device ID macros
- HID: intel-ish-hid: ipc: Add Lunar Lake-M PCI device ID

Qianru Huang (2):
  Documentation: hid: intel-ish-hid: remove section numbering
  Documentation: hid: intel-ish-hid: add section for firmware loading

Zhang Lixu (3):
  HID: intel-ish-hid: Add driver_data for specifying the firmware
    filename
  HID: intel-ish-hid: Implement loading firmware from host feature
  HID: intel-ish-hid: handler multiple MNG_RESET_NOTIFY messages

 Documentation/hid/intel-ish-hid.rst         | 137 +++++++---
 drivers/hid/intel-ish-hid/Makefile          |   1 +
 drivers/hid/intel-ish-hid/ipc/ipc.c         |   7 +-
 drivers/hid/intel-ish-hid/ipc/pci-ish.c     |  18 +-
 drivers/hid/intel-ish-hid/ishtp/hbm.c       |  21 ++
 drivers/hid/intel-ish-hid/ishtp/init.c      |   8 +
 drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h |  28 ++
 drivers/hid/intel-ish-hid/ishtp/loader.c    | 275 ++++++++++++++++++++
 drivers/hid/intel-ish-hid/ishtp/loader.h    | 226 ++++++++++++++++
 9 files changed, 681 insertions(+), 40 deletions(-)
 create mode 100644 drivers/hid/intel-ish-hid/ishtp/loader.c
 create mode 100644 drivers/hid/intel-ish-hid/ishtp/loader.h


base-commit: 9221b2819b8a4196eecf5476d66201be60fbcf29
-- 
2.34.1


^ permalink raw reply

* Re: [PATCH v6 3/5] regulator: add regulators driver for Marvell 88PM886 PMIC
From: Mark Brown @ 2024-05-06  1:04 UTC (permalink / raw)
  To: Karel Balej
  Cc: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Liam Girdwood, devicetree, linux-kernel,
	linux-input, Duje Mihanović, ~postmarketos/upstreaming,
	phone-devel
In-Reply-To: <D11XRKUAK8EM.20N91SDPCH584@matfyz.cz>

[-- Attachment #1: Type: text/plain, Size: 156 bytes --]

On Sun, May 05, 2024 at 08:52:06PM +0200, Karel Balej wrote:

> Should I then drop this op and the max_uA values from all the
> regulators?

Probably, yes.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH v2] bpftool, selftests/hid/bpf: fix 29 clang warnings
From: Quentin Monnet @ 2024-05-06  0:00 UTC (permalink / raw)
  To: John Hubbard, Shuah Khan
  Cc: Jiri Kosina, Benjamin Tissoires, Justin Stitt, Peter Hutterer,
	Jason Gerecke, Joshua Dickens, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Martin KaFai Lau,
	Eduard Zingerman, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf,
	linux-input, Valentin Obst, linux-kselftest, LKML, llvm
In-Reply-To: <20240505230054.13813-1-jhubbard@nvidia.com>

On 06/05/2024 00:00, John Hubbard wrote:
> When building either tools/bpf/bpftool, or tools/testing/selftests/hid,
> (the same Makefile is used for these), clang generates many instances of
> the following:
> 
>     "clang: warning: -lLLVM-17: 'linker' input unused"
> 
> Quentin points out that the LLVM version is only required in $(LIBS),
> not in $(CFLAGS), so the fix is to remove it from CFLAGS.
> 
> Suggested-by: Quentin Monnet <qmo@kernel.org>
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Acked-by: Quentin Monnet <qmo@kernel.org>

Thank you!

^ permalink raw reply

* [PATCH v2] bpftool, selftests/hid/bpf: fix 29 clang warnings
From: John Hubbard @ 2024-05-05 23:00 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Jiri Kosina, Benjamin Tissoires, Justin Stitt, Peter Hutterer,
	Jason Gerecke, Joshua Dickens, Quentin Monnet, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Martin KaFai Lau,
	Eduard Zingerman, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf,
	linux-input, Valentin Obst, linux-kselftest, LKML, llvm,
	John Hubbard

When building either tools/bpf/bpftool, or tools/testing/selftests/hid,
(the same Makefile is used for these), clang generates many instances of
the following:

    "clang: warning: -lLLVM-17: 'linker' input unused"

Quentin points out that the LLVM version is only required in $(LIBS),
not in $(CFLAGS), so the fix is to remove it from CFLAGS.

Suggested-by: Quentin Monnet <qmo@kernel.org>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
 tools/bpf/bpftool/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index e9154ace80ff..a5445a422109 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -143,7 +143,7 @@ ifeq ($(feature-llvm),1)
   # If LLVM is available, use it for JIT disassembly
   CFLAGS  += -DHAVE_LLVM_SUPPORT
   LLVM_CONFIG_LIB_COMPONENTS := mcdisassembler all-targets
-  CFLAGS  += $(shell $(LLVM_CONFIG) --cflags --libs $(LLVM_CONFIG_LIB_COMPONENTS))
+  CFLAGS  += $(shell $(LLVM_CONFIG) --cflags)
   LIBS    += $(shell $(LLVM_CONFIG) --libs $(LLVM_CONFIG_LIB_COMPONENTS))
   ifeq ($(shell $(LLVM_CONFIG) --shared-mode),static)
     LIBS += $(shell $(LLVM_CONFIG) --system-libs $(LLVM_CONFIG_LIB_COMPONENTS))

base-commit: f462ae0edd3703edd6f22fe41d336369c38b884b
prerequisite-patch-id: b901ece2a5b78503e2fb5480f20e304d36a0ea27
-- 
2.45.0


^ permalink raw reply related

* Re: [PATCH] bpftool, selftests/hid/bpf: fix 29 clang warnings
From: Quentin Monnet @ 2024-05-05 22:51 UTC (permalink / raw)
  To: John Hubbard, Shuah Khan
  Cc: Jiri Kosina, Benjamin Tissoires, Justin Stitt, Peter Hutterer,
	Jason Gerecke, Joshua Dickens, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Martin KaFai Lau,
	Eduard Zingerman, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf,
	linux-input, Valentin Obst, linux-kselftest, LKML, llvm
In-Reply-To: <c0a8ffa7-0609-4904-961c-3f4357c53237@nvidia.com>

On 05/05/2024 23:48, John Hubbard wrote:
> On 5/5/24 3:36 PM, Quentin Monnet wrote:
>> On 05/05/2024 22:56, John Hubbard wrote:
> ...
>> Thanks! If possible, I'd rather keep the warning enabled, and fix the
>> command line instead. Looking at the error and the Makefile, we may not
>> need the -lLLVM<version> in the CFLAGS at all, but only in $(LIBS). On
>> my setup, I can build successfully, without the warnings, with the
>> following patch:
>>
>> ------
>> diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
>> index b67454b45a49..dfa4f1bebbb3 100644
>> --- a/tools/bpf/bpftool/Makefile
>> +++ b/tools/bpf/bpftool/Makefile
>> @@ -147,7 +147,7 @@ ifeq ($(feature-llvm),1)
>>     # If LLVM is available, use it for JIT disassembly
>>     CFLAGS  += -DHAVE_LLVM_SUPPORT
>>     LLVM_CONFIG_LIB_COMPONENTS := mcdisassembler all-targets
>> -  CFLAGS  += $(shell $(LLVM_CONFIG) --cflags --libs
>> $(LLVM_CONFIG_LIB_COMPONENTS))
>> +  CFLAGS  += $(shell $(LLVM_CONFIG) --cflags)
>>     LIBS    += $(shell $(LLVM_CONFIG) --libs
>> $(LLVM_CONFIG_LIB_COMPONENTS))
>>     ifeq ($(shell $(LLVM_CONFIG) --shared-mode),static)
>>       LIBS += $(shell $(LLVM_CONFIG) --system-libs
>> $(LLVM_CONFIG_LIB_COMPONENTS))
>> ------
>>
>> Could you please check whether that works on your side, too?
>>
> 
> Yes, that works, and of course that's much better. Please let me
> know if you prefer me to post a v2 with that, or if you plan
> on sending it yourself?
Please go ahead!
Quentin

^ permalink raw reply

* Re: [PATCH] bpftool, selftests/hid/bpf: fix 29 clang warnings
From: John Hubbard @ 2024-05-05 22:48 UTC (permalink / raw)
  To: Quentin Monnet, Shuah Khan
  Cc: Jiri Kosina, Benjamin Tissoires, Justin Stitt, Peter Hutterer,
	Jason Gerecke, Joshua Dickens, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Martin KaFai Lau,
	Eduard Zingerman, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf,
	linux-input, Valentin Obst, linux-kselftest, LKML, llvm
In-Reply-To: <4f947691-bf25-460b-bc08-da29de3fdaa6@kernel.org>

On 5/5/24 3:36 PM, Quentin Monnet wrote:
> On 05/05/2024 22:56, John Hubbard wrote:
...
> Thanks! If possible, I'd rather keep the warning enabled, and fix the
> command line instead. Looking at the error and the Makefile, we may not
> need the -lLLVM<version> in the CFLAGS at all, but only in $(LIBS). On
> my setup, I can build successfully, without the warnings, with the
> following patch:
> 
> ------
> diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
> index b67454b45a49..dfa4f1bebbb3 100644
> --- a/tools/bpf/bpftool/Makefile
> +++ b/tools/bpf/bpftool/Makefile
> @@ -147,7 +147,7 @@ ifeq ($(feature-llvm),1)
>     # If LLVM is available, use it for JIT disassembly
>     CFLAGS  += -DHAVE_LLVM_SUPPORT
>     LLVM_CONFIG_LIB_COMPONENTS := mcdisassembler all-targets
> -  CFLAGS  += $(shell $(LLVM_CONFIG) --cflags --libs $(LLVM_CONFIG_LIB_COMPONENTS))
> +  CFLAGS  += $(shell $(LLVM_CONFIG) --cflags)
>     LIBS    += $(shell $(LLVM_CONFIG) --libs $(LLVM_CONFIG_LIB_COMPONENTS))
>     ifeq ($(shell $(LLVM_CONFIG) --shared-mode),static)
>       LIBS += $(shell $(LLVM_CONFIG) --system-libs $(LLVM_CONFIG_LIB_COMPONENTS))
> ------
> 
> Could you please check whether that works on your side, too?
> 

Yes, that works, and of course that's much better. Please let me
know if you prefer me to post a v2 with that, or if you plan
on sending it yourself?

thanks,
-- 
John Hubbard
NVIDIA


^ permalink raw reply

* [syzbot] [input?] [usb?] WARNING in hid_output_report
From: syzbot @ 2024-05-05 22:36 UTC (permalink / raw)
  To: bentiss, jikos, linux-input, linux-kernel, linux-usb,
	syzkaller-bugs

Hello,

syzbot found the following issue on:

HEAD commit:    18daea77cca6 Merge tag 'for-linus' of git://git.kernel.org..
git tree:       upstream
console+strace: https://syzkaller.appspot.com/x/log.txt?x=159f1f17180000
kernel config:  https://syzkaller.appspot.com/x/.config?x=d2f00edef461175
dashboard link: https://syzkaller.appspot.com/bug?extid=5186630949e3c55f0799
compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=13deb917180000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=1035ae87180000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/4614372cf68b/disk-18daea77.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/e118db95ea43/vmlinux-18daea77.xz
kernel image: https://storage.googleapis.com/syzbot-assets/998cf091eeb5/bzImage-18daea77.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+5186630949e3c55f0799@syzkaller.appspotmail.com

keytouch 0003:0926:3333.0001: implement() called with too large value 8 (n: 1)! (kworker/0:0)
------------[ cut here ]------------
WARNING: CPU: 0 PID: 7 at drivers/hid/hid-core.c:1451 implement drivers/hid/hid-core.c:1451 [inline]
WARNING: CPU: 0 PID: 7 at drivers/hid/hid-core.c:1451 hid_output_report+0x548/0x760 drivers/hid/hid-core.c:1863
Modules linked in:
CPU: 0 PID: 7 Comm: kworker/0:0 Not tainted 6.9.0-rc6-syzkaller-00046-g18daea77cca6 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024
Workqueue: events hidinput_led_worker
RIP: 0010:implement drivers/hid/hid-core.c:1451 [inline]
RIP: 0010:hid_output_report+0x548/0x760 drivers/hid/hid-core.c:1863
Code: a8 08 00 00 48 8b 44 24 40 48 8d b8 38 19 00 00 48 c7 c6 40 f7 aa 8c 48 c7 c2 c9 10 c9 8d 44 89 f1 45 89 e8 e8 99 e3 ca 02 90 <0f> 0b 90 44 23 74 24 18 e9 b7 fd ff ff 89 d9 80 e1 07 80 c1 03 38
RSP: 0018:ffffc900000c7a90 EFLAGS: 00010046
RAX: 65120fbe4e3ed400 RBX: 0000000000000001 RCX: 65120fbe4e3ed400
RDX: 0000000000000000 RSI: 0000000080000001 RDI: 0000000000000000
RBP: 0000000000000000 R08: ffffffff8176b74c R09: 1ffff92000018ea8
R10: dffffc0000000000 R11: fffff52000018ea9 R12: 0000000000000000
R13: 0000000000000001 R14: 0000000000000008 R15: 0000000000000000
FS:  0000000000000000(0000) GS:ffff8880b9400000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000000000066c7e0 CR3: 00000000234e6000 CR4: 00000000003506f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 __usbhid_submit_report drivers/hid/usbhid/hid-core.c:591 [inline]
 usbhid_submit_report+0x43d/0x9e0 drivers/hid/usbhid/hid-core.c:636
 process_one_work kernel/workqueue.c:3267 [inline]
 process_scheduled_works+0xa10/0x17c0 kernel/workqueue.c:3348
 worker_thread+0x86d/0xd70 kernel/workqueue.c:3429
 kthread+0x2f0/0x390 kernel/kthread.c:388
 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
 </TASK>


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply

* Re: [PATCH] bpftool, selftests/hid/bpf: fix 29 clang warnings
From: Quentin Monnet @ 2024-05-05 22:36 UTC (permalink / raw)
  To: John Hubbard, Shuah Khan
  Cc: Jiri Kosina, Benjamin Tissoires, Justin Stitt, Peter Hutterer,
	Jason Gerecke, Joshua Dickens, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Martin KaFai Lau,
	Eduard Zingerman, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf,
	linux-input, Valentin Obst, linux-kselftest, LKML, llvm
In-Reply-To: <20240505215636.63592-1-jhubbard@nvidia.com>

On 05/05/2024 22:56, John Hubbard wrote:
> When building either tools/bpf/bpftool, or tools/testing/selftests/hid,
> (the same Makefile is used for these), clang generates many instances of
> a warning that is useless here:
> 
>     "clang: warning: -lLLVM-17: 'linker' input unused"
> 
> Silence this in both locations, by disabling that warning when building
> with clang.
> 
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
> ---
>  tools/bpf/bpftool/Makefile | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
> index e9154ace80ff..c7457921d136 100644
> --- a/tools/bpf/bpftool/Makefile
> +++ b/tools/bpf/bpftool/Makefile
> @@ -133,6 +133,10 @@ CFLAGS += -DUSE_LIBCAP
>  LIBS += -lcap
>  endif
>  
> +ifneq ($(LLVM),)
> +    CFLAGS += -Wno-unused-command-line-argument
> +endif
Thanks! If possible, I'd rather keep the warning enabled, and fix the
command line instead. Looking at the error and the Makefile, we may not 
need the -lLLVM<version> in the CFLAGS at all, but only in $(LIBS). On
my setup, I can build successfully, without the warnings, with the
following patch:

------
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index b67454b45a49..dfa4f1bebbb3 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -147,7 +147,7 @@ ifeq ($(feature-llvm),1)
   # If LLVM is available, use it for JIT disassembly
   CFLAGS  += -DHAVE_LLVM_SUPPORT
   LLVM_CONFIG_LIB_COMPONENTS := mcdisassembler all-targets
-  CFLAGS  += $(shell $(LLVM_CONFIG) --cflags --libs $(LLVM_CONFIG_LIB_COMPONENTS))
+  CFLAGS  += $(shell $(LLVM_CONFIG) --cflags)
   LIBS    += $(shell $(LLVM_CONFIG) --libs $(LLVM_CONFIG_LIB_COMPONENTS))
   ifeq ($(shell $(LLVM_CONFIG) --shared-mode),static)
     LIBS += $(shell $(LLVM_CONFIG) --system-libs $(LLVM_CONFIG_LIB_COMPONENTS))
------

Could you please check whether that works on your side, too?

Quentin

^ permalink raw reply related

* [PATCH] bpftool, selftests/hid/bpf: fix 29 clang warnings
From: John Hubbard @ 2024-05-05 21:56 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Jiri Kosina, Benjamin Tissoires, Justin Stitt, Peter Hutterer,
	Jason Gerecke, Joshua Dickens, Quentin Monnet, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Martin KaFai Lau,
	Eduard Zingerman, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf,
	linux-input, Valentin Obst, linux-kselftest, LKML, llvm,
	John Hubbard

When building either tools/bpf/bpftool, or tools/testing/selftests/hid,
(the same Makefile is used for these), clang generates many instances of
a warning that is useless here:

    "clang: warning: -lLLVM-17: 'linker' input unused"

Silence this in both locations, by disabling that warning when building
with clang.

Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
 tools/bpf/bpftool/Makefile | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index e9154ace80ff..c7457921d136 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -133,6 +133,10 @@ CFLAGS += -DUSE_LIBCAP
 LIBS += -lcap
 endif
 
+ifneq ($(LLVM),)
+    CFLAGS += -Wno-unused-command-line-argument
+endif
+
 include $(wildcard $(OUTPUT)*.d)
 
 all: $(OUTPUT)bpftool

base-commit: f462ae0edd3703edd6f22fe41d336369c38b884b
prerequisite-patch-id: b901ece2a5b78503e2fb5480f20e304d36a0ea27
-- 
2.45.0


^ permalink raw reply related

* [PATCH v2 2/3] dt-bindings: touchscreen: elan,ektf2127: Add EKTF2232
From: Andreas Kemnade @ 2024-05-05 21:47 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, andreas,
	u.kleine-koenig, hdegoede, andy.shevchenko, siebren.vroegindeweij,
	linux-input, devicetree, linux-kernel
In-Reply-To: <20240505214754.891700-1-andreas@kemnade.info>

Add a compatible for the EKTF2232, which is similar to other chips in this
document.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 .../devicetree/bindings/input/touchscreen/elan,ektf2127.yaml     | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml b/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml
index 5c4c29da0b11d..ff0ec3fd24c5d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml
@@ -17,6 +17,7 @@ properties:
     enum:
       - elan,ektf2127
       - elan,ektf2132
+      - elan,ektf2232
 
   reg:
     maxItems: 1
-- 
2.39.2


^ permalink raw reply related

* [PATCH v2 3/3] Input: ektf2127 - add ektf2232 support
From: Andreas Kemnade @ 2024-05-05 21:47 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, andreas,
	u.kleine-koenig, hdegoede, andy.shevchenko, siebren.vroegindeweij,
	linux-input, devicetree, linux-kernel
In-Reply-To: <20240505214754.891700-1-andreas@kemnade.info>

The chip is similar, but has status bits at different positions,
so use the correct bits.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 drivers/input/touchscreen/ektf2127.c | 41 ++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
index cc3103b9cbfba..028b605d1bb74 100644
--- a/drivers/input/touchscreen/ektf2127.c
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -13,6 +13,7 @@
  * Hans de Goede <hdegoede@redhat.com>
  */
 
+#include <linux/bits.h>
 #include <linux/gpio/consumer.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
@@ -46,6 +47,11 @@ struct ektf2127_ts {
 	struct input_dev *input;
 	struct gpio_desc *power_gpios;
 	struct touchscreen_properties prop;
+	int status_shift;
+};
+
+struct ektf2127_i2c_chip_data {
+	int status_shift;
 };
 
 static void ektf2127_parse_coordinates(const u8 *buf, unsigned int touch_count,
@@ -112,8 +118,8 @@ static void ektf2127_report2_contact(struct ektf2127_ts *ts, int slot,
 
 static void ektf2127_report2_event(struct ektf2127_ts *ts, const u8 *buf)
 {
-	ektf2127_report2_contact(ts, 0, &buf[1], !!(buf[7] & 2));
-	ektf2127_report2_contact(ts, 1, &buf[4], !!(buf[7] & 4));
+	ektf2127_report2_contact(ts, 0, &buf[1], !!(buf[7] & BIT(ts->status_shift)));
+	ektf2127_report2_contact(ts, 1, &buf[4], !!(buf[7] & BIT(ts->status_shift + 1)));
 
 	input_mt_sync_frame(ts->input);
 	input_sync(ts->input);
@@ -246,7 +252,9 @@ static int ektf2127_query_dimension(struct i2c_client *client, bool width)
 
 static int ektf2127_probe(struct i2c_client *client)
 {
+	const struct i2c_device_id *id = i2c_client_get_device_id(client);
 	struct device *dev = &client->dev;
+	const struct ektf2127_i2c_chip_data *chip_data;
 	struct ektf2127_ts *ts;
 	struct input_dev *input;
 	u8 buf[4];
@@ -303,6 +311,17 @@ static int ektf2127_probe(struct i2c_client *client)
 		return error;
 
 	ts->input = input;
+
+	chip_data = device_get_match_data(&client->dev);
+	if (!chip_data)
+		chip_data = (const struct ektf2127_i2c_chip_data *)id->driver_data;
+	if (!chip_data) {
+		dev_err(&client->dev, "missing chip data\n");
+		return -EINVAL;
+	}
+
+	ts->status_shift = chip_data->status_shift;
+
 	input_set_drvdata(input, ts);
 
 	error = devm_request_threaded_irq(dev, client->irq,
@@ -325,18 +344,28 @@ static int ektf2127_probe(struct i2c_client *client)
 	return 0;
 }
 
+static const struct ektf2127_i2c_chip_data ektf2127_data = {
+	.status_shift = 1,
+};
+
+static const struct ektf2127_i2c_chip_data ektf2232_data = {
+	.status_shift = 0,
+};
+
 #ifdef CONFIG_OF
 static const struct of_device_id ektf2127_of_match[] = {
-	{ .compatible = "elan,ektf2127" },
-	{ .compatible = "elan,ektf2132" },
+	{ .compatible = "elan,ektf2127",	.data = &ektf2127_data},
+	{ .compatible = "elan,ektf2132",	.data = &ektf2127_data},
+	{ .compatible = "elan,ektf2232",	.data = &ektf2232_data},
 	{}
 };
 MODULE_DEVICE_TABLE(of, ektf2127_of_match);
 #endif
 
 static const struct i2c_device_id ektf2127_i2c_id[] = {
-	{ "ektf2127", 0 },
-	{ "ektf2132", 0 },
+	{ .name = "ektf2127", .driver_data = (long)&ektf2127_data },
+	{ .name = "ektf2132", .driver_data = (long)&ektf2127_data },
+	{ .name = "ektf2232", .driver_data = (long)&ektf2232_data },
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, ektf2127_i2c_id);
-- 
2.39.2


^ permalink raw reply related

* [PATCH v2 1/3] dt-bindings: touchscreen: convert elan,ektf2127 to json-schema
From: Andreas Kemnade @ 2024-05-05 21:47 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, andreas,
	u.kleine-koenig, hdegoede, andy.shevchenko, siebren.vroegindeweij,
	linux-input, devicetree, linux-kernel
In-Reply-To: <20240505214754.891700-1-andreas@kemnade.info>

Convert EKTF2127 infrared touchscreen controller binding to DT schema
and add ektf2232 compatible.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 .../bindings/input/touchscreen/ektf2127.txt   | 25 --------
 .../input/touchscreen/elan,ektf2127.yaml      | 57 +++++++++++++++++++
 2 files changed, 57 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml

diff --git a/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt b/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
deleted file mode 100644
index c9f2c9f578e34..0000000000000
--- a/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-* Elan eKTF2127 I2C touchscreen controller
-
-Required properties:
- - compatible		  : "elan,ektf2127" or "elan,ektf2132"
- - reg			  : I2C slave address of the chip (0x40)
- - interrupts		  : interrupt specification for the ektf2127 interrupt
- - power-gpios		  : GPIO specification for the pin connected to the
-			    ektf2127's wake input. This needs to be driven high
-			    to take ektf2127 out of its low power state
-
-For additional optional properties see: touchscreen.txt
-
-Example:
-
-i2c@00000000 {
-	ektf2127: touchscreen@15 {
-		compatible = "elan,ektf2127";
-		reg = <0x15>;
-		interrupt-parent = <&pio>;
-		interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>
-		power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>;
-		touchscreen-inverted-x;
-		touchscreen-swapped-x-y;
-	};
-};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml b/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml
new file mode 100644
index 0000000000000..5c4c29da0b11d
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/elan,ektf2127.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Elan eKTF2127 I2C touchscreen controller
+
+maintainers:
+  - Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+properties:
+  compatible:
+    enum:
+      - elan,ektf2127
+      - elan,ektf2132
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-gpios:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-gpios
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        touchscreen@15 {
+            compatible = "elan,ektf2127";
+            reg = <0x15>;
+            interrupt-parent = <&pio>;
+            interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>;
+            power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>;
+            touchscreen-inverted-x;
+            touchscreen-swapped-x-y;
+        };
+    };
+...
-- 
2.39.2


^ permalink raw reply related

* [PATCH v2 0/3] Input: Add ektf2232 support
From: Andreas Kemnade @ 2024-05-05 21:47 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, andreas,
	u.kleine-koenig, hdegoede, andy.shevchenko, siebren.vroegindeweij,
	linux-input, devicetree, linux-kernel

Add support for the EKTF2232 to the ektf2127 driver which
contains support for similar chips.

Add the needed compatible to bindings and convert them.

Changes in v2:
- separate patch for adding compatible
- use match data for selecting status shift

Andreas Kemnade (3):
  dt-bindings: touchscreen: convert elan,ektf2127 to json-schema
  dt-bindings: touchscreen: elan,ektf2127: Add EKTF2232
  Input: ektf2127 - add ektf2232 support

 .../bindings/input/touchscreen/ektf2127.txt   | 25 --------
 .../input/touchscreen/elan,ektf2127.yaml      | 58 +++++++++++++++++++
 drivers/input/touchscreen/ektf2127.c          | 41 +++++++++++--
 3 files changed, 93 insertions(+), 31 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml

-- 
2.39.2


^ permalink raw reply

* Re: [PATCH v6 3/5] regulator: add regulators driver for Marvell 88PM886 PMIC
From: Karel Balej @ 2024-05-05 18:52 UTC (permalink / raw)
  To: Mark Brown
  Cc: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Liam Girdwood, devicetree, linux-kernel,
	linux-input, Duje Mihanović, ~postmarketos/upstreaming,
	phone-devel
In-Reply-To: <ZjeidfoIbjvejphU@finisterre.sirena.org.uk>

Mark Brown, 2024-05-06T00:15:01+09:00:
> On Sat, May 04, 2024 at 09:37:06PM +0200, Karel Balej wrote:
>
> > +static const struct regulator_ops pm886_ldo_ops = {
> > +	.list_voltage = regulator_list_voltage_table,
> > +	.map_voltage = regulator_map_voltage_iterate,
> > +	.set_voltage_sel = regulator_set_voltage_sel_regmap,
> > +	.get_voltage_sel = regulator_get_voltage_sel_regmap,
> > +	.enable = regulator_enable_regmap,
> > +	.disable = regulator_disable_regmap,
> > +	.is_enabled = regulator_is_enabled_regmap,
> > +	.get_current_limit = pm886_regulator_get_ilim,
>
> Do these regulators actually enforce this limit or is this just a spec
> limit beyond which regulation may fail?  If it's just a spec limit I'd
> not expect this operation to be provided, it's more for a hard limit
> where the regulator will detect and act on issues.  I don't see an error
> interrupt or anything and this would be an unusual feature for a LDO.

I'm afraid I don't have the answer -- my only reference is the vendor
version of the driver and I don't see anything there based on which I
would be able to tell.

But based on what you write, my guess would be that it's just a spec limit.

Should I then drop this op and the max_uA values from all the
regulators?

Thank you,
K. B.

^ permalink raw reply

* Re: [PATCH v9 2/8] x86/vmware: Move common macros to vmware.h
From: Borislav Petkov @ 2024-05-05 18:28 UTC (permalink / raw)
  To: Alexey Makhalov
  Cc: linux-kernel, virtualization, hpa, dave.hansen, mingo, tglx, x86,
	netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
	linux-graphics-maintainer, pv-drivers, timothym, akaher,
	dri-devel, daniel, airlied, tzimmermann, mripard,
	maarten.lankhorst, horms, kirill.shutemov, Nadav Amit
In-Reply-To: <20240424231407.14098-2-alexey.makhalov@broadcom.com>

On Wed, Apr 24, 2024 at 04:14:07PM -0700, Alexey Makhalov wrote:
> +#define VMWARE_CMD_GETVERSION		10
> +#define VMWARE_CMD_GETHZ		45
> +#define VMWARE_CMD_GETVCPU_INFO		68
> +#define VMWARE_CMD_STEALCLOCK		91

Ok, what part in

"* first patch: sole code movement, no changes whatsoever"

wasn't clear?

You're adding those macros above to a patch which claims that it does
code movement only. Don't do that.

Let me try again:

* first patch: *ONLY* code movement. No new code, no new defines, no new
functions, no nada! Only move code and do fixups so that it still builds
like the export you're doing.

* follow-on patches: other changes.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply

* Re: [git pull] Input updates for v6.9-rc6
From: pr-tracker-bot @ 2024-05-05 17:12 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Linus Torvalds, linux-kernel, linux-input
In-Reply-To: <Zjb8RrOFLHFSk_Gv@google.com>

The pull request you sent on Sat, 4 May 2024 20:25:58 -0700:

> git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git tags/input-for-v6.9-rc6

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/3f1d0865002795eb45c49e30a4fbc40f7956b6ae

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply

* Re: [PATCH v6 3/5] regulator: add regulators driver for Marvell 88PM886 PMIC
From: Mark Brown @ 2024-05-05 15:15 UTC (permalink / raw)
  To: Karel Balej
  Cc: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Liam Girdwood, devicetree, linux-kernel,
	linux-input, Duje Mihanović, ~postmarketos/upstreaming,
	phone-devel
In-Reply-To: <20240504194632.2456-4-balejk@matfyz.cz>

[-- Attachment #1: Type: text/plain, Size: 864 bytes --]

On Sat, May 04, 2024 at 09:37:06PM +0200, Karel Balej wrote:

> +static const struct regulator_ops pm886_ldo_ops = {
> +	.list_voltage = regulator_list_voltage_table,
> +	.map_voltage = regulator_map_voltage_iterate,
> +	.set_voltage_sel = regulator_set_voltage_sel_regmap,
> +	.get_voltage_sel = regulator_get_voltage_sel_regmap,
> +	.enable = regulator_enable_regmap,
> +	.disable = regulator_disable_regmap,
> +	.is_enabled = regulator_is_enabled_regmap,
> +	.get_current_limit = pm886_regulator_get_ilim,

Do these regulators actually enforce this limit or is this just a spec
limit beyond which regulation may fail?  If it's just a spec limit I'd
not expect this operation to be provided, it's more for a hard limit
where the regulator will detect and act on issues.  I don't see an error
interrupt or anything and this would be an unusual feature for a LDO.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* [PATCH] dt-bindings: Use full path to other schemas
From: Krzysztof Kozlowski @ 2024-05-05  8:46 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Ming Qian, Zhou Peng, Mauro Carvalho Chehab, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Jeff LaBundy, Shijie Qin,
	linux-input, devicetree, linux-kernel, linux-media, linux-mtd
  Cc: Krzysztof Kozlowski

When referencing other schema, it is preferred to use an absolute path
(/schemas/....), which allows also an seamless move of particular schema
out of Linux kernel to dtschema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

---

Rob, maybe you can take it directly? Should apply cleanly on your tree.
---
 Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml | 2 +-
 Documentation/devicetree/bindings/media/amphion,vpu.yaml    | 2 +-
 Documentation/devicetree/bindings/mtd/mtd.yaml              | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
index 5b1769c19b17..418c168b223b 100644
--- a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
+++ b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
@@ -784,7 +784,7 @@ patternProperties:
       gpio-2: GPIO4
 
     allOf:
-      - $ref: ../pinctrl/pincfg-node.yaml#
+      - $ref: /schemas/pinctrl/pincfg-node.yaml#
 
     properties:
       drive-open-drain: true
diff --git a/Documentation/devicetree/bindings/media/amphion,vpu.yaml b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
index c0d83d755239..9801de3ed84e 100644
--- a/Documentation/devicetree/bindings/media/amphion,vpu.yaml
+++ b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
@@ -44,7 +44,7 @@ patternProperties:
     description:
       Each vpu encoder or decoder correspond a MU, which used for communication
       between driver and firmware. Implement via mailbox on driver.
-    $ref: ../mailbox/fsl,mu.yaml#
+    $ref: /schemas/mailbox/fsl,mu.yaml#
 
 
   "^vpu-core@[0-9a-f]+$":
diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml b/Documentation/devicetree/bindings/mtd/mtd.yaml
index ee442ecb11cd..bbb56216a4e2 100644
--- a/Documentation/devicetree/bindings/mtd/mtd.yaml
+++ b/Documentation/devicetree/bindings/mtd/mtd.yaml
@@ -48,8 +48,8 @@ patternProperties:
     type: object
 
     allOf:
-      - $ref: ../nvmem/nvmem.yaml#
-      - $ref: ../nvmem/nvmem-deprecated-cells.yaml#
+      - $ref: /schemas/nvmem/nvmem.yaml#
+      - $ref: /schemas/nvmem/nvmem-deprecated-cells.yaml#
 
     unevaluatedProperties: false
 
-- 
2.43.0


^ permalink raw reply related

* [git pull] Input updates for v6.9-rc6
From: Dmitry Torokhov @ 2024-05-05  3:25 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-input

Hi Linus,

Please pull from:

	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git tags/input-for-v6.9-rc6

to receive updates for the input subsystem. You will get:

- a new ID for ASUS ROG RAIKIRI controllers added to xpad driver

- amimouse driver structure annotated with __refdata to prevent section
  mismatch warnings.

Changelog:
---------

Uwe Kleine-König (1):
      Input: amimouse - mark driver struct with __refdata to prevent section mismatch

Vicki Pfau (1):
      Input: xpad - add support for ASUS ROG RAIKIRI

Diffstat:
--------

 drivers/input/joystick/xpad.c  | 2 ++
 drivers/input/mouse/amimouse.c | 8 +++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

Thanks.


-- 
Dmitry

^ permalink raw reply

* [PATCH v6 3/5] regulator: add regulators driver for Marvell 88PM886 PMIC
From: Karel Balej @ 2024-05-04 19:37 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Liam Girdwood, Mark Brown, devicetree,
	linux-kernel, linux-input
  Cc: Duje Mihanović, ~postmarketos/upstreaming, phone-devel,
	balejk
In-Reply-To: <20240504194632.2456-1-balejk@matfyz.cz>

Support the LDO and buck regulators of the Marvell 88PM886 PMIC.

Signed-off-by: Karel Balej <balejk@matfyz.cz>
---

Notes:
    v6:
    - Remove all definitions (now present in the header).
    v5:
    - Add remaining regulators.
    - Clean up includes.
    - Address Mark's feedback:
      - Use dedicated regmap config.
    RFC v4:
    - Initialize regulators regmap in the regulators driver.
    - Register all regulators at once.
    - Drop regulator IDs.
    - Add missing '\n' to dev_err_probe message.
    - Fix includes.
    - Add ID table.
    RFC v3:
    - Do not have a variable for each regulator -- define them all in the
      pm886_regulators array.
    - Use new regulators regmap index name.
    - Use dev_err_probe.
    RFC v2:
    - Drop of_compatible and related code.
    - Drop unused include.
    - Remove some abstraction: use only one regmap for all regulators and
      only mention 88PM886 in Kconfig description.
    - Reword commit message.

 drivers/regulator/88pm886-regulator.c | 476 ++++++++++++++++++++++++++
 drivers/regulator/Kconfig             |   6 +
 drivers/regulator/Makefile            |   1 +
 3 files changed, 483 insertions(+)
 create mode 100644 drivers/regulator/88pm886-regulator.c

diff --git a/drivers/regulator/88pm886-regulator.c b/drivers/regulator/88pm886-regulator.c
new file mode 100644
index 000000000000..7d6e113c93b3
--- /dev/null
+++ b/drivers/regulator/88pm886-regulator.c
@@ -0,0 +1,476 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+#include <linux/mfd/88pm886.h>
+
+static const struct regmap_config pm886_regulator_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = PM886_REG_BUCK5_VOUT,
+};
+
+struct pm886_regulator {
+	struct regulator_desc desc;
+	int max_uA;
+};
+
+static int pm886_regulator_get_ilim(struct regulator_dev *rdev)
+{
+	struct pm886_regulator *data = rdev_get_drvdata(rdev);
+
+	if (!data) {
+		dev_err(&rdev->dev, "Failed to get regulator data\n");
+		return -EINVAL;
+	}
+	return data->max_uA;
+}
+
+static const struct regulator_ops pm886_ldo_ops = {
+	.list_voltage = regulator_list_voltage_table,
+	.map_voltage = regulator_map_voltage_iterate,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.get_current_limit = pm886_regulator_get_ilim,
+};
+
+static const struct regulator_ops pm886_buck_ops = {
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.get_current_limit = pm886_regulator_get_ilim,
+};
+
+static const unsigned int pm886_ldo_volt_table1[] = {
+	1700000, 1800000, 1900000, 2500000, 2800000, 2900000, 3100000, 3300000,
+};
+
+static const unsigned int pm886_ldo_volt_table2[] = {
+	1200000, 1250000, 1700000, 1800000, 1850000, 1900000, 2500000, 2600000,
+	2700000, 2750000, 2800000, 2850000, 2900000, 3000000, 3100000, 3300000,
+};
+
+static const unsigned int pm886_ldo_volt_table3[] = {
+	1700000, 1800000, 1900000, 2000000, 2100000, 2500000, 2700000, 2800000,
+};
+
+static const struct linear_range pm886_buck_volt_ranges1[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0, 79, 12500),
+	REGULATOR_LINEAR_RANGE(1600000, 80, 84, 50000),
+};
+
+static const struct linear_range pm886_buck_volt_ranges2[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0, 79, 12500),
+	REGULATOR_LINEAR_RANGE(1600000, 80, 114, 50000),
+};
+
+static struct pm886_regulator pm886_regulators[] = {
+	{
+		.desc = {
+			.name = "LDO1",
+			.regulators_node = "regulators",
+			.of_match = "ldo1",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN1,
+			.enable_mask = BIT(0),
+			.volt_table = pm886_ldo_volt_table1,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table1),
+			.vsel_reg = PM886_REG_LDO1_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 100000,
+	},
+	{
+		.desc = {
+			.name = "LDO2",
+			.regulators_node = "regulators",
+			.of_match = "ldo2",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN1,
+			.enable_mask = BIT(1),
+			.volt_table = pm886_ldo_volt_table1,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table1),
+			.vsel_reg = PM886_REG_LDO2_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 100000,
+	},
+	{
+		.desc = {
+			.name = "LDO3",
+			.regulators_node = "regulators",
+			.of_match = "ldo3",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN1,
+			.enable_mask = BIT(2),
+			.volt_table = pm886_ldo_volt_table1,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table1),
+			.vsel_reg = PM886_REG_LDO3_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 100000,
+	},
+	{
+		.desc = {
+			.name = "LDO4",
+			.regulators_node = "regulators",
+			.of_match = "ldo4",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN1,
+			.enable_mask = BIT(3),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO4_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 400000,
+	},
+	{
+		.desc = {
+			.name = "LDO5",
+			.regulators_node = "regulators",
+			.of_match = "ldo5",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN1,
+			.enable_mask = BIT(4),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO5_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 400000,
+	},
+	{
+		.desc = {
+			.name = "LDO6",
+			.regulators_node = "regulators",
+			.of_match = "ldo6",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN1,
+			.enable_mask = BIT(5),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO6_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 400000,
+	},
+	{
+		.desc = {
+			.name = "LDO7",
+			.regulators_node = "regulators",
+			.of_match = "ldo7",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN1,
+			.enable_mask = BIT(6),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO7_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 400000,
+	},
+	{
+		.desc = {
+			.name = "LDO8",
+			.regulators_node = "regulators",
+			.of_match = "ldo8",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN1,
+			.enable_mask = BIT(7),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO8_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 400000,
+	},
+	{
+		.desc = {
+			.name = "LDO9",
+			.regulators_node = "regulators",
+			.of_match = "ldo9",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN2,
+			.enable_mask = BIT(0),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO9_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 400000,
+	},
+	{
+		.desc = {
+			.name = "LDO10",
+			.regulators_node = "regulators",
+			.of_match = "ldo10",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN2,
+			.enable_mask = BIT(1),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO10_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 200000,
+	},
+	{
+		.desc = {
+			.name = "LDO11",
+			.regulators_node = "regulators",
+			.of_match = "ldo11",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN2,
+			.enable_mask = BIT(2),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO11_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 200000,
+	},
+	{
+		.desc = {
+			.name = "LDO12",
+			.regulators_node = "regulators",
+			.of_match = "ldo12",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN2,
+			.enable_mask = BIT(3),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO12_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 200000,
+	},
+	{
+		.desc = {
+			.name = "LDO13",
+			.regulators_node = "regulators",
+			.of_match = "ldo13",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN2,
+			.enable_mask = BIT(4),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO13_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 200000,
+	},
+	{
+		.desc = {
+			.name = "LDO14",
+			.regulators_node = "regulators",
+			.of_match = "ldo14",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN2,
+			.enable_mask = BIT(5),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO14_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 200000,
+	},
+	{
+		.desc = {
+			.name = "LDO15",
+			.regulators_node = "regulators",
+			.of_match = "ldo15",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN2,
+			.enable_mask = BIT(6),
+			.volt_table = pm886_ldo_volt_table2,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table2),
+			.vsel_reg = PM886_REG_LDO15_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 200000,
+	},
+	{
+		.desc = {
+			.name = "LDO16",
+			.regulators_node = "regulators",
+			.of_match = "ldo16",
+			.ops = &pm886_ldo_ops,
+			.type = REGULATOR_VOLTAGE,
+			.enable_reg = PM886_REG_LDO_EN2,
+			.enable_mask = BIT(7),
+			.volt_table = pm886_ldo_volt_table3,
+			.n_voltages = ARRAY_SIZE(pm886_ldo_volt_table3),
+			.vsel_reg = PM886_REG_LDO16_VOUT,
+			.vsel_mask = PM886_LDO_VSEL_MASK,
+		},
+		.max_uA = 200000,
+	},
+	{
+		.desc = {
+			.name = "buck1",
+			.regulators_node = "regulators",
+			.of_match = "buck1",
+			.ops = &pm886_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = 85,
+			.linear_ranges = pm886_buck_volt_ranges1,
+			.n_linear_ranges = ARRAY_SIZE(pm886_buck_volt_ranges1),
+			.vsel_reg = PM886_REG_BUCK1_VOUT,
+			.vsel_mask = PM886_BUCK_VSEL_MASK,
+			.enable_reg = PM886_REG_BUCK_EN,
+			.enable_mask = BIT(0),
+		},
+		.max_uA = 3000000,
+	},
+	{
+		.desc = {
+			.name = "buck2",
+			.regulators_node = "regulators",
+			.of_match = "buck2",
+			.ops = &pm886_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = 115,
+			.linear_ranges = pm886_buck_volt_ranges2,
+			.n_linear_ranges = ARRAY_SIZE(pm886_buck_volt_ranges2),
+			.vsel_reg = PM886_REG_BUCK2_VOUT,
+			.vsel_mask = PM886_BUCK_VSEL_MASK,
+			.enable_reg = PM886_REG_BUCK_EN,
+			.enable_mask = BIT(1),
+		},
+		.max_uA = 1200000,
+	},
+	{
+		.desc = {
+			.name = "buck3",
+			.regulators_node = "regulators",
+			.of_match = "buck3",
+			.ops = &pm886_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = 115,
+			.linear_ranges = pm886_buck_volt_ranges2,
+			.n_linear_ranges = ARRAY_SIZE(pm886_buck_volt_ranges2),
+			.vsel_reg = PM886_REG_BUCK3_VOUT,
+			.vsel_mask = PM886_BUCK_VSEL_MASK,
+			.enable_reg = PM886_REG_BUCK_EN,
+			.enable_mask = BIT(2),
+		},
+		.max_uA = 1200000,
+	},
+	{
+		.desc = {
+			.name = "buck4",
+			.regulators_node = "regulators",
+			.of_match = "buck4",
+			.ops = &pm886_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = 115,
+			.linear_ranges = pm886_buck_volt_ranges2,
+			.n_linear_ranges = ARRAY_SIZE(pm886_buck_volt_ranges2),
+			.vsel_reg = PM886_REG_BUCK4_VOUT,
+			.vsel_mask = PM886_BUCK_VSEL_MASK,
+			.enable_reg = PM886_REG_BUCK_EN,
+			.enable_mask = BIT(3),
+		},
+		.max_uA = 1200000,
+	},
+	{
+		.desc = {
+			.name = "buck5",
+			.regulators_node = "regulators",
+			.of_match = "buck5",
+			.ops = &pm886_buck_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = 115,
+			.linear_ranges = pm886_buck_volt_ranges2,
+			.n_linear_ranges = ARRAY_SIZE(pm886_buck_volt_ranges2),
+			.vsel_reg = PM886_REG_BUCK5_VOUT,
+			.vsel_mask = PM886_BUCK_VSEL_MASK,
+			.enable_reg = PM886_REG_BUCK_EN,
+			.enable_mask = BIT(4),
+		},
+		.max_uA = 1200000,
+	},
+};
+
+static int pm886_regulator_probe(struct platform_device *pdev)
+{
+	struct pm886_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_config rcfg = { };
+	struct pm886_regulator *regulator;
+	struct device *dev = &pdev->dev;
+	struct regulator_desc *rdesc;
+	struct regulator_dev *rdev;
+	struct i2c_client *page;
+	struct regmap *regmap;
+
+	page = devm_i2c_new_dummy_device(dev, chip->client->adapter,
+			chip->client->addr + PM886_PAGE_OFFSET_REGULATORS);
+	if (IS_ERR(page))
+		return dev_err_probe(dev, PTR_ERR(page),
+				"Failed to initialize regulators client\n");
+
+	regmap = devm_regmap_init_i2c(page, &pm886_regulator_regmap_config);
+	if (IS_ERR(regmap))
+		return dev_err_probe(dev, PTR_ERR(regmap),
+				"Failed to initialize regulators regmap\n");
+	rcfg.regmap = regmap;
+
+	rcfg.dev = dev->parent;
+
+	for (int i = 0; i < ARRAY_SIZE(pm886_regulators); i++) {
+		regulator = &pm886_regulators[i];
+		rdesc = &regulator->desc;
+		rcfg.driver_data = regulator;
+		rdev = devm_regulator_register(dev, rdesc, &rcfg);
+		if (IS_ERR(rdev))
+			return dev_err_probe(dev, PTR_ERR(rdev),
+					"Failed to register %s\n", rdesc->name);
+	}
+
+	return 0;
+}
+
+static const struct platform_device_id pm886_regulator_id_table[] = {
+	{ "88pm886-regulator", },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, pm886_regulator_id_table);
+
+static struct platform_driver pm886_regulator_driver = {
+	.driver = {
+		.name = "88pm886-regulator",
+	},
+	.probe = pm886_regulator_probe,
+	.id_table = pm886_regulator_id_table,
+};
+module_platform_driver(pm886_regulator_driver);
+
+MODULE_DESCRIPTION("Marvell 88PM886 PMIC regulator driver");
+MODULE_AUTHOR("Karel Balej <balejk@matfyz.cz>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7db0a29b5b8d..89845892c533 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -91,6 +91,12 @@ config REGULATOR_88PM8607
 	help
 	  This driver supports 88PM8607 voltage regulator chips.
 
+config REGULATOR_88PM886
+	tristate "Marvell 88PM886 voltage regulators"
+	depends on MFD_88PM886_PMIC
+	help
+	  This driver implements support for Marvell 88PM886 voltage regulators.
+
 config REGULATOR_ACT8865
 	tristate "Active-semi act8865 voltage regulator"
 	depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 46fb569e6be8..f30089b74b2e 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
 obj-$(CONFIG_REGULATOR_88PG86X) += 88pg86x.o
 obj-$(CONFIG_REGULATOR_88PM800) += 88pm800-regulator.o
 obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
+obj-$(CONFIG_REGULATOR_88PM886) += 88pm886-regulator.o
 obj-$(CONFIG_REGULATOR_CROS_EC) += cros-ec-regulator.o
 obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o
 obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
-- 
2.45.0


^ permalink raw reply related

* [PATCH v6 1/5] dt-bindings: mfd: add entry for Marvell 88PM886 PMIC
From: Karel Balej @ 2024-05-04 19:37 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Liam Girdwood, Mark Brown, devicetree,
	linux-kernel, linux-input
  Cc: Duje Mihanović, ~postmarketos/upstreaming, phone-devel,
	balejk
In-Reply-To: <20240504194632.2456-1-balejk@matfyz.cz>

Marvell 88PM886 is a PMIC with several subdevices such as onkey,
regulators or battery and charger. It comes in at least two revisions,
A0 and A1 -- only A1 is described here at the moment.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Karel Balej <balejk@matfyz.cz>
---

Notes:
    RFC v4:
    - Address Krzysztof's comments:
      - Fix regulators indentation.
      - Add Krzysztof's trailer.
    RFC v3:
    - Add wakeup-source property.
    - Address Rob's feedback:
      - Move regulators into the MFD file.
      - Remove interrupt-controller and #interrupt-cells properties.
    RFC v2:
    - Address Rob's feedback:
      - Drop mention of 88PM880.
      - Make sure the file passes bindings check (add the necessary header
        and fix `interrupt-cells`).
      - Other small changes.
    - Add regulators. Changes with respect to the regulator RFC series:
      - Address Krzysztof's comments:
        - Drop unused compatible.
        - Fix sub-node pattern.

 .../bindings/mfd/marvell,88pm886-a1.yaml      | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml

diff --git a/Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml b/Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml
new file mode 100644
index 000000000000..d6a71c912b76
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/marvell,88pm886-a1.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell 88PM886 PMIC core
+
+maintainers:
+  - Karel Balej <balejk@matfyz.cz>
+
+description:
+  Marvell 88PM886 is a PMIC providing several functions such as onkey,
+  regulators or battery and charger.
+
+properties:
+  compatible:
+    const: marvell,88pm886-a1
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  wakeup-source: true
+
+  regulators:
+    type: object
+    additionalProperties: false
+    patternProperties:
+      "^(ldo(1[0-6]|[1-9])|buck[1-5])$":
+        type: object
+        $ref: /schemas/regulator/regulator.yaml#
+        description: LDO or buck regulator.
+        unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      pmic@30 {
+        compatible = "marvell,88pm886-a1";
+        reg = <0x30>;
+        interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&gic>;
+        wakeup-source;
+
+        regulators {
+          ldo2: ldo2 {
+            regulator-min-microvolt = <3100000>;
+            regulator-max-microvolt = <3300000>;
+          };
+
+          ldo15: ldo15 {
+            regulator-min-microvolt = <3300000>;
+            regulator-max-microvolt = <3300000>;
+          };
+
+          buck2: buck2 {
+            regulator-min-microvolt = <1800000>;
+            regulator-max-microvolt = <1800000>;
+          };
+        };
+      };
+    };
+...
-- 
2.45.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox