summaryrefslogtreecommitdiff
path: root/drivers/w1
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1')
-rw-r--r--drivers/w1/masters/Kconfig10
-rw-r--r--drivers/w1/masters/Makefile1
-rw-r--r--drivers/w1/masters/amd_axi_w1.c2
-rw-r--r--drivers/w1/masters/ds2482.c30
-rw-r--r--drivers/w1/masters/mxc_w1.c4
-rw-r--r--drivers/w1/masters/omap_hdq.c4
-rw-r--r--drivers/w1/masters/sgi_w1.c4
-rw-r--r--drivers/w1/masters/w1-gpio.c66
-rw-r--r--drivers/w1/masters/w1-uart.c415
-rw-r--r--drivers/w1/slaves/w1_ds2406.c22
-rw-r--r--drivers/w1/slaves/w1_ds2408.c42
-rw-r--r--drivers/w1/slaves/w1_ds2413.c14
-rw-r--r--drivers/w1/slaves/w1_ds2430.c10
-rw-r--r--drivers/w1/slaves/w1_ds2431.c10
-rw-r--r--drivers/w1/slaves/w1_ds2433.c24
-rw-r--r--drivers/w1/slaves/w1_ds2438.c34
-rw-r--r--drivers/w1/slaves/w1_ds2780.c8
-rw-r--r--drivers/w1/slaves/w1_ds2781.c8
-rw-r--r--drivers/w1/slaves/w1_ds2805.c10
-rw-r--r--drivers/w1/slaves/w1_ds28e04.c18
-rw-r--r--drivers/w1/slaves/w1_ds28e17.c4
-rw-r--r--drivers/w1/slaves/w1_therm.c12
-rw-r--r--drivers/w1/w1.c16
-rw-r--r--drivers/w1/w1_int.c6
-rw-r--r--drivers/w1/w1_netlink.c42
25 files changed, 598 insertions, 218 deletions
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 513c0b114337..e6049a75b35b 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -78,5 +78,15 @@ config W1_MASTER_SGI
This support is also available as a module. If so, the module
will be called sgi_w1.
+config W1_MASTER_UART
+ tristate "UART 1-wire driver"
+ depends on SERIAL_DEV_BUS
+ help
+ Say Y here if you want to communicate with your 1-wire devices using
+ UART interface.
+
+ This support is also available as a module. If so, the module
+ will be called w1-uart.
+
endmenu
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile
index 6c5a21f9b88c..227f80987e69 100644
--- a/drivers/w1/masters/Makefile
+++ b/drivers/w1/masters/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_W1_MASTER_MXC) += mxc_w1.o
obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o
obj-$(CONFIG_HDQ_MASTER_OMAP) += omap_hdq.o
obj-$(CONFIG_W1_MASTER_SGI) += sgi_w1.o
+obj-$(CONFIG_W1_MASTER_UART) += w1-uart.o
diff --git a/drivers/w1/masters/amd_axi_w1.c b/drivers/w1/masters/amd_axi_w1.c
index 4d3a68ca9263..5da8b8d86811 100644
--- a/drivers/w1/masters/amd_axi_w1.c
+++ b/drivers/w1/masters/amd_axi_w1.c
@@ -383,7 +383,7 @@ MODULE_DEVICE_TABLE(of, amd_axi_w1_of_match);
static struct platform_driver amd_axi_w1_driver = {
.probe = amd_axi_w1_probe,
- .remove_new = amd_axi_w1_remove,
+ .remove = amd_axi_w1_remove,
.driver = {
.name = DRIVER_NAME,
.of_match_table = amd_axi_w1_of_match,
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
index b2d76c1784bd..e2a568c9a43a 100644
--- a/drivers/w1/masters/ds2482.c
+++ b/drivers/w1/masters/ds2482.c
@@ -7,7 +7,7 @@
* It is a I2C to 1-wire bridge.
* There are two variations: -100 and -800, which have 1 or 8 1-wire ports.
* The complete datasheet can be obtained from MAXIM's website at:
- * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/4382
+ * https://www.analog.com/en/products/ds2482-100.html
*/
#include <linux/module.h>
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
#include <linux/w1.h>
@@ -445,17 +446,20 @@ static int ds2482_probe(struct i2c_client *client)
int err = -ENODEV;
int temp1;
int idx;
+ int ret;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
I2C_FUNC_SMBUS_BYTE))
return -ENODEV;
- data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
+ data = devm_kzalloc(&client->dev, sizeof(struct ds2482_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ ret = devm_regulator_get_enable(&client->dev, "vcc");
+ if (ret)
+ return dev_err_probe(&client->dev, ret, "Failed to enable regulator\n");
data->client = client;
i2c_set_clientdata(client, data);
@@ -463,7 +467,7 @@ static int ds2482_probe(struct i2c_client *client)
/* Reset the device (sets the read_ptr to status) */
if (ds2482_send_cmd(data, DS2482_CMD_RESET) < 0) {
dev_warn(&client->dev, "DS2482 reset failed.\n");
- goto exit_free;
+ return err;
}
/* Sleep at least 525ns to allow the reset to complete */
@@ -474,7 +478,7 @@ static int ds2482_probe(struct i2c_client *client)
if (temp1 != (DS2482_REG_STS_LL | DS2482_REG_STS_RST)) {
dev_warn(&client->dev, "DS2482 reset status "
"0x%02X - not a DS2482\n", temp1);
- goto exit_free;
+ return err;
}
/* Detect the 8-port version */
@@ -516,9 +520,6 @@ exit_w1_remove:
if (data->w1_ch[idx].pdev != NULL)
w1_remove_master_device(&data->w1_ch[idx].w1_bm);
}
-exit_free:
- kfree(data);
-exit:
return err;
}
@@ -532,17 +533,14 @@ static void ds2482_remove(struct i2c_client *client)
if (data->w1_ch[idx].pdev != NULL)
w1_remove_master_device(&data->w1_ch[idx].w1_bm);
}
-
- /* Free the memory */
- kfree(data);
}
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id ds2482_id[] = {
- { "ds2482", 0 },
- { "ds2484", 0 },
+ { "ds2482" },
+ { "ds2484" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ds2482_id);
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
index 090cbbf9e1e2..30a190ce4298 100644
--- a/drivers/w1/masters/mxc_w1.c
+++ b/drivers/w1/masters/mxc_w1.c
@@ -151,15 +151,13 @@ out_disable_clk:
/*
* disassociate the w1 device from the driver
*/
-static int mxc_w1_remove(struct platform_device *pdev)
+static void mxc_w1_remove(struct platform_device *pdev)
{
struct mxc_w1_device *mdev = platform_get_drvdata(pdev);
w1_remove_master_device(&mdev->bus_master);
clk_disable_unprepare(mdev->clk);
-
- return 0;
}
static const struct of_device_id mxc_w1_dt_ids[] = {
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
index 6a39b71eb718..69b1d145657a 100644
--- a/drivers/w1/masters/omap_hdq.c
+++ b/drivers/w1/masters/omap_hdq.c
@@ -647,7 +647,7 @@ err_w1:
return ret;
}
-static int omap_hdq_remove(struct platform_device *pdev)
+static void omap_hdq_remove(struct platform_device *pdev)
{
int active;
@@ -661,8 +661,6 @@ static int omap_hdq_remove(struct platform_device *pdev)
if (active >= 0)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct of_device_id omap_hdq_dt_ids[] = {
diff --git a/drivers/w1/masters/sgi_w1.c b/drivers/w1/masters/sgi_w1.c
index d7fbc3c146e1..af6b1186b763 100644
--- a/drivers/w1/masters/sgi_w1.c
+++ b/drivers/w1/masters/sgi_w1.c
@@ -105,13 +105,11 @@ static int sgi_w1_probe(struct platform_device *pdev)
/*
* disassociate the w1 device from the driver
*/
-static int sgi_w1_remove(struct platform_device *pdev)
+static void sgi_w1_remove(struct platform_device *pdev)
{
struct sgi_w1_device *sdev = platform_get_drvdata(pdev);
w1_remove_master_device(&sdev->bus_master);
-
- return 0;
}
static struct platform_driver sgi_w1_driver = {
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index 05c67038ed20..a579f95be8f1 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -5,15 +5,15 @@
* Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi>
*/
-#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/gpio/consumer.h>
-#include <linux/of_platform.h>
-#include <linux/err.h>
-#include <linux/of.h>
-#include <linux/delay.h>
+#include <linux/property.h>
+#include <linux/types.h>
#include <linux/w1.h>
@@ -63,20 +63,11 @@ static u8 w1_gpio_read_bit(void *data)
return gpiod_get_value(ddata->gpiod) ? 1 : 0;
}
-#if defined(CONFIG_OF)
-static const struct of_device_id w1_gpio_dt_ids[] = {
- { .compatible = "w1-gpio" },
- {}
-};
-MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
-#endif
-
static int w1_gpio_probe(struct platform_device *pdev)
{
struct w1_bus_master *master;
struct w1_gpio_ddata *ddata;
struct device *dev = &pdev->dev;
- struct device_node *np = dev->of_node;
/* Enforce open drain mode by default */
enum gpiod_flags gflags = GPIOD_OUT_LOW_OPEN_DRAIN;
int err;
@@ -91,27 +82,22 @@ static int w1_gpio_probe(struct platform_device *pdev)
* driver it high/low like we are in full control of the line and
* open drain will happen transparently.
*/
- if (of_property_present(np, "linux,open-drain"))
+ if (device_property_present(dev, "linux,open-drain"))
gflags = GPIOD_OUT_LOW;
- master = devm_kzalloc(dev, sizeof(struct w1_bus_master),
- GFP_KERNEL);
+ master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL);
if (!master)
return -ENOMEM;
ddata->gpiod = devm_gpiod_get_index(dev, NULL, 0, gflags);
- if (IS_ERR(ddata->gpiod)) {
- dev_err(dev, "gpio_request (pin) failed\n");
- return PTR_ERR(ddata->gpiod);
- }
+ if (IS_ERR(ddata->gpiod))
+ return dev_err_probe(dev, PTR_ERR(ddata->gpiod), "gpio_request (pin) failed\n");
ddata->pullup_gpiod =
devm_gpiod_get_index_optional(dev, NULL, 1, GPIOD_OUT_LOW);
- if (IS_ERR(ddata->pullup_gpiod)) {
- dev_err(dev, "gpio_request_one "
- "(ext_pullup_enable_pin) failed\n");
- return PTR_ERR(ddata->pullup_gpiod);
- }
+ if (IS_ERR(ddata->pullup_gpiod))
+ return dev_err_probe(dev, PTR_ERR(ddata->pullup_gpiod),
+ "gpio_request (ext_pullup_enable_pin) failed\n");
master->data = ddata;
master->read_bit = w1_gpio_read_bit;
@@ -128,36 +114,36 @@ static int w1_gpio_probe(struct platform_device *pdev)
master->set_pullup = w1_gpio_set_pullup;
err = w1_add_master_device(master);
- if (err) {
- dev_err(dev, "w1_add_master device failed\n");
- return err;
- }
+ if (err)
+ return dev_err_probe(dev, err, "w1_add_master device failed\n");
- if (ddata->pullup_gpiod)
- gpiod_set_value(ddata->pullup_gpiod, 1);
+ gpiod_set_value(ddata->pullup_gpiod, 1);
platform_set_drvdata(pdev, master);
return 0;
}
-static int w1_gpio_remove(struct platform_device *pdev)
+static void w1_gpio_remove(struct platform_device *pdev)
{
struct w1_bus_master *master = platform_get_drvdata(pdev);
struct w1_gpio_ddata *ddata = master->data;
- if (ddata->pullup_gpiod)
- gpiod_set_value(ddata->pullup_gpiod, 0);
+ gpiod_set_value(ddata->pullup_gpiod, 0);
w1_remove_master_device(master);
-
- return 0;
}
+static const struct of_device_id w1_gpio_dt_ids[] = {
+ { .compatible = "w1-gpio" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
+
static struct platform_driver w1_gpio_driver = {
.driver = {
.name = "w1-gpio",
- .of_match_table = of_match_ptr(w1_gpio_dt_ids),
+ .of_match_table = w1_gpio_dt_ids,
},
.probe = w1_gpio_probe,
.remove = w1_gpio_remove,
diff --git a/drivers/w1/masters/w1-uart.c b/drivers/w1/masters/w1-uart.c
new file mode 100644
index 000000000000..c87eea347806
--- /dev/null
+++ b/drivers/w1/masters/w1-uart.c
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * w1-uart - UART 1-Wire bus driver
+ *
+ * Uses the UART interface (via Serial Device Bus) to create the 1-Wire
+ * timing patterns. Implements the following 1-Wire master interface:
+ *
+ * - reset_bus: requests baud-rate 9600
+ *
+ * - touch_bit: requests baud-rate 115200
+ *
+ * Author: Christoph Winklhofer <cj.winklhofer@gmail.com>
+ */
+
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/serdev.h>
+#include <linux/w1.h>
+
+/* UART packet contains start and stop bit */
+#define W1_UART_BITS_PER_PACKET (BITS_PER_BYTE + 2)
+
+/* Timeout to wait for completion of serdev-receive */
+#define W1_UART_TIMEOUT msecs_to_jiffies(500)
+
+/**
+ * struct w1_uart_config - configuration for 1-Wire operation
+ * @baudrate: baud-rate returned from serdev
+ * @delay_us: delay to complete a 1-Wire cycle (in us)
+ * @tx_byte: byte to generate 1-Wire timing pattern
+ */
+struct w1_uart_config {
+ unsigned int baudrate;
+ unsigned int delay_us;
+ u8 tx_byte;
+};
+
+/**
+ * struct w1_uart_device - 1-Wire UART device structure
+ * @serdev: serial device
+ * @bus: w1-bus master
+ * @cfg_reset: config for 1-Wire reset
+ * @cfg_touch_0: config for 1-Wire write-0 cycle
+ * @cfg_touch_1: config for 1-Wire write-1 and read cycle
+ * @rx_byte_received: completion for serdev receive
+ * @rx_mutex: mutex to protect rx_err and rx_byte
+ * @rx_err: indicates an error in serdev-receive
+ * @rx_byte: result byte from serdev-receive
+ */
+struct w1_uart_device {
+ struct serdev_device *serdev;
+ struct w1_bus_master bus;
+
+ struct w1_uart_config cfg_reset;
+ struct w1_uart_config cfg_touch_0;
+ struct w1_uart_config cfg_touch_1;
+
+ struct completion rx_byte_received;
+ /*
+ * protect rx_err and rx_byte from concurrent access in
+ * w1-callbacks and serdev-receive.
+ */
+ struct mutex rx_mutex;
+ int rx_err;
+ u8 rx_byte;
+};
+
+/**
+ * struct w1_uart_limits - limits for 1-Wire operations
+ * @baudrate: Requested baud-rate to create 1-Wire timing pattern
+ * @bit_min_us: minimum time for a bit (in us)
+ * @bit_max_us: maximum time for a bit (in us)
+ * @sample_us: timespan to sample 1-Wire response
+ * @cycle_us: duration of the 1-Wire cycle
+ */
+struct w1_uart_limits {
+ unsigned int baudrate;
+ unsigned int bit_min_us;
+ unsigned int bit_max_us;
+ unsigned int sample_us;
+ unsigned int cycle_us;
+};
+
+static inline unsigned int baud_to_bit_ns(unsigned int baud)
+{
+ return NSEC_PER_SEC / baud;
+}
+
+static inline unsigned int to_ns(unsigned int us)
+{
+ return us * NSEC_PER_USEC;
+}
+
+/*
+ * Set baud-rate, delay and tx-byte to create a 1-Wire pulse and adapt
+ * the tx-byte according to the actual baud-rate.
+ *
+ * Reject when:
+ * - time for a bit outside min/max range
+ * - a 1-Wire response is not detectable for sent byte
+ */
+static int w1_uart_set_config(struct serdev_device *serdev,
+ const struct w1_uart_limits *limits,
+ struct w1_uart_config *w1cfg)
+{
+ unsigned int packet_ns;
+ unsigned int bits_low;
+ unsigned int bit_ns;
+ unsigned int low_ns;
+
+ w1cfg->baudrate = serdev_device_set_baudrate(serdev, limits->baudrate);
+ if (w1cfg->baudrate == 0)
+ return -EINVAL;
+
+ /* Compute in nanoseconds for accuracy */
+ bit_ns = baud_to_bit_ns(w1cfg->baudrate);
+ bits_low = to_ns(limits->bit_min_us) / bit_ns;
+ /* start bit is always low */
+ low_ns = bit_ns * (bits_low + 1);
+
+ if (low_ns < to_ns(limits->bit_min_us))
+ return -EINVAL;
+
+ if (low_ns > to_ns(limits->bit_max_us))
+ return -EINVAL;
+
+ /* 1-Wire response detectable for sent byte */
+ if (limits->sample_us > 0 &&
+ bit_ns * BITS_PER_BYTE < low_ns + to_ns(limits->sample_us))
+ return -EINVAL;
+
+ /* delay: 1-Wire cycle takes longer than the UART packet */
+ packet_ns = bit_ns * W1_UART_BITS_PER_PACKET;
+ w1cfg->delay_us = 0;
+ if (to_ns(limits->cycle_us) > packet_ns)
+ w1cfg->delay_us =
+ (to_ns(limits->cycle_us) - packet_ns) / NSEC_PER_USEC;
+
+ /* byte to create 1-Wire pulse */
+ w1cfg->tx_byte = 0xff << bits_low;
+
+ return 0;
+}
+
+/*
+ * Configuration for reset and presence detect
+ * - bit_min_us is 480us, add margin and use 485us
+ * - limits for sample time 60us-75us, use 65us
+ */
+static int w1_uart_set_config_reset(struct w1_uart_device *w1dev)
+{
+ struct serdev_device *serdev = w1dev->serdev;
+ struct device_node *np = serdev->dev.of_node;
+
+ struct w1_uart_limits limits = { .baudrate = 9600,
+ .bit_min_us = 485,
+ .bit_max_us = 640,
+ .sample_us = 65,
+ .cycle_us = 960 };
+
+ of_property_read_u32(np, "reset-bps", &limits.baudrate);
+
+ return w1_uart_set_config(serdev, &limits, &w1dev->cfg_reset);
+}
+
+/*
+ * Configuration for write-0 cycle (touch bit 0)
+ * - bit_min_us is 60us, add margin and use 65us
+ * - no sampling required, sample_us = 0
+ */
+static int w1_uart_set_config_touch_0(struct w1_uart_device *w1dev)
+{
+ struct serdev_device *serdev = w1dev->serdev;
+ struct device_node *np = serdev->dev.of_node;
+
+ struct w1_uart_limits limits = { .baudrate = 115200,
+ .bit_min_us = 65,
+ .bit_max_us = 120,
+ .sample_us = 0,
+ .cycle_us = 70 };
+
+ of_property_read_u32(np, "write-0-bps", &limits.baudrate);
+
+ return w1_uart_set_config(serdev, &limits, &w1dev->cfg_touch_0);
+}
+
+/*
+ * Configuration for write-1 and read cycle (touch bit 1)
+ * - bit_min_us is 5us, add margin and use 6us
+ * - limits for sample time 5us-15us, use 15us
+ */
+static int w1_uart_set_config_touch_1(struct w1_uart_device *w1dev)
+{
+ struct serdev_device *serdev = w1dev->serdev;
+ struct device_node *np = serdev->dev.of_node;
+
+ struct w1_uart_limits limits = { .baudrate = 115200,
+ .bit_min_us = 6,
+ .bit_max_us = 15,
+ .sample_us = 15,
+ .cycle_us = 70 };
+
+ of_property_read_u32(np, "write-1-bps", &limits.baudrate);
+
+ return w1_uart_set_config(serdev, &limits, &w1dev->cfg_touch_1);
+}
+
+/*
+ * Configure and open the serial device
+ */
+static int w1_uart_serdev_open(struct w1_uart_device *w1dev)
+{
+ struct serdev_device *serdev = w1dev->serdev;
+ struct device *dev = &serdev->dev;
+ int ret;
+
+ ret = devm_serdev_device_open(dev, serdev);
+ if (ret < 0)
+ return ret;
+
+ ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
+ if (ret < 0) {
+ dev_err(dev, "set parity failed\n");
+ return ret;
+ }
+
+ ret = w1_uart_set_config_reset(w1dev);
+ if (ret < 0) {
+ dev_err(dev, "config for reset failed\n");
+ return ret;
+ }
+
+ ret = w1_uart_set_config_touch_0(w1dev);
+ if (ret < 0) {
+ dev_err(dev, "config for touch-0 failed\n");
+ return ret;
+ }
+
+ ret = w1_uart_set_config_touch_1(w1dev);
+ if (ret < 0) {
+ dev_err(dev, "config for touch-1 failed\n");
+ return ret;
+ }
+
+ serdev_device_set_flow_control(serdev, false);
+
+ return 0;
+}
+
+/*
+ * Send one byte (tx_byte) and read one byte (rx_byte) via serdev.
+ */
+static int w1_uart_serdev_tx_rx(struct w1_uart_device *w1dev,
+ const struct w1_uart_config *w1cfg, u8 *rx_byte)
+{
+ struct serdev_device *serdev = w1dev->serdev;
+ int ret;
+
+ serdev_device_write_flush(serdev);
+ serdev_device_set_baudrate(serdev, w1cfg->baudrate);
+
+ /* write and immediately read one byte */
+ reinit_completion(&w1dev->rx_byte_received);
+ ret = serdev_device_write_buf(serdev, &w1cfg->tx_byte, 1);
+ if (ret != 1)
+ return -EIO;
+ ret = wait_for_completion_interruptible_timeout(
+ &w1dev->rx_byte_received, W1_UART_TIMEOUT);
+ if (ret <= 0)
+ return -EIO;
+
+ /* locking could fail when serdev is unexpectedly receiving. */
+ if (!mutex_trylock(&w1dev->rx_mutex))
+ return -EIO;
+
+ ret = w1dev->rx_err;
+ if (ret == 0)
+ *rx_byte = w1dev->rx_byte;
+
+ mutex_unlock(&w1dev->rx_mutex);
+
+ if (w1cfg->delay_us > 0)
+ fsleep(w1cfg->delay_us);
+
+ return ret;
+}
+
+static size_t w1_uart_serdev_receive_buf(struct serdev_device *serdev,
+ const u8 *buf, size_t count)
+{
+ struct w1_uart_device *w1dev = serdev_device_get_drvdata(serdev);
+
+ mutex_lock(&w1dev->rx_mutex);
+
+ /* sent a single byte and receive one single byte */
+ if (count == 1) {
+ w1dev->rx_byte = buf[0];
+ w1dev->rx_err = 0;
+ } else {
+ w1dev->rx_err = -EIO;
+ }
+
+ mutex_unlock(&w1dev->rx_mutex);
+ complete(&w1dev->rx_byte_received);
+
+ return count;
+}
+
+static const struct serdev_device_ops w1_uart_serdev_ops = {
+ .receive_buf = w1_uart_serdev_receive_buf,
+ .write_wakeup = serdev_device_write_wakeup,
+};
+
+/*
+ * 1-wire reset and presence detect: A present slave will manipulate
+ * the received byte by pulling the 1-Wire low.
+ */
+static u8 w1_uart_reset_bus(void *data)
+{
+ struct w1_uart_device *w1dev = data;
+ const struct w1_uart_config *w1cfg = &w1dev->cfg_reset;
+ int ret;
+ u8 val;
+
+ ret = w1_uart_serdev_tx_rx(w1dev, w1cfg, &val);
+ if (ret < 0)
+ return -1;
+
+ /* Device present (0) or no device (1) */
+ return val != w1cfg->tx_byte ? 0 : 1;
+}
+
+/*
+ * 1-Wire read and write cycle: Only the read-0 manipulates the
+ * received byte, all others left the line untouched.
+ */
+static u8 w1_uart_touch_bit(void *data, u8 bit)
+{
+ struct w1_uart_device *w1dev = data;
+ const struct w1_uart_config *w1cfg = bit ? &w1dev->cfg_touch_1 :
+ &w1dev->cfg_touch_0;
+ int ret;
+ u8 val;
+
+ ret = w1_uart_serdev_tx_rx(w1dev, w1cfg, &val);
+
+ /* return inactive bus state on error */
+ if (ret < 0)
+ return 1;
+
+ return val == w1cfg->tx_byte ? 1 : 0;
+}
+
+static int w1_uart_probe(struct serdev_device *serdev)
+{
+ struct device *dev = &serdev->dev;
+ struct w1_uart_device *w1dev;
+ int ret;
+
+ w1dev = devm_kzalloc(dev, sizeof(*w1dev), GFP_KERNEL);
+ if (!w1dev)
+ return -ENOMEM;
+ w1dev->bus.data = w1dev;
+ w1dev->bus.reset_bus = w1_uart_reset_bus;
+ w1dev->bus.touch_bit = w1_uart_touch_bit;
+ w1dev->serdev = serdev;
+
+ init_completion(&w1dev->rx_byte_received);
+ mutex_init(&w1dev->rx_mutex);
+
+ serdev_device_set_drvdata(serdev, w1dev);
+ serdev_device_set_client_ops(serdev, &w1_uart_serdev_ops);
+ ret = w1_uart_serdev_open(w1dev);
+ if (ret < 0)
+ return ret;
+
+ return w1_add_master_device(&w1dev->bus);
+}
+
+static void w1_uart_remove(struct serdev_device *serdev)
+{
+ struct w1_uart_device *w1dev = serdev_device_get_drvdata(serdev);
+
+ /*
+ * Waits until w1-uart callbacks are finished, serdev is closed
+ * and its device data released automatically by devres (waits
+ * until serdev-receive is finished).
+ */
+ w1_remove_master_device(&w1dev->bus);
+}
+
+static const struct of_device_id w1_uart_of_match[] = {
+ { .compatible = "w1-uart" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, w1_uart_of_match);
+
+static struct serdev_device_driver w1_uart_driver = {
+ .driver = {
+ .name = "w1-uart",
+ .of_match_table = w1_uart_of_match,
+ },
+ .probe = w1_uart_probe,
+ .remove = w1_uart_remove,
+};
+
+module_serdev_device_driver(w1_uart_driver);
+
+MODULE_DESCRIPTION("UART w1 bus driver");
+MODULE_AUTHOR("Christoph Winklhofer <cj.winklhofer@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/w1/slaves/w1_ds2406.c b/drivers/w1/slaves/w1_ds2406.c
index 2f5926859b8b..76026d615111 100644
--- a/drivers/w1/slaves/w1_ds2406.c
+++ b/drivers/w1/slaves/w1_ds2406.c
@@ -24,13 +24,11 @@
static ssize_t w1_f12_read_state(
struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
u8 w1_buf[6] = {W1_F12_FUNC_READ_STATUS, 7, 0, 0, 0, 0};
struct w1_slave *sl = kobj_to_w1_slave(kobj);
- u16 crc = 0;
- int i;
ssize_t rtnval = 1;
if (off != 0)
@@ -47,9 +45,7 @@ static ssize_t w1_f12_read_state(
w1_write_block(sl->master, w1_buf, 3);
w1_read_block(sl->master, w1_buf+3, 3);
- for (i = 0; i < 6; i++)
- crc = crc16_byte(crc, w1_buf[i]);
- if (crc == 0xb001) /* good read? */
+ if (crc16(0, w1_buf, sizeof(w1_buf)) == 0xb001) /* good read? */
*buf = ((w1_buf[3]>>5)&3)|0x30;
else
rtnval = -EIO;
@@ -61,13 +57,11 @@ static ssize_t w1_f12_read_state(
static ssize_t w1_f12_write_output(
struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
u8 w1_buf[6] = {W1_F12_FUNC_WRITE_STATUS, 7, 0, 0, 0, 0};
- u16 crc = 0;
- int i;
ssize_t rtnval = 1;
if (count != 1 || off != 0)
@@ -83,9 +77,7 @@ static ssize_t w1_f12_write_output(
w1_buf[3] = (((*buf)&3)<<5)|0x1F;
w1_write_block(sl->master, w1_buf, 4);
w1_read_block(sl->master, w1_buf+4, 2);
- for (i = 0; i < 6; i++)
- crc = crc16_byte(crc, w1_buf[i]);
- if (crc == 0xb001) /* good read? */
+ if (crc16(0, w1_buf, sizeof(w1_buf)) == 0xb001) /* good read? */
w1_write_8(sl->master, 0xFF);
else
rtnval = -EIO;
@@ -95,14 +87,14 @@ static ssize_t w1_f12_write_output(
}
#define NB_SYSFS_BIN_FILES 2
-static struct bin_attribute w1_f12_sysfs_bin_files[NB_SYSFS_BIN_FILES] = {
+static const struct bin_attribute w1_f12_sysfs_bin_files[NB_SYSFS_BIN_FILES] = {
{
.attr = {
.name = "state",
.mode = 0444,
},
.size = 1,
- .read = w1_f12_read_state,
+ .read_new = w1_f12_read_state,
},
{
.attr = {
@@ -110,7 +102,7 @@ static struct bin_attribute w1_f12_sysfs_bin_files[NB_SYSFS_BIN_FILES] = {
.mode = 0664,
},
.size = 1,
- .write = w1_f12_write_output,
+ .write_new = w1_f12_write_output,
}
};
diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c
index 56f822a1dfdb..beccd2912d2a 100644
--- a/drivers/w1/slaves/w1_ds2408.c
+++ b/drivers/w1/slaves/w1_ds2408.c
@@ -65,8 +65,8 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char *buf)
}
static ssize_t state_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off,
- size_t count)
+ const struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
dev_dbg(&kobj_to_w1_slave(kobj)->dev,
"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
@@ -77,7 +77,7 @@ static ssize_t state_read(struct file *filp, struct kobject *kobj,
}
static ssize_t output_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
dev_dbg(&kobj_to_w1_slave(kobj)->dev,
@@ -90,7 +90,7 @@ static ssize_t output_read(struct file *filp, struct kobject *kobj,
}
static ssize_t activity_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
dev_dbg(&kobj_to_w1_slave(kobj)->dev,
@@ -103,8 +103,8 @@ static ssize_t activity_read(struct file *filp, struct kobject *kobj,
}
static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
- loff_t off, size_t count)
+ const struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
{
dev_dbg(&kobj_to_w1_slave(kobj)->dev,
"Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
@@ -117,7 +117,7 @@ static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj,
static ssize_t cond_search_polarity_read(struct file *filp,
struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
if (count != 1 || off != 0)
@@ -127,8 +127,8 @@ static ssize_t cond_search_polarity_read(struct file *filp,
}
static ssize_t status_control_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
- loff_t off, size_t count)
+ const struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
{
if (count != 1 || off != 0)
return -EFAULT;
@@ -160,7 +160,7 @@ static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
#endif
static ssize_t output_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -210,7 +210,7 @@ out:
* Writing to the activity file resets the activity latches.
*/
static ssize_t activity_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -240,8 +240,8 @@ error:
}
static ssize_t status_control_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
- loff_t off, size_t count)
+ const struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
u8 w1_buf[4];
@@ -310,14 +310,14 @@ out:
return res;
}
-static BIN_ATTR_RO(state, 1);
-static BIN_ATTR_RW(output, 1);
-static BIN_ATTR_RW(activity, 1);
-static BIN_ATTR_RO(cond_search_mask, 1);
-static BIN_ATTR_RO(cond_search_polarity, 1);
-static BIN_ATTR_RW(status_control, 1);
+static const BIN_ATTR_RO(state, 1);
+static const BIN_ATTR_RW(output, 1);
+static const BIN_ATTR_RW(activity, 1);
+static const BIN_ATTR_RO(cond_search_mask, 1);
+static const BIN_ATTR_RO(cond_search_polarity, 1);
+static const BIN_ATTR_RW(status_control, 1);
-static struct bin_attribute *w1_f29_bin_attrs[] = {
+static const struct bin_attribute *const w1_f29_bin_attrs[] = {
&bin_attr_state,
&bin_attr_output,
&bin_attr_activity,
@@ -328,7 +328,7 @@ static struct bin_attribute *w1_f29_bin_attrs[] = {
};
static const struct attribute_group w1_f29_group = {
- .bin_attrs = w1_f29_bin_attrs,
+ .bin_attrs_new = w1_f29_bin_attrs,
};
static const struct attribute_group *w1_f29_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds2413.c b/drivers/w1/slaves/w1_ds2413.c
index 739009806467..5fa46017ca7c 100644
--- a/drivers/w1/slaves/w1_ds2413.c
+++ b/drivers/w1/slaves/w1_ds2413.c
@@ -25,8 +25,8 @@
#define W1_F3A_INVALID_PIO_STATE 0xFF
static ssize_t state_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off,
- size_t count)
+ const struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
unsigned int retries = W1_F3A_RETRIES;
@@ -78,10 +78,10 @@ out:
return bytes_read;
}
-static BIN_ATTR_RO(state, 1);
+static const BIN_ATTR_RO(state, 1);
static ssize_t output_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -128,16 +128,16 @@ out:
return bytes_written;
}
-static BIN_ATTR(output, 0664, NULL, output_write, 1);
+static const BIN_ATTR(output, 0664, NULL, output_write, 1);
-static struct bin_attribute *w1_f3a_bin_attrs[] = {
+static const struct bin_attribute *const w1_f3a_bin_attrs[] = {
&bin_attr_state,
&bin_attr_output,
NULL,
};
static const struct attribute_group w1_f3a_group = {
- .bin_attrs = w1_f3a_bin_attrs,
+ .bin_attrs_new = w1_f3a_bin_attrs,
};
static const struct attribute_group *w1_f3a_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds2430.c b/drivers/w1/slaves/w1_ds2430.c
index 0ea7d779d17a..ff56e2e68e58 100644
--- a/drivers/w1/slaves/w1_ds2430.c
+++ b/drivers/w1/slaves/w1_ds2430.c
@@ -95,7 +95,7 @@ static int w1_f14_readblock(struct w1_slave *sl, int off, int count, char *buf)
}
static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -202,7 +202,7 @@ retry:
}
static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -263,15 +263,15 @@ out_up:
return count;
}
-static BIN_ATTR_RW(eeprom, W1_F14_EEPROM_SIZE);
+static const BIN_ATTR_RW(eeprom, W1_F14_EEPROM_SIZE);
-static struct bin_attribute *w1_f14_bin_attrs[] = {
+static const struct bin_attribute *const w1_f14_bin_attrs[] = {
&bin_attr_eeprom,
NULL,
};
static const struct attribute_group w1_f14_group = {
- .bin_attrs = w1_f14_bin_attrs,
+ .bin_attrs_new = w1_f14_bin_attrs,
};
static const struct attribute_group *w1_f14_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c
index 6856b1c29e17..27b390fb59da 100644
--- a/drivers/w1/slaves/w1_ds2431.c
+++ b/drivers/w1/slaves/w1_ds2431.c
@@ -95,7 +95,7 @@ static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf)
}
static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -201,7 +201,7 @@ retry:
}
static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -262,15 +262,15 @@ out_up:
return count;
}
-static BIN_ATTR_RW(eeprom, W1_F2D_EEPROM_SIZE);
+static const BIN_ATTR_RW(eeprom, W1_F2D_EEPROM_SIZE);
-static struct bin_attribute *w1_f2d_bin_attrs[] = {
+static const struct bin_attribute *const w1_f2d_bin_attrs[] = {
&bin_attr_eeprom,
NULL,
};
static const struct attribute_group w1_f2d_group = {
- .bin_attrs = w1_f2d_bin_attrs,
+ .bin_attrs_new = w1_f2d_bin_attrs,
};
static const struct attribute_group *w1_f2d_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c
index 250b7f7ec429..22331d840ec1 100644
--- a/drivers/w1/slaves/w1_ds2433.c
+++ b/drivers/w1/slaves/w1_ds2433.c
@@ -110,7 +110,7 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data,
#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -224,7 +224,7 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
}
static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -274,27 +274,27 @@ out_up:
return count;
}
-static struct bin_attribute bin_attr_f23_eeprom = {
+static const struct bin_attribute bin_attr_f23_eeprom = {
.attr = { .name = "eeprom", .mode = 0644 },
- .read = eeprom_read,
- .write = eeprom_write,
+ .read_new = eeprom_read,
+ .write_new = eeprom_write,
.size = W1_EEPROM_DS2433_SIZE,
};
-static struct bin_attribute bin_attr_f43_eeprom = {
+static const struct bin_attribute bin_attr_f43_eeprom = {
.attr = { .name = "eeprom", .mode = 0644 },
- .read = eeprom_read,
- .write = eeprom_write,
+ .read_new = eeprom_read,
+ .write_new = eeprom_write,
.size = W1_EEPROM_DS28EC20_SIZE,
};
-static struct bin_attribute *w1_f23_bin_attributes[] = {
+static const struct bin_attribute *const w1_f23_bin_attributes[] = {
&bin_attr_f23_eeprom,
NULL,
};
static const struct attribute_group w1_f23_group = {
- .bin_attrs = w1_f23_bin_attributes,
+ .bin_attrs_new = w1_f23_bin_attributes,
};
static const struct attribute_group *w1_f23_groups[] = {
@@ -302,13 +302,13 @@ static const struct attribute_group *w1_f23_groups[] = {
NULL,
};
-static struct bin_attribute *w1_f43_bin_attributes[] = {
+static const struct bin_attribute *const w1_f43_bin_attributes[] = {
&bin_attr_f43_eeprom,
NULL,
};
static const struct attribute_group w1_f43_group = {
- .bin_attrs = w1_f43_bin_attributes,
+ .bin_attrs_new = w1_f43_bin_attributes,
};
static const struct attribute_group *w1_f43_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds2438.c b/drivers/w1/slaves/w1_ds2438.c
index e008c27b3db9..630a6db5045e 100644
--- a/drivers/w1/slaves/w1_ds2438.c
+++ b/drivers/w1/slaves/w1_ds2438.c
@@ -288,7 +288,7 @@ static int w1_ds2438_get_current(struct w1_slave *sl, int16_t *voltage)
}
static ssize_t iad_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -310,7 +310,7 @@ static ssize_t iad_write(struct file *filp, struct kobject *kobj,
}
static ssize_t iad_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -331,7 +331,7 @@ static ssize_t iad_read(struct file *filp, struct kobject *kobj,
}
static ssize_t page0_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -361,7 +361,7 @@ static ssize_t page0_read(struct file *filp, struct kobject *kobj,
}
static ssize_t page1_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -391,7 +391,7 @@ static ssize_t page1_read(struct file *filp, struct kobject *kobj,
}
static ssize_t offset_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -410,7 +410,7 @@ static ssize_t offset_write(struct file *filp, struct kobject *kobj,
}
static ssize_t temperature_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -431,7 +431,7 @@ static ssize_t temperature_read(struct file *filp, struct kobject *kobj,
}
static ssize_t vad_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -452,7 +452,7 @@ static ssize_t vad_read(struct file *filp, struct kobject *kobj,
}
static ssize_t vdd_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -472,15 +472,15 @@ static ssize_t vdd_read(struct file *filp, struct kobject *kobj,
return ret;
}
-static BIN_ATTR_RW(iad, 0);
-static BIN_ATTR_RO(page0, DS2438_PAGE_SIZE);
-static BIN_ATTR_RO(page1, DS2438_PAGE_SIZE);
-static BIN_ATTR_WO(offset, 2);
-static BIN_ATTR_RO(temperature, 0/* real length varies */);
-static BIN_ATTR_RO(vad, 0/* real length varies */);
-static BIN_ATTR_RO(vdd, 0/* real length varies */);
+static const BIN_ATTR_RW(iad, 0);
+static const BIN_ATTR_RO(page0, DS2438_PAGE_SIZE);
+static const BIN_ATTR_RO(page1, DS2438_PAGE_SIZE);
+static const BIN_ATTR_WO(offset, 2);
+static const BIN_ATTR_RO(temperature, 0/* real length varies */);
+static const BIN_ATTR_RO(vad, 0/* real length varies */);
+static const BIN_ATTR_RO(vdd, 0/* real length varies */);
-static struct bin_attribute *w1_ds2438_bin_attrs[] = {
+static const struct bin_attribute *const w1_ds2438_bin_attrs[] = {
&bin_attr_iad,
&bin_attr_page0,
&bin_attr_page1,
@@ -492,7 +492,7 @@ static struct bin_attribute *w1_ds2438_bin_attrs[] = {
};
static const struct attribute_group w1_ds2438_group = {
- .bin_attrs = w1_ds2438_bin_attrs,
+ .bin_attrs_new = w1_ds2438_bin_attrs,
};
static const struct attribute_group *w1_ds2438_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c
index 3cde1bb1886b..ba7beb7b01f9 100644
--- a/drivers/w1/slaves/w1_ds2780.c
+++ b/drivers/w1/slaves/w1_ds2780.c
@@ -87,7 +87,7 @@ int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd)
EXPORT_SYMBOL(w1_ds2780_eeprom_cmd);
static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct device *dev = kobj_to_dev(kobj);
@@ -95,15 +95,15 @@ static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
return w1_ds2780_io(dev, buf, off, count, 0);
}
-static BIN_ATTR_RO(w1_slave, DS2780_DATA_SIZE);
+static const BIN_ATTR_RO(w1_slave, DS2780_DATA_SIZE);
-static struct bin_attribute *w1_ds2780_bin_attrs[] = {
+static const struct bin_attribute *const w1_ds2780_bin_attrs[] = {
&bin_attr_w1_slave,
NULL,
};
static const struct attribute_group w1_ds2780_group = {
- .bin_attrs = w1_ds2780_bin_attrs,
+ .bin_attrs_new = w1_ds2780_bin_attrs,
};
static const struct attribute_group *w1_ds2780_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c
index e418484b4a49..acd04ee96e81 100644
--- a/drivers/w1/slaves/w1_ds2781.c
+++ b/drivers/w1/slaves/w1_ds2781.c
@@ -84,7 +84,7 @@ int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd)
EXPORT_SYMBOL(w1_ds2781_eeprom_cmd);
static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct device *dev = kobj_to_dev(kobj);
@@ -92,15 +92,15 @@ static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
return w1_ds2781_io(dev, buf, off, count, 0);
}
-static BIN_ATTR_RO(w1_slave, DS2781_DATA_SIZE);
+static const BIN_ATTR_RO(w1_slave, DS2781_DATA_SIZE);
-static struct bin_attribute *w1_ds2781_bin_attrs[] = {
+static const struct bin_attribute *const w1_ds2781_bin_attrs[] = {
&bin_attr_w1_slave,
NULL,
};
static const struct attribute_group w1_ds2781_group = {
- .bin_attrs = w1_ds2781_bin_attrs,
+ .bin_attrs_new = w1_ds2781_bin_attrs,
};
static const struct attribute_group *w1_ds2781_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds2805.c b/drivers/w1/slaves/w1_ds2805.c
index 4c1a2c515317..6ee895640d4a 100644
--- a/drivers/w1/slaves/w1_ds2805.c
+++ b/drivers/w1/slaves/w1_ds2805.c
@@ -92,7 +92,7 @@ static int w1_f0d_readblock(struct w1_slave *sl, int off, int count, char *buf)
}
static ssize_t w1_f0d_read_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -200,7 +200,7 @@ retry:
}
static ssize_t w1_f0d_write_bin(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -261,14 +261,14 @@ out_up:
return count;
}
-static struct bin_attribute w1_f0d_bin_attr = {
+static const struct bin_attribute w1_f0d_bin_attr = {
.attr = {
.name = "eeprom",
.mode = 0644,
},
.size = W1_F0D_EEPROM_SIZE,
- .read = w1_f0d_read_bin,
- .write = w1_f0d_write_bin,
+ .read_new = w1_f0d_read_bin,
+ .write_new = w1_f0d_write_bin,
};
static int w1_f0d_add_slave(struct w1_slave *sl)
diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c
index 2854b8b9e93f..d99ffadbe29b 100644
--- a/drivers/w1/slaves/w1_ds28e04.c
+++ b/drivers/w1/slaves/w1_ds28e04.c
@@ -112,7 +112,7 @@ static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data)
}
static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -223,7 +223,7 @@ static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data)
}
static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
+ const struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
@@ -276,10 +276,10 @@ out_up:
return count;
}
-static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE);
+static const BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE);
static ssize_t pio_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off,
+ const struct bin_attribute *bin_attr, char *buf, loff_t off,
size_t count)
{
@@ -298,8 +298,8 @@ static ssize_t pio_read(struct file *filp, struct kobject *kobj,
}
static ssize_t pio_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off,
- size_t count)
+ const struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -337,7 +337,7 @@ static ssize_t pio_write(struct file *filp, struct kobject *kobj,
return count;
}
-static BIN_ATTR_RW(pio, 1);
+static const BIN_ATTR_RW(pio, 1);
static ssize_t crccheck_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -363,7 +363,7 @@ static struct attribute *w1_f1C_attrs[] = {
NULL,
};
-static struct bin_attribute *w1_f1C_bin_attrs[] = {
+static const struct bin_attribute *const w1_f1C_bin_attrs[] = {
&bin_attr_eeprom,
&bin_attr_pio,
NULL,
@@ -371,7 +371,7 @@ static struct bin_attribute *w1_f1C_bin_attrs[] = {
static const struct attribute_group w1_f1C_group = {
.attrs = w1_f1C_attrs,
- .bin_attrs = w1_f1C_bin_attrs,
+ .bin_attrs_new = w1_f1C_bin_attrs,
};
static const struct attribute_group *w1_f1C_groups[] = {
diff --git a/drivers/w1/slaves/w1_ds28e17.c b/drivers/w1/slaves/w1_ds28e17.c
index 52261b54d842..5738cbce1a37 100644
--- a/drivers/w1/slaves/w1_ds28e17.c
+++ b/drivers/w1/slaves/w1_ds28e17.c
@@ -583,7 +583,7 @@ static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
return result;
/* Return current speed value. */
- return sprintf(buf, "%d\n", result);
+ return sysfs_emit(buf, "%d\n", result);
}
static ssize_t speed_store(struct device *dev, struct device_attribute *attr,
@@ -633,7 +633,7 @@ static ssize_t stretch_show(struct device *dev, struct device_attribute *attr,
struct w1_f19_data *data = sl->family_data;
/* Return current stretch value. */
- return sprintf(buf, "%d\n", data->stretch);
+ return sysfs_emit(buf, "%d\n", data->stretch);
}
static ssize_t stretch_store(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index c85e80c7e130..9ccedb3264fb 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -444,18 +444,8 @@ static int w1_read(struct device *dev, enum hwmon_sensor_types type,
}
}
-static const u32 w1_temp_config[] = {
- HWMON_T_INPUT,
- 0
-};
-
-static const struct hwmon_channel_info w1_temp = {
- .type = hwmon_temp,
- .config = w1_temp_config,
-};
-
static const struct hwmon_channel_info * const w1_info[] = {
- &w1_temp,
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
NULL
};
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 5353cbd75126..29f200bbab41 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -111,7 +111,7 @@ ATTRIBUTE_GROUPS(w1_slave);
/* Default family */
static ssize_t rw_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off,
+ const struct bin_attribute *bin_attr, char *buf, loff_t off,
size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -130,8 +130,8 @@ out_up:
}
static ssize_t rw_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf, loff_t off,
- size_t count)
+ const struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
@@ -141,15 +141,15 @@ static ssize_t rw_read(struct file *filp, struct kobject *kobj,
return count;
}
-static BIN_ATTR_RW(rw, PAGE_SIZE);
+static const BIN_ATTR_RW(rw, PAGE_SIZE);
-static struct bin_attribute *w1_slave_bin_attrs[] = {
+static const struct bin_attribute *const w1_slave_bin_attrs[] = {
&bin_attr_rw,
NULL,
};
static const struct attribute_group w1_slave_default_group = {
- .bin_attrs = w1_slave_bin_attrs,
+ .bin_attrs_new = w1_slave_bin_attrs,
};
static const struct attribute_group *w1_slave_default_groups[] = {
@@ -167,7 +167,7 @@ static struct w1_family w1_default_family = {
static int w1_uevent(const struct device *dev, struct kobj_uevent_env *env);
-static struct bus_type w1_bus_type = {
+static const struct bus_type w1_bus_type = {
.name = "w1",
.uevent = w1_uevent,
};
@@ -504,7 +504,7 @@ static ssize_t w1_master_attribute_store_remove(struct device *dev,
if (result == 0)
result = count;
} else {
- dev_info(dev, "Device %02x-%012llx doesn't exists\n", rn.family,
+ dev_info(dev, "Device %02x-%012llx doesn't exist\n", rn.family,
(unsigned long long)rn.id);
result = -EINVAL;
}
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 3a71c5eb2f83..19a0ea28e9f3 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -32,12 +32,8 @@ static struct w1_master *w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
* We are in process context(kernel thread), so can sleep.
*/
dev = kzalloc(sizeof(struct w1_master) + sizeof(struct w1_bus_master), GFP_KERNEL);
- if (!dev) {
- pr_err("Failed to allocate %zd bytes for new w1 device.\n",
- sizeof(struct w1_master));
+ if (!dev)
return NULL;
- }
-
dev->bus_master = (struct w1_bus_master *)(dev + 1);
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 691978cddab7..e6b59d921076 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -194,16 +194,16 @@ static void w1_netlink_queue_status(struct w1_cb_block *block,
static void w1_netlink_send_error(struct cn_msg *cn, struct w1_netlink_msg *msg,
int portid, int error)
{
- struct {
- struct cn_msg cn;
- struct w1_netlink_msg msg;
- } packet;
- memcpy(&packet.cn, cn, sizeof(packet.cn));
- memcpy(&packet.msg, msg, sizeof(packet.msg));
- packet.cn.len = sizeof(packet.msg);
- packet.msg.len = 0;
- packet.msg.status = (u8)-error;
- cn_netlink_send(&packet.cn, portid, 0, GFP_KERNEL);
+ DEFINE_RAW_FLEX(struct cn_msg, packet, data,
+ sizeof(struct w1_netlink_msg));
+ struct w1_netlink_msg *pkt_msg = (struct w1_netlink_msg *)packet->data;
+
+ *packet = *cn;
+ *pkt_msg = *msg;
+ packet->len = sizeof(*pkt_msg);
+ pkt_msg->len = 0;
+ pkt_msg->status = (u8)-error;
+ cn_netlink_send(packet, portid, 0, GFP_KERNEL);
}
/**
@@ -215,22 +215,20 @@ static void w1_netlink_send_error(struct cn_msg *cn, struct w1_netlink_msg *msg,
*/
void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
{
- struct {
- struct cn_msg cn;
- struct w1_netlink_msg msg;
- } packet;
- memset(&packet, 0, sizeof(packet));
+ DEFINE_RAW_FLEX(struct cn_msg, packet, data,
+ sizeof(struct w1_netlink_msg));
+ struct w1_netlink_msg *pkt_msg = (struct w1_netlink_msg *)packet->data;
- packet.cn.id.idx = CN_W1_IDX;
- packet.cn.id.val = CN_W1_VAL;
+ packet->id.idx = CN_W1_IDX;
+ packet->id.val = CN_W1_VAL;
- packet.cn.seq = dev->seq++;
- packet.cn.len = sizeof(*msg);
+ packet->seq = dev->seq++;
+ packet->len = sizeof(*msg);
- memcpy(&packet.msg, msg, sizeof(*msg));
- packet.msg.len = 0;
+ *pkt_msg = *msg;
+ pkt_msg->len = 0;
- cn_netlink_send(&packet.cn, 0, 0, GFP_KERNEL);
+ cn_netlink_send(packet, 0, 0, GFP_KERNEL);
}
static void w1_send_slave(struct w1_master *dev, u64 rn)