diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 210ed6619df4..3a695f06905e 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -1810,6 +1810,15 @@ static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev, return 0; } +static void f71882fg_remove_sysfs_files(struct platform_device *pdev, + struct sensor_device_attribute_2 *attr, int count) +{ + int i; + + for (i = 0; i < count; i++) + device_remove_file(&pdev->dev, &attr[i].dev_attr); +} + static int __devinit f71882fg_probe(struct platform_device *pdev) { struct f71882fg_data *data; @@ -1974,42 +1983,74 @@ exit_free: static int f71882fg_remove(struct platform_device *pdev) { - int i, j; struct f71882fg_data *data = platform_get_drvdata(pdev); + int nr_fans = (data->type == f71882fg) ? 4 : 3; + u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); platform_set_drvdata(pdev, NULL); if (data->hwmon_dev) hwmon_device_unregister(data->hwmon_dev); - /* Note we are not looping over all attr arrays we have as the ones - below are supersets of the ones skipped. */ device_remove_file(&pdev->dev, &dev_attr_name); - for (i = 0; i < ARRAY_SIZE(fxxxx_in_temp_attr); i++) - device_remove_file(&pdev->dev, - &fxxxx_in_temp_attr[i].dev_attr); + if (start_reg & 0x01) { + switch (data->type) { + case f71858fg: + if (data->temp_config & 0x10) + f71882fg_remove_sysfs_files(pdev, + f8000_in_temp_attr, + ARRAY_SIZE(f8000_in_temp_attr)); + else + f71882fg_remove_sysfs_files(pdev, + f71858fg_in_temp_attr, + ARRAY_SIZE(f71858fg_in_temp_attr)); + break; + case f71882fg: + f71882fg_remove_sysfs_files(pdev, + fxxxx_in1_alarm_attr, + ARRAY_SIZE(fxxxx_in1_alarm_attr)); + /* fall through! */ + case f71862fg: + f71882fg_remove_sysfs_files(pdev, + fxxxx_in_temp_attr, + ARRAY_SIZE(fxxxx_in_temp_attr)); + break; + case f8000: + f71882fg_remove_sysfs_files(pdev, + f8000_in_temp_attr, + ARRAY_SIZE(f8000_in_temp_attr)); + break; + } + } - for (i = 0; i < ARRAY_SIZE(fxxxx_in1_alarm_attr); i++) - device_remove_file(&pdev->dev, - &fxxxx_in1_alarm_attr[i].dev_attr); + if (start_reg & 0x02) { + f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0], + ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans); - for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++) - for (j = 0; j < ARRAY_SIZE(fxxxx_fan_attr[0]); j++) - device_remove_file(&pdev->dev, - &fxxxx_fan_attr[i][j].dev_attr); + if (data->type == f71862fg || data->type == f71882fg) + f71882fg_remove_sysfs_files(pdev, + fxxxx_fan_beep_attr, nr_fans); - for (i = 0; i < ARRAY_SIZE(fxxxx_fan_beep_attr); i++) - device_remove_file(&pdev->dev, - &fxxxx_fan_beep_attr[i].dev_attr); - - for (i = 0; i < ARRAY_SIZE(fxxxx_auto_pwm_attr); i++) - for (j = 0; j < ARRAY_SIZE(fxxxx_auto_pwm_attr[0]); j++) - device_remove_file(&pdev->dev, - &fxxxx_auto_pwm_attr[i][j].dev_attr); - - for (i = 0; i < ARRAY_SIZE(f8000_auto_pwm_attr); i++) - device_remove_file(&pdev->dev, - &f8000_auto_pwm_attr[i].dev_attr); + switch (data->type) { + case f71862fg: + f71882fg_remove_sysfs_files(pdev, + f71862fg_auto_pwm_attr, + ARRAY_SIZE(f71862fg_auto_pwm_attr)); + break; + case f8000: + f71882fg_remove_sysfs_files(pdev, + f8000_fan_attr, + ARRAY_SIZE(f8000_fan_attr)); + f71882fg_remove_sysfs_files(pdev, + f8000_auto_pwm_attr, + ARRAY_SIZE(f8000_auto_pwm_attr)); + break; + default: /* f71858fg / f71882fg / f71889fg */ + f71882fg_remove_sysfs_files(pdev, + &fxxxx_auto_pwm_attr[0][0], + ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); + } + } kfree(data);