summaryrefslogtreecommitdiff
path: root/drivers/hwmon/pmbus/ucd9000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/pmbus/ucd9000.c')
-rw-r--r--drivers/hwmon/pmbus/ucd9000.c88
1 files changed, 15 insertions, 73 deletions
diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c
index 8d9d422450e5..2bc8cccb01fd 100644
--- a/drivers/hwmon/pmbus/ucd9000.c
+++ b/drivers/hwmon/pmbus/ucd9000.c
@@ -67,7 +67,6 @@ struct ucd9000_data {
struct gpio_chip gpio;
#endif
struct dentry *debugfs;
- ktime_t write_time;
};
#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)
@@ -80,68 +79,11 @@ struct ucd9000_debugfs_entry {
* It has been observed that the UCD90320 randomly fails register access when
* doing another access right on the back of a register write. To mitigate this
* make sure that there is a minimum delay between a write access and the
- * following access. The 250us is based on experimental data. At a delay of
- * 200us the issue seems to go away. Add a bit of extra margin to allow for
+ * following access. The 500 is based on experimental data. At a delay of
+ * 350us the issue seems to go away. Add a bit of extra margin to allow for
* system to system differences.
*/
-#define UCD90320_WAIT_DELAY_US 250
-
-static inline void ucd90320_wait(const struct ucd9000_data *data)
-{
- s64 delta = ktime_us_delta(ktime_get(), data->write_time);
-
- if (delta < UCD90320_WAIT_DELAY_US)
- udelay(UCD90320_WAIT_DELAY_US - delta);
-}
-
-static int ucd90320_read_word_data(struct i2c_client *client, int page,
- int phase, int reg)
-{
- const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
- struct ucd9000_data *data = to_ucd9000_data(info);
-
- if (reg >= PMBUS_VIRT_BASE)
- return -ENXIO;
-
- ucd90320_wait(data);
- return pmbus_read_word_data(client, page, phase, reg);
-}
-
-static int ucd90320_read_byte_data(struct i2c_client *client, int page, int reg)
-{
- const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
- struct ucd9000_data *data = to_ucd9000_data(info);
-
- ucd90320_wait(data);
- return pmbus_read_byte_data(client, page, reg);
-}
-
-static int ucd90320_write_word_data(struct i2c_client *client, int page,
- int reg, u16 word)
-{
- const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
- struct ucd9000_data *data = to_ucd9000_data(info);
- int ret;
-
- ucd90320_wait(data);
- ret = pmbus_write_word_data(client, page, reg, word);
- data->write_time = ktime_get();
-
- return ret;
-}
-
-static int ucd90320_write_byte(struct i2c_client *client, int page, u8 value)
-{
- const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
- struct ucd9000_data *data = to_ucd9000_data(info);
- int ret;
-
- ucd90320_wait(data);
- ret = pmbus_write_byte(client, page, value);
- data->write_time = ktime_get();
-
- return ret;
-}
+#define UCD90320_WAIT_DELAY_US 500
static int ucd9000_get_fan_config(struct i2c_client *client, int fan)
{
@@ -270,8 +212,8 @@ static int ucd9000_gpio_get(struct gpio_chip *gc, unsigned int offset)
return !!(ret & UCD9000_GPIO_CONFIG_STATUS);
}
-static void ucd9000_gpio_set(struct gpio_chip *gc, unsigned int offset,
- int value)
+static int ucd9000_gpio_set(struct gpio_chip *gc, unsigned int offset,
+ int value)
{
struct i2c_client *client = gpiochip_get_data(gc);
int ret;
@@ -280,17 +222,17 @@ static void ucd9000_gpio_set(struct gpio_chip *gc, unsigned int offset,
if (ret < 0) {
dev_dbg(&client->dev, "failed to read GPIO %d config: %d\n",
offset, ret);
- return;
+ return ret;
}
if (value) {
if (ret & UCD9000_GPIO_CONFIG_STATUS)
- return;
+ return 0;
ret |= UCD9000_GPIO_CONFIG_STATUS;
} else {
if (!(ret & UCD9000_GPIO_CONFIG_STATUS))
- return;
+ return 0;
ret &= ~UCD9000_GPIO_CONFIG_STATUS;
}
@@ -302,7 +244,7 @@ static void ucd9000_gpio_set(struct gpio_chip *gc, unsigned int offset,
if (ret < 0) {
dev_dbg(&client->dev, "Failed to write GPIO %d config: %d\n",
offset, ret);
- return;
+ return ret;
}
ret &= ~UCD9000_GPIO_CONFIG_ENABLE;
@@ -311,6 +253,8 @@ static void ucd9000_gpio_set(struct gpio_chip *gc, unsigned int offset,
if (ret < 0)
dev_dbg(&client->dev, "Failed to write GPIO %d config: %d\n",
offset, ret);
+
+ return ret;
}
static int ucd9000_gpio_get_direction(struct gpio_chip *gc,
@@ -420,7 +364,7 @@ static void ucd9000_probe_gpio(struct i2c_client *client,
data->gpio.direction_input = ucd9000_gpio_direction_input;
data->gpio.direction_output = ucd9000_gpio_direction_output;
data->gpio.get = ucd9000_gpio_get;
- data->gpio.set = ucd9000_gpio_set;
+ data->gpio.set_rv = ucd9000_gpio_set;
data->gpio.can_sleep = true;
data->gpio.base = -1;
data->gpio.parent = &client->dev;
@@ -667,10 +611,8 @@ static int ucd9000_probe(struct i2c_client *client)
info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12
| PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34;
} else if (mid->driver_data == ucd90320) {
- info->read_byte_data = ucd90320_read_byte_data;
- info->read_word_data = ucd90320_read_word_data;
- info->write_byte = ucd90320_write_byte;
- info->write_word_data = ucd90320_write_word_data;
+ /* Delay SMBus operations after a write */
+ info->write_delay = UCD90320_WAIT_DELAY_US;
}
ucd9000_probe_gpio(client, mid, data);
@@ -702,4 +644,4 @@ module_i2c_driver(ucd9000_driver);
MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx");
MODULE_LICENSE("GPL");
-MODULE_IMPORT_NS(PMBUS);
+MODULE_IMPORT_NS("PMBUS");