Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966406AbeAJQhF (ORCPT + 1 other); Wed, 10 Jan 2018 11:37:05 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:34570 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S966221AbeAJQhC (ORCPT ); Wed, 10 Jan 2018 11:37:02 -0500 Subject: Re: [PATCH] hwmon (pmbus): cffps: Add led class device for power supply fault led To: Guenter Roeck Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org, jdelvare@suse.com, joel@jms.id.au References: <1515535524-27458-1-git-send-email-eajames@linux.vnet.ibm.com> <20180109225042.GB26819@roeck-us.net> From: Eddie James Date: Wed, 10 Jan 2018 10:36:56 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: <20180109225042.GB26819@roeck-us.net> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-US X-TM-AS-GCONF: 00 x-cbid: 18011016-0016-0000-0000-000008179A42 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008354; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000245; SDB=6.00973043; UDB=6.00492998; IPR=6.00752992; BA=6.00005772; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00018963; XFM=3.00000015; UTC=2018-01-10 16:37:00 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18011016-0017-0000-0000-00003CFC765F Message-Id: X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2018-01-10_08:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1801100232 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On 01/09/2018 04:50 PM, Guenter Roeck wrote: > 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 >> --- >> 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 >> #include >> #include >> +#include >> #include >> #include >> #include >> @@ -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 ? Well we need that struct allocated for debugfs as well. I'll clarify the comment. > >> + >> + 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. Sure. > >> + rc); >> + > Please move the led initialization code into its own function. Sure. > >> /* 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 ? Thought it made sense to move it with the allocation, but I can leave it where it is. Thanks, Eddie > >> for (i = 0; i < CFFPS_DEBUGFS_NUM_ENTRIES; ++i) >> psu->debugfs_entries[i] = i; >> >> -- >> 1.8.3.1 >>