drivers/gpu/drm/xe/xe_i2c.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_i2c.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_i2c.c
Extension
.c
Size
9465 bytes
Lines
385
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
 * Intel Xe I2C attached Microcontroller Units (MCU)
 *
 * Copyright (C) 2025 Intel Corporation.
 */

#include <drm/drm_print.h>
#include <linux/array_size.h>
#include <linux/container_of.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/notifier.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/sprintf.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/workqueue.h>

#include "regs/xe_i2c_regs.h"
#include "regs/xe_irq_regs.h"

#include "xe_device.h"
#include "xe_i2c.h"
#include "xe_mmio.h"
#include "xe_sriov.h"
#include "xe_survivability_mode.h"

/**
 * DOC: Xe I2C devices
 *
 * Register a platform device for the I2C host controller (Synpsys DesignWare
 * I2C) if the registers of that controller are mapped to the MMIO, and also the
 * I2C client device for the Add-In Management Controller (the MCU) attached to
 * the host controller.
 *
 * See drivers/i2c/busses/i2c-designware-* for more information on the I2C host
 * controller.
 */

static const char adapter_name[] = "i2c_designware";

static const struct property_entry xe_i2c_adapter_properties[] = {
	PROPERTY_ENTRY_STRING("compatible", "intel,xe-i2c"),
	PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_FAST_MODE_PLUS_FREQ),
	{ }
};

static inline void xe_i2c_read_endpoint(struct xe_mmio *mmio, void *ep)
{
	u32 *val = ep;

	val[0] = xe_mmio_read32(mmio, REG_SG_REMAP_ADDR_PREFIX);
	val[1] = xe_mmio_read32(mmio, REG_SG_REMAP_ADDR_POSTFIX);
}

static void xe_i2c_client_work(struct work_struct *work)
{
	struct xe_i2c *i2c = container_of(work, struct xe_i2c, work);
	struct i2c_board_info info = {
		.type	= "amc",
		.flags	= I2C_CLIENT_HOST_NOTIFY,
		.addr	= i2c->ep.addr[1],
	};

	i2c->client[0] = i2c_new_client_device(i2c->adapter, &info);
}

static int xe_i2c_notifier(struct notifier_block *nb, unsigned long action, void *data)
{
	struct xe_i2c *i2c = container_of(nb, struct xe_i2c, bus_notifier);
	struct i2c_adapter *adapter = i2c_verify_adapter(data);
	struct device *dev = data;

	if (action == BUS_NOTIFY_ADD_DEVICE &&
	    adapter && dev->parent == &i2c->pdev->dev) {
		i2c->adapter = adapter;
		schedule_work(&i2c->work);
		return NOTIFY_OK;
	}

	return NOTIFY_DONE;
}

Annotation

Implementation Notes