drivers/thermal/thermal_netlink.c

Source file repositories/reference/linux-study-clean/drivers/thermal/thermal_netlink.c

File Facts

System
Linux kernel
Corpus path
drivers/thermal/thermal_netlink.c
Extension
.c
Size
24959 bytes
Lines
938
Domain
Driver Families
Bucket
drivers/thermal
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 param {
	struct nlattr **attrs;
	struct sk_buff *msg;
	const char *name;
	int tz_id;
	int cdev_id;
	int trip_id;
	int trip_temp;
	int trip_type;
	int trip_hyst;
	int temp;
	int prev_temp;
	int direction;
	int cdev_state;
	int cdev_max_state;
	struct thermal_genl_cpu_caps *cpu_capabilities;
	int cpu_capabilities_count;
};

typedef int (*cb_t)(struct param *);

static struct genl_family thermal_genl_family;
static BLOCKING_NOTIFIER_HEAD(thermal_genl_chain);

static int thermal_group_has_listeners(enum thermal_genl_multicast_groups group)
{
	return genl_has_listeners(&thermal_genl_family, &init_net, group);
}

/************************** Sampling encoding *******************************/

int thermal_genl_sampling_temp(int id, int temp)
{
	struct sk_buff *skb;
	void *hdr;

	if (!thermal_group_has_listeners(THERMAL_GENL_SAMPLING_GROUP))
		return 0;

	skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	hdr = genlmsg_put(skb, 0, 0, &thermal_genl_family, 0,
			  THERMAL_GENL_SAMPLING_TEMP);
	if (!hdr)
		goto out_free;

	if (nla_put_u32(skb, THERMAL_GENL_ATTR_TZ_ID, id))
		goto out_cancel;

	if (nla_put_u32(skb, THERMAL_GENL_ATTR_TZ_TEMP, temp))
		goto out_cancel;

	genlmsg_end(skb, hdr);

	genlmsg_multicast(&thermal_genl_family, skb, 0, THERMAL_GENL_SAMPLING_GROUP, GFP_KERNEL);

	return 0;
out_cancel:
	genlmsg_cancel(skb, hdr);
out_free:
	nlmsg_free(skb);

	return -EMSGSIZE;
}

/**************************** Event encoding *********************************/

static int thermal_genl_event_tz_create(struct param *p)
{
	if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id) ||
	    nla_put_string(p->msg, THERMAL_GENL_ATTR_TZ_NAME, p->name))
		return -EMSGSIZE;

	return 0;
}

static int thermal_genl_event_tz(struct param *p)
{
	if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id))
		return -EMSGSIZE;

	return 0;
}

static int thermal_genl_event_tz_trip_up(struct param *p)
{
	if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id) ||
	    nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, p->trip_id) ||

Annotation

Implementation Notes