hwmon: (it87) Use is_visible for pwm attributes
authorGuenter Roeck <linux@roeck-us.net>
Sat, 30 Mar 2013 22:02:12 +0000 (15:02 -0700)
committerGuenter Roeck <linux@roeck-us.net>
Tue, 19 Apr 2016 13:32:36 +0000 (06:32 -0700)
Simplify code and reduce object size by about 250 bytes on x86_64.

Tested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/it87.c

index e70d227c2bf8208da0a174dd2067a7b03000156a..0c13d640bcc7afa5660ac810a97751b0f09da2ca 100644 (file)
@@ -498,6 +498,7 @@ struct it87_data {
         * is no longer needed, but it is still done to keep the driver
         * simple.
         */
+       u8 has_pwm;             /* Bitfield, pwm control enabled */
        u8 pwm_ctrl[6];         /* Register value */
        u8 pwm_duty[6];         /* Manual PWM value set by user */
        u8 pwm_temp_map[6];     /* PWM to temp. chan. mapping (bits 1-0) */
@@ -1340,15 +1341,6 @@ static ssize_t set_pwm_temp_map(struct device *dev,
        long val;
        u8 reg;
 
-       /*
-        * This check can go away if we ever support automatic fan speed
-        * control on newer chips.
-        */
-       if (!has_old_autopwm(data)) {
-               dev_notice(dev, "Mapping change disabled for safety reasons\n");
-               return -EINVAL;
-       }
-
        if (kstrtol(buf, 10, &val) < 0)
                return -EINVAL;
 
@@ -1482,7 +1474,7 @@ static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
 static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
 static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq,
                          set_pwm_freq, 0);
-static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO,
                          show_pwm_temp_map, set_pwm_temp_map, 0);
 static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR,
                            show_auto_pwm, set_auto_pwm, 0, 0);
@@ -1507,7 +1499,7 @@ static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
                          show_pwm_enable, set_pwm_enable, 1);
 static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1);
 static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, set_pwm_freq, 1);
-static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO,
                          show_pwm_temp_map, set_pwm_temp_map, 1);
 static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR,
                            show_auto_pwm, set_auto_pwm, 1, 0);
@@ -1532,7 +1524,7 @@ static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
                          show_pwm_enable, set_pwm_enable, 2);
 static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2);
 static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL, 2);
-static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO,
                          show_pwm_temp_map, set_pwm_temp_map, 2);
 static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR,
                            show_auto_pwm, set_auto_pwm, 2, 0);
@@ -1557,21 +1549,21 @@ static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR,
                          show_pwm_enable, set_pwm_enable, 3);
 static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 3);
 static SENSOR_DEVICE_ATTR(pwm4_freq, S_IRUGO, show_pwm_freq, NULL, 3);
-static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO,
                          show_pwm_temp_map, set_pwm_temp_map, 3);
 
 static SENSOR_DEVICE_ATTR(pwm5_enable, S_IRUGO | S_IWUSR,
                          show_pwm_enable, set_pwm_enable, 4);
 static SENSOR_DEVICE_ATTR(pwm5, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 4);
 static SENSOR_DEVICE_ATTR(pwm5_freq, S_IRUGO, show_pwm_freq, NULL, 4);
-static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO,
                          show_pwm_temp_map, set_pwm_temp_map, 4);
 
 static SENSOR_DEVICE_ATTR(pwm6_enable, S_IRUGO | S_IWUSR,
                          show_pwm_enable, set_pwm_enable, 5);
 static SENSOR_DEVICE_ATTR(pwm6, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 5);
 static SENSOR_DEVICE_ATTR(pwm6_freq, S_IRUGO, show_pwm_freq, NULL, 5);
-static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO,
                          show_pwm_temp_map, set_pwm_temp_map, 5);
 
 /* Alarms */
@@ -1969,67 +1961,81 @@ static const struct attribute_group it87_group_fan = {
        .is_visible = it87_fan_is_visible,
 };
 
-static struct attribute *it87_attributes_pwm[6][4+1] = { {
+static umode_t it87_pwm_is_visible(struct kobject *kobj,
+                                  struct attribute *attr, int index)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct it87_data *data = dev_get_drvdata(dev);
+       int i = index / 4;      /* pwm index */
+       int a = index % 4;      /* attribute index */
+
+       if (!(data->has_pwm & (1 << i)))
+               return 0;
+
+       /* pwmX_auto_channels_temp is only writable for old auto pwm */
+       if (a == 3 && has_old_autopwm(data))
+               return attr->mode | S_IWUSR;
+
+       /* pwm2_freq is writable if there are two pwm frequency selects */
+       if (has_pwm_freq2(data) && i == 1 && a == 2)
+               return attr->mode | S_IWUSR;
+
+       return attr->mode;
+}
+
+static struct attribute *it87_attributes_pwm[] = {
        &sensor_dev_attr_pwm1_enable.dev_attr.attr,
        &sensor_dev_attr_pwm1.dev_attr.attr,
        &sensor_dev_attr_pwm1_freq.dev_attr.attr,
        &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
-       NULL
-}, {
+
        &sensor_dev_attr_pwm2_enable.dev_attr.attr,
        &sensor_dev_attr_pwm2.dev_attr.attr,
        &sensor_dev_attr_pwm2_freq.dev_attr.attr,
        &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
-       NULL
-}, {
+
        &sensor_dev_attr_pwm3_enable.dev_attr.attr,
        &sensor_dev_attr_pwm3.dev_attr.attr,
        &sensor_dev_attr_pwm3_freq.dev_attr.attr,
        &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
-       NULL
-}, {
+
        &sensor_dev_attr_pwm4_enable.dev_attr.attr,
        &sensor_dev_attr_pwm4.dev_attr.attr,
        &sensor_dev_attr_pwm4_freq.dev_attr.attr,
        &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr,
-       NULL
-}, {
+
        &sensor_dev_attr_pwm5_enable.dev_attr.attr,
        &sensor_dev_attr_pwm5.dev_attr.attr,
        &sensor_dev_attr_pwm5_freq.dev_attr.attr,
        &sensor_dev_attr_pwm5_auto_channels_temp.dev_attr.attr,
-       NULL
-}, {
+
        &sensor_dev_attr_pwm6_enable.dev_attr.attr,
        &sensor_dev_attr_pwm6.dev_attr.attr,
        &sensor_dev_attr_pwm6_freq.dev_attr.attr,
        &sensor_dev_attr_pwm6_auto_channels_temp.dev_attr.attr,
+
        NULL
-} };
+};
 
-static umode_t pwm_attribute_mode(struct kobject *kobj, struct attribute *attr,
-                                 int index)
+static const struct attribute_group it87_group_pwm = {
+       .attrs = it87_attributes_pwm,
+       .is_visible = it87_pwm_is_visible,
+};
+
+static umode_t it87_auto_pwm_is_visible(struct kobject *kobj,
+                                       struct attribute *attr, int index)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
        struct it87_data *data = dev_get_drvdata(dev);
+       int i = index / 9;      /* pwm index */
 
-       if (has_pwm_freq2(data) && index == 2)
-               return attr->mode | S_IWUSR;
+       if (!(data->has_pwm & (1 << i)))
+               return 0;
 
        return attr->mode;
 }
 
-static const struct attribute_group it87_group_pwm[6] = {
-       { .attrs = it87_attributes_pwm[0] },
-       { .attrs = it87_attributes_pwm[1],
-         .is_visible = pwm_attribute_mode, },
-       { .attrs = it87_attributes_pwm[2] },
-       { .attrs = it87_attributes_pwm[3] },
-       { .attrs = it87_attributes_pwm[4] },
-       { .attrs = it87_attributes_pwm[5] },
-};
-
-static struct attribute *it87_attributes_autopwm[3][9+1] = { {
+static struct attribute *it87_attributes_auto_pwm[] = {
        &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
@@ -2039,8 +2045,7 @@ static struct attribute *it87_attributes_autopwm[3][9+1] = { {
        &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
        &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
        &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
-       NULL
-}, {
+
        &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr,
@@ -2050,8 +2055,7 @@ static struct attribute *it87_attributes_autopwm[3][9+1] = { {
        &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
        &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
        &sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr,
-       NULL
-}, {
+
        &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr,
@@ -2061,13 +2065,13 @@ static struct attribute *it87_attributes_autopwm[3][9+1] = { {
        &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
        &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
        &sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr,
-       NULL
-} };
 
-static const struct attribute_group it87_group_autopwm[3] = {
-       { .attrs = it87_attributes_autopwm[0] },
-       { .attrs = it87_attributes_autopwm[1] },
-       { .attrs = it87_attributes_autopwm[2] },
+       NULL,
+};
+
+static const struct attribute_group it87_group_auto_pwm = {
+       .attrs = it87_attributes_auto_pwm,
+       .is_visible = it87_auto_pwm_is_visible,
 };
 
 static struct attribute *it87_attributes_vid[] = {
@@ -2456,23 +2460,15 @@ exit:
 
 static void it87_remove_files(struct device *dev)
 {
-       struct it87_data *data = dev_get_drvdata(dev);
        struct it87_sio_data *sio_data = dev_get_platdata(dev);
-       int i;
 
        sysfs_remove_group(&dev->kobj, &it87_group);
        sysfs_remove_group(&dev->kobj, &it87_group_in);
        sysfs_remove_group(&dev->kobj, &it87_group_temp);
        sysfs_remove_group(&dev->kobj, &it87_group_fan);
+       sysfs_remove_group(&dev->kobj, &it87_group_pwm);
+       sysfs_remove_group(&dev->kobj, &it87_group_auto_pwm);
 
-       for (i = 0; i < 6; i++) {
-               if (sio_data->skip_pwm & (1 << i))
-                       continue;
-               sysfs_remove_group(&dev->kobj, &it87_group_pwm[i]);
-               if (has_old_autopwm(data))
-                       sysfs_remove_group(&dev->kobj,
-                                          &it87_group_autopwm[i]);
-       }
        if (!sio_data->skip_vid)
                sysfs_remove_group(&dev->kobj, &it87_group_vid);
        sysfs_remove_group(&dev->kobj, &it87_group_label);
@@ -2760,18 +2756,15 @@ static int it87_probe(struct platform_device *pdev)
                goto error;
 
        if (enable_pwm_interface) {
-               for (i = 0; i < 6; i++) {
-                       if (sio_data->skip_pwm & (1 << i))
-                               continue;
-                       err = sysfs_create_group(&dev->kobj,
-                                                &it87_group_pwm[i]);
-                       if (err)
-                               goto error;
+               data->has_pwm = (1 << ARRAY_SIZE(IT87_REG_PWM)) - 1;
+               data->has_pwm &= ~sio_data->skip_pwm;
 
-                       if (!has_old_autopwm(data))
-                               continue;
+               err = sysfs_create_group(&dev->kobj, &it87_group_pwm);
+               if (err)
+                       goto error;
+               if (has_old_autopwm(data)) {
                        err = sysfs_create_group(&dev->kobj,
-                                                &it87_group_autopwm[i]);
+                                                &it87_group_auto_pwm);
                        if (err)
                                goto error;
                }