Commit 8d4a9c69 authored by Dustin L. Howett's avatar Dustin L. Howett Committed by Tzung-Bi Shih
Browse files

platform/chrome: cros_ec_lpc: introduce a priv struct for the lpc device



lpc_driver_data stores the MMIO port base for EC mapped memory.
cros_ec_lpc_readmem uses this port base instead of hardcoding
EC_LPC_ADDR_MEMMAP.

Signed-off-by: default avatarDustin L. Howett <dustin@howett.net>
Reviewed-by: default avatarThomas Weißschuh <linux@weissschuh.net>
Tested-by: default avatarThomas Weißschuh <linux@weissschuh.net>
Tested-by: default avatarMario Limonciello <superm1@gmail.com>
Link: https://lore.kernel.org/r/20240403004713.130365-2-dustin@howett.net


Signed-off-by: default avatarTzung-Bi Shih <tzungbi@kernel.org>
parent d33d2255
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -34,6 +34,14 @@
/* True if ACPI device is present */
static bool cros_ec_lpc_acpi_device_found;

/**
 * struct cros_ec_lpc - LPC device-specific data
 * @mmio_memory_base: The first I/O port addressing EC mapped memory.
 */
struct cros_ec_lpc {
	u16 mmio_memory_base;
};

/**
 * struct lpc_driver_ops - LPC driver operations
 * @read: Copy length bytes from EC address offset into buffer dest. Returns
@@ -290,6 +298,7 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec,
static int cros_ec_lpc_readmem(struct cros_ec_device *ec, unsigned int offset,
			       unsigned int bytes, void *dest)
{
	struct cros_ec_lpc *ec_lpc = ec->priv;
	int i = offset;
	char *s = dest;
	int cnt = 0;
@@ -299,13 +308,13 @@ static int cros_ec_lpc_readmem(struct cros_ec_device *ec, unsigned int offset,

	/* fixed length */
	if (bytes) {
		cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + offset, bytes, s);
		cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + offset, bytes, s);
		return bytes;
	}

	/* string */
	for (; i < EC_MEMMAP_SIZE; i++, s++) {
		cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + i, 1, s);
		cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + i, 1, s);
		cnt++;
		if (!*s)
			break;
@@ -353,9 +362,16 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
	struct acpi_device *adev;
	acpi_status status;
	struct cros_ec_device *ec_dev;
	struct cros_ec_lpc *ec_lpc;
	u8 buf[2] = {};
	int irq, ret;

	ec_lpc = devm_kzalloc(dev, sizeof(*ec_lpc), GFP_KERNEL);
	if (!ec_lpc)
		return -ENOMEM;

	ec_lpc->mmio_memory_base = EC_LPC_ADDR_MEMMAP;

	/*
	 * The Framework Laptop (and possibly other non-ChromeOS devices)
	 * only exposes the eight I/O ports that are required for the Microchip EC.
@@ -380,7 +396,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
	cros_ec_lpc_ops.write = cros_ec_lpc_mec_write_bytes;
	cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf);
	if (buf[0] != 'E' || buf[1] != 'C') {
		if (!devm_request_region(dev, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE,
		if (!devm_request_region(dev, ec_lpc->mmio_memory_base, EC_MEMMAP_SIZE,
					 dev_name(dev))) {
			dev_err(dev, "couldn't reserve memmap region\n");
			return -EBUSY;
@@ -389,7 +405,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
		/* Re-assign read/write operations for the non MEC variant */
		cros_ec_lpc_ops.read = cros_ec_lpc_read_bytes;
		cros_ec_lpc_ops.write = cros_ec_lpc_write_bytes;
		cros_ec_lpc_ops.read(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2,
		cros_ec_lpc_ops.read(ec_lpc->mmio_memory_base + EC_MEMMAP_ID, 2,
				     buf);
		if (buf[0] != 'E' || buf[1] != 'C') {
			dev_err(dev, "EC ID not detected\n");
@@ -423,6 +439,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
	ec_dev->din_size = sizeof(struct ec_host_response) +
			   sizeof(struct ec_response_get_protocol_info);
	ec_dev->dout_size = sizeof(struct ec_host_request);
	ec_dev->priv = ec_lpc;

	/*
	 * Some boards do not have an IRQ allotted for cros_ec_lpc,