drivers/memory/ti-aemif.c

Source file repositories/reference/linux-study-clean/drivers/memory/ti-aemif.c

File Facts

System
Linux kernel
Corpus path
drivers/memory/ti-aemif.c
Extension
.c
Size
12395 bytes
Lines
447
Domain
Driver Families
Bucket
drivers/memory
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 aemif_cs_data {
	struct aemif_cs_timings timings;
	u8	cs;
	u8	enable_ss;
	u8	enable_ew;
	u8	asize;
};

/**
 * struct aemif_device: structure to hold device data
 * @base: base address of AEMIF registers
 * @clk: source clock
 * @clk_rate: clock's rate in kHz
 * @num_cs: number of assigned chip-selects
 * @cs_offset: start number of cs nodes
 * @cs_data: array of chip-select settings
 * @config_cs_lock: lock used to access CS configuration
 */
struct aemif_device {
	void __iomem *base;
	struct clk *clk;
	unsigned long clk_rate;
	u8 num_cs;
	int cs_offset;
	struct aemif_cs_data cs_data[NUM_CS];
	struct mutex config_cs_lock;
};

/**
 * aemif_check_cs_timings() - Check the validity of a CS timing configuration.
 * @timings: timings configuration
 *
 * @return: 0 if the timing configuration is valid, negative error number otherwise.
 */
int aemif_check_cs_timings(struct aemif_cs_timings *timings)
{
	if (timings->ta > TA_MAX)
		return -EINVAL;

	if (timings->rhold > RHOLD_MAX)
		return -EINVAL;

	if (timings->rstrobe > RSTROBE_MAX)
		return -EINVAL;

	if (timings->rsetup > RSETUP_MAX)
		return -EINVAL;

	if (timings->whold > WHOLD_MAX)
		return -EINVAL;

	if (timings->wstrobe > WSTROBE_MAX)
		return -EINVAL;

	if (timings->wsetup > WSETUP_MAX)
		return -EINVAL;

	return 0;
}
EXPORT_SYMBOL_GPL(aemif_check_cs_timings);

/**
 * aemif_set_cs_timings() - Set the timing configuration of a given chip select.
 * @aemif: aemif device to configure
 * @cs: index of the chip select to configure
 * @timings: timings configuration to set
 *
 * @return: 0 on success, else negative errno.
 */
int aemif_set_cs_timings(struct aemif_device *aemif, u8 cs,
			 struct aemif_cs_timings *timings)
{
	unsigned int offset;
	u32 val, set;
	int ret;

	if (!timings || !aemif)
		return -EINVAL;

	if (cs > aemif->num_cs)
		return -EINVAL;

	ret = aemif_check_cs_timings(timings);
	if (ret)
		return ret;

	set = TA(timings->ta) | RHOLD(timings->rhold) | RSTROBE(timings->rstrobe) |
	      RSETUP(timings->rsetup) | WHOLD(timings->whold) |
	      WSTROBE(timings->wstrobe) | WSETUP(timings->wsetup);

Annotation

Implementation Notes