drivers/gpu/drm/amd/ras/rascore/ras_eeprom.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/ras/rascore/ras_eeprom.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/ras/rascore/ras_eeprom.c
Extension
.c
Size
40051 bytes
Lines
1363
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

if ((ret > 0) && !read) {
			/* According to EEPROM specs the length of the
			 * self-writing cycle, tWR (tW), is 10 ms.
			 *
			 * TODO: Use polling on ACK, aka Acknowledge
			 * Polling, to minimize waiting for the
			 * internal write cycle to complete, as it is
			 * usually smaller than tWR (tW).
			 */
			msleep(10);
		}

		return ret;
	}

	RAS_DEV_ERR(ras_core->dev, "Error: No eeprom i2c system xfer function!\n");
	return -EINVAL;
}

static int __eeprom_xfer(struct ras_core_context *ras_core, u32 eeprom_addr,
			      u8 *eeprom_buf, u32 buf_size, bool read)
{
	u16 limit;
	u16 ps; /* Partial size */
	int res = 0, r;

	if (read)
		limit = ras_core->ras_eeprom.max_read_len;
	else
		limit = ras_core->ras_eeprom.max_write_len;

	if (limit && (limit <= EEPROM_OFFSET_SIZE)) {
		RAS_DEV_ERR(ras_core->dev,
				"maddr:0x%04X size:0x%02X:quirk max_%s_len must be > %d",
				eeprom_addr, buf_size,
				read ? "read" : "write", EEPROM_OFFSET_SIZE);
		return -EINVAL;
	}

	ras_core_down_gpu_reset_lock(ras_core);

	if (limit == 0) {
		res = __ras_eeprom_xfer(ras_core, eeprom_addr,
					eeprom_buf, buf_size, read);
	} else {
		/* The "limit" includes all data bytes sent/received,
		 * which would include the EEPROM_OFFSET_SIZE bytes.
		 * Account for them here.
		 */
		limit -= EEPROM_OFFSET_SIZE;
		for ( ; buf_size > 0;
			buf_size -= ps, eeprom_addr += ps, eeprom_buf += ps) {
			ps = (buf_size < limit) ? buf_size : limit;

			r = __ras_eeprom_xfer(ras_core, eeprom_addr,
						eeprom_buf, ps, read);
			if (r < 0)
				break;

			res += r;
		}
	}

	ras_core_up_gpu_reset_lock(ras_core);

	return res;
}

static int __eeprom_read(struct ras_core_context *ras_core,
			      u32 eeprom_addr, u8 *eeprom_buf, u32 bytes)
{
	return __eeprom_xfer(ras_core, eeprom_addr,
			   eeprom_buf, bytes, true);
}

static int __eeprom_write(struct ras_core_context *ras_core,
			       u32 eeprom_addr, u8 *eeprom_buf, u32 bytes)
{
	return __eeprom_xfer(ras_core, eeprom_addr,
			   eeprom_buf, bytes, false);
}

static void
__encode_table_header_to_buf(struct ras_eeprom_table_header *hdr,
			     unsigned char *buf)
{
	u32 *pp = (uint32_t *)buf;

	pp[0] = cpu_to_le32(hdr->header);
	pp[1] = cpu_to_le32(hdr->version);

Annotation

Implementation Notes