On Tue, Jan 09, 2018 at 04:05:24PM -0600, Eddie James wrote:
> This power supply device doesn't correctly manage it's own fault led.
> Add an led class device and register it so that userspace can manage
> power supply fault led as necessary.
> 
> Signed-off-by: Eddie James <eaja...@linux.vnet.ibm.com>
> ---
>  drivers/hwmon/pmbus/ibm-cffps.c | 90 
> +++++++++++++++++++++++++++++++++++++----
>  1 file changed, 82 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/hwmon/pmbus/ibm-cffps.c b/drivers/hwmon/pmbus/ibm-cffps.c
> index 2d6f4f4..1e95dea 100644
> --- a/drivers/hwmon/pmbus/ibm-cffps.c
> +++ b/drivers/hwmon/pmbus/ibm-cffps.c
> @@ -13,6 +13,7 @@
>  #include <linux/fs.h>
>  #include <linux/i2c.h>
>  #include <linux/jiffies.h>
> +#include <linux/leds.h>
>  #include <linux/module.h>
>  #include <linux/mutex.h>
>  #include <linux/pmbus.h>
> @@ -25,6 +26,7 @@
>  #define CFFPS_CCIN_CMD                               0xBD
>  #define CFFPS_FW_CMD_START                   0xFA
>  #define CFFPS_FW_NUM_BYTES                   4
> +#define CFFPS_SYS_CONFIG_CMD                 0xDA
>  
>  #define CFFPS_INPUT_HISTORY_CMD                      0xD6
>  #define CFFPS_INPUT_HISTORY_SIZE             100
> @@ -39,6 +41,11 @@
>  #define CFFPS_MFR_VAUX_FAULT                 BIT(6)
>  #define CFFPS_MFR_CURRENT_SHARE_WARNING              BIT(7)
>  
> +#define CFFPS_LED_BLINK                              BIT(0)
> +#define CFFPS_LED_ON                         BIT(1)
> +#define CFFPS_LED_OFF                                BIT(2)
> +#define CFFPS_BLINK_RATE_MS                  250
> +
>  enum {
>       CFFPS_DEBUGFS_INPUT_HISTORY = 0,
>       CFFPS_DEBUGFS_FRU,
> @@ -63,6 +70,9 @@ struct ibm_cffps {
>       struct ibm_cffps_input_history input_history;
>  
>       int debugfs_entries[CFFPS_DEBUGFS_NUM_ENTRIES];
> +
> +     u8 led_state;
> +     struct led_classdev led;
>  };
>  
>  #define to_psu(x, y) container_of((x), struct ibm_cffps, 
> debugfs_entries[(y)])
> @@ -258,6 +268,51 @@ static int ibm_cffps_read_word_data(struct i2c_client 
> *client, int page,
>       return rc;
>  }
>  
> +static void ibm_cffps_led_brightness_set(struct led_classdev *led_cdev,
> +                                      enum led_brightness brightness)
> +{
> +     int rc;
> +     struct ibm_cffps *psu = container_of(led_cdev, struct ibm_cffps, led);
> +
> +     if (brightness == LED_OFF) {
> +             psu->led_state = CFFPS_LED_OFF;
> +     } else {
> +             brightness = LED_FULL;
> +             if (psu->led_state != CFFPS_LED_BLINK)
> +                     psu->led_state = CFFPS_LED_ON;
> +     }
> +
> +     rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD,
> +                                    psu->led_state);
> +     if (rc < 0)
> +             return;
> +
> +     led_cdev->brightness = brightness;
> +}
> +
> +static int ibm_cffps_led_blink_set(struct led_classdev *led_cdev,
> +                                unsigned long *delay_on,
> +                                unsigned long *delay_off)
> +{
> +     int rc;
> +     struct ibm_cffps *psu = container_of(led_cdev, struct ibm_cffps, led);
> +
> +     psu->led_state = CFFPS_LED_BLINK;
> +
> +     if (led_cdev->brightness == LED_OFF)
> +             return 0;
> +
> +     rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD,
> +                                    CFFPS_LED_BLINK);
> +     if (rc < 0)
> +             return rc;
> +
> +     *delay_on = CFFPS_BLINK_RATE_MS;
> +     *delay_off = CFFPS_BLINK_RATE_MS;
> +
> +     return 0;
> +}
> +
>  static struct pmbus_driver_info ibm_cffps_info = {
>       .pages = 1,
>       .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
> @@ -277,6 +332,8 @@ static int ibm_cffps_probe(struct i2c_client *client,
>                          const struct i2c_device_id *id)
>  {
>       int i, rc;
> +     char *led_name;
> +     size_t name_length;
>       struct dentry *debugfs;
>       struct dentry *ibm_cffps_dir;
>       struct ibm_cffps *psu;
> @@ -286,6 +343,31 @@ static int ibm_cffps_probe(struct i2c_client *client,
>       if (rc)
>               return rc;
>  
> +     /* client name, '-', 8 chars for addr, and null */
> +     name_length = strlen(client->name) + 10;
> +
> +     /* Don't fail the probe if we can't create led devices */
> +     psu = devm_kzalloc(&client->dev, sizeof(*psu) + name_length,
> +                        GFP_KERNEL);
> +     if (!psu)
> +             return 0;

... and no debugfs either ?

> +
> +     psu->client = client;
> +     mutex_init(&psu->input_history.update_lock);
> +     psu->input_history.last_update = jiffies - HZ;
> +
> +     led_name = (void *)(&psu[1]);
> +     snprintf(led_name, name_length, "%s-%x", client->name, client->addr);
> +     psu->led.name = led_name;
> +     psu->led.max_brightness = LED_FULL;
> +     psu->led.brightness_set = ibm_cffps_led_brightness_set;
> +     psu->led.blink_set = ibm_cffps_led_blink_set;
> +
> +     rc = devm_led_classdev_register(&client->dev, &psu->led);
> +     if (rc)
> +             dev_info(&client->dev, "failed to register led class: %d\n",

dev_warn() might be more appropriate.

> +                      rc);
> +

Please move the led initialization code into its own function.

>       /* Don't fail the probe if we can't create debugfs */
>       debugfs = pmbus_get_debugfs_dir(client);
>       if (!debugfs)
> @@ -295,14 +377,6 @@ static int ibm_cffps_probe(struct i2c_client *client,
>       if (!ibm_cffps_dir)
>               return 0;
>  
> -     psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
> -     if (!psu)
> -             return 0;
> -
> -     psu->client = client;
> -     mutex_init(&psu->input_history.update_lock);
> -     psu->input_history.last_update = jiffies - HZ;
> -
unrelated ?

>       for (i = 0; i < CFFPS_DEBUGFS_NUM_ENTRIES; ++i)
>               psu->debugfs_entries[i] = i;
>  
> -- 
> 1.8.3.1
> 

Reply via email to