drivers/crypto/hisilicon/sec/sec_drv.c

Source file repositories/reference/linux-study-clean/drivers/crypto/hisilicon/sec/sec_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/hisilicon/sec/sec_drv.c
Extension
.c
Size
33882 bytes
Lines
1321
Domain
Driver Families
Bucket
drivers/crypto
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

struct sec_debug_bd_info {
#define SEC_DEBUG_BD_INFO_SOFT_ERR_CHECK_M	GENMASK(22, 0)
	u32 soft_err_check;
#define SEC_DEBUG_BD_INFO_HARD_ERR_CHECK_M	GENMASK(9, 0)
	u32 hard_err_check;
	u32 icv_mac1st_word;
#define SEC_DEBUG_BD_INFO_GET_ID_M		GENMASK(19, 0)
	u32 sec_get_id;
	/* W4---W15 */
	u32 reserv_left[12];
};

struct sec_out_bd_info	{
#define SEC_OUT_BD_INFO_Q_ID_M			GENMASK(11, 0)
#define SEC_OUT_BD_INFO_ECC_2BIT_ERR		BIT(14)
	u16 data;
};

#define SEC_MAX_DEVICES				8
static struct sec_dev_info *sec_devices[SEC_MAX_DEVICES];
static DEFINE_MUTEX(sec_id_lock);

static int sec_queue_map_io(struct sec_queue *queue)
{
	struct device *dev = queue->dev_info->dev;
	struct resource *res;

	res = platform_get_resource(to_platform_device(dev),
				    IORESOURCE_MEM,
				    2 + queue->queue_id);
	if (!res) {
		dev_err(dev, "Failed to get queue %u memory resource\n",
			queue->queue_id);
		return -ENOMEM;
	}
	queue->regs = ioremap(res->start, resource_size(res));
	if (!queue->regs)
		return -ENOMEM;

	return 0;
}

static void sec_queue_unmap_io(struct sec_queue *queue)
{
	 iounmap(queue->regs);
}

static int sec_queue_ar_pkgattr(struct sec_queue *queue, u32 ar_pkg)
{
	void __iomem *addr = queue->regs +  SEC_Q_ARUSER_CFG_REG;
	u32 regval;

	regval = readl_relaxed(addr);
	if (ar_pkg)
		regval |= SEC_Q_ARUSER_CFG_PKG;
	else
		regval &= ~SEC_Q_ARUSER_CFG_PKG;
	writel_relaxed(regval, addr);

	return 0;
}

static int sec_queue_aw_pkgattr(struct sec_queue *queue, u32 aw_pkg)
{
	void __iomem *addr = queue->regs + SEC_Q_AWUSER_CFG_REG;
	u32 regval;

	regval = readl_relaxed(addr);
	regval |= SEC_Q_AWUSER_CFG_PKG;
	writel_relaxed(regval, addr);

	return 0;
}

static int sec_clk_en(struct sec_dev_info *info)
{
	void __iomem *base = info->regs[SEC_COMMON];
	u32 i = 0;

	writel_relaxed(0x7, base + SEC_ALGSUB_CLK_EN_REG);
	do {
		usleep_range(1000, 10000);
		if ((readl_relaxed(base + SEC_ALGSUB_CLK_ST_REG) & 0x7) == 0x7)
			return 0;
		i++;
	} while (i < 10);
	dev_err(info->dev, "sec clock enable fail!\n");

	return -EIO;
}

Annotation

Implementation Notes