Skip to content

Commit

Permalink
hwmon/f71882fg: Make the decision wether to register fan attr. per fan
Browse files Browse the repository at this point in the history
Before this patch the f71882fg driver completely fails to initialize
on systems which have reserved settings in the pwm enable register, and
it disables all auto pwm sysfs attributes if any fan is controlled by
a digital sensor reading.

This patch changes the fail to initialize into don't register any attributes
for the fan for which there are reserved settings in the pwm enable register
and also makes the not registering of auto pwm sysfs attributes a per fan
thing.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
  • Loading branch information
Hans de Goede authored and Guenter Roeck committed Oct 24, 2011
1 parent 9af0794 commit 6543439
Showing 1 changed file with 54 additions and 65 deletions.
119 changes: 54 additions & 65 deletions drivers/hwmon/f71882fg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2155,11 +2155,37 @@ static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
}

static int __devinit f71882fg_create_fan_sysfs_files(
struct platform_device *pdev, int idx, bool pwm_auto_point)
struct platform_device *pdev, int idx)
{
struct f71882fg_data *data = platform_get_drvdata(pdev);
int err;

/* Sanity check the pwm setting */
err = 0;
switch (data->type) {
case f71858fg:
if (((data->pwm_enable >> (idx * 2)) & 3) == 3)
err = 1;
break;
case f71862fg:
if (((data->pwm_enable >> (idx * 2)) & 1) != 1)
err = 1;
break;
case f8000:
if (idx == 2)
err = data->pwm_enable & 0x20;
break;
default:
break;
}
if (err) {
dev_err(&pdev->dev,
"Invalid (reserved) pwm settings: 0x%02x, "
"skipping fan %d\n",
(data->pwm_enable >> (idx * 2)) & 3, idx + 1);
return 0; /* This is a non fatal condition */
}

err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[idx][0],
ARRAY_SIZE(fxxxx_fan_attr[0]));
if (err)
Expand All @@ -2173,8 +2199,32 @@ static int __devinit f71882fg_create_fan_sysfs_files(
return err;
}

if (!pwm_auto_point)
return 0; /* All done */
dev_info(&pdev->dev, "Fan: %d is in %s mode\n", idx + 1,
(data->pwm_enable & (1 << (2 * idx))) ? "duty-cycle" : "RPM");

/* Check for unsupported auto pwm settings */
switch (data->type) {
case f71808e:
case f71808a:
case f71869:
case f71869a:
case f71889fg:
case f71889ed:
case f71889a:
data->pwm_auto_point_mapping[idx] =
f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(idx));
if ((data->pwm_auto_point_mapping[idx] & 0x80) ||
(data->pwm_auto_point_mapping[idx] & 3) == 0) {
dev_warn(&pdev->dev,
"Auto pwm controlled by raw digital "
"data, disabling pwm auto_point "
"sysfs attributes for fan %d\n", idx + 1);
return 0; /* This is a non fatal condition */
}
break;
default:
break;
}

switch (data->type) {
case f71862fg:
Expand Down Expand Up @@ -2295,8 +2345,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
}

if (start_reg & 0x02) {
bool pwm_auto_point = true;

switch (data->type) {
case f71808e:
case f71808a:
Expand All @@ -2322,69 +2370,10 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
data->pwm_enable =
f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);

/* Sanity check the pwm settings */
switch (data->type) {
case f71858fg:
err = 0;
for (i = 0; i < nr_fans; i++)
if (((data->pwm_enable >> (i * 2)) & 3) == 3)
err = 1;
break;
case f71862fg:
err = (data->pwm_enable & 0x15) != 0x15;
break;
case f8000:
err = data->pwm_enable & 0x20;
break;
default:
err = 0;
break;
}
if (err) {
dev_err(&pdev->dev,
"Invalid (reserved) pwm settings: 0x%02x\n",
(unsigned int)data->pwm_enable);
err = -ENODEV;
goto exit_unregister_sysfs;
}

switch (data->type) {
case f71808e:
case f71808a:
case f71869:
case f71869a:
case f71889fg:
case f71889ed:
case f71889a:
for (i = 0; i < nr_fans; i++) {
data->pwm_auto_point_mapping[i] =
f71882fg_read8(data,
F71882FG_REG_POINT_MAPPING(i));
if ((data->pwm_auto_point_mapping[i] & 0x80) ||
(data->pwm_auto_point_mapping[i] & 3) == 0)
break;
}
if (i != nr_fans) {
dev_warn(&pdev->dev,
"Auto pwm controlled by raw digital "
"data, disabling pwm auto_point "
"sysfs attributes\n");
pwm_auto_point = false;
}
break;
default:
break;
}

for (i = 0; i < nr_fans; i++) {
err = f71882fg_create_fan_sysfs_files(pdev, i,
pwm_auto_point);
err = f71882fg_create_fan_sysfs_files(pdev, i);
if (err)
goto exit_unregister_sysfs;

dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
(data->pwm_enable & (1 << 2 * i)) ?
"duty-cycle" : "RPM");
}

/* Some types have 1 extra fan with limited functionality */
Expand Down

0 comments on commit 6543439

Please sign in to comment.