diff options
Diffstat (limited to 'drivers/hwmon/hwmon.c')
| -rw-r--r-- | drivers/hwmon/hwmon.c | 68 | 
1 files changed, 41 insertions, 27 deletions
| diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 1f3b30b085b9..d018b20089ec 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -51,6 +51,7 @@ struct hwmon_device_attribute {  #define to_hwmon_attr(d) \  	container_of(d, struct hwmon_device_attribute, dev_attr) +#define to_dev_attr(a) container_of(a, struct device_attribute, attr)  /*   * Thermal zone information @@ -58,7 +59,7 @@ struct hwmon_device_attribute {   * also provides the sensor index.   */  struct hwmon_thermal_data { -	struct hwmon_device *hwdev;	/* Reference to hwmon device */ +	struct device *dev;		/* Reference to hwmon device */  	int index;			/* sensor index */  }; @@ -95,9 +96,27 @@ static const struct attribute_group *hwmon_dev_attr_groups[] = {  	NULL  }; +static void hwmon_free_attrs(struct attribute **attrs) +{ +	int i; + +	for (i = 0; attrs[i]; i++) { +		struct device_attribute *dattr = to_dev_attr(attrs[i]); +		struct hwmon_device_attribute *hattr = to_hwmon_attr(dattr); + +		kfree(hattr); +	} +	kfree(attrs); +} +  static void hwmon_dev_release(struct device *dev)  { -	kfree(to_hwmon_device(dev)); +	struct hwmon_device *hwdev = to_hwmon_device(dev); + +	if (hwdev->group.attrs) +		hwmon_free_attrs(hwdev->group.attrs); +	kfree(hwdev->groups); +	kfree(hwdev);  }  static struct class hwmon_class = { @@ -119,11 +138,11 @@ static DEFINE_IDA(hwmon_ida);  static int hwmon_thermal_get_temp(void *data, int *temp)  {  	struct hwmon_thermal_data *tdata = data; -	struct hwmon_device *hwdev = tdata->hwdev; +	struct hwmon_device *hwdev = to_hwmon_device(tdata->dev);  	int ret;  	long t; -	ret = hwdev->chip->ops->read(&hwdev->dev, hwmon_temp, hwmon_temp_input, +	ret = hwdev->chip->ops->read(tdata->dev, hwmon_temp, hwmon_temp_input,  				     tdata->index, &t);  	if (ret < 0)  		return ret; @@ -137,8 +156,7 @@ static const struct thermal_zone_of_device_ops hwmon_thermal_ops = {  	.get_temp = hwmon_thermal_get_temp,  }; -static int hwmon_thermal_add_sensor(struct device *dev, -				    struct hwmon_device *hwdev, int index) +static int hwmon_thermal_add_sensor(struct device *dev, int index)  {  	struct hwmon_thermal_data *tdata;  	struct thermal_zone_device *tzd; @@ -147,10 +165,10 @@ static int hwmon_thermal_add_sensor(struct device *dev,  	if (!tdata)  		return -ENOMEM; -	tdata->hwdev = hwdev; +	tdata->dev = dev;  	tdata->index = index; -	tzd = devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, +	tzd = devm_thermal_zone_of_sensor_register(dev, index, tdata,  						   &hwmon_thermal_ops);  	/*  	 * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, @@ -162,8 +180,7 @@ static int hwmon_thermal_add_sensor(struct device *dev,  	return 0;  }  #else -static int hwmon_thermal_add_sensor(struct device *dev, -				    struct hwmon_device *hwdev, int index) +static int hwmon_thermal_add_sensor(struct device *dev, int index)  {  	return 0;  } @@ -250,8 +267,7 @@ static bool is_string_attr(enum hwmon_sensor_types type, u32 attr)  	       (type == hwmon_fan && attr == hwmon_fan_label);  } -static struct attribute *hwmon_genattr(struct device *dev, -				       const void *drvdata, +static struct attribute *hwmon_genattr(const void *drvdata,  				       enum hwmon_sensor_types type,  				       u32 attr,  				       int index, @@ -279,7 +295,7 @@ static struct attribute *hwmon_genattr(struct device *dev,  	if ((mode & 0222) && !ops->write)  		return ERR_PTR(-EINVAL); -	hattr = devm_kzalloc(dev, sizeof(*hattr), GFP_KERNEL); +	hattr = kzalloc(sizeof(*hattr), GFP_KERNEL);  	if (!hattr)  		return ERR_PTR(-ENOMEM); @@ -492,8 +508,7 @@ static int hwmon_num_channel_attrs(const struct hwmon_channel_info *info)  	return n;  } -static int hwmon_genattrs(struct device *dev, -			  const void *drvdata, +static int hwmon_genattrs(const void *drvdata,  			  struct attribute **attrs,  			  const struct hwmon_ops *ops,  			  const struct hwmon_channel_info *info) @@ -519,7 +534,7 @@ static int hwmon_genattrs(struct device *dev,  			attr_mask &= ~BIT(attr);  			if (attr >= template_size)  				return -EINVAL; -			a = hwmon_genattr(dev, drvdata, info->type, attr, i, +			a = hwmon_genattr(drvdata, info->type, attr, i,  					  templates[attr], ops);  			if (IS_ERR(a)) {  				if (PTR_ERR(a) != -ENOENT) @@ -533,8 +548,7 @@ static int hwmon_genattrs(struct device *dev,  }  static struct attribute ** -__hwmon_create_attrs(struct device *dev, const void *drvdata, -		     const struct hwmon_chip_info *chip) +__hwmon_create_attrs(const void *drvdata, const struct hwmon_chip_info *chip)  {  	int ret, i, aindex = 0, nattrs = 0;  	struct attribute **attrs; @@ -545,15 +559,17 @@ __hwmon_create_attrs(struct device *dev, const void *drvdata,  	if (nattrs == 0)  		return ERR_PTR(-EINVAL); -	attrs = devm_kcalloc(dev, nattrs + 1, sizeof(*attrs), GFP_KERNEL); +	attrs = kcalloc(nattrs + 1, sizeof(*attrs), GFP_KERNEL);  	if (!attrs)  		return ERR_PTR(-ENOMEM);  	for (i = 0; chip->info[i]; i++) { -		ret = hwmon_genattrs(dev, drvdata, &attrs[aindex], chip->ops, +		ret = hwmon_genattrs(drvdata, &attrs[aindex], chip->ops,  				     chip->info[i]); -		if (ret < 0) +		if (ret < 0) { +			hwmon_free_attrs(attrs);  			return ERR_PTR(ret); +		}  		aindex += ret;  	} @@ -595,14 +611,13 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,  			for (i = 0; groups[i]; i++)  				ngroups++; -		hwdev->groups = devm_kcalloc(dev, ngroups, sizeof(*groups), -					     GFP_KERNEL); +		hwdev->groups = kcalloc(ngroups, sizeof(*groups), GFP_KERNEL);  		if (!hwdev->groups) {  			err = -ENOMEM;  			goto free_hwmon;  		} -		attrs = __hwmon_create_attrs(dev, drvdata, chip); +		attrs = __hwmon_create_attrs(drvdata, chip);  		if (IS_ERR(attrs)) {  			err = PTR_ERR(attrs);  			goto free_hwmon; @@ -647,8 +662,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,  							   hwmon_temp_input, j))  					continue;  				if (info[i]->config[j] & HWMON_T_INPUT) { -					err = hwmon_thermal_add_sensor(dev, -								hwdev, j); +					err = hwmon_thermal_add_sensor(hdev, j);  					if (err) {  						device_unregister(hdev);  						/* @@ -667,7 +681,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,  	return hdev;  free_hwmon: -	kfree(hwdev); +	hwmon_dev_release(hdev);  ida_remove:  	ida_simple_remove(&hwmon_ida, id);  	return ERR_PTR(err); | 
