drivers/crypto/gemini/sl3516-ce-core.c

Source file repositories/reference/linux-study-clean/drivers/crypto/gemini/sl3516-ce-core.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/gemini/sl3516-ce-core.c
Extension
.c
Size
13760 bytes
Lines
544
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

switch (ce_algs[i].type) {
		case CRYPTO_ALG_TYPE_SKCIPHER:
			seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n",
				   ce_algs[i].alg.skcipher.base.base.cra_driver_name,
				   ce_algs[i].alg.skcipher.base.base.cra_name,
				   ce_algs[i].stat_req, ce_algs[i].stat_fb);
			break;
		}
	}
	return 0;
}

DEFINE_SHOW_ATTRIBUTE(sl3516_ce_debugfs);

static int sl3516_ce_register_algs(struct sl3516_ce_dev *ce)
{
	int err;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
		ce_algs[i].ce = ce;
		switch (ce_algs[i].type) {
		case CRYPTO_ALG_TYPE_SKCIPHER:
			dev_info(ce->dev, "DEBUG: Register %s\n",
				 ce_algs[i].alg.skcipher.base.base.cra_name);
			err = crypto_engine_register_skcipher(&ce_algs[i].alg.skcipher);
			if (err) {
				dev_err(ce->dev, "Fail to register %s\n",
					ce_algs[i].alg.skcipher.base.base.cra_name);
				ce_algs[i].ce = NULL;
				return err;
			}
			break;
		default:
			ce_algs[i].ce = NULL;
			dev_err(ce->dev, "ERROR: tried to register an unknown algo\n");
		}
	}
	return 0;
}

static void sl3516_ce_unregister_algs(struct sl3516_ce_dev *ce)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
		if (!ce_algs[i].ce)
			continue;
		switch (ce_algs[i].type) {
		case CRYPTO_ALG_TYPE_SKCIPHER:
			dev_info(ce->dev, "Unregister %d %s\n", i,
				 ce_algs[i].alg.skcipher.base.base.cra_name);
			crypto_engine_unregister_skcipher(&ce_algs[i].alg.skcipher);
			break;
		}
	}
}

static void sl3516_ce_start(struct sl3516_ce_dev *ce)
{
	ce->ctx = 0;
	ce->crx = 0;
	writel(ce->dtx, ce->base + IPSEC_TXDMA_CURR_DESC);
	writel(ce->drx, ce->base + IPSEC_RXDMA_CURR_DESC);
	writel(0, ce->base + IPSEC_DMA_STATUS);
}

/*
 * Power management strategy: The device is suspended unless a TFM exists for
 * one of the algorithms proposed by this driver.
 */
static int sl3516_ce_pm_suspend(struct device *dev)
{
	struct sl3516_ce_dev *ce = dev_get_drvdata(dev);

	reset_control_assert(ce->reset);
	clk_disable_unprepare(ce->clks);
	return 0;
}

static int sl3516_ce_pm_resume(struct device *dev)
{
	struct sl3516_ce_dev *ce = dev_get_drvdata(dev);
	int err;

	err = clk_prepare_enable(ce->clks);
	if (err) {
		dev_err(ce->dev, "Cannot prepare_enable\n");
		goto error;
	}

Annotation

Implementation Notes