drivers/sbus/char/envctrl.c

Source file repositories/reference/linux-study-clean/drivers/sbus/char/envctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/sbus/char/envctrl.c
Extension
.c
Size
30785 bytes
Lines
1135
Domain
Driver Families
Bucket
drivers/sbus
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations envctrl_fops = {
	.owner =		THIS_MODULE,
	.read =			envctrl_read,
	.unlocked_ioctl =	envctrl_ioctl,
	.compat_ioctl =		compat_ptr_ioctl,
	.open =			envctrl_open,
	.release =		envctrl_release,
	.llseek =		noop_llseek,
};	

static struct miscdevice envctrl_dev = {
	ENVCTRL_MINOR,
	"envctrl",
	&envctrl_fops
};

/* Function Description: Set monitor type based on firmware description.
 * Return: None.
 */
static void envctrl_set_mon(struct i2c_child_t *pchild,
			    const char *chnl_desc,
			    int chnl_no)
{
	/* Firmware only has temperature type.  It does not distinguish
	 * different kinds of temperatures.  We use channel description
	 * to disinguish them.
	 */
	if (!(strcmp(chnl_desc,"temp,cpu")) ||
	    !(strcmp(chnl_desc,"temp,cpu0")) ||
	    !(strcmp(chnl_desc,"temp,cpu1")) ||
	    !(strcmp(chnl_desc,"temp,cpu2")) ||
	    !(strcmp(chnl_desc,"temp,cpu3")))
		pchild->mon_type[chnl_no] = ENVCTRL_CPUTEMP_MON;

	if (!(strcmp(chnl_desc,"vddcore,cpu0")) ||
	    !(strcmp(chnl_desc,"vddcore,cpu1")) ||
	    !(strcmp(chnl_desc,"vddcore,cpu2")) ||
	    !(strcmp(chnl_desc,"vddcore,cpu3")))
		pchild->mon_type[chnl_no] = ENVCTRL_CPUVOLTAGE_MON;

	if (!(strcmp(chnl_desc,"temp,motherboard")))
		pchild->mon_type[chnl_no] = ENVCTRL_MTHRBDTEMP_MON;

	if (!(strcmp(chnl_desc,"temp,scsi")))
		pchild->mon_type[chnl_no] = ENVCTRL_SCSITEMP_MON;

	if (!(strcmp(chnl_desc,"temp,ethernet")))
		pchild->mon_type[chnl_no] = ENVCTRL_ETHERTEMP_MON;
}

/* Function Description: Initialize monitor channel with channel desc,
 *                       decoding tables, monitor type, optional properties.
 * Return: None.
 */
static void envctrl_init_adc(struct i2c_child_t *pchild, struct device_node *dp)
{
	int i = 0, len;
	const char *pos;
	const unsigned int *pval;

	/* Firmware describe channels into a stream separated by a '\0'. */
	pos = of_get_property(dp, "channels-description", &len);

	while (len > 0) {
		int l = strlen(pos) + 1;
		envctrl_set_mon(pchild, pos, i++);
		len -= l;
		pos += l;
	}

	/* Get optional properties. */
	pval = of_get_property(dp, "warning-temp", NULL);
	if (pval)
		warning_temperature = *pval;

	pval = of_get_property(dp, "shutdown-temp", NULL);
	if (pval)
		shutdown_temperature = *pval;
}

/* Function Description: Initialize child device monitoring fan status.
 * Return: None.
 */
static void envctrl_init_fanstat(struct i2c_child_t *pchild)
{
	int i;

	/* Go through all channels and set up the mask. */
	for (i = 0; i < pchild->total_chnls; i++)
		pchild->fan_mask |= chnls_mask[(pchild->chnl_array[i]).chnl_no];

Annotation

Implementation Notes