diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 210ed6619df48178cd68f2022ce0d5bfc4ffd51d..3a695f06905e2abcf1b9ad2ce89f7e50a6499c39 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);
-
-	for (i = 0; i < ARRAY_SIZE(fxxxx_in1_alarm_attr); i++)
-		device_remove_file(&pdev->dev,
-					&fxxxx_in1_alarm_attr[i].dev_attr);
-
-	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 (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_fan_beep_attr); i++)
-		device_remove_file(&pdev->dev,
-				   &fxxxx_fan_beep_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_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);
+		if (data->type == f71862fg || data->type == f71882fg)
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_fan_beep_attr, nr_fans);
 
-	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);