Commit 55fb8b06813b190a9366fee396fac109638a9c9d

Authored by Jamie Lentin
Committed by Jason Cooper
1 parent f37fbd36c5

hwmon: Add devicetree bindings to gpio-fan

Allow a gpio-fan to be defined in devicetree, see binding documentation
for details.

Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
Acked-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>

Showing 2 changed files with 145 additions and 0 deletions Side-by-side Diff

Documentation/devicetree/bindings/gpio/gpio-fan.txt
  1 +Bindings for fan connected to GPIO lines
  2 +
  3 +Required properties:
  4 +- compatible : "gpio-fan"
  5 +- gpios: Specifies the pins that map to bits in the control value,
  6 + ordered MSB-->LSB.
  7 +- gpio-fan,speed-map: A mapping of possible fan RPM speeds and the
  8 + control value that should be set to achieve them. This array
  9 + must have the RPM values in ascending order.
  10 +
  11 +Optional properties:
  12 +- alarm-gpios: This pin going active indicates something is wrong with
  13 + the fan, and a udev event will be fired.
  14 +
  15 +Examples:
  16 +
  17 + gpio_fan {
  18 + compatible = "gpio-fan";
  19 + gpios = <&gpio1 14 1
  20 + &gpio1 13 1>;
  21 + gpio-fan,speed-map = <0 0
  22 + 3000 1
  23 + 6000 2>;
  24 + alarm-gpios = <&gpio1 15 1>;
  25 + };
drivers/hwmon/gpio-fan.c
... ... @@ -31,6 +31,8 @@
31 31 #include <linux/hwmon.h>
32 32 #include <linux/gpio.h>
33 33 #include <linux/gpio-fan.h>
  34 +#include <linux/of_platform.h>
  35 +#include <linux/of_gpio.h>
34 36  
35 37 struct gpio_fan_data {
36 38 struct platform_device *pdev;
37 39  
38 40  
... ... @@ -400,14 +402,131 @@
400 402  
401 403 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
402 404  
  405 +
  406 +#ifdef CONFIG_OF_GPIO
  407 +/*
  408 + * Translate OpenFirmware node properties into platform_data
  409 + */
  410 +static int gpio_fan_get_of_pdata(struct device *dev,
  411 + struct gpio_fan_platform_data *pdata)
  412 +{
  413 + struct device_node *node;
  414 + struct gpio_fan_speed *speed;
  415 + unsigned *ctrl;
  416 + unsigned i;
  417 + u32 u;
  418 + struct property *prop;
  419 + const __be32 *p;
  420 +
  421 + node = dev->of_node;
  422 +
  423 + /* Fill GPIO pin array */
  424 + pdata->num_ctrl = of_gpio_count(node);
  425 + if (!pdata->num_ctrl) {
  426 + dev_err(dev, "gpios DT property empty / missing");
  427 + return -ENODEV;
  428 + }
  429 + ctrl = devm_kzalloc(dev, pdata->num_ctrl * sizeof(unsigned),
  430 + GFP_KERNEL);
  431 + if (!ctrl)
  432 + return -ENOMEM;
  433 + for (i = 0; i < pdata->num_ctrl; i++) {
  434 + int val;
  435 +
  436 + val = of_get_gpio(node, i);
  437 + if (val < 0)
  438 + return val;
  439 + ctrl[i] = val;
  440 + }
  441 + pdata->ctrl = ctrl;
  442 +
  443 + /* Get number of RPM/ctrl_val pairs in speed map */
  444 + prop = of_find_property(node, "gpio-fan,speed-map", &i);
  445 + if (!prop) {
  446 + dev_err(dev, "gpio-fan,speed-map DT property missing");
  447 + return -ENODEV;
  448 + }
  449 + i = i / sizeof(u32);
  450 + if (i == 0 || i & 1) {
  451 + dev_err(dev, "gpio-fan,speed-map contains zero/odd number of entries");
  452 + return -ENODEV;
  453 + }
  454 + pdata->num_speed = i / 2;
  455 +
  456 + /*
  457 + * Populate speed map
  458 + * Speed map is in the form <RPM ctrl_val RPM ctrl_val ...>
  459 + * this needs splitting into pairs to create gpio_fan_speed structs
  460 + */
  461 + speed = devm_kzalloc(dev,
  462 + pdata->num_speed * sizeof(struct gpio_fan_speed),
  463 + GFP_KERNEL);
  464 + if (!speed)
  465 + return -ENOMEM;
  466 + p = NULL;
  467 + for (i = 0; i < pdata->num_speed; i++) {
  468 + p = of_prop_next_u32(prop, p, &u);
  469 + if (!p)
  470 + return -ENODEV;
  471 + speed[i].rpm = u;
  472 + p = of_prop_next_u32(prop, p, &u);
  473 + if (!p)
  474 + return -ENODEV;
  475 + speed[i].ctrl_val = u;
  476 + }
  477 + pdata->speed = speed;
  478 +
  479 + /* Alarm GPIO if one exists */
  480 + if (of_gpio_named_count(node, "alarm-gpios")) {
  481 + struct gpio_fan_alarm *alarm;
  482 + int val;
  483 + enum of_gpio_flags flags;
  484 +
  485 + alarm = devm_kzalloc(dev, sizeof(struct gpio_fan_alarm),
  486 + GFP_KERNEL);
  487 + if (!alarm)
  488 + return -ENOMEM;
  489 +
  490 + val = of_get_named_gpio_flags(node, "alarm-gpios", 0, &flags);
  491 + if (val < 0)
  492 + return val;
  493 + alarm->gpio = val;
  494 + alarm->active_low = flags & OF_GPIO_ACTIVE_LOW;
  495 +
  496 + pdata->alarm = alarm;
  497 + }
  498 +
  499 + return 0;
  500 +}
  501 +
  502 +static struct of_device_id of_gpio_fan_match[] __devinitdata = {
  503 + { .compatible = "gpio-fan", },
  504 + {},
  505 +};
  506 +#endif /* CONFIG_OF_GPIO */
  507 +
403 508 static int __devinit gpio_fan_probe(struct platform_device *pdev)
404 509 {
405 510 int err;
406 511 struct gpio_fan_data *fan_data;
407 512 struct gpio_fan_platform_data *pdata = pdev->dev.platform_data;
408 513  
  514 +#ifdef CONFIG_OF_GPIO
  515 + if (!pdata) {
  516 + pdata = devm_kzalloc(&pdev->dev,
  517 + sizeof(struct gpio_fan_platform_data),
  518 + GFP_KERNEL);
  519 + if (!pdata)
  520 + return -ENOMEM;
  521 +
  522 + err = gpio_fan_get_of_pdata(&pdev->dev, pdata);
  523 + if (err)
  524 + return err;
  525 + }
  526 +#else /* CONFIG_OF_GPIO */
409 527 if (!pdata)
410 528 return -EINVAL;
  529 +#endif /* CONFIG_OF_GPIO */
411 530  
412 531 fan_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_fan_data),
413 532 GFP_KERNEL);
... ... @@ -511,6 +630,7 @@
511 630 .driver = {
512 631 .name = "gpio-fan",
513 632 .pm = GPIO_FAN_PM,
  633 + .of_match_table = of_match_ptr(of_gpio_fan_match),
514 634 },
515 635 };
516 636