diff options
Diffstat (limited to 'drivers/hwmon/g762.c')
| -rw-r--r-- | drivers/hwmon/g762.c | 296 |
1 files changed, 135 insertions, 161 deletions
diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c index 73adf01b0ef2..4fa3aa1271da 100644 --- a/drivers/hwmon/g762.c +++ b/drivers/hwmon/g762.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * g762 - Driver for the Global Mixed-mode Technology Inc. fan speed * PWM controller chips from G762 family, i.e. G762 and G763 @@ -24,20 +25,6 @@ * * g762: minimal datasheet available at: * http://www.gmt.com.tw/product/datasheet/EDS-762_3.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation. */ #include <linux/device.h> @@ -52,14 +39,14 @@ #include <linux/kernel.h> #include <linux/clk.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_data/g762.h> #define DRVNAME "g762" static const struct i2c_device_id g762_id[] = { - { "g762", 0 }, - { "g763", 0 }, + { "g761" }, + { "g762" }, + { "g763" }, { } }; MODULE_DEVICE_TABLE(i2c, g762_id); @@ -83,6 +70,7 @@ enum g762_regs { #define G762_REG_FAN_CMD1_PWM_POLARITY 0x02 /* PWM polarity */ #define G762_REG_FAN_CMD1_PULSE_PER_REV 0x01 /* pulse per fan revolution */ +#define G761_REG_FAN_CMD2_FAN_CLOCK 0x20 /* choose internal clock*/ #define G762_REG_FAN_CMD2_GEAR_MODE_1 0x08 /* fan gear mode */ #define G762_REG_FAN_CMD2_GEAR_MODE_0 0x04 #define G762_REG_FAN_CMD2_FAN_STARTV_1 0x02 /* fan startup voltage */ @@ -129,7 +117,7 @@ enum g762_regs { struct g762_data { struct i2c_client *client; - struct device *hwmon_dev; + bool internal_clock; struct clk *clk; /* update mutex */ @@ -193,21 +181,24 @@ static inline unsigned int rpm_from_cnt(u8 cnt, u32 clk_freq, u16 p, * Convert fan RPM value from sysfs into count value for fan controller * register (FAN_SET_CNT). */ -static inline unsigned char cnt_from_rpm(u32 rpm, u32 clk_freq, u16 p, +static inline unsigned char cnt_from_rpm(unsigned long rpm, u32 clk_freq, u16 p, u8 clk_div, u8 gear_mult) { - if (!rpm) /* to stop the fan, set cnt to 255 */ + unsigned long f1 = clk_freq * 30 * gear_mult; + unsigned long f2 = p * clk_div; + + if (!rpm) /* to stop the fan, set cnt to 255 */ return 0xff; - return clamp_val(((clk_freq * 30 * gear_mult) / (rpm * p * clk_div)), - 0, 255); + rpm = clamp_val(rpm, f1 / (255 * f2), ULONG_MAX / f2); + return DIV_ROUND_CLOSEST(f1, rpm * f2); } /* helper to grab and cache data, at most one time per second */ static struct g762_data *g762_update_client(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct g762_data *data = i2c_get_clientdata(client); + struct g762_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; int ret = 0; mutex_lock(&data->update_lock); @@ -266,8 +257,7 @@ static struct g762_data *g762_update_client(struct device *dev) */ static int do_set_clk_freq(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); - struct g762_data *data = i2c_get_clientdata(client); + struct g762_data *data = dev_get_drvdata(dev); if (val > 0xffffff) return -EINVAL; @@ -282,7 +272,6 @@ static int do_set_clk_freq(struct device *dev, unsigned long val) /* Set pwm mode. Accepts either 0 (PWM mode) or 1 (DC mode) */ static int do_set_pwm_mode(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); int ret; @@ -301,7 +290,7 @@ static int do_set_pwm_mode(struct device *dev, unsigned long val) ret = -EINVAL; goto out; } - ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1, + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, data->fan_cmd1); data->valid = false; out: @@ -313,7 +302,6 @@ static int do_set_pwm_mode(struct device *dev, unsigned long val) /* Set fan clock divisor. Accepts either 1, 2, 4 or 8. */ static int do_set_fan_div(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); int ret; @@ -342,7 +330,7 @@ static int do_set_fan_div(struct device *dev, unsigned long val) ret = -EINVAL; goto out; } - ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1, + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, data->fan_cmd1); data->valid = false; out: @@ -354,7 +342,6 @@ static int do_set_fan_div(struct device *dev, unsigned long val) /* Set fan gear mode. Accepts either 0, 1 or 2. */ static int do_set_fan_gear_mode(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); int ret; @@ -379,7 +366,7 @@ static int do_set_fan_gear_mode(struct device *dev, unsigned long val) ret = -EINVAL; goto out; } - ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2, + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, data->fan_cmd2); data->valid = false; out: @@ -391,7 +378,6 @@ static int do_set_fan_gear_mode(struct device *dev, unsigned long val) /* Set number of fan pulses per revolution. Accepts either 2 or 4. */ static int do_set_fan_pulses(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); int ret; @@ -410,7 +396,7 @@ static int do_set_fan_pulses(struct device *dev, unsigned long val) ret = -EINVAL; goto out; } - ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1, + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, data->fan_cmd1); data->valid = false; out: @@ -422,7 +408,6 @@ static int do_set_fan_pulses(struct device *dev, unsigned long val) /* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */ static int do_set_pwm_enable(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); int ret; @@ -444,15 +429,15 @@ static int do_set_pwm_enable(struct device *dev, unsigned long val) * value of 254 if it is 255 when switching to open-loop. */ if (data->set_cnt == 0xff) - i2c_smbus_write_byte_data(client, G762_REG_SET_CNT, - 254); + i2c_smbus_write_byte_data(data->client, + G762_REG_SET_CNT, 254); break; default: ret = -EINVAL; goto out; } - ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1, + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, data->fan_cmd1); data->valid = false; out: @@ -464,7 +449,6 @@ static int do_set_pwm_enable(struct device *dev, unsigned long val) /* Set PWM polarity. Accepts either 0 (positive duty) or 1 (negative duty) */ static int do_set_pwm_polarity(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); int ret; @@ -483,7 +467,7 @@ static int do_set_pwm_polarity(struct device *dev, unsigned long val) ret = -EINVAL; goto out; } - ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1, + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, data->fan_cmd1); data->valid = false; out: @@ -498,8 +482,8 @@ static int do_set_pwm_polarity(struct device *dev, unsigned long val) */ static int do_set_pwm(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); - struct g762_data *data = i2c_get_clientdata(client); + struct g762_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; int ret; if (val > 255) @@ -519,7 +503,6 @@ static int do_set_pwm(struct device *dev, unsigned long val) */ static int do_set_fan_target(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); int ret; @@ -531,7 +514,7 @@ static int do_set_fan_target(struct device *dev, unsigned long val) G762_PULSE_FROM_REG(data->fan_cmd1), G762_CLKDIV_FROM_REG(data->fan_cmd1), G762_GEARMULT_FROM_REG(data->fan_cmd2)); - ret = i2c_smbus_write_byte_data(client, G762_REG_SET_CNT, + ret = i2c_smbus_write_byte_data(data->client, G762_REG_SET_CNT, data->set_cnt); data->valid = false; mutex_unlock(&data->update_lock); @@ -542,7 +525,6 @@ static int do_set_fan_target(struct device *dev, unsigned long val) /* Set fan startup voltage. Accepted values are either 0, 1, 2 or 3. */ static int do_set_fan_startv(struct device *dev, unsigned long val) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); int ret; @@ -571,7 +553,7 @@ static int do_set_fan_startv(struct device *dev, unsigned long val) ret = -EINVAL; goto out; } - ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2, + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, data->fan_cmd2); data->valid = false; out: @@ -586,11 +568,13 @@ static int do_set_fan_startv(struct device *dev, unsigned long val) */ #ifdef CONFIG_OF -static struct of_device_id g762_dt_match[] = { +static const struct of_device_id g762_dt_match[] = { + { .compatible = "gmt,g761" }, { .compatible = "gmt,g762" }, { .compatible = "gmt,g763" }, { }, }; +MODULE_DEVICE_TABLE(of, g762_dt_match); /* * Grab clock (a required property), enable it, get (fixed) clock frequency @@ -599,6 +583,14 @@ static struct of_device_id g762_dt_match[] = { * call to g762_of_clock_disable(). Note that a reference to clock is kept * in our private data structure to be used in this function. */ +static void g762_of_clock_disable(void *data) +{ + struct g762_data *g762 = data; + + clk_disable_unprepare(g762->clk); + clk_put(g762->clk); +} + static int g762_of_clock_enable(struct i2c_client *client) { struct g762_data *data; @@ -609,6 +601,21 @@ static int g762_of_clock_enable(struct i2c_client *client) if (!client->dev.of_node) return 0; + data = i2c_get_clientdata(client); + + /* + * Skip CLK detection and handling if we use internal clock. + * This is only valid for g761. + */ + data->internal_clock = of_device_is_compatible(client->dev.of_node, + "gmt,g761") && + !of_property_present(client->dev.of_node, + "clocks"); + if (data->internal_clock) { + do_set_clk_freq(&client->dev, 32768); + return 0; + } + clk = of_clk_get(client->dev.of_node, 0); if (IS_ERR(clk)) { dev_err(&client->dev, "failed to get clock\n"); @@ -628,9 +635,14 @@ static int g762_of_clock_enable(struct i2c_client *client) goto clk_unprep; } - data = i2c_get_clientdata(client); data->clk = clk; + ret = devm_add_action(&client->dev, g762_of_clock_disable, data); + if (ret) { + dev_err(&client->dev, "failed to add disable clock action\n"); + goto clk_unprep; + } + return 0; clk_unprep: @@ -642,31 +654,17 @@ static int g762_of_clock_enable(struct i2c_client *client) return ret; } -static void g762_of_clock_disable(struct i2c_client *client) -{ - struct g762_data *data = i2c_get_clientdata(client); - - if (!data->clk) - return; - - clk_disable_unprepare(data->clk); - clk_put(data->clk); -} - static int g762_of_prop_import_one(struct i2c_client *client, const char *pname, int (*psetter)(struct device *dev, unsigned long val)) { - const __be32 *prop; - int len, ret; + int ret; u32 pval; - prop = of_get_property(client->dev.of_node, pname, &len); - if (!prop || len != sizeof(u32)) + if (of_property_read_u32(client->dev.of_node, pname, &pval)) return 0; - pval = be32_to_cpu(prop[0]); dev_dbg(&client->dev, "found %s (%d)\n", pname, pval); ret = (*psetter)(&client->dev, pval); if (ret) @@ -706,8 +704,6 @@ static int g762_of_clock_enable(struct i2c_client *client) { return 0; } - -static void g762_of_clock_disable(struct i2c_client *client) { } #endif /* @@ -717,7 +713,7 @@ static void g762_of_clock_disable(struct i2c_client *client) { } static int g762_pdata_prop_import(struct i2c_client *client) { - struct g762_platform_data *pdata = client->dev.platform_data; + struct g762_platform_data *pdata = dev_get_platdata(&client->dev); int ret; if (!pdata) @@ -746,8 +742,8 @@ static int g762_pdata_prop_import(struct i2c_client *client) * Read function for fan1_input sysfs file. Return current fan RPM value, or * 0 if fan is out of control. */ -static ssize_t get_fan_rpm(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t fan1_input_show(struct device *dev, + struct device_attribute *da, char *buf) { struct g762_data *data = g762_update_client(dev); unsigned int rpm = 0; @@ -772,8 +768,8 @@ static ssize_t get_fan_rpm(struct device *dev, struct device_attribute *da, * Read and write functions for pwm1_mode sysfs file. Get and set fan speed * control mode i.e. PWM (1) or DC (0). */ -static ssize_t get_pwm_mode(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t pwm1_mode_show(struct device *dev, struct device_attribute *da, + char *buf) { struct g762_data *data = g762_update_client(dev); @@ -784,8 +780,9 @@ static ssize_t get_pwm_mode(struct device *dev, struct device_attribute *da, !!(data->fan_cmd1 & G762_REG_FAN_CMD1_OUT_MODE)); } -static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t pwm1_mode_store(struct device *dev, + struct device_attribute *da, const char *buf, + size_t count) { unsigned long val; int ret; @@ -804,8 +801,8 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *da, * Read and write functions for fan1_div sysfs file. Get and set fan * controller prescaler value */ -static ssize_t get_fan_div(struct device *dev, - struct device_attribute *da, char *buf) +static ssize_t fan1_div_show(struct device *dev, struct device_attribute *da, + char *buf) { struct g762_data *data = g762_update_client(dev); @@ -815,9 +812,8 @@ static ssize_t get_fan_div(struct device *dev, return sprintf(buf, "%d\n", G762_CLKDIV_FROM_REG(data->fan_cmd1)); } -static ssize_t set_fan_div(struct device *dev, - struct device_attribute *da, - const char *buf, size_t count) +static ssize_t fan1_div_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) { unsigned long val; int ret; @@ -836,8 +832,8 @@ static ssize_t set_fan_div(struct device *dev, * Read and write functions for fan1_pulses sysfs file. Get and set number * of tachometer pulses per fan revolution. */ -static ssize_t get_fan_pulses(struct device *dev, - struct device_attribute *da, char *buf) +static ssize_t fan1_pulses_show(struct device *dev, + struct device_attribute *da, char *buf) { struct g762_data *data = g762_update_client(dev); @@ -847,9 +843,9 @@ static ssize_t get_fan_pulses(struct device *dev, return sprintf(buf, "%d\n", G762_PULSE_FROM_REG(data->fan_cmd1)); } -static ssize_t set_fan_pulses(struct device *dev, - struct device_attribute *da, - const char *buf, size_t count) +static ssize_t fan1_pulses_store(struct device *dev, + struct device_attribute *da, const char *buf, + size_t count) { unsigned long val; int ret; @@ -869,7 +865,7 @@ static ssize_t set_fan_pulses(struct device *dev, * (i.e. closed or open-loop). * * Following documentation about hwmon's sysfs interface, a pwm1_enable node - * should accept followings: + * should accept the following: * * 0 : no fan speed control (i.e. fan at full speed) * 1 : manual fan speed control enabled (use pwm[1-*]) (open-loop) @@ -878,8 +874,8 @@ static ssize_t set_fan_pulses(struct device *dev, * but we do not accept 0 as this mode is not natively supported by the chip * and it is not emulated by g762 driver. -EINVAL is returned in this case. */ -static ssize_t get_pwm_enable(struct device *dev, - struct device_attribute *da, char *buf) +static ssize_t pwm1_enable_show(struct device *dev, + struct device_attribute *da, char *buf) { struct g762_data *data = g762_update_client(dev); @@ -890,9 +886,9 @@ static ssize_t get_pwm_enable(struct device *dev, (!!(data->fan_cmd1 & G762_REG_FAN_CMD1_FAN_MODE)) + 1); } -static ssize_t set_pwm_enable(struct device *dev, - struct device_attribute *da, - const char *buf, size_t count) +static ssize_t pwm1_enable_store(struct device *dev, + struct device_attribute *da, const char *buf, + size_t count) { unsigned long val; int ret; @@ -912,8 +908,8 @@ static ssize_t set_pwm_enable(struct device *dev, * (which affects fan speed) in open-loop mode. 0 stops the fan and 255 * makes it run at full speed. */ -static ssize_t get_pwm(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t pwm1_show(struct device *dev, struct device_attribute *da, + char *buf) { struct g762_data *data = g762_update_client(dev); @@ -923,8 +919,8 @@ static ssize_t get_pwm(struct device *dev, struct device_attribute *da, return sprintf(buf, "%d\n", data->set_out); } -static ssize_t set_pwm(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t pwm1_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) { unsigned long val; int ret; @@ -950,8 +946,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *da, * Also note that due to rounding errors it is possible that you don't read * back exactly the value you have set. */ -static ssize_t get_fan_target(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t fan1_target_show(struct device *dev, + struct device_attribute *da, char *buf) { struct g762_data *data = g762_update_client(dev); unsigned int rpm; @@ -969,8 +965,9 @@ static ssize_t get_fan_target(struct device *dev, struct device_attribute *da, return sprintf(buf, "%u\n", rpm); } -static ssize_t set_fan_target(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t fan1_target_store(struct device *dev, + struct device_attribute *da, const char *buf, + size_t count) { unsigned long val; int ret; @@ -986,7 +983,7 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *da, } /* read function for fan1_fault sysfs file. */ -static ssize_t get_fan_failure(struct device *dev, struct device_attribute *da, +static ssize_t fan1_fault_show(struct device *dev, struct device_attribute *da, char *buf) { struct g762_data *data = g762_update_client(dev); @@ -1001,8 +998,8 @@ static ssize_t get_fan_failure(struct device *dev, struct device_attribute *da, * read function for fan1_alarm sysfs file. Note that OOC condition is * enabled low */ -static ssize_t get_fan_ooc(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t fan1_alarm_show(struct device *dev, + struct device_attribute *da, char *buf) { struct g762_data *data = g762_update_client(dev); @@ -1012,21 +1009,18 @@ static ssize_t get_fan_ooc(struct device *dev, struct device_attribute *da, return sprintf(buf, "%u\n", !(data->fan_sta & G762_REG_FAN_STA_OOC)); } -static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); -static DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, get_pwm_mode, set_pwm_mode); -static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, - get_pwm_enable, set_pwm_enable); -static DEVICE_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL); -static DEVICE_ATTR(fan1_alarm, S_IRUGO, get_fan_ooc, NULL); -static DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan_failure, NULL); -static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, - get_fan_target, set_fan_target); -static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_fan_div, set_fan_div); -static DEVICE_ATTR(fan1_pulses, S_IWUSR | S_IRUGO, - get_fan_pulses, set_fan_pulses); +static DEVICE_ATTR_RW(pwm1); +static DEVICE_ATTR_RW(pwm1_mode); +static DEVICE_ATTR_RW(pwm1_enable); +static DEVICE_ATTR_RO(fan1_input); +static DEVICE_ATTR_RO(fan1_alarm); +static DEVICE_ATTR_RO(fan1_fault); +static DEVICE_ATTR_RW(fan1_target); +static DEVICE_ATTR_RW(fan1_div); +static DEVICE_ATTR_RW(fan1_pulses); /* Driver data */ -static struct attribute *g762_attributes[] = { +static struct attribute *g762_attrs[] = { &dev_attr_fan1_input.attr, &dev_attr_fan1_alarm.attr, &dev_attr_fan1_fault.attr, @@ -1039,9 +1033,7 @@ static struct attribute *g762_attributes[] = { NULL }; -static const struct attribute_group g762_group = { - .attrs = g762_attributes, -}; +ATTRIBUTE_GROUPS(g762); /* * Enable both fan failure detection and fan out of control protection. The @@ -1050,22 +1042,33 @@ static const struct attribute_group g762_group = { */ static inline int g762_fan_init(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); struct g762_data *data = g762_update_client(dev); + int ret; if (IS_ERR(data)) return PTR_ERR(data); + /* internal_clock can only be set with compatible g761 */ + if (data->internal_clock) + data->fan_cmd2 |= G761_REG_FAN_CMD2_FAN_CLOCK; + data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_FAIL; data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC; data->valid = false; - return i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1, - data->fan_cmd1); + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, + data->fan_cmd1); + if (ret) + return ret; + + return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, + data->fan_cmd2); } -static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int g762_probe(struct i2c_client *client) { + struct device *dev = &client->dev; + struct device *hwmon_dev; struct g762_data *data; int ret; @@ -1073,7 +1076,7 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id) I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - data = devm_kzalloc(&client->dev, sizeof(struct g762_data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct g762_data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -1081,64 +1084,35 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id) data->client = client; mutex_init(&data->update_lock); - /* Enable fan failure detection and fan out of control protection */ - ret = g762_fan_init(&client->dev); + /* Get configuration via DT ... */ + ret = g762_of_clock_enable(client); if (ret) return ret; - /* Get configuration via DT ... */ - ret = g762_of_clock_enable(client); + /* Enable fan failure detection and fan out of control protection */ + ret = g762_fan_init(dev); if (ret) return ret; + ret = g762_of_prop_import(client); if (ret) - goto clock_dis; + return ret; /* ... or platform_data */ ret = g762_pdata_prop_import(client); if (ret) - goto clock_dis; - - /* Register sysfs hooks */ - ret = sysfs_create_group(&client->dev.kobj, &g762_group); - if (ret) - goto clock_dis; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - ret = PTR_ERR(data->hwmon_dev); - goto sysfs_rem; - } - - return 0; - - sysfs_rem: - sysfs_remove_group(&client->dev.kobj, &g762_group); - - clock_dis: - g762_of_clock_disable(client); - - return ret; -} - -static int g762_remove(struct i2c_client *client) -{ - struct g762_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &g762_group); - g762_of_clock_disable(client); + return ret; - return 0; + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, g762_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); } static struct i2c_driver g762_driver = { .driver = { .name = DRVNAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(g762_dt_match), }, - .probe = g762_probe, - .remove = g762_remove, + .probe = g762_probe, .id_table = g762_id, }; |
