aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-12-09 14:36:01 -0500
committerJean Delvare <khali@linux-fr.org>2009-12-09 14:36:01 -0500
commitfc16c56e694d361388bae701894fd719dbc0f7eb (patch)
tree08f28db4acb5a8c1c045d78777c08d28f5df6820 /drivers
parentb69b039922673dfabe0b5774f2e313f2a2297d01 (diff)
hwmon: (f71882fg) Fix sysfs file removal
There is a bug in the old sysfs file removal, as it uses fxxxx_in_temp_attr to remove the in and temp sysfs attributes, but fxxxx_in_temp_attr has temp#_alarm, where as f71858fg_in_temp_attr has temp#_max_alarm, so the temp#_max_alarm attributes for the f71858fg never get removed. This patch fixes this by doing the sysfs removal exactly the same way as the creation instead of being (too) clever, this will also avoid similar bugs in the future. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/f71882fg.c91
1 files changed, 66 insertions, 25 deletions
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,
1810 return 0; 1810 return 0;
1811} 1811}
1812 1812
1813static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
1814 struct sensor_device_attribute_2 *attr, int count)
1815{
1816 int i;
1817
1818 for (i = 0; i < count; i++)
1819 device_remove_file(&pdev->dev, &attr[i].dev_attr);
1820}
1821
1813static int __devinit f71882fg_probe(struct platform_device *pdev) 1822static int __devinit f71882fg_probe(struct platform_device *pdev)
1814{ 1823{
1815 struct f71882fg_data *data; 1824 struct f71882fg_data *data;
@@ -1974,42 +1983,74 @@ exit_free:
1974 1983
1975static int f71882fg_remove(struct platform_device *pdev) 1984static int f71882fg_remove(struct platform_device *pdev)
1976{ 1985{
1977 int i, j;
1978 struct f71882fg_data *data = platform_get_drvdata(pdev); 1986 struct f71882fg_data *data = platform_get_drvdata(pdev);
1987 int nr_fans = (data->type == f71882fg) ? 4 : 3;
1988 u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
1979 1989
1980 platform_set_drvdata(pdev, NULL); 1990 platform_set_drvdata(pdev, NULL);
1981 if (data->hwmon_dev) 1991 if (data->hwmon_dev)
1982 hwmon_device_unregister(data->hwmon_dev); 1992 hwmon_device_unregister(data->hwmon_dev);
1983 1993
1984 /* Note we are not looping over all attr arrays we have as the ones
1985 below are supersets of the ones skipped. */
1986 device_remove_file(&pdev->dev, &dev_attr_name); 1994 device_remove_file(&pdev->dev, &dev_attr_name);
1987 1995
1988 for (i = 0; i < ARRAY_SIZE(fxxxx_in_temp_attr); i++) 1996 if (start_reg & 0x01) {
1989 device_remove_file(&pdev->dev, 1997 switch (data->type) {
1990 &fxxxx_in_temp_attr[i].dev_attr); 1998 case f71858fg:
1991 1999 if (data->temp_config & 0x10)
1992 for (i = 0; i < ARRAY_SIZE(fxxxx_in1_alarm_attr); i++) 2000 f71882fg_remove_sysfs_files(pdev,
1993 device_remove_file(&pdev->dev, 2001 f8000_in_temp_attr,
1994 &fxxxx_in1_alarm_attr[i].dev_attr); 2002 ARRAY_SIZE(f8000_in_temp_attr));
1995 2003 else
1996 for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++) 2004 f71882fg_remove_sysfs_files(pdev,
1997 for (j = 0; j < ARRAY_SIZE(fxxxx_fan_attr[0]); j++) 2005 f71858fg_in_temp_attr,
1998 device_remove_file(&pdev->dev, 2006 ARRAY_SIZE(f71858fg_in_temp_attr));
1999 &fxxxx_fan_attr[i][j].dev_attr); 2007 break;
2008 case f71882fg:
2009 f71882fg_remove_sysfs_files(pdev,
2010 fxxxx_in1_alarm_attr,
2011 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2012 /* fall through! */
2013 case f71862fg:
2014 f71882fg_remove_sysfs_files(pdev,
2015 fxxxx_in_temp_attr,
2016 ARRAY_SIZE(fxxxx_in_temp_attr));
2017 break;
2018 case f8000:
2019 f71882fg_remove_sysfs_files(pdev,
2020 f8000_in_temp_attr,
2021 ARRAY_SIZE(f8000_in_temp_attr));
2022 break;
2023 }
2024 }
2000 2025
2001 for (i = 0; i < ARRAY_SIZE(fxxxx_fan_beep_attr); i++) 2026 if (start_reg & 0x02) {
2002 device_remove_file(&pdev->dev, 2027 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2003 &fxxxx_fan_beep_attr[i].dev_attr); 2028 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2004 2029
2005 for (i = 0; i < ARRAY_SIZE(fxxxx_auto_pwm_attr); i++) 2030 if (data->type == f71862fg || data->type == f71882fg)
2006 for (j = 0; j < ARRAY_SIZE(fxxxx_auto_pwm_attr[0]); j++) 2031 f71882fg_remove_sysfs_files(pdev,
2007 device_remove_file(&pdev->dev, 2032 fxxxx_fan_beep_attr, nr_fans);
2008 &fxxxx_auto_pwm_attr[i][j].dev_attr);
2009 2033
2010 for (i = 0; i < ARRAY_SIZE(f8000_auto_pwm_attr); i++) 2034 switch (data->type) {
2011 device_remove_file(&pdev->dev, 2035 case f71862fg:
2012 &f8000_auto_pwm_attr[i].dev_attr); 2036 f71882fg_remove_sysfs_files(pdev,
2037 f71862fg_auto_pwm_attr,
2038 ARRAY_SIZE(f71862fg_auto_pwm_attr));
2039 break;
2040 case f8000:
2041 f71882fg_remove_sysfs_files(pdev,
2042 f8000_fan_attr,
2043 ARRAY_SIZE(f8000_fan_attr));
2044 f71882fg_remove_sysfs_files(pdev,
2045 f8000_auto_pwm_attr,
2046 ARRAY_SIZE(f8000_auto_pwm_attr));
2047 break;
2048 default: /* f71858fg / f71882fg / f71889fg */
2049 f71882fg_remove_sysfs_files(pdev,
2050 &fxxxx_auto_pwm_attr[0][0],
2051 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2052 }
2053 }
2013 2054
2014 kfree(data); 2055 kfree(data);
2015 2056