drivers/reset/reset-npcm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/reset/reset-npcm.c
Extension
.c
Size
13485 bytes
Lines
498
Domain
Driver Families
Bucket
drivers/reset
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 npcm_reset_info {
	u32 bmc_id;
	u32 num_ipsrst;
	const u32 *ipsrst;
};

static const struct npcm_reset_info npxm7xx_reset_info[] = {
	{.bmc_id = BMC_NPCM7XX, .num_ipsrst = 3, .ipsrst = npxm7xx_ipsrst}};
static const struct npcm_reset_info npxm8xx_reset_info[] = {
	{.bmc_id = BMC_NPCM8XX, .num_ipsrst = 4, .ipsrst = npxm8xx_ipsrst}};

struct npcm_rc_data {
	struct reset_controller_dev rcdev;
	const struct npcm_reset_info *info;
	struct regmap *gcr_regmap;
	u32 sw_reset_number;
	struct device *dev;
	void __iomem *base;
	spinlock_t lock;
};

#define to_rc_data(p) container_of(p, struct npcm_rc_data, rcdev)

static int npcm_rc_restart(struct sys_off_data *data)
{
	struct npcm_rc_data *rc = data->cb_data;

	writel(NPCM_SWRST << rc->sw_reset_number, rc->base + NPCM_SWRSTR);
	mdelay(1000);

	pr_emerg("%s: unable to restart system\n", __func__);

	return NOTIFY_DONE;
}

static int npcm_rc_setclear_reset(struct reset_controller_dev *rcdev,
				  unsigned long id, bool set)
{
	struct npcm_rc_data *rc = to_rc_data(rcdev);
	unsigned int rst_bit = BIT(id & NPCM_MASK_RESETS);
	unsigned int ctrl_offset = id >> 8;
	unsigned long flags;
	u32 stat;

	spin_lock_irqsave(&rc->lock, flags);
	stat = readl(rc->base + ctrl_offset);
	if (set)
		writel(stat | rst_bit, rc->base + ctrl_offset);
	else
		writel(stat & ~rst_bit, rc->base + ctrl_offset);
	spin_unlock_irqrestore(&rc->lock, flags);

	return 0;
}

static int npcm_rc_assert(struct reset_controller_dev *rcdev, unsigned long id)
{
	return npcm_rc_setclear_reset(rcdev, id, true);
}

static int npcm_rc_deassert(struct reset_controller_dev *rcdev,
			    unsigned long id)
{
	return npcm_rc_setclear_reset(rcdev, id, false);
}

static int npcm_rc_status(struct reset_controller_dev *rcdev,
			  unsigned long id)
{
	struct npcm_rc_data *rc = to_rc_data(rcdev);
	unsigned int rst_bit = BIT(id & NPCM_MASK_RESETS);
	unsigned int ctrl_offset = id >> 8;

	return (readl(rc->base + ctrl_offset) & rst_bit);
}

static int npcm_reset_xlate(struct reset_controller_dev *rcdev,
			    const struct of_phandle_args *reset_spec)
{
	struct npcm_rc_data *rc = to_rc_data(rcdev);
	unsigned int offset, bit;
	bool offset_found = false;
	int off_num;

	offset = reset_spec->args[0];
	for (off_num = 0 ; off_num < rc->info->num_ipsrst ; off_num++) {
		if (offset == rc->info->ipsrst[off_num]) {
			offset_found = true;
			break;
		}

Annotation

Implementation Notes