drivers/power/reset/at91-reset.c

Source file repositories/reference/linux-study-clean/drivers/power/reset/at91-reset.c

File Facts

System
Linux kernel
Corpus path
drivers/power/reset/at91-reset.c
Extension
.c
Size
11735 bytes
Lines
440
Domain
Driver Families
Bucket
drivers/power
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 at91_reset {
	void __iomem *rstc_base;
	void __iomem *ramc_base[2];
	void __iomem *dev_base;
	struct clk *sclk;
	const struct at91_reset_data *data;
	struct reset_controller_dev rcdev;
	spinlock_t lock;
	struct notifier_block nb;
	u32 args;
	u32 ramc_lpr;
};

#define to_at91_reset(r)	container_of(r, struct at91_reset, rcdev)

/**
 * struct at91_reset_data - AT91 reset data
 * @reset_args:			SoC specific system reset arguments
 * @n_device_reset:		number of device resets
 * @device_reset_min_id:	min id for device reset
 * @device_reset_max_id:	max id for device reset
 */
struct at91_reset_data {
	u32 reset_args;
	u32 n_device_reset;
	u8 device_reset_min_id;
	u8 device_reset_max_id;
};

/*
* unless the SDRAM is cleanly shutdown before we hit the
* reset register it can be left driving the data bus and
* killing the chance of a subsequent boot from NAND
*/
static int at91_reset(struct notifier_block *this, unsigned long mode,
		      void *cmd)
{
	struct at91_reset *reset = container_of(this, struct at91_reset, nb);

	asm volatile(
		/* Align to cache lines */
		".balign 32\n\t"

		/* Disable SDRAM0 accesses */
		"	tst	%0, #0\n\t"
		"	beq	1f\n\t"
		"	str	%3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
		/* Power down SDRAM0 */
		"	str	%4, [%0, %6]\n\t"
		/* Disable SDRAM1 accesses */
		"1:	tst	%1, #0\n\t"
		"	strne	%3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
		/* Power down SDRAM1 */
		"	strne	%4, [%1, %6]\n\t"
		/* Reset CPU */
		"	str	%5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"

		"	b	.\n\t"
		:
		: "r" (reset->ramc_base[0]),
		  "r" (reset->ramc_base[1]),
		  "r" (reset->rstc_base),
		  "r" (1),
		  "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN),
		  "r" (reset->data->reset_args),
		  "r" (reset->ramc_lpr)
	);

	return NOTIFY_DONE;
}

static const char *at91_reset_reason(struct at91_reset *reset)
{
	u32 reg = readl(reset->rstc_base + AT91_RSTC_SR);
	const char *reason;

	switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
	case RESET_TYPE_GENERAL:
		reason = POWER_ON_REASON_REGULAR;
		break;
	case RESET_TYPE_WAKEUP:
		reason = POWER_ON_REASON_RTC;
		break;
	case RESET_TYPE_WATCHDOG:
		reason = POWER_ON_REASON_WATCHDOG;
		break;
	case RESET_TYPE_SOFTWARE:
		reason = POWER_ON_REASON_SOFTWARE;
		break;
	case RESET_TYPE_USER:

Annotation

Implementation Notes