drivers/power/supply/surface_charger.c

Source file repositories/reference/linux-study-clean/drivers/power/supply/surface_charger.c

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/surface_charger.c
Extension
.c
Size
6822 bytes
Lines
283
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 spwr_psy_properties {
	const char *name;
	struct ssam_event_registry registry;
};

struct spwr_ac_device {
	struct ssam_device *sdev;

	char name[32];
	struct power_supply *psy;
	struct power_supply_desc psy_desc;

	struct ssam_event_notifier notif;

	struct mutex lock;  /* Guards access to state below. */

	__le32 state;
};


/* -- State management. ----------------------------------------------------- */

static int spwr_ac_update_unlocked(struct spwr_ac_device *ac)
{
	__le32 old = ac->state;
	int status;

	lockdep_assert_held(&ac->lock);

	status = ssam_retry(ssam_bat_get_psrc, ac->sdev, &ac->state);
	if (status < 0)
		return status;

	return old != ac->state;
}

static int spwr_ac_update(struct spwr_ac_device *ac)
{
	int status;

	mutex_lock(&ac->lock);
	status = spwr_ac_update_unlocked(ac);
	mutex_unlock(&ac->lock);

	return status;
}

static int spwr_ac_recheck(struct spwr_ac_device *ac)
{
	int status;

	status = spwr_ac_update(ac);
	if (status > 0)
		power_supply_changed(ac->psy);

	return status >= 0 ? 0 : status;
}

static u32 spwr_notify_ac(struct ssam_event_notifier *nf, const struct ssam_event *event)
{
	struct spwr_ac_device *ac;
	int status;

	ac = container_of(nf, struct spwr_ac_device, notif);

	dev_dbg(&ac->sdev->dev, "power event (cid = %#04x, iid = %#04x, tid = %#04x)\n",
		event->command_id, event->instance_id, event->target_id);

	/*
	 * Allow events of all targets/instances here. Global adapter status
	 * seems to be handled via target=1 and instance=1, but events are
	 * reported on all targets/instances in use.
	 *
	 * While it should be enough to just listen on 1/1, listen everywhere to
	 * make sure we don't miss anything.
	 */

	switch (event->command_id) {
	case SAM_EVENT_CID_BAT_ADP:
		status = spwr_ac_recheck(ac);
		return ssam_notifier_from_errno(status) | SSAM_NOTIF_HANDLED;

	default:
		return 0;
	}
}


/* -- Properties. ----------------------------------------------------------- */

Annotation

Implementation Notes