v4.19.13 snapshot.
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
new file mode 100644
index 0000000..00827d2
--- /dev/null
+++ b/drivers/w1/masters/Kconfig
@@ -0,0 +1,68 @@
+#
+# 1-wire bus master configuration
+#
+
+menu "1-wire Bus Masters"
+
+config W1_MASTER_MATROX
+	tristate "Matrox G400 transport layer for 1-wire"
+	depends on PCI
+	help
+	  Say Y here if you want to communicate with your 1-wire devices
+	  using Matrox's G400 GPIO pins.
+
+	  This support is also available as a module.  If so, the module
+	  will be called matrox_w1.
+
+config W1_MASTER_DS2490
+	tristate "DS2490 USB <-> W1 transport layer for 1-wire"
+  	depends on USB
+  	help
+	  Say Y here if you want to have a driver for DS2490 based USB <-> W1 bridges,
+	  for example DS9490*.
+
+  	  This support is also available as a module.  If so, the module
+	  will be called ds2490.
+
+config W1_MASTER_DS2482
+	tristate "Maxim DS2482 I2C to 1-Wire bridge"
+	depends on I2C
+	help
+	  If you say yes here you get support for the Maxim DS2482
+	  I2C to 1-Wire bridge.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called ds2482.
+
+config W1_MASTER_MXC
+	tristate "Freescale MXC 1-wire busmaster"
+	depends on ARCH_MXC || COMPILE_TEST
+	help
+	  Say Y here to enable MXC 1-wire host
+
+config W1_MASTER_DS1WM
+	tristate "Maxim DS1WM 1-wire busmaster"
+	help
+	  Say Y here to enable the DS1WM 1-wire driver, such as that
+	  in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like
+	  hx4700.
+
+config W1_MASTER_GPIO
+	tristate "GPIO 1-wire busmaster"
+	depends on GPIOLIB || COMPILE_TEST
+	help
+	  Say Y here if you want to communicate with your 1-wire devices using
+	  GPIO pins. This driver uses the GPIO API to control the wire.
+
+	  This support is also available as a module.  If so, the module
+	  will be called w1-gpio.
+
+config HDQ_MASTER_OMAP
+	tristate "OMAP HDQ driver"
+	depends on ARCH_OMAP
+	help
+	  Say Y here if you want support for the 1-wire or HDQ Interface
+	  on an OMAP processor.
+
+endmenu
+
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile
new file mode 100644
index 0000000..18954ca
--- /dev/null
+++ b/drivers/w1/masters/Makefile
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for 1-wire bus master drivers.
+#
+
+obj-$(CONFIG_W1_MASTER_MATROX)		+= matrox_w1.o
+obj-$(CONFIG_W1_MASTER_DS2490)		+= ds2490.o
+obj-$(CONFIG_W1_MASTER_DS2482)		+= ds2482.o
+obj-$(CONFIG_W1_MASTER_MXC)		+= mxc_w1.o
+
+obj-$(CONFIG_W1_MASTER_DS1WM)		+= ds1wm.o
+obj-$(CONFIG_W1_MASTER_GPIO)		+= w1-gpio.o
+obj-$(CONFIG_HDQ_MASTER_OMAP)		+= omap_hdq.o
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
new file mode 100644
index 0000000..f661695
--- /dev/null
+++ b/drivers/w1/masters/ds1wm.c
@@ -0,0 +1,675 @@
+/*
+ * 1-wire busmaster driver for DS1WM and ASICs with embedded DS1WMs
+ * such as HP iPAQs (including h5xxx, h2200, and devices with ASIC3
+ * like hx4700).
+ *
+ * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ * Copyright (c) 2004-2007, Matt Reimer <mreimer@vpop.net>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+
+#include <linux/w1.h>
+
+
+#define DS1WM_CMD	0x00	/* R/W 4 bits command */
+#define DS1WM_DATA	0x01	/* R/W 8 bits, transmit/receive buffer */
+#define DS1WM_INT	0x02	/* R/W interrupt status */
+#define DS1WM_INT_EN	0x03	/* R/W interrupt enable */
+#define DS1WM_CLKDIV	0x04	/* R/W 5 bits of divisor and pre-scale */
+#define DS1WM_CNTRL	0x05	/* R/W master control register (not used yet) */
+
+#define DS1WM_CMD_1W_RESET  (1 << 0)	/* force reset on 1-wire bus */
+#define DS1WM_CMD_SRA	    (1 << 1)	/* enable Search ROM accelerator mode */
+#define DS1WM_CMD_DQ_OUTPUT (1 << 2)	/* write only - forces bus low */
+#define DS1WM_CMD_DQ_INPUT  (1 << 3)	/* read only - reflects state of bus */
+#define DS1WM_CMD_RST	    (1 << 5)	/* software reset */
+#define DS1WM_CMD_OD	    (1 << 7)	/* overdrive */
+
+#define DS1WM_INT_PD	    (1 << 0)	/* presence detect */
+#define DS1WM_INT_PDR	    (1 << 1)	/* presence detect result */
+#define DS1WM_INT_TBE	    (1 << 2)	/* tx buffer empty */
+#define DS1WM_INT_TSRE	    (1 << 3)	/* tx shift register empty */
+#define DS1WM_INT_RBF	    (1 << 4)	/* rx buffer full */
+#define DS1WM_INT_RSRF	    (1 << 5)	/* rx shift register full */
+
+#define DS1WM_INTEN_EPD	    (1 << 0)	/* enable presence detect int */
+#define DS1WM_INTEN_IAS	    (1 << 1)	/* INTR active state */
+#define DS1WM_INTEN_ETBE    (1 << 2)	/* enable tx buffer empty int */
+#define DS1WM_INTEN_ETMT    (1 << 3)	/* enable tx shift register empty int */
+#define DS1WM_INTEN_ERBF    (1 << 4)	/* enable rx buffer full int */
+#define DS1WM_INTEN_ERSRF   (1 << 5)	/* enable rx shift register full int */
+#define DS1WM_INTEN_DQO	    (1 << 6)	/* enable direct bus driving ops */
+
+#define DS1WM_INTEN_NOT_IAS (~DS1WM_INTEN_IAS)	/* all but INTR active state */
+
+#define DS1WM_TIMEOUT (HZ * 5)
+
+static struct {
+	unsigned long freq;
+	unsigned long divisor;
+} freq[] = {
+	{   1000000, 0x80 },
+	{   2000000, 0x84 },
+	{   3000000, 0x81 },
+	{   4000000, 0x88 },
+	{   5000000, 0x82 },
+	{   6000000, 0x85 },
+	{   7000000, 0x83 },
+	{   8000000, 0x8c },
+	{  10000000, 0x86 },
+	{  12000000, 0x89 },
+	{  14000000, 0x87 },
+	{  16000000, 0x90 },
+	{  20000000, 0x8a },
+	{  24000000, 0x8d },
+	{  28000000, 0x8b },
+	{  32000000, 0x94 },
+	{  40000000, 0x8e },
+	{  48000000, 0x91 },
+	{  56000000, 0x8f },
+	{  64000000, 0x98 },
+	{  80000000, 0x92 },
+	{  96000000, 0x95 },
+	{ 112000000, 0x93 },
+	{ 128000000, 0x9c },
+/* you can continue this table, consult the OPERATION - CLOCK DIVISOR
+   section of the ds1wm spec sheet. */
+};
+
+struct ds1wm_data {
+	void     __iomem *map;
+	unsigned int      bus_shift; /* # of shifts to calc register offsets */
+	bool      is_hw_big_endian;
+	struct platform_device *pdev;
+	const struct mfd_cell   *cell;
+	int      irq;
+	int      slave_present;
+	void     *reset_complete;
+	void     *read_complete;
+	void     *write_complete;
+	int      read_error;
+	/* last byte received */
+	u8       read_byte;
+	/* byte to write that makes all intr disabled, */
+	/* considering active_state (IAS) (optimization) */
+	u8       int_en_reg_none;
+	unsigned int reset_recover_delay; /* see ds1wm.h */
+};
+
+static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
+					u8 val)
+{
+	if (ds1wm_data->is_hw_big_endian) {
+		switch (ds1wm_data->bus_shift) {
+		case 0:
+			iowrite8(val, ds1wm_data->map + (reg << 0));
+			break;
+		case 1:
+			iowrite16be((u16)val, ds1wm_data->map + (reg << 1));
+			break;
+		case 2:
+			iowrite32be((u32)val, ds1wm_data->map + (reg << 2));
+			break;
+		}
+	} else {
+		switch (ds1wm_data->bus_shift) {
+		case 0:
+			iowrite8(val, ds1wm_data->map + (reg << 0));
+			break;
+		case 1:
+			iowrite16((u16)val, ds1wm_data->map + (reg << 1));
+			break;
+		case 2:
+			iowrite32((u32)val, ds1wm_data->map + (reg << 2));
+			break;
+		}
+	}
+}
+
+static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg)
+{
+	u32 val = 0;
+
+	if (ds1wm_data->is_hw_big_endian) {
+		switch (ds1wm_data->bus_shift) {
+		case 0:
+			val = ioread8(ds1wm_data->map + (reg << 0));
+			break;
+		case 1:
+			val = ioread16be(ds1wm_data->map + (reg << 1));
+			break;
+		case 2:
+			val = ioread32be(ds1wm_data->map + (reg << 2));
+			break;
+		}
+	} else {
+		switch (ds1wm_data->bus_shift) {
+		case 0:
+			val = ioread8(ds1wm_data->map + (reg << 0));
+			break;
+		case 1:
+			val = ioread16(ds1wm_data->map + (reg << 1));
+			break;
+		case 2:
+			val = ioread32(ds1wm_data->map + (reg << 2));
+			break;
+		}
+	}
+	dev_dbg(&ds1wm_data->pdev->dev,
+		"ds1wm_read_register reg: %d, 32 bit val:%x\n", reg, val);
+	return (u8)val;
+}
+
+
+static irqreturn_t ds1wm_isr(int isr, void *data)
+{
+	struct ds1wm_data *ds1wm_data = data;
+	u8 intr;
+	u8 inten = ds1wm_read_register(ds1wm_data, DS1WM_INT_EN);
+	/* if no bits are set in int enable register (except the IAS)
+	than go no further, reading the regs below has side effects */
+	if (!(inten & DS1WM_INTEN_NOT_IAS))
+		return IRQ_NONE;
+
+	ds1wm_write_register(ds1wm_data,
+		DS1WM_INT_EN, ds1wm_data->int_en_reg_none);
+
+	/* this read action clears the INTR and certain flags in ds1wm */
+	intr = ds1wm_read_register(ds1wm_data, DS1WM_INT);
+
+	ds1wm_data->slave_present = (intr & DS1WM_INT_PDR) ? 0 : 1;
+
+	if ((intr & DS1WM_INT_TSRE) && ds1wm_data->write_complete) {
+		inten &= ~DS1WM_INTEN_ETMT;
+		complete(ds1wm_data->write_complete);
+	}
+	if (intr & DS1WM_INT_RBF) {
+		/* this read clears the RBF flag */
+		ds1wm_data->read_byte = ds1wm_read_register(ds1wm_data,
+		DS1WM_DATA);
+		inten &= ~DS1WM_INTEN_ERBF;
+		if (ds1wm_data->read_complete)
+			complete(ds1wm_data->read_complete);
+	}
+	if ((intr & DS1WM_INT_PD) && ds1wm_data->reset_complete) {
+		inten &= ~DS1WM_INTEN_EPD;
+		complete(ds1wm_data->reset_complete);
+	}
+
+	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, inten);
+	return IRQ_HANDLED;
+}
+
+static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
+{
+	unsigned long timeleft;
+	DECLARE_COMPLETION_ONSTACK(reset_done);
+
+	ds1wm_data->reset_complete = &reset_done;
+
+	/* enable Presence detect only */
+	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, DS1WM_INTEN_EPD |
+	ds1wm_data->int_en_reg_none);
+
+	ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_1W_RESET);
+
+	timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT);
+	ds1wm_data->reset_complete = NULL;
+	if (!timeleft) {
+		dev_err(&ds1wm_data->pdev->dev, "reset failed, timed out\n");
+		return 1;
+	}
+
+	if (!ds1wm_data->slave_present) {
+		dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n");
+		return 1;
+	}
+
+	if (ds1wm_data->reset_recover_delay)
+		msleep(ds1wm_data->reset_recover_delay);
+
+	return 0;
+}
+
+static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data)
+{
+	unsigned long timeleft;
+	DECLARE_COMPLETION_ONSTACK(write_done);
+	ds1wm_data->write_complete = &write_done;
+
+	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
+	ds1wm_data->int_en_reg_none | DS1WM_INTEN_ETMT);
+
+	ds1wm_write_register(ds1wm_data, DS1WM_DATA, data);
+
+	timeleft = wait_for_completion_timeout(&write_done, DS1WM_TIMEOUT);
+
+	ds1wm_data->write_complete = NULL;
+	if (!timeleft) {
+		dev_err(&ds1wm_data->pdev->dev, "write failed, timed out\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static u8 ds1wm_read(struct ds1wm_data *ds1wm_data, unsigned char write_data)
+{
+	unsigned long timeleft;
+	u8 intEnable = DS1WM_INTEN_ERBF | ds1wm_data->int_en_reg_none;
+	DECLARE_COMPLETION_ONSTACK(read_done);
+
+	ds1wm_read_register(ds1wm_data, DS1WM_DATA);
+
+	ds1wm_data->read_complete = &read_done;
+	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, intEnable);
+
+	ds1wm_write_register(ds1wm_data, DS1WM_DATA, write_data);
+	timeleft = wait_for_completion_timeout(&read_done, DS1WM_TIMEOUT);
+
+	ds1wm_data->read_complete = NULL;
+	if (!timeleft) {
+		dev_err(&ds1wm_data->pdev->dev, "read failed, timed out\n");
+		ds1wm_data->read_error = -ETIMEDOUT;
+		return 0xFF;
+	}
+	ds1wm_data->read_error = 0;
+	return ds1wm_data->read_byte;
+}
+
+static int ds1wm_find_divisor(int gclk)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(freq)-1; i >= 0; --i)
+		if (gclk >= freq[i].freq)
+			return freq[i].divisor;
+
+	return 0;
+}
+
+static void ds1wm_up(struct ds1wm_data *ds1wm_data)
+{
+	int divisor;
+	struct device *dev = &ds1wm_data->pdev->dev;
+	struct ds1wm_driver_data *plat = dev_get_platdata(dev);
+
+	if (ds1wm_data->cell->enable)
+		ds1wm_data->cell->enable(ds1wm_data->pdev);
+
+	divisor = ds1wm_find_divisor(plat->clock_rate);
+	dev_dbg(dev, "found divisor 0x%x for clock %d\n",
+		divisor, plat->clock_rate);
+	if (divisor == 0) {
+		dev_err(dev, "no suitable divisor for %dHz clock\n",
+			plat->clock_rate);
+		return;
+	}
+	ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
+
+	/* Let the w1 clock stabilize. */
+	msleep(1);
+
+	ds1wm_reset(ds1wm_data);
+}
+
+static void ds1wm_down(struct ds1wm_data *ds1wm_data)
+{
+	ds1wm_reset(ds1wm_data);
+
+	/* Disable interrupts. */
+	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
+		ds1wm_data->int_en_reg_none);
+
+	if (ds1wm_data->cell->disable)
+		ds1wm_data->cell->disable(ds1wm_data->pdev);
+}
+
+/* --------------------------------------------------------------------- */
+/* w1 methods */
+
+static u8 ds1wm_read_byte(void *data)
+{
+	struct ds1wm_data *ds1wm_data = data;
+
+	return ds1wm_read(ds1wm_data, 0xff);
+}
+
+static void ds1wm_write_byte(void *data, u8 byte)
+{
+	struct ds1wm_data *ds1wm_data = data;
+
+	ds1wm_write(ds1wm_data, byte);
+}
+
+static u8 ds1wm_reset_bus(void *data)
+{
+	struct ds1wm_data *ds1wm_data = data;
+
+	ds1wm_reset(ds1wm_data);
+
+	return 0;
+}
+
+static void ds1wm_search(void *data, struct w1_master *master_dev,
+			u8 search_type, w1_slave_found_callback slave_found)
+{
+	struct ds1wm_data *ds1wm_data = data;
+	int i;
+	int ms_discrep_bit = -1;
+	u64 r = 0; /* holds the progress of the search */
+	u64 r_prime, d;
+	unsigned slaves_found = 0;
+	unsigned int pass = 0;
+
+	dev_dbg(&ds1wm_data->pdev->dev, "search begin\n");
+	while (true) {
+		++pass;
+		if (pass > 100) {
+			dev_dbg(&ds1wm_data->pdev->dev,
+				"too many attempts (100), search aborted\n");
+			return;
+		}
+
+		mutex_lock(&master_dev->bus_mutex);
+		if (ds1wm_reset(ds1wm_data)) {
+			mutex_unlock(&master_dev->bus_mutex);
+			dev_dbg(&ds1wm_data->pdev->dev,
+				"pass: %d reset error (or no slaves)\n", pass);
+			break;
+		}
+
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d r : %0#18llx writing SEARCH_ROM\n", pass, r);
+		ds1wm_write(ds1wm_data, search_type);
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d entering ASM\n", pass);
+		ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_SRA);
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d beginning nibble loop\n", pass);
+
+		r_prime = 0;
+		d = 0;
+		/* we work one nibble at a time */
+		/* each nibble is interleaved to form a byte */
+		for (i = 0; i < 16; i++) {
+
+			unsigned char resp, _r, _r_prime, _d;
+
+			_r = (r >> (4*i)) & 0xf;
+			_r = ((_r & 0x1) << 1) |
+			((_r & 0x2) << 2) |
+			((_r & 0x4) << 3) |
+			((_r & 0x8) << 4);
+
+			/* writes _r, then reads back: */
+			resp = ds1wm_read(ds1wm_data, _r);
+
+			if (ds1wm_data->read_error) {
+				dev_err(&ds1wm_data->pdev->dev,
+				"pass: %d nibble: %d read error\n", pass, i);
+				break;
+			}
+
+			_r_prime = ((resp & 0x02) >> 1) |
+			((resp & 0x08) >> 2) |
+			((resp & 0x20) >> 3) |
+			((resp & 0x80) >> 4);
+
+			_d = ((resp & 0x01) >> 0) |
+			((resp & 0x04) >> 1) |
+			((resp & 0x10) >> 2) |
+			((resp & 0x40) >> 3);
+
+			r_prime |= (unsigned long long) _r_prime << (i * 4);
+			d |= (unsigned long long) _d << (i * 4);
+
+		}
+		if (ds1wm_data->read_error) {
+			mutex_unlock(&master_dev->bus_mutex);
+			dev_err(&ds1wm_data->pdev->dev,
+				"pass: %d read error, retrying\n", pass);
+			break;
+		}
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d r\': %0#18llx d:%0#18llx\n",
+			pass, r_prime, d);
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d nibble loop complete, exiting ASM\n", pass);
+		ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d resetting bus\n", pass);
+		ds1wm_reset(ds1wm_data);
+		mutex_unlock(&master_dev->bus_mutex);
+		if ((r_prime & ((u64)1 << 63)) && (d & ((u64)1 << 63))) {
+			dev_err(&ds1wm_data->pdev->dev,
+				"pass: %d bus error, retrying\n", pass);
+			continue; /* start over */
+		}
+
+
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d found %0#18llx\n", pass, r_prime);
+		slave_found(master_dev, r_prime);
+		++slaves_found;
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d complete, preparing next pass\n", pass);
+
+		/* any discrepency found which we already choose the
+		   '1' branch is now is now irrelevant we reveal the
+		   next branch with this: */
+		d &= ~r;
+		/* find last bit set, i.e. the most signif. bit set */
+		ms_discrep_bit = fls64(d) - 1;
+		dev_dbg(&ds1wm_data->pdev->dev,
+			"pass: %d new d:%0#18llx MS discrep bit:%d\n",
+			pass, d, ms_discrep_bit);
+
+		/* prev_ms_discrep_bit = ms_discrep_bit;
+		   prepare for next ROM search:		    */
+		if (ms_discrep_bit == -1)
+			break;
+
+		r = (r &  ~(~0ull << (ms_discrep_bit))) | 1 << ms_discrep_bit;
+	} /* end while true */
+	dev_dbg(&ds1wm_data->pdev->dev,
+		"pass: %d total: %d search done ms d bit pos: %d\n", pass,
+		slaves_found, ms_discrep_bit);
+}
+
+/* --------------------------------------------------------------------- */
+
+static struct w1_bus_master ds1wm_master = {
+	.read_byte  = ds1wm_read_byte,
+	.write_byte = ds1wm_write_byte,
+	.reset_bus  = ds1wm_reset_bus,
+	.search	    = ds1wm_search,
+};
+
+static int ds1wm_probe(struct platform_device *pdev)
+{
+	struct ds1wm_data *ds1wm_data;
+	struct ds1wm_driver_data *plat;
+	struct resource *res;
+	int ret;
+	u8 inten;
+
+	if (!pdev)
+		return -ENODEV;
+
+	ds1wm_data = devm_kzalloc(&pdev->dev, sizeof(*ds1wm_data), GFP_KERNEL);
+	if (!ds1wm_data)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ds1wm_data);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+	ds1wm_data->map = devm_ioremap(&pdev->dev, res->start,
+				       resource_size(res));
+	if (!ds1wm_data->map)
+		return -ENOMEM;
+
+	ds1wm_data->pdev = pdev;
+	ds1wm_data->cell = mfd_get_cell(pdev);
+	if (!ds1wm_data->cell)
+		return -ENODEV;
+	plat = dev_get_platdata(&pdev->dev);
+	if (!plat)
+		return -ENODEV;
+
+	/* how many bits to shift register number to get register offset */
+	if (plat->bus_shift > 2) {
+		dev_err(&ds1wm_data->pdev->dev,
+			"illegal bus shift %d, not written",
+			ds1wm_data->bus_shift);
+		return -EINVAL;
+	}
+
+	ds1wm_data->bus_shift = plat->bus_shift;
+	/* make sure resource has space for 8 registers */
+	if ((8 << ds1wm_data->bus_shift) > resource_size(res)) {
+		dev_err(&ds1wm_data->pdev->dev,
+			"memory resource size %d to small, should be %d\n",
+			(int)resource_size(res),
+			8 << ds1wm_data->bus_shift);
+		return -EINVAL;
+	}
+
+	ds1wm_data->is_hw_big_endian = plat->is_hw_big_endian;
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res)
+		return -ENXIO;
+	ds1wm_data->irq = res->start;
+	ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0);
+	ds1wm_data->reset_recover_delay = plat->reset_recover_delay;
+
+	/* Mask interrupts, set IAS before claiming interrupt */
+	inten = ds1wm_read_register(ds1wm_data, DS1WM_INT_EN);
+	ds1wm_write_register(ds1wm_data,
+		DS1WM_INT_EN, ds1wm_data->int_en_reg_none);
+
+	if (res->flags & IORESOURCE_IRQ_HIGHEDGE)
+		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING);
+	if (res->flags & IORESOURCE_IRQ_LOWEDGE)
+		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
+	if (res->flags & IORESOURCE_IRQ_HIGHLEVEL)
+		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_HIGH);
+	if (res->flags & IORESOURCE_IRQ_LOWLEVEL)
+		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_LOW);
+
+	ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr,
+			IRQF_SHARED, "ds1wm", ds1wm_data);
+	if (ret) {
+		dev_err(&ds1wm_data->pdev->dev,
+			"devm_request_irq %d failed with errno %d\n",
+			ds1wm_data->irq,
+			ret);
+
+		return ret;
+	}
+
+	ds1wm_up(ds1wm_data);
+
+	ds1wm_master.data = (void *)ds1wm_data;
+
+	ret = w1_add_master_device(&ds1wm_master);
+	if (ret)
+		goto err;
+
+	dev_dbg(&ds1wm_data->pdev->dev,
+		"ds1wm: probe successful, IAS: %d, rec.delay: %d, clockrate: %d, bus-shift: %d, is Hw Big Endian: %d\n",
+		plat->active_high,
+		plat->reset_recover_delay,
+		plat->clock_rate,
+		ds1wm_data->bus_shift,
+		ds1wm_data->is_hw_big_endian);
+	return 0;
+
+err:
+	ds1wm_down(ds1wm_data);
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int ds1wm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+	ds1wm_down(ds1wm_data);
+
+	return 0;
+}
+
+static int ds1wm_resume(struct platform_device *pdev)
+{
+	struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+	ds1wm_up(ds1wm_data);
+
+	return 0;
+}
+#else
+#define ds1wm_suspend NULL
+#define ds1wm_resume NULL
+#endif
+
+static int ds1wm_remove(struct platform_device *pdev)
+{
+	struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+	w1_remove_master_device(&ds1wm_master);
+	ds1wm_down(ds1wm_data);
+
+	return 0;
+}
+
+static struct platform_driver ds1wm_driver = {
+	.driver   = {
+		.name = "ds1wm",
+	},
+	.probe    = ds1wm_probe,
+	.remove   = ds1wm_remove,
+	.suspend  = ds1wm_suspend,
+	.resume   = ds1wm_resume
+};
+
+static int __init ds1wm_init(void)
+{
+	pr_info("DS1WM w1 busmaster driver - (c) 2004 Szabolcs Gyurko\n");
+	return platform_driver_register(&ds1wm_driver);
+}
+
+static void __exit ds1wm_exit(void)
+{
+	platform_driver_unregister(&ds1wm_driver);
+}
+
+module_init(ds1wm_init);
+module_exit(ds1wm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
+	"Matt Reimer <mreimer@vpop.net>,"
+	"Jean-Francois Dagenais <dagenaisj@sonatest.com>");
+MODULE_DESCRIPTION("DS1WM w1 busmaster driver");
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
new file mode 100644
index 0000000..8b5e598
--- /dev/null
+++ b/drivers/w1/masters/ds2482.c
@@ -0,0 +1,565 @@
+/**
+ * ds2482.c - provides i2c to w1-master bridge(s)
+ * Copyright (C) 2005  Ben Gardner <bgardner@wabtec.com>
+ *
+ * The DS2482 is a sensor chip made by Dallas Semiconductor (Maxim).
+ * 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
+ *
+ * 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; version 2 of the License.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <asm/delay.h>
+
+#include <linux/w1.h>
+
+/**
+ * Allow the active pullup to be disabled, default is enabled.
+ *
+ * Note from the DS2482 datasheet:
+ * The APU bit controls whether an active pullup (controlled slew-rate
+ * transistor) or a passive pullup (Rwpu resistor) will be used to drive
+ * a 1-Wire line from low to high. When APU = 0, active pullup is disabled
+ * (resistor mode). Active Pullup should always be selected unless there is
+ * only a single slave on the 1-Wire line.
+ */
+static int ds2482_active_pullup = 1;
+module_param_named(active_pullup, ds2482_active_pullup, int, 0644);
+MODULE_PARM_DESC(active_pullup, "Active pullup (apply to all buses): " \
+				"0-disable, 1-enable (default)");
+
+/**
+ * The DS2482 registers - there are 3 registers that are addressed by a read
+ * pointer. The read pointer is set by the last command executed.
+ *
+ * To read the data, issue a register read for any address
+ */
+#define DS2482_CMD_RESET		0xF0	/* No param */
+#define DS2482_CMD_SET_READ_PTR		0xE1	/* Param: DS2482_PTR_CODE_xxx */
+#define DS2482_CMD_CHANNEL_SELECT	0xC3	/* Param: Channel byte - DS2482-800 only */
+#define DS2482_CMD_WRITE_CONFIG		0xD2	/* Param: Config byte */
+#define DS2482_CMD_1WIRE_RESET		0xB4	/* Param: None */
+#define DS2482_CMD_1WIRE_SINGLE_BIT	0x87	/* Param: Bit byte (bit7) */
+#define DS2482_CMD_1WIRE_WRITE_BYTE	0xA5	/* Param: Data byte */
+#define DS2482_CMD_1WIRE_READ_BYTE	0x96	/* Param: None */
+/* Note to read the byte, Set the ReadPtr to Data then read (any addr) */
+#define DS2482_CMD_1WIRE_TRIPLET	0x78	/* Param: Dir byte (bit7) */
+
+/* Values for DS2482_CMD_SET_READ_PTR */
+#define DS2482_PTR_CODE_STATUS		0xF0
+#define DS2482_PTR_CODE_DATA		0xE1
+#define DS2482_PTR_CODE_CHANNEL		0xD2	/* DS2482-800 only */
+#define DS2482_PTR_CODE_CONFIG		0xC3
+
+/**
+ * Configure Register bit definitions
+ * The top 4 bits always read 0.
+ * To write, the top nibble must be the 1's compl. of the low nibble.
+ */
+#define DS2482_REG_CFG_1WS		0x08	/* 1-wire speed */
+#define DS2482_REG_CFG_SPU		0x04	/* strong pull-up */
+#define DS2482_REG_CFG_PPM		0x02	/* presence pulse masking */
+#define DS2482_REG_CFG_APU		0x01	/* active pull-up */
+
+/* extra configurations - e.g. 1WS */
+static int extra_config;
+
+/**
+ * Write and verify codes for the CHANNEL_SELECT command (DS2482-800 only).
+ * To set the channel, write the value at the index of the channel.
+ * Read and compare against the corresponding value to verify the change.
+ */
+static const u8 ds2482_chan_wr[8] =
+	{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 };
+static const u8 ds2482_chan_rd[8] =
+	{ 0xB8, 0xB1, 0xAA, 0xA3, 0x9C, 0x95, 0x8E, 0x87 };
+
+
+/**
+ * Status Register bit definitions (read only)
+ */
+#define DS2482_REG_STS_DIR		0x80
+#define DS2482_REG_STS_TSB		0x40
+#define DS2482_REG_STS_SBR		0x20
+#define DS2482_REG_STS_RST		0x10
+#define DS2482_REG_STS_LL		0x08
+#define DS2482_REG_STS_SD		0x04
+#define DS2482_REG_STS_PPD		0x02
+#define DS2482_REG_STS_1WB		0x01
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct ds2482_data;
+
+struct ds2482_w1_chan {
+	struct ds2482_data	*pdev;
+	u8			channel;
+	struct w1_bus_master	w1_bm;
+};
+
+struct ds2482_data {
+	struct i2c_client	*client;
+	struct mutex		access_lock;
+
+	/* 1-wire interface(s) */
+	int			w1_count;	/* 1 or 8 */
+	struct ds2482_w1_chan	w1_ch[8];
+
+	/* per-device values */
+	u8			channel;
+	u8			read_prt;	/* see DS2482_PTR_CODE_xxx */
+	u8			reg_config;
+};
+
+
+/**
+ * Helper to calculate values for configuration register
+ * @param conf the raw config value
+ * @return the value w/ complements that can be written to register
+ */
+static inline u8 ds2482_calculate_config(u8 conf)
+{
+	if (ds2482_active_pullup)
+		conf |= DS2482_REG_CFG_APU;
+
+	return conf | ((~conf & 0x0f) << 4);
+}
+
+
+/**
+ * Sets the read pointer.
+ * @param pdev		The ds2482 client pointer
+ * @param read_ptr	see DS2482_PTR_CODE_xxx above
+ * @return -1 on failure, 0 on success
+ */
+static inline int ds2482_select_register(struct ds2482_data *pdev, u8 read_ptr)
+{
+	if (pdev->read_prt != read_ptr) {
+		if (i2c_smbus_write_byte_data(pdev->client,
+					      DS2482_CMD_SET_READ_PTR,
+					      read_ptr) < 0)
+			return -1;
+
+		pdev->read_prt = read_ptr;
+	}
+	return 0;
+}
+
+/**
+ * Sends a command without a parameter
+ * @param pdev	The ds2482 client pointer
+ * @param cmd	DS2482_CMD_RESET,
+ *		DS2482_CMD_1WIRE_RESET,
+ *		DS2482_CMD_1WIRE_READ_BYTE
+ * @return -1 on failure, 0 on success
+ */
+static inline int ds2482_send_cmd(struct ds2482_data *pdev, u8 cmd)
+{
+	if (i2c_smbus_write_byte(pdev->client, cmd) < 0)
+		return -1;
+
+	pdev->read_prt = DS2482_PTR_CODE_STATUS;
+	return 0;
+}
+
+/**
+ * Sends a command with a parameter
+ * @param pdev	The ds2482 client pointer
+ * @param cmd	DS2482_CMD_WRITE_CONFIG,
+ *		DS2482_CMD_1WIRE_SINGLE_BIT,
+ *		DS2482_CMD_1WIRE_WRITE_BYTE,
+ *		DS2482_CMD_1WIRE_TRIPLET
+ * @param byte	The data to send
+ * @return -1 on failure, 0 on success
+ */
+static inline int ds2482_send_cmd_data(struct ds2482_data *pdev,
+				       u8 cmd, u8 byte)
+{
+	if (i2c_smbus_write_byte_data(pdev->client, cmd, byte) < 0)
+		return -1;
+
+	/* all cmds leave in STATUS, except CONFIG */
+	pdev->read_prt = (cmd != DS2482_CMD_WRITE_CONFIG) ?
+			 DS2482_PTR_CODE_STATUS : DS2482_PTR_CODE_CONFIG;
+	return 0;
+}
+
+
+/*
+ * 1-Wire interface code
+ */
+
+#define DS2482_WAIT_IDLE_TIMEOUT	100
+
+/**
+ * Waits until the 1-wire interface is idle (not busy)
+ *
+ * @param pdev Pointer to the device structure
+ * @return the last value read from status or -1 (failure)
+ */
+static int ds2482_wait_1wire_idle(struct ds2482_data *pdev)
+{
+	int temp = -1;
+	int retries = 0;
+
+	if (!ds2482_select_register(pdev, DS2482_PTR_CODE_STATUS)) {
+		do {
+			temp = i2c_smbus_read_byte(pdev->client);
+		} while ((temp >= 0) && (temp & DS2482_REG_STS_1WB) &&
+			 (++retries < DS2482_WAIT_IDLE_TIMEOUT));
+	}
+
+	if (retries >= DS2482_WAIT_IDLE_TIMEOUT)
+		pr_err("%s: timeout on channel %d\n",
+		       __func__, pdev->channel);
+
+	return temp;
+}
+
+/**
+ * Selects a w1 channel.
+ * The 1-wire interface must be idle before calling this function.
+ *
+ * @param pdev		The ds2482 client pointer
+ * @param channel	0-7
+ * @return		-1 (failure) or 0 (success)
+ */
+static int ds2482_set_channel(struct ds2482_data *pdev, u8 channel)
+{
+	if (i2c_smbus_write_byte_data(pdev->client, DS2482_CMD_CHANNEL_SELECT,
+				      ds2482_chan_wr[channel]) < 0)
+		return -1;
+
+	pdev->read_prt = DS2482_PTR_CODE_CHANNEL;
+	pdev->channel = -1;
+	if (i2c_smbus_read_byte(pdev->client) == ds2482_chan_rd[channel]) {
+		pdev->channel = channel;
+		return 0;
+	}
+	return -1;
+}
+
+
+/**
+ * Performs the touch-bit function, which writes a 0 or 1 and reads the level.
+ *
+ * @param data	The ds2482 channel pointer
+ * @param bit	The level to write: 0 or non-zero
+ * @return	The level read: 0 or 1
+ */
+static u8 ds2482_w1_touch_bit(void *data, u8 bit)
+{
+	struct ds2482_w1_chan *pchan = data;
+	struct ds2482_data    *pdev = pchan->pdev;
+	int status = -1;
+
+	mutex_lock(&pdev->access_lock);
+
+	/* Select the channel */
+	ds2482_wait_1wire_idle(pdev);
+	if (pdev->w1_count > 1)
+		ds2482_set_channel(pdev, pchan->channel);
+
+	/* Send the touch command, wait until 1WB == 0, return the status */
+	if (!ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_SINGLE_BIT,
+				  bit ? 0xFF : 0))
+		status = ds2482_wait_1wire_idle(pdev);
+
+	mutex_unlock(&pdev->access_lock);
+
+	return (status & DS2482_REG_STS_SBR) ? 1 : 0;
+}
+
+/**
+ * Performs the triplet function, which reads two bits and writes a bit.
+ * The bit written is determined by the two reads:
+ *   00 => dbit, 01 => 0, 10 => 1
+ *
+ * @param data	The ds2482 channel pointer
+ * @param dbit	The direction to choose if both branches are valid
+ * @return	b0=read1 b1=read2 b3=bit written
+ */
+static u8 ds2482_w1_triplet(void *data, u8 dbit)
+{
+	struct ds2482_w1_chan *pchan = data;
+	struct ds2482_data    *pdev = pchan->pdev;
+	int status = (3 << 5);
+
+	mutex_lock(&pdev->access_lock);
+
+	/* Select the channel */
+	ds2482_wait_1wire_idle(pdev);
+	if (pdev->w1_count > 1)
+		ds2482_set_channel(pdev, pchan->channel);
+
+	/* Send the triplet command, wait until 1WB == 0, return the status */
+	if (!ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_TRIPLET,
+				  dbit ? 0xFF : 0))
+		status = ds2482_wait_1wire_idle(pdev);
+
+	mutex_unlock(&pdev->access_lock);
+
+	/* Decode the status */
+	return (status >> 5);
+}
+
+/**
+ * Performs the write byte function.
+ *
+ * @param data	The ds2482 channel pointer
+ * @param byte	The value to write
+ */
+static void ds2482_w1_write_byte(void *data, u8 byte)
+{
+	struct ds2482_w1_chan *pchan = data;
+	struct ds2482_data    *pdev = pchan->pdev;
+
+	mutex_lock(&pdev->access_lock);
+
+	/* Select the channel */
+	ds2482_wait_1wire_idle(pdev);
+	if (pdev->w1_count > 1)
+		ds2482_set_channel(pdev, pchan->channel);
+
+	/* Send the write byte command */
+	ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_WRITE_BYTE, byte);
+
+	mutex_unlock(&pdev->access_lock);
+}
+
+/**
+ * Performs the read byte function.
+ *
+ * @param data	The ds2482 channel pointer
+ * @return	The value read
+ */
+static u8 ds2482_w1_read_byte(void *data)
+{
+	struct ds2482_w1_chan *pchan = data;
+	struct ds2482_data    *pdev = pchan->pdev;
+	int result;
+
+	mutex_lock(&pdev->access_lock);
+
+	/* Select the channel */
+	ds2482_wait_1wire_idle(pdev);
+	if (pdev->w1_count > 1)
+		ds2482_set_channel(pdev, pchan->channel);
+
+	/* Send the read byte command */
+	ds2482_send_cmd(pdev, DS2482_CMD_1WIRE_READ_BYTE);
+
+	/* Wait until 1WB == 0 */
+	ds2482_wait_1wire_idle(pdev);
+
+	/* Select the data register */
+	ds2482_select_register(pdev, DS2482_PTR_CODE_DATA);
+
+	/* Read the data byte */
+	result = i2c_smbus_read_byte(pdev->client);
+
+	mutex_unlock(&pdev->access_lock);
+
+	return result;
+}
+
+
+/**
+ * Sends a reset on the 1-wire interface
+ *
+ * @param data	The ds2482 channel pointer
+ * @return	0=Device present, 1=No device present or error
+ */
+static u8 ds2482_w1_reset_bus(void *data)
+{
+	struct ds2482_w1_chan *pchan = data;
+	struct ds2482_data    *pdev = pchan->pdev;
+	int err;
+	u8 retval = 1;
+
+	mutex_lock(&pdev->access_lock);
+
+	/* Select the channel */
+	ds2482_wait_1wire_idle(pdev);
+	if (pdev->w1_count > 1)
+		ds2482_set_channel(pdev, pchan->channel);
+
+	/* Send the reset command */
+	err = ds2482_send_cmd(pdev, DS2482_CMD_1WIRE_RESET);
+	if (err >= 0) {
+		/* Wait until the reset is complete */
+		err = ds2482_wait_1wire_idle(pdev);
+		retval = !(err & DS2482_REG_STS_PPD);
+
+		/* If the chip did reset since detect, re-config it */
+		if (err & DS2482_REG_STS_RST)
+			ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
+					ds2482_calculate_config(extra_config));
+	}
+
+	mutex_unlock(&pdev->access_lock);
+
+	return retval;
+}
+
+static u8 ds2482_w1_set_pullup(void *data, int delay)
+{
+	struct ds2482_w1_chan *pchan = data;
+	struct ds2482_data    *pdev = pchan->pdev;
+	u8 retval = 1;
+
+	/* if delay is non-zero activate the pullup,
+	 * the strong pullup will be automatically deactivated
+	 * by the master, so do not explicitly deactive it
+	 */
+	if (delay) {
+		/* both waits are crucial, otherwise devices might not be
+		 * powered long enough, causing e.g. a w1_therm sensor to
+		 * provide wrong conversion results
+		 */
+		ds2482_wait_1wire_idle(pdev);
+		/* note: it seems like both SPU and APU have to be set! */
+		retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
+			ds2482_calculate_config(extra_config|DS2482_REG_CFG_SPU|DS2482_REG_CFG_APU));
+		ds2482_wait_1wire_idle(pdev);
+	}
+
+	return retval;
+}
+
+
+static int ds2482_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct ds2482_data *data;
+	int err = -ENODEV;
+	int temp1;
+	int idx;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+				     I2C_FUNC_SMBUS_BYTE))
+		return -ENODEV;
+
+	if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	data->client = client;
+	i2c_set_clientdata(client, data);
+
+	/* 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;
+	}
+
+	/* Sleep at least 525ns to allow the reset to complete */
+	ndelay(525);
+
+	/* Read the status byte - only reset bit and line should be set */
+	temp1 = i2c_smbus_read_byte(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;
+	}
+
+	/* Detect the 8-port version */
+	data->w1_count = 1;
+	if (ds2482_set_channel(data, 7) == 0)
+		data->w1_count = 8;
+
+	/* Set all config items to 0 (off) */
+	ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG,
+		ds2482_calculate_config(extra_config));
+
+	mutex_init(&data->access_lock);
+
+	/* Register 1-wire interface(s) */
+	for (idx = 0; idx < data->w1_count; idx++) {
+		data->w1_ch[idx].pdev = data;
+		data->w1_ch[idx].channel = idx;
+
+		/* Populate all the w1 bus master stuff */
+		data->w1_ch[idx].w1_bm.data       = &data->w1_ch[idx];
+		data->w1_ch[idx].w1_bm.read_byte  = ds2482_w1_read_byte;
+		data->w1_ch[idx].w1_bm.write_byte = ds2482_w1_write_byte;
+		data->w1_ch[idx].w1_bm.touch_bit  = ds2482_w1_touch_bit;
+		data->w1_ch[idx].w1_bm.triplet    = ds2482_w1_triplet;
+		data->w1_ch[idx].w1_bm.reset_bus  = ds2482_w1_reset_bus;
+		data->w1_ch[idx].w1_bm.set_pullup = ds2482_w1_set_pullup;
+
+		err = w1_add_master_device(&data->w1_ch[idx].w1_bm);
+		if (err) {
+			data->w1_ch[idx].pdev = NULL;
+			goto exit_w1_remove;
+		}
+	}
+
+	return 0;
+
+exit_w1_remove:
+	for (idx = 0; idx < data->w1_count; idx++) {
+		if (data->w1_ch[idx].pdev != NULL)
+			w1_remove_master_device(&data->w1_ch[idx].w1_bm);
+	}
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int ds2482_remove(struct i2c_client *client)
+{
+	struct ds2482_data   *data = i2c_get_clientdata(client);
+	int idx;
+
+	/* Unregister the 1-wire bridge(s) */
+	for (idx = 0; idx < data->w1_count; idx++) {
+		if (data->w1_ch[idx].pdev != NULL)
+			w1_remove_master_device(&data->w1_ch[idx].w1_bm);
+	}
+
+	/* Free the memory */
+	kfree(data);
+	return 0;
+}
+
+/**
+ * Driver data (common to all clients)
+ */
+static const struct i2c_device_id ds2482_id[] = {
+	{ "ds2482", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ds2482_id);
+
+static struct i2c_driver ds2482_driver = {
+	.driver = {
+		.name	= "ds2482",
+	},
+	.probe		= ds2482_probe,
+	.remove		= ds2482_remove,
+	.id_table	= ds2482_id,
+};
+module_i2c_driver(ds2482_driver);
+
+MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
+MODULE_DESCRIPTION("DS2482 driver");
+module_param(extra_config, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(extra_config, "Extra Configuration settings 1=APU,2=PPM,3=SPU,8=1WS");
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
new file mode 100644
index 0000000..0f4ecfc
--- /dev/null
+++ b/drivers/w1/masters/ds2490.c
@@ -0,0 +1,1105 @@
+/*
+ *	ds2490.c  USB to one wire bridge
+ *
+ * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>
+ *
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+
+#include <linux/w1.h>
+
+/* USB Standard */
+/* USB Control request vendor type */
+#define VENDOR				0x40
+
+/* COMMAND TYPE CODES */
+#define CONTROL_CMD			0x00
+#define COMM_CMD			0x01
+#define MODE_CMD			0x02
+
+/* CONTROL COMMAND CODES */
+#define CTL_RESET_DEVICE		0x0000
+#define CTL_START_EXE			0x0001
+#define CTL_RESUME_EXE			0x0002
+#define CTL_HALT_EXE_IDLE		0x0003
+#define CTL_HALT_EXE_DONE		0x0004
+#define CTL_FLUSH_COMM_CMDS		0x0007
+#define CTL_FLUSH_RCV_BUFFER		0x0008
+#define CTL_FLUSH_XMT_BUFFER		0x0009
+#define CTL_GET_COMM_CMDS		0x000A
+
+/* MODE COMMAND CODES */
+#define MOD_PULSE_EN			0x0000
+#define MOD_SPEED_CHANGE_EN		0x0001
+#define MOD_1WIRE_SPEED			0x0002
+#define MOD_STRONG_PU_DURATION		0x0003
+#define MOD_PULLDOWN_SLEWRATE		0x0004
+#define MOD_PROG_PULSE_DURATION		0x0005
+#define MOD_WRITE1_LOWTIME		0x0006
+#define MOD_DSOW0_TREC			0x0007
+
+/* COMMUNICATION COMMAND CODES */
+#define COMM_ERROR_ESCAPE		0x0601
+#define COMM_SET_DURATION		0x0012
+#define COMM_BIT_IO			0x0020
+#define COMM_PULSE			0x0030
+#define COMM_1_WIRE_RESET		0x0042
+#define COMM_BYTE_IO			0x0052
+#define COMM_MATCH_ACCESS		0x0064
+#define COMM_BLOCK_IO			0x0074
+#define COMM_READ_STRAIGHT		0x0080
+#define COMM_DO_RELEASE			0x6092
+#define COMM_SET_PATH			0x00A2
+#define COMM_WRITE_SRAM_PAGE		0x00B2
+#define COMM_WRITE_EPROM		0x00C4
+#define COMM_READ_CRC_PROT_PAGE		0x00D4
+#define COMM_READ_REDIRECT_PAGE_CRC	0x21E4
+#define COMM_SEARCH_ACCESS		0x00F4
+
+/* Communication command bits */
+#define COMM_TYPE			0x0008
+#define COMM_SE				0x0008
+#define COMM_D				0x0008
+#define COMM_Z				0x0008
+#define COMM_CH				0x0008
+#define COMM_SM				0x0008
+#define COMM_R				0x0008
+#define COMM_IM				0x0001
+
+#define COMM_PS				0x4000
+#define COMM_PST			0x4000
+#define COMM_CIB			0x4000
+#define COMM_RTS			0x4000
+#define COMM_DT				0x2000
+#define COMM_SPU			0x1000
+#define COMM_F				0x0800
+#define COMM_NTF			0x0400
+#define COMM_ICP			0x0200
+#define COMM_RST			0x0100
+
+#define PULSE_PROG			0x01
+#define PULSE_SPUE			0x02
+
+#define BRANCH_MAIN			0xCC
+#define BRANCH_AUX			0x33
+
+/* Status flags */
+#define ST_SPUA				0x01  /* Strong Pull-up is active */
+#define ST_PRGA				0x02  /* 12V programming pulse is being generated */
+#define ST_12VP				0x04  /* external 12V programming voltage is present */
+#define ST_PMOD				0x08  /* DS2490 powered from USB and external sources */
+#define ST_HALT				0x10  /* DS2490 is currently halted */
+#define ST_IDLE				0x20  /* DS2490 is currently idle */
+#define ST_EPOF				0x80
+/* Status transfer size, 16 bytes status, 16 byte result flags */
+#define ST_SIZE				0x20
+
+/* Result Register flags */
+#define RR_DETECT			0xA5 /* New device detected */
+#define RR_NRS				0x01 /* Reset no presence or ... */
+#define RR_SH				0x02 /* short on reset or set path */
+#define RR_APP				0x04 /* alarming presence on reset */
+#define RR_VPP				0x08 /* 12V expected not seen */
+#define RR_CMP				0x10 /* compare error */
+#define RR_CRC				0x20 /* CRC error detected */
+#define RR_RDP				0x40 /* redirected page */
+#define RR_EOS				0x80 /* end of search error */
+
+#define SPEED_NORMAL			0x00
+#define SPEED_FLEXIBLE			0x01
+#define SPEED_OVERDRIVE			0x02
+
+#define NUM_EP				4
+#define EP_CONTROL			0
+#define EP_STATUS			1
+#define EP_DATA_OUT			2
+#define EP_DATA_IN			3
+
+struct ds_device {
+	struct list_head	ds_entry;
+
+	struct usb_device	*udev;
+	struct usb_interface	*intf;
+
+	int			ep[NUM_EP];
+
+	/* Strong PullUp
+	 * 0: pullup not active, else duration in milliseconds
+	 */
+	int			spu_sleep;
+	/* spu_bit contains COMM_SPU or 0 depending on if the strong pullup
+	 * should be active or not for writes.
+	 */
+	u16			spu_bit;
+
+	u8			st_buf[ST_SIZE];
+	u8			byte_buf;
+
+	struct w1_bus_master	master;
+};
+
+struct ds_status {
+	u8			enable;
+	u8			speed;
+	u8			pullup_dur;
+	u8			ppuls_dur;
+	u8			pulldown_slew;
+	u8			write1_time;
+	u8			write0_time;
+	u8			reserved0;
+	u8			status;
+	u8			command0;
+	u8			command1;
+	u8			command_buffer_status;
+	u8			data_out_buffer_status;
+	u8			data_in_buffer_status;
+	u8			reserved1;
+	u8			reserved2;
+};
+
+static LIST_HEAD(ds_devices);
+static DEFINE_MUTEX(ds_mutex);
+
+static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
+{
+	int err;
+
+	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+			CONTROL_CMD, VENDOR, value, index, NULL, 0, 1000);
+	if (err < 0) {
+		pr_err("Failed to send command control message %x.%x: err=%d.\n",
+				value, index, err);
+		return err;
+	}
+
+	return err;
+}
+
+static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
+{
+	int err;
+
+	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+			MODE_CMD, VENDOR, value, index, NULL, 0, 1000);
+	if (err < 0) {
+		pr_err("Failed to send mode control message %x.%x: err=%d.\n",
+				value, index, err);
+		return err;
+	}
+
+	return err;
+}
+
+static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
+{
+	int err;
+
+	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+			COMM_CMD, VENDOR, value, index, NULL, 0, 1000);
+	if (err < 0) {
+		pr_err("Failed to send control message %x.%x: err=%d.\n",
+				value, index, err);
+		return err;
+	}
+
+	return err;
+}
+
+static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
+{
+	pr_info("%45s: %8x\n", str, buf[off]);
+}
+
+static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
+{
+	int i;
+
+	pr_info("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
+	for (i = 0; i < count; ++i)
+		pr_info("%02x ", buf[i]);
+	pr_info("\n");
+
+	if (count >= 16) {
+		ds_print_msg(buf, "enable flag", 0);
+		ds_print_msg(buf, "1-wire speed", 1);
+		ds_print_msg(buf, "strong pullup duration", 2);
+		ds_print_msg(buf, "programming pulse duration", 3);
+		ds_print_msg(buf, "pulldown slew rate control", 4);
+		ds_print_msg(buf, "write-1 low time", 5);
+		ds_print_msg(buf, "data sample offset/write-0 recovery time",
+			6);
+		ds_print_msg(buf, "reserved (test register)", 7);
+		ds_print_msg(buf, "device status flags", 8);
+		ds_print_msg(buf, "communication command byte 1", 9);
+		ds_print_msg(buf, "communication command byte 2", 10);
+		ds_print_msg(buf, "communication command buffer status", 11);
+		ds_print_msg(buf, "1-wire data output buffer status", 12);
+		ds_print_msg(buf, "1-wire data input buffer status", 13);
+		ds_print_msg(buf, "reserved", 14);
+		ds_print_msg(buf, "reserved", 15);
+	}
+	for (i = 16; i < count; ++i) {
+		if (buf[i] == RR_DETECT) {
+			ds_print_msg(buf, "new device detect", i);
+			continue;
+		}
+		ds_print_msg(buf, "Result Register Value: ", i);
+		if (buf[i] & RR_NRS)
+			pr_info("NRS: Reset no presence or ...\n");
+		if (buf[i] & RR_SH)
+			pr_info("SH: short on reset or set path\n");
+		if (buf[i] & RR_APP)
+			pr_info("APP: alarming presence on reset\n");
+		if (buf[i] & RR_VPP)
+			pr_info("VPP: 12V expected not seen\n");
+		if (buf[i] & RR_CMP)
+			pr_info("CMP: compare error\n");
+		if (buf[i] & RR_CRC)
+			pr_info("CRC: CRC error detected\n");
+		if (buf[i] & RR_RDP)
+			pr_info("RDP: redirected page\n");
+		if (buf[i] & RR_EOS)
+			pr_info("EOS: end of search error\n");
+	}
+}
+
+static int ds_recv_status(struct ds_device *dev, struct ds_status *st,
+			  bool dump)
+{
+	int count, err;
+
+	if (st)
+		memset(st, 0, sizeof(*st));
+
+	count = 0;
+	err = usb_interrupt_msg(dev->udev,
+				usb_rcvintpipe(dev->udev,
+					       dev->ep[EP_STATUS]),
+				dev->st_buf, sizeof(dev->st_buf),
+				&count, 1000);
+	if (err < 0) {
+		pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n",
+		       dev->ep[EP_STATUS], err);
+		return err;
+	}
+
+	if (dump)
+		ds_dump_status(dev, dev->st_buf, count);
+
+	if (st && count >= sizeof(*st))
+		memcpy(st, dev->st_buf, sizeof(*st));
+
+	return count;
+}
+
+static void ds_reset_device(struct ds_device *dev)
+{
+	ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
+	/* Always allow strong pullup which allow individual writes to use
+	 * the strong pullup.
+	 */
+	if (ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE))
+		pr_err("ds_reset_device: Error allowing strong pullup\n");
+	/* Chip strong pullup time was cleared. */
+	if (dev->spu_sleep) {
+		/* lower 4 bits are 0, see ds_set_pullup */
+		u8 del = dev->spu_sleep>>4;
+		if (ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del))
+			pr_err("ds_reset_device: Error setting duration\n");
+	}
+}
+
+static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
+{
+	int count, err;
+
+	/* Careful on size.  If size is less than what is available in
+	 * the input buffer, the device fails the bulk transfer and
+	 * clears the input buffer.  It could read the maximum size of
+	 * the data buffer, but then do you return the first, last, or
+	 * some set of the middle size bytes?  As long as the rest of
+	 * the code is correct there will be size bytes waiting.  A
+	 * call to ds_wait_status will wait until the device is idle
+	 * and any data to be received would have been available.
+	 */
+	count = 0;
+	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
+				buf, size, &count, 1000);
+	if (err < 0) {
+		pr_info("Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
+		usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
+		ds_recv_status(dev, NULL, true);
+		return err;
+	}
+
+#if 0
+	{
+		int i;
+
+		printk("%s: count=%d: ", __func__, count);
+		for (i = 0; i < count; ++i)
+			printk("%02x ", buf[i]);
+		printk("\n");
+	}
+#endif
+	return count;
+}
+
+static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
+{
+	int count, err;
+
+	count = 0;
+	err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
+	if (err < 0) {
+		pr_err("Failed to write 1-wire data to ep0x%x: "
+			"err=%d.\n", dev->ep[EP_DATA_OUT], err);
+		return err;
+	}
+
+	return err;
+}
+
+#if 0
+
+int ds_stop_pulse(struct ds_device *dev, int limit)
+{
+	struct ds_status st;
+	int count = 0, err = 0;
+
+	do {
+		err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
+		if (err)
+			break;
+		err = ds_send_control(dev, CTL_RESUME_EXE, 0);
+		if (err)
+			break;
+		err = ds_recv_status(dev, &st, false);
+		if (err)
+			break;
+
+		if ((st.status & ST_SPUA) == 0) {
+			err = ds_send_control_mode(dev, MOD_PULSE_EN, 0);
+			if (err)
+				break;
+		}
+	} while (++count < limit);
+
+	return err;
+}
+
+int ds_detect(struct ds_device *dev, struct ds_status *st)
+{
+	int err;
+
+	err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
+	if (err)
+		return err;
+
+	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0);
+	if (err)
+		return err;
+
+	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40);
+	if (err)
+		return err;
+
+	err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG);
+	if (err)
+		return err;
+
+	err = ds_dump_status(dev, st);
+
+	return err;
+}
+
+#endif  /*  0  */
+
+static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
+{
+	int err, count = 0;
+
+	do {
+		st->status = 0;
+		err = ds_recv_status(dev, st, false);
+#if 0
+		if (err >= 0) {
+			int i;
+			printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
+			for (i = 0; i < err; ++i)
+				printk("%02x ", dev->st_buf[i]);
+			printk("\n");
+		}
+#endif
+	} while (!(st->status & ST_IDLE) && !(err < 0) && ++count < 100);
+
+	if (err >= 16 && st->status & ST_EPOF) {
+		pr_info("Resetting device after ST_EPOF.\n");
+		ds_reset_device(dev);
+		/* Always dump the device status. */
+		count = 101;
+	}
+
+	/* Dump the status for errors or if there is extended return data.
+	 * The extended status includes new device detection (maybe someone
+	 * can do something with it).
+	 */
+	if (err > 16 || count >= 100 || err < 0)
+		ds_dump_status(dev, dev->st_buf, err);
+
+	/* Extended data isn't an error.  Well, a short is, but the dump
+	 * would have already told the user that and we can't do anything
+	 * about it in software anyway.
+	 */
+	if (count >= 100 || err < 0)
+		return -1;
+	else
+		return 0;
+}
+
+static int ds_reset(struct ds_device *dev)
+{
+	int err;
+
+	/* Other potentionally interesting flags for reset.
+	 *
+	 * COMM_NTF: Return result register feedback.  This could be used to
+	 * detect some conditions such as short, alarming presence, or
+	 * detect if a new device was detected.
+	 *
+	 * COMM_SE which allows SPEED_NORMAL, SPEED_FLEXIBLE, SPEED_OVERDRIVE:
+	 * Select the data transfer rate.
+	 */
+	err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_IM, SPEED_NORMAL);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+#if 0
+static int ds_set_speed(struct ds_device *dev, int speed)
+{
+	int err;
+
+	if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE)
+		return -EINVAL;
+
+	if (speed != SPEED_OVERDRIVE)
+		speed = SPEED_FLEXIBLE;
+
+	speed &= 0xff;
+
+	err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed);
+	if (err)
+		return err;
+
+	return err;
+}
+#endif  /*  0  */
+
+static int ds_set_pullup(struct ds_device *dev, int delay)
+{
+	int err = 0;
+	u8 del = 1 + (u8)(delay >> 4);
+	/* Just storing delay would not get the trunication and roundup. */
+	int ms = del<<4;
+
+	/* Enable spu_bit if a delay is set. */
+	dev->spu_bit = delay ? COMM_SPU : 0;
+	/* If delay is zero, it has already been disabled, if the time is
+	 * the same as the hardware was last programmed to, there is also
+	 * nothing more to do.  Compare with the recalculated value ms
+	 * rather than del or delay which can have a different value.
+	 */
+	if (delay == 0 || ms == dev->spu_sleep)
+		return err;
+
+	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del);
+	if (err)
+		return err;
+
+	dev->spu_sleep = ms;
+
+	return err;
+}
+
+static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit ? COMM_D : 0),
+		0);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_recv_data(dev, tbit, sizeof(*tbit));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+#if 0
+static int ds_write_bit(struct ds_device *dev, u8 bit)
+{
+	int err;
+	struct ds_status st;
+
+	/* Set COMM_ICP to write without a readback.  Note, this will
+	 * produce one time slot, a down followed by an up with COMM_D
+	 * only determing the timing.
+	 */
+	err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_ICP |
+		(bit ? COMM_D : 0), 0);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	return 0;
+}
+#endif
+
+static int ds_write_byte(struct ds_device *dev, u8 byte)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte);
+	if (err)
+		return err;
+
+	if (dev->spu_bit)
+		msleep(dev->spu_sleep);
+
+	err = ds_wait_status(dev, &st);
+	if (err)
+		return err;
+
+	err = ds_recv_data(dev, &dev->byte_buf, 1);
+	if (err < 0)
+		return err;
+
+	return !(byte == dev->byte_buf);
+}
+
+static int ds_read_byte(struct ds_device *dev, u8 *byte)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM, 0xff);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_recv_data(dev, byte, sizeof(*byte));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int ds_read_block(struct ds_device *dev, u8 *buf, int len)
+{
+	struct ds_status st;
+	int err;
+
+	if (len > 64*1024)
+		return -E2BIG;
+
+	memset(buf, 0xFF, len);
+
+	err = ds_send_data(dev, buf, len);
+	if (err < 0)
+		return err;
+
+	err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM, len);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	memset(buf, 0x00, len);
+	err = ds_recv_data(dev, buf, len);
+
+	return err;
+}
+
+static int ds_write_block(struct ds_device *dev, u8 *buf, int len)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_data(dev, buf, len);
+	if (err < 0)
+		return err;
+
+	err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | dev->spu_bit, len);
+	if (err)
+		return err;
+
+	if (dev->spu_bit)
+		msleep(dev->spu_sleep);
+
+	ds_wait_status(dev, &st);
+
+	err = ds_recv_data(dev, buf, len);
+	if (err < 0)
+		return err;
+
+	return !(err == len);
+}
+
+static void ds9490r_search(void *data, struct w1_master *master,
+	u8 search_type, w1_slave_found_callback callback)
+{
+	/* When starting with an existing id, the first id returned will
+	 * be that device (if it is still on the bus most likely).
+	 *
+	 * If the number of devices found is less than or equal to the
+	 * search_limit, that number of IDs will be returned.  If there are
+	 * more, search_limit IDs will be returned followed by a non-zero
+	 * discrepency value.
+	 */
+	struct ds_device *dev = data;
+	int err;
+	u16 value, index;
+	struct ds_status st;
+	int search_limit;
+	int found = 0;
+	int i;
+
+	/* DS18b20 spec, 13.16 ms per device, 75 per second, sleep for
+	 * discovering 8 devices (1 bulk transfer and 1/2 FIFO size) at a time.
+	 */
+	const unsigned long jtime = msecs_to_jiffies(1000*8/75);
+	/* FIFO 128 bytes, bulk packet size 64, read a multiple of the
+	 * packet size.
+	 */
+	const size_t bufsize = 2 * 64;
+	u64 *buf;
+
+	buf = kmalloc(bufsize, GFP_KERNEL);
+	if (!buf)
+		return;
+
+	mutex_lock(&master->bus_mutex);
+
+	/* address to start searching at */
+	if (ds_send_data(dev, (u8 *)&master->search_id, 8) < 0)
+		goto search_out;
+	master->search_id = 0;
+
+	value = COMM_SEARCH_ACCESS | COMM_IM | COMM_RST | COMM_SM | COMM_F |
+		COMM_RTS;
+	search_limit = master->max_slave_count;
+	if (search_limit > 255)
+		search_limit = 0;
+	index = search_type | (search_limit << 8);
+	if (ds_send_control(dev, value, index) < 0)
+		goto search_out;
+
+	do {
+		schedule_timeout(jtime);
+
+		err = ds_recv_status(dev, &st, false);
+		if (err < 0 || err < sizeof(st))
+			break;
+
+		if (st.data_in_buffer_status) {
+			/* Bulk in can receive partial ids, but when it does
+			 * they fail crc and will be discarded anyway.
+			 * That has only been seen when status in buffer
+			 * is 0 and bulk is read anyway, so don't read
+			 * bulk without first checking if status says there
+			 * is data to read.
+			 */
+			err = ds_recv_data(dev, (u8 *)buf, bufsize);
+			if (err < 0)
+				break;
+			for (i = 0; i < err/8; ++i) {
+				++found;
+				if (found <= search_limit)
+					callback(master, buf[i]);
+				/* can't know if there will be a discrepancy
+				 * value after until the next id */
+				if (found == search_limit)
+					master->search_id = buf[i];
+			}
+		}
+
+		if (test_bit(W1_ABORT_SEARCH, &master->flags))
+			break;
+	} while (!(st.status & (ST_IDLE | ST_HALT)));
+
+	/* only continue the search if some weren't found */
+	if (found <= search_limit) {
+		master->search_id = 0;
+	} else if (!test_bit(W1_WARN_MAX_COUNT, &master->flags)) {
+		/* Only max_slave_count will be scanned in a search,
+		 * but it will start where it left off next search
+		 * until all ids are identified and then it will start
+		 * over.  A continued search will report the previous
+		 * last id as the first id (provided it is still on the
+		 * bus).
+		 */
+		dev_info(&dev->udev->dev, "%s: max_slave_count %d reached, "
+			"will continue next search.\n", __func__,
+			master->max_slave_count);
+		set_bit(W1_WARN_MAX_COUNT, &master->flags);
+	}
+search_out:
+	mutex_unlock(&master->bus_mutex);
+	kfree(buf);
+}
+
+#if 0
+/*
+ * FIXME: if this disabled code is ever used in the future all ds_send_data()
+ * calls must be changed to use a DMAable buffer.
+ */
+static int ds_match_access(struct ds_device *dev, u64 init)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_data(dev, (unsigned char *)&init, sizeof(init));
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	return 0;
+}
+
+static int ds_set_path(struct ds_device *dev, u64 init)
+{
+	int err;
+	struct ds_status st;
+	u8 buf[9];
+
+	memcpy(buf, &init, 8);
+	buf[8] = BRANCH_MAIN;
+
+	err = ds_send_data(dev, buf, sizeof(buf));
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	return 0;
+}
+
+#endif  /*  0  */
+
+static u8 ds9490r_touch_bit(void *data, u8 bit)
+{
+	struct ds_device *dev = data;
+
+	if (ds_touch_bit(dev, bit, &dev->byte_buf))
+		return 0;
+
+	return dev->byte_buf;
+}
+
+#if 0
+static void ds9490r_write_bit(void *data, u8 bit)
+{
+	struct ds_device *dev = data;
+
+	ds_write_bit(dev, bit);
+}
+
+static u8 ds9490r_read_bit(void *data)
+{
+	struct ds_device *dev = data;
+	int err;
+
+	err = ds_touch_bit(dev, 1, &dev->byte_buf);
+	if (err)
+		return 0;
+
+	return dev->byte_buf & 1;
+}
+#endif
+
+static void ds9490r_write_byte(void *data, u8 byte)
+{
+	struct ds_device *dev = data;
+
+	ds_write_byte(dev, byte);
+}
+
+static u8 ds9490r_read_byte(void *data)
+{
+	struct ds_device *dev = data;
+	int err;
+
+	err = ds_read_byte(dev, &dev->byte_buf);
+	if (err)
+		return 0;
+
+	return dev->byte_buf;
+}
+
+static void ds9490r_write_block(void *data, const u8 *buf, int len)
+{
+	struct ds_device *dev = data;
+	u8 *tbuf;
+
+	if (len <= 0)
+		return;
+
+	tbuf = kmemdup(buf, len, GFP_KERNEL);
+	if (!tbuf)
+		return;
+
+	ds_write_block(dev, tbuf, len);
+
+	kfree(tbuf);
+}
+
+static u8 ds9490r_read_block(void *data, u8 *buf, int len)
+{
+	struct ds_device *dev = data;
+	int err;
+	u8 *tbuf;
+
+	if (len <= 0)
+		return 0;
+
+	tbuf = kmalloc(len, GFP_KERNEL);
+	if (!tbuf)
+		return 0;
+
+	err = ds_read_block(dev, tbuf, len);
+	if (err >= 0)
+		memcpy(buf, tbuf, len);
+
+	kfree(tbuf);
+
+	return err >= 0 ? len : 0;
+}
+
+static u8 ds9490r_reset(void *data)
+{
+	struct ds_device *dev = data;
+	int err;
+
+	err = ds_reset(dev);
+	if (err)
+		return 1;
+
+	return 0;
+}
+
+static u8 ds9490r_set_pullup(void *data, int delay)
+{
+	struct ds_device *dev = data;
+
+	if (ds_set_pullup(dev, delay))
+		return 1;
+
+	return 0;
+}
+
+static int ds_w1_init(struct ds_device *dev)
+{
+	memset(&dev->master, 0, sizeof(struct w1_bus_master));
+
+	/* Reset the device as it can be in a bad state.
+	 * This is necessary because a block write will wait for data
+	 * to be placed in the output buffer and block any later
+	 * commands which will keep accumulating and the device will
+	 * not be idle.  Another case is removing the ds2490 module
+	 * while a bus search is in progress, somehow a few commands
+	 * get through, but the input transfers fail leaving data in
+	 * the input buffer.  This will cause the next read to fail
+	 * see the note in ds_recv_data.
+	 */
+	ds_reset_device(dev);
+
+	dev->master.data	= dev;
+	dev->master.touch_bit	= &ds9490r_touch_bit;
+	/* read_bit and write_bit in w1_bus_master are expected to set and
+	 * sample the line level.  For write_bit that means it is expected to
+	 * set it to that value and leave it there.  ds2490 only supports an
+	 * individual time slot at the lowest level.  The requirement from
+	 * pulling the bus state down to reading the state is 15us, something
+	 * that isn't realistic on the USB bus anyway.
+	dev->master.read_bit	= &ds9490r_read_bit;
+	dev->master.write_bit	= &ds9490r_write_bit;
+	*/
+	dev->master.read_byte	= &ds9490r_read_byte;
+	dev->master.write_byte	= &ds9490r_write_byte;
+	dev->master.read_block	= &ds9490r_read_block;
+	dev->master.write_block	= &ds9490r_write_block;
+	dev->master.reset_bus	= &ds9490r_reset;
+	dev->master.set_pullup	= &ds9490r_set_pullup;
+	dev->master.search	= &ds9490r_search;
+
+	return w1_add_master_device(&dev->master);
+}
+
+static void ds_w1_fini(struct ds_device *dev)
+{
+	w1_remove_master_device(&dev->master);
+}
+
+static int ds_probe(struct usb_interface *intf,
+		    const struct usb_device_id *udev_id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_host_interface *iface_desc;
+	struct ds_device *dev;
+	int i, err, alt;
+
+	dev = kzalloc(sizeof(struct ds_device), GFP_KERNEL);
+	if (!dev) {
+		pr_info("Failed to allocate new DS9490R structure.\n");
+		return -ENOMEM;
+	}
+	dev->udev = usb_get_dev(udev);
+	if (!dev->udev) {
+		err = -ENOMEM;
+		goto err_out_free;
+	}
+	memset(dev->ep, 0, sizeof(dev->ep));
+
+	usb_set_intfdata(intf, dev);
+
+	err = usb_reset_configuration(dev->udev);
+	if (err) {
+		dev_err(&dev->udev->dev,
+			"Failed to reset configuration: err=%d.\n", err);
+		goto err_out_clear;
+	}
+
+	/* alternative 3, 1ms interrupt (greatly speeds search), 64 byte bulk */
+	alt = 3;
+	err = usb_set_interface(dev->udev,
+		intf->altsetting[alt].desc.bInterfaceNumber, alt);
+	if (err) {
+		dev_err(&dev->udev->dev, "Failed to set alternative setting %d "
+			"for %d interface: err=%d.\n", alt,
+			intf->altsetting[alt].desc.bInterfaceNumber, err);
+		goto err_out_clear;
+	}
+
+	iface_desc = &intf->altsetting[alt];
+	if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
+		pr_info("Num endpoints=%d. It is not DS9490R.\n",
+			iface_desc->desc.bNumEndpoints);
+		err = -EINVAL;
+		goto err_out_clear;
+	}
+
+	/*
+	 * This loop doesn'd show control 0 endpoint,
+	 * so we will fill only 1-3 endpoints entry.
+	 */
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		dev->ep[i+1] = endpoint->bEndpointAddress;
+#if 0
+		printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
+			i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
+			(endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
+			endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+#endif
+	}
+
+	err = ds_w1_init(dev);
+	if (err)
+		goto err_out_clear;
+
+	mutex_lock(&ds_mutex);
+	list_add_tail(&dev->ds_entry, &ds_devices);
+	mutex_unlock(&ds_mutex);
+
+	return 0;
+
+err_out_clear:
+	usb_set_intfdata(intf, NULL);
+	usb_put_dev(dev->udev);
+err_out_free:
+	kfree(dev);
+	return err;
+}
+
+static void ds_disconnect(struct usb_interface *intf)
+{
+	struct ds_device *dev;
+
+	dev = usb_get_intfdata(intf);
+	if (!dev)
+		return;
+
+	mutex_lock(&ds_mutex);
+	list_del(&dev->ds_entry);
+	mutex_unlock(&ds_mutex);
+
+	ds_w1_fini(dev);
+
+	usb_set_intfdata(intf, NULL);
+
+	usb_put_dev(dev->udev);
+	kfree(dev);
+}
+
+static const struct usb_device_id ds_id_table[] = {
+	{ USB_DEVICE(0x04fa, 0x2490) },
+	{ },
+};
+MODULE_DEVICE_TABLE(usb, ds_id_table);
+
+static struct usb_driver ds_driver = {
+	.name =		"DS9490R",
+	.probe =	ds_probe,
+	.disconnect =	ds_disconnect,
+	.id_table =	ds_id_table,
+};
+module_usb_driver(ds_driver);
+
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c
new file mode 100644
index 0000000..d83d7c9
--- /dev/null
+++ b/drivers/w1/masters/matrox_w1.c
@@ -0,0 +1,222 @@
+/*
+ *	matrox_w1.c
+ *
+ * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>
+ *
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <asm/types.h>
+#include <linux/atomic.h>
+#include <asm/io.h>
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/pci_ids.h>
+#include <linux/pci.h>
+
+#include <linux/w1.h>
+
+/*
+ * Matrox G400 DDC registers.
+ */
+
+#define MATROX_G400_DDC_CLK		(1<<4)
+#define MATROX_G400_DDC_DATA		(1<<1)
+
+#define MATROX_BASE			0x3C00
+#define MATROX_STATUS			0x1e14
+
+#define MATROX_PORT_INDEX_OFFSET	0x00
+#define MATROX_PORT_DATA_OFFSET		0x0A
+
+#define MATROX_GET_CONTROL		0x2A
+#define MATROX_GET_DATA			0x2B
+#define MATROX_CURSOR_CTL		0x06
+
+struct matrox_device
+{
+	void __iomem *base_addr;
+	void __iomem *port_index;
+	void __iomem *port_data;
+	u8 data_mask;
+
+	unsigned long phys_addr;
+	void __iomem *virt_addr;
+	unsigned long found;
+
+	struct w1_bus_master *bus_master;
+};
+
+/*
+ * These functions read and write DDC Data bit.
+ *
+ * Using tristate pins, since i can't find any open-drain pin in whole motherboard.
+ * Unfortunately we can't connect to Intel's 82801xx IO controller
+ * since we don't know motherboard schema, which has pretty unused(may be not) GPIO.
+ *
+ * I've heard that PIIX also has open drain pin.
+ *
+ * Port mapping.
+ */
+static __inline__ u8 matrox_w1_read_reg(struct matrox_device *dev, u8 reg)
+{
+	u8 ret;
+
+	writeb(reg, dev->port_index);
+	ret = readb(dev->port_data);
+	barrier();
+
+	return ret;
+}
+
+static __inline__ void matrox_w1_write_reg(struct matrox_device *dev, u8 reg, u8 val)
+{
+	writeb(reg, dev->port_index);
+	writeb(val, dev->port_data);
+	wmb();
+}
+
+static void matrox_w1_write_ddc_bit(void *data, u8 bit)
+{
+	u8 ret;
+	struct matrox_device *dev = data;
+
+	if (bit)
+		bit = 0;
+	else
+		bit = dev->data_mask;
+
+	ret = matrox_w1_read_reg(dev, MATROX_GET_CONTROL);
+	matrox_w1_write_reg(dev, MATROX_GET_CONTROL, ((ret & ~dev->data_mask) | bit));
+	matrox_w1_write_reg(dev, MATROX_GET_DATA, 0x00);
+}
+
+static u8 matrox_w1_read_ddc_bit(void *data)
+{
+	u8 ret;
+	struct matrox_device *dev = data;
+
+	ret = matrox_w1_read_reg(dev, MATROX_GET_DATA);
+
+	return ret;
+}
+
+static void matrox_w1_hw_init(struct matrox_device *dev)
+{
+	matrox_w1_write_reg(dev, MATROX_GET_DATA, 0xFF);
+	matrox_w1_write_reg(dev, MATROX_GET_CONTROL, 0x00);
+}
+
+static int matrox_w1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct matrox_device *dev;
+	int err;
+
+	if (pdev->vendor != PCI_VENDOR_ID_MATROX || pdev->device != PCI_DEVICE_ID_MATROX_G400)
+		return -ENODEV;
+
+	dev = kzalloc(sizeof(struct matrox_device) +
+		       sizeof(struct w1_bus_master), GFP_KERNEL);
+	if (!dev) {
+		dev_err(&pdev->dev,
+			"%s: Failed to create new matrox_device object.\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+
+	dev->bus_master = (struct w1_bus_master *)(dev + 1);
+
+	/*
+	 * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c
+	 */
+
+	dev->phys_addr = pci_resource_start(pdev, 1);
+
+	dev->virt_addr = ioremap_nocache(dev->phys_addr, 16384);
+	if (!dev->virt_addr) {
+		dev_err(&pdev->dev, "%s: failed to ioremap(0x%lx, %d).\n",
+			__func__, dev->phys_addr, 16384);
+		err = -EIO;
+		goto err_out_free_device;
+	}
+
+	dev->base_addr = dev->virt_addr + MATROX_BASE;
+	dev->port_index = dev->base_addr + MATROX_PORT_INDEX_OFFSET;
+	dev->port_data = dev->base_addr + MATROX_PORT_DATA_OFFSET;
+	dev->data_mask = (MATROX_G400_DDC_DATA);
+
+	matrox_w1_hw_init(dev);
+
+	dev->bus_master->data = dev;
+	dev->bus_master->read_bit = &matrox_w1_read_ddc_bit;
+	dev->bus_master->write_bit = &matrox_w1_write_ddc_bit;
+
+	err = w1_add_master_device(dev->bus_master);
+	if (err)
+		goto err_out_free_device;
+
+	pci_set_drvdata(pdev, dev);
+
+	dev->found = 1;
+
+	dev_info(&pdev->dev, "Matrox G400 GPIO transport layer for 1-wire.\n");
+
+	return 0;
+
+err_out_free_device:
+	if (dev->virt_addr)
+		iounmap(dev->virt_addr);
+	kfree(dev);
+
+	return err;
+}
+
+static void matrox_w1_remove(struct pci_dev *pdev)
+{
+	struct matrox_device *dev = pci_get_drvdata(pdev);
+
+	if (dev->found) {
+		w1_remove_master_device(dev->bus_master);
+		iounmap(dev->virt_addr);
+	}
+	kfree(dev);
+}
+
+static struct pci_device_id matrox_w1_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400) },
+	{ },
+};
+MODULE_DEVICE_TABLE(pci, matrox_w1_tbl);
+
+static struct pci_driver matrox_w1_pci_driver = {
+	.name = "matrox_w1",
+	.id_table = matrox_w1_tbl,
+	.probe = matrox_w1_probe,
+	.remove = matrox_w1_remove,
+};
+module_pci_driver(matrox_w1_pci_driver);
+
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_DESCRIPTION("Driver for transport(Dallas 1-wire protocol) over VGA DDC(matrox gpio).");
+MODULE_LICENSE("GPL");
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
new file mode 100644
index 0000000..50b46c4
--- /dev/null
+++ b/drivers/w1/masters/mxc_w1.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Luotao Fu, kernel@pengutronix.de
+ *
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+
+#include <linux/w1.h>
+
+/*
+ * MXC W1 Register offsets
+ */
+#define MXC_W1_CONTROL		0x00
+# define MXC_W1_CONTROL_RDST	BIT(3)
+# define MXC_W1_CONTROL_WR(x)	BIT(5 - (x))
+# define MXC_W1_CONTROL_PST	BIT(6)
+# define MXC_W1_CONTROL_RPP	BIT(7)
+#define MXC_W1_TIME_DIVIDER	0x02
+#define MXC_W1_RESET		0x04
+# define MXC_W1_RESET_RST	BIT(0)
+
+struct mxc_w1_device {
+	void __iomem *regs;
+	struct clk *clk;
+	struct w1_bus_master bus_master;
+};
+
+/*
+ * this is the low level routine to
+ * reset the device on the One Wire interface
+ * on the hardware
+ */
+static u8 mxc_w1_ds2_reset_bus(void *data)
+{
+	struct mxc_w1_device *dev = data;
+	unsigned long timeout;
+
+	writeb(MXC_W1_CONTROL_RPP, dev->regs + MXC_W1_CONTROL);
+
+	/* Wait for reset sequence 511+512us, use 1500us for sure */
+	timeout = jiffies + usecs_to_jiffies(1500);
+
+	udelay(511 + 512);
+
+	do {
+		u8 ctrl = readb(dev->regs + MXC_W1_CONTROL);
+
+		/* PST bit is valid after the RPP bit is self-cleared */
+		if (!(ctrl & MXC_W1_CONTROL_RPP))
+			return !(ctrl & MXC_W1_CONTROL_PST);
+	} while (time_is_after_jiffies(timeout));
+
+	return 1;
+}
+
+/*
+ * this is the low level routine to read/write a bit on the One Wire
+ * interface on the hardware. It does write 0 if parameter bit is set
+ * to 0, otherwise a write 1/read.
+ */
+static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)
+{
+	struct mxc_w1_device *dev = data;
+	unsigned long timeout;
+
+	writeb(MXC_W1_CONTROL_WR(bit), dev->regs + MXC_W1_CONTROL);
+
+	/* Wait for read/write bit (60us, Max 120us), use 200us for sure */
+	timeout = jiffies + usecs_to_jiffies(200);
+
+	udelay(60);
+
+	do {
+		u8 ctrl = readb(dev->regs + MXC_W1_CONTROL);
+
+		/* RDST bit is valid after the WR1/RD bit is self-cleared */
+		if (!(ctrl & MXC_W1_CONTROL_WR(bit)))
+			return !!(ctrl & MXC_W1_CONTROL_RDST);
+	} while (time_is_after_jiffies(timeout));
+
+	return 0;
+}
+
+static int mxc_w1_probe(struct platform_device *pdev)
+{
+	struct mxc_w1_device *mdev;
+	unsigned long clkrate;
+	struct resource *res;
+	unsigned int clkdiv;
+	int err;
+
+	mdev = devm_kzalloc(&pdev->dev, sizeof(struct mxc_w1_device),
+			    GFP_KERNEL);
+	if (!mdev)
+		return -ENOMEM;
+
+	mdev->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mdev->clk))
+		return PTR_ERR(mdev->clk);
+
+	err = clk_prepare_enable(mdev->clk);
+	if (err)
+		return err;
+
+	clkrate = clk_get_rate(mdev->clk);
+	if (clkrate < 10000000)
+		dev_warn(&pdev->dev,
+			 "Low clock frequency causes improper function\n");
+
+	clkdiv = DIV_ROUND_CLOSEST(clkrate, 1000000);
+	clkrate /= clkdiv;
+	if ((clkrate < 980000) || (clkrate > 1020000))
+		dev_warn(&pdev->dev,
+			 "Incorrect time base frequency %lu Hz\n", clkrate);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mdev->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mdev->regs)) {
+		err = PTR_ERR(mdev->regs);
+		goto out_disable_clk;
+	}
+
+	/* Software reset 1-Wire module */
+	writeb(MXC_W1_RESET_RST, mdev->regs + MXC_W1_RESET);
+	writeb(0, mdev->regs + MXC_W1_RESET);
+
+	writeb(clkdiv - 1, mdev->regs + MXC_W1_TIME_DIVIDER);
+
+	mdev->bus_master.data = mdev;
+	mdev->bus_master.reset_bus = mxc_w1_ds2_reset_bus;
+	mdev->bus_master.touch_bit = mxc_w1_ds2_touch_bit;
+
+	platform_set_drvdata(pdev, mdev);
+
+	err = w1_add_master_device(&mdev->bus_master);
+	if (err)
+		goto out_disable_clk;
+
+	return 0;
+
+out_disable_clk:
+	clk_disable_unprepare(mdev->clk);
+	return err;
+}
+
+/*
+ * disassociate the w1 device from the driver
+ */
+static int 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[] = {
+	{ .compatible = "fsl,imx21-owire" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mxc_w1_dt_ids);
+
+static struct platform_driver mxc_w1_driver = {
+	.driver = {
+		.name = "mxc_w1",
+		.of_match_table = mxc_w1_dt_ids,
+	},
+	.probe = mxc_w1_probe,
+	.remove = mxc_w1_remove,
+};
+module_platform_driver(mxc_w1_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Freescale Semiconductors Inc");
+MODULE_DESCRIPTION("Driver for One-Wire on MXC");
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
new file mode 100644
index 0000000..3099052
--- /dev/null
+++ b/drivers/w1/masters/omap_hdq.c
@@ -0,0 +1,790 @@
+/*
+ * drivers/w1/masters/omap_hdq.c
+ *
+ * Copyright (C) 2007,2012 Texas Instruments, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+
+#include <linux/w1.h>
+
+#define	MOD_NAME	"OMAP_HDQ:"
+
+#define OMAP_HDQ_REVISION			0x00
+#define OMAP_HDQ_TX_DATA			0x04
+#define OMAP_HDQ_RX_DATA			0x08
+#define OMAP_HDQ_CTRL_STATUS			0x0c
+#define OMAP_HDQ_CTRL_STATUS_SINGLE		BIT(7)
+#define OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK	BIT(6)
+#define OMAP_HDQ_CTRL_STATUS_CLOCKENABLE	BIT(5)
+#define OMAP_HDQ_CTRL_STATUS_GO                 BIT(4)
+#define OMAP_HDQ_CTRL_STATUS_PRESENCE		BIT(3)
+#define OMAP_HDQ_CTRL_STATUS_INITIALIZATION	BIT(2)
+#define OMAP_HDQ_CTRL_STATUS_DIR		BIT(1)
+#define OMAP_HDQ_INT_STATUS			0x10
+#define OMAP_HDQ_INT_STATUS_TXCOMPLETE		BIT(2)
+#define OMAP_HDQ_INT_STATUS_RXCOMPLETE		BIT(1)
+#define OMAP_HDQ_INT_STATUS_TIMEOUT		BIT(0)
+#define OMAP_HDQ_SYSCONFIG			0x14
+#define OMAP_HDQ_SYSCONFIG_SOFTRESET		BIT(1)
+#define OMAP_HDQ_SYSCONFIG_AUTOIDLE		BIT(0)
+#define OMAP_HDQ_SYSCONFIG_NOIDLE		0x0
+#define OMAP_HDQ_SYSSTATUS			0x18
+#define OMAP_HDQ_SYSSTATUS_RESETDONE		BIT(0)
+
+#define OMAP_HDQ_FLAG_CLEAR			0
+#define OMAP_HDQ_FLAG_SET			1
+#define OMAP_HDQ_TIMEOUT			(HZ/5)
+
+#define OMAP_HDQ_MAX_USER			4
+
+static DECLARE_WAIT_QUEUE_HEAD(hdq_wait_queue);
+
+static int w1_id;
+module_param(w1_id, int, S_IRUSR);
+MODULE_PARM_DESC(w1_id, "1-wire id for the slave detection in HDQ mode");
+
+struct hdq_data {
+	struct device		*dev;
+	void __iomem		*hdq_base;
+	/* lock status update */
+	struct  mutex		hdq_mutex;
+	int			hdq_usecount;
+	u8			hdq_irqstatus;
+	/* device lock */
+	spinlock_t		hdq_spinlock;
+	/*
+	 * Used to control the call to omap_hdq_get and omap_hdq_put.
+	 * HDQ Protocol: Write the CMD|REG_address first, followed by
+	 * the data wrire or read.
+	 */
+	int			init_trans;
+	int                     rrw;
+	/* mode: 0-HDQ 1-W1 */
+	int                     mode;
+
+};
+
+/* HDQ register I/O routines */
+static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset)
+{
+	return __raw_readl(hdq_data->hdq_base + offset);
+}
+
+static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val)
+{
+	__raw_writel(val, hdq_data->hdq_base + offset);
+}
+
+static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset,
+			u8 val, u8 mask)
+{
+	u8 new_val = (__raw_readl(hdq_data->hdq_base + offset) & ~mask)
+			| (val & mask);
+	__raw_writel(new_val, hdq_data->hdq_base + offset);
+
+	return new_val;
+}
+
+static void hdq_disable_interrupt(struct hdq_data *hdq_data, u32 offset,
+				  u32 mask)
+{
+	u32 ie;
+
+	ie = readl(hdq_data->hdq_base + offset);
+	writel(ie & mask, hdq_data->hdq_base + offset);
+}
+
+/*
+ * Wait for one or more bits in flag change.
+ * HDQ_FLAG_SET: wait until any bit in the flag is set.
+ * HDQ_FLAG_CLEAR: wait until all bits in the flag are cleared.
+ * return 0 on success and -ETIMEDOUT in the case of timeout.
+ */
+static int hdq_wait_for_flag(struct hdq_data *hdq_data, u32 offset,
+		u8 flag, u8 flag_set, u8 *status)
+{
+	int ret = 0;
+	unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT;
+
+	if (flag_set == OMAP_HDQ_FLAG_CLEAR) {
+		/* wait for the flag clear */
+		while (((*status = hdq_reg_in(hdq_data, offset)) & flag)
+			&& time_before(jiffies, timeout)) {
+			schedule_timeout_uninterruptible(1);
+		}
+		if (*status & flag)
+			ret = -ETIMEDOUT;
+	} else if (flag_set == OMAP_HDQ_FLAG_SET) {
+		/* wait for the flag set */
+		while (!((*status = hdq_reg_in(hdq_data, offset)) & flag)
+			&& time_before(jiffies, timeout)) {
+			schedule_timeout_uninterruptible(1);
+		}
+		if (!(*status & flag))
+			ret = -ETIMEDOUT;
+	} else
+		return -EINVAL;
+
+	return ret;
+}
+
+/* write out a byte and fill *status with HDQ_INT_STATUS */
+static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status)
+{
+	int ret;
+	u8 tmp_status;
+	unsigned long irqflags;
+
+	*status = 0;
+
+	spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags);
+	/* clear interrupt flags via a dummy read */
+	hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS);
+	/* ISR loads it with new INT_STATUS */
+	hdq_data->hdq_irqstatus = 0;
+	spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags);
+
+	hdq_reg_out(hdq_data, OMAP_HDQ_TX_DATA, val);
+
+	/* set the GO bit */
+	hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, OMAP_HDQ_CTRL_STATUS_GO,
+		OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO);
+	/* wait for the TXCOMPLETE bit */
+	ret = wait_event_timeout(hdq_wait_queue,
+		hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT);
+	if (ret == 0) {
+		dev_dbg(hdq_data->dev, "TX wait elapsed\n");
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	*status = hdq_data->hdq_irqstatus;
+	/* check irqstatus */
+	if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) {
+		dev_dbg(hdq_data->dev, "timeout waiting for"
+			" TXCOMPLETE/RXCOMPLETE, %x", *status);
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	/* wait for the GO bit return to zero */
+	ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_CTRL_STATUS,
+			OMAP_HDQ_CTRL_STATUS_GO,
+			OMAP_HDQ_FLAG_CLEAR, &tmp_status);
+	if (ret) {
+		dev_dbg(hdq_data->dev, "timeout waiting GO bit"
+			" return to zero, %x", tmp_status);
+	}
+
+out:
+	return ret;
+}
+
+/* HDQ Interrupt service routine */
+static irqreturn_t hdq_isr(int irq, void *_hdq)
+{
+	struct hdq_data *hdq_data = _hdq;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags);
+	hdq_data->hdq_irqstatus = hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS);
+	spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags);
+	dev_dbg(hdq_data->dev, "hdq_isr: %x", hdq_data->hdq_irqstatus);
+
+	if (hdq_data->hdq_irqstatus &
+		(OMAP_HDQ_INT_STATUS_TXCOMPLETE | OMAP_HDQ_INT_STATUS_RXCOMPLETE
+		| OMAP_HDQ_INT_STATUS_TIMEOUT)) {
+		/* wake up sleeping process */
+		wake_up(&hdq_wait_queue);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/* W1 search callback function  in HDQ mode */
+static void omap_w1_search_bus(void *_hdq, struct w1_master *master_dev,
+		u8 search_type, w1_slave_found_callback slave_found)
+{
+	u64 module_id, rn_le, cs, id;
+
+	if (w1_id)
+		module_id = w1_id;
+	else
+		module_id = 0x1;
+
+	rn_le = cpu_to_le64(module_id);
+	/*
+	 * HDQ might not obey truly the 1-wire spec.
+	 * So calculate CRC based on module parameter.
+	 */
+	cs = w1_calc_crc8((u8 *)&rn_le, 7);
+	id = (cs << 56) | module_id;
+
+	slave_found(master_dev, id);
+}
+
+static int _omap_hdq_reset(struct hdq_data *hdq_data)
+{
+	int ret;
+	u8 tmp_status;
+
+	hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG,
+		    OMAP_HDQ_SYSCONFIG_SOFTRESET);
+	/*
+	 * Select HDQ/1W mode & enable clocks.
+	 * It is observed that INT flags can't be cleared via a read and GO/INIT
+	 * won't return to zero if interrupt is disabled. So we always enable
+	 * interrupt.
+	 */
+	hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS,
+		OMAP_HDQ_CTRL_STATUS_CLOCKENABLE |
+		OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK);
+
+	/* wait for reset to complete */
+	ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_SYSSTATUS,
+		OMAP_HDQ_SYSSTATUS_RESETDONE, OMAP_HDQ_FLAG_SET, &tmp_status);
+	if (ret)
+		dev_dbg(hdq_data->dev, "timeout waiting HDQ reset, %x",
+				tmp_status);
+	else {
+		hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS,
+			OMAP_HDQ_CTRL_STATUS_CLOCKENABLE |
+			OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK |
+			hdq_data->mode);
+		hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG,
+			OMAP_HDQ_SYSCONFIG_AUTOIDLE);
+	}
+
+	return ret;
+}
+
+/* Issue break pulse to the device */
+static int omap_hdq_break(struct hdq_data *hdq_data)
+{
+	int ret = 0;
+	u8 tmp_status;
+	unsigned long irqflags;
+
+	ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+	if (ret < 0) {
+		dev_dbg(hdq_data->dev, "Could not acquire mutex\n");
+		ret = -EINTR;
+		goto rtn;
+	}
+
+	spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags);
+	/* clear interrupt flags via a dummy read */
+	hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS);
+	/* ISR loads it with new INT_STATUS */
+	hdq_data->hdq_irqstatus = 0;
+	spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags);
+
+	/* set the INIT and GO bit */
+	hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS,
+		OMAP_HDQ_CTRL_STATUS_INITIALIZATION | OMAP_HDQ_CTRL_STATUS_GO,
+		OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_INITIALIZATION |
+		OMAP_HDQ_CTRL_STATUS_GO);
+
+	/* wait for the TIMEOUT bit */
+	ret = wait_event_timeout(hdq_wait_queue,
+		hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT);
+	if (ret == 0) {
+		dev_dbg(hdq_data->dev, "break wait elapsed\n");
+		ret = -EINTR;
+		goto out;
+	}
+
+	tmp_status = hdq_data->hdq_irqstatus;
+	/* check irqstatus */
+	if (!(tmp_status & OMAP_HDQ_INT_STATUS_TIMEOUT)) {
+		dev_dbg(hdq_data->dev, "timeout waiting for TIMEOUT, %x",
+				tmp_status);
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	/*
+	 * check for the presence detect bit to get
+	 * set to show that the slave is responding
+	 */
+	if (!(hdq_reg_in(hdq_data, OMAP_HDQ_CTRL_STATUS) &
+			OMAP_HDQ_CTRL_STATUS_PRESENCE)) {
+		dev_dbg(hdq_data->dev, "Presence bit not set\n");
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	/*
+	 * wait for both INIT and GO bits rerurn to zero.
+	 * zero wait time expected for interrupt mode.
+	 */
+	ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_CTRL_STATUS,
+			OMAP_HDQ_CTRL_STATUS_INITIALIZATION |
+			OMAP_HDQ_CTRL_STATUS_GO, OMAP_HDQ_FLAG_CLEAR,
+			&tmp_status);
+	if (ret)
+		dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits"
+			" return to zero, %x", tmp_status);
+
+out:
+	mutex_unlock(&hdq_data->hdq_mutex);
+rtn:
+	return ret;
+}
+
+static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val)
+{
+	int ret = 0;
+	u8 status;
+
+	ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+	if (ret < 0) {
+		ret = -EINTR;
+		goto rtn;
+	}
+
+	if (!hdq_data->hdq_usecount) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!(hdq_data->hdq_irqstatus & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) {
+		hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS,
+			OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO,
+			OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO);
+		/*
+		 * The RX comes immediately after TX.
+		 */
+		wait_event_timeout(hdq_wait_queue,
+				   (hdq_data->hdq_irqstatus
+				    & OMAP_HDQ_INT_STATUS_RXCOMPLETE),
+				   OMAP_HDQ_TIMEOUT);
+
+		hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, 0,
+			OMAP_HDQ_CTRL_STATUS_DIR);
+		status = hdq_data->hdq_irqstatus;
+		/* check irqstatus */
+		if (!(status & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) {
+			dev_dbg(hdq_data->dev, "timeout waiting for"
+				" RXCOMPLETE, %x", status);
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+	}
+	/* the data is ready. Read it in! */
+	*val = hdq_reg_in(hdq_data, OMAP_HDQ_RX_DATA);
+out:
+	mutex_unlock(&hdq_data->hdq_mutex);
+rtn:
+	return ret;
+
+}
+
+/* Enable clocks and set the controller to HDQ/1W mode */
+static int omap_hdq_get(struct hdq_data *hdq_data)
+{
+	int ret = 0;
+
+	ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+	if (ret < 0) {
+		ret = -EINTR;
+		goto rtn;
+	}
+
+	if (OMAP_HDQ_MAX_USER == hdq_data->hdq_usecount) {
+		dev_dbg(hdq_data->dev, "attempt to exceed the max use count");
+		ret = -EINVAL;
+		goto out;
+	} else {
+		hdq_data->hdq_usecount++;
+		try_module_get(THIS_MODULE);
+		if (1 == hdq_data->hdq_usecount) {
+
+			pm_runtime_get_sync(hdq_data->dev);
+
+			/* make sure HDQ/1W is out of reset */
+			if (!(hdq_reg_in(hdq_data, OMAP_HDQ_SYSSTATUS) &
+				OMAP_HDQ_SYSSTATUS_RESETDONE)) {
+				ret = _omap_hdq_reset(hdq_data);
+				if (ret)
+					/* back up the count */
+					hdq_data->hdq_usecount--;
+			} else {
+				/* select HDQ/1W mode & enable clocks */
+				hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS,
+					OMAP_HDQ_CTRL_STATUS_CLOCKENABLE |
+					OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK |
+					hdq_data->mode);
+				hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG,
+					OMAP_HDQ_SYSCONFIG_NOIDLE);
+				hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS);
+			}
+		}
+	}
+
+out:
+	mutex_unlock(&hdq_data->hdq_mutex);
+rtn:
+	return ret;
+}
+
+/* Disable clocks to the module */
+static int omap_hdq_put(struct hdq_data *hdq_data)
+{
+	int ret = 0;
+
+	ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+	if (ret < 0)
+		return -EINTR;
+
+	hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG,
+		    OMAP_HDQ_SYSCONFIG_AUTOIDLE);
+	if (0 == hdq_data->hdq_usecount) {
+		dev_dbg(hdq_data->dev, "attempt to decrement use count"
+			" when it is zero");
+		ret = -EINVAL;
+	} else {
+		hdq_data->hdq_usecount--;
+		module_put(THIS_MODULE);
+		if (0 == hdq_data->hdq_usecount)
+			pm_runtime_put_sync(hdq_data->dev);
+	}
+	mutex_unlock(&hdq_data->hdq_mutex);
+
+	return ret;
+}
+
+/*
+ * W1 triplet callback function - used for searching ROM addresses.
+ * Registered only when controller is in 1-wire mode.
+ */
+static u8 omap_w1_triplet(void *_hdq, u8 bdir)
+{
+	u8 id_bit, comp_bit;
+	int err;
+	u8 ret = 0x3; /* no slaves responded */
+	struct hdq_data *hdq_data = _hdq;
+	u8 ctrl = OMAP_HDQ_CTRL_STATUS_SINGLE | OMAP_HDQ_CTRL_STATUS_GO |
+		  OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK;
+	u8 mask = ctrl | OMAP_HDQ_CTRL_STATUS_DIR;
+
+	omap_hdq_get(_hdq);
+
+	err = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+	if (err < 0) {
+		dev_dbg(hdq_data->dev, "Could not acquire mutex\n");
+		goto rtn;
+	}
+
+	hdq_data->hdq_irqstatus = 0;
+	/* read id_bit */
+	hdq_reg_merge(_hdq, OMAP_HDQ_CTRL_STATUS,
+		      ctrl | OMAP_HDQ_CTRL_STATUS_DIR, mask);
+	err = wait_event_timeout(hdq_wait_queue,
+				 (hdq_data->hdq_irqstatus
+				  & OMAP_HDQ_INT_STATUS_RXCOMPLETE),
+				 OMAP_HDQ_TIMEOUT);
+	if (err == 0) {
+		dev_dbg(hdq_data->dev, "RX wait elapsed\n");
+		goto out;
+	}
+	id_bit = (hdq_reg_in(_hdq, OMAP_HDQ_RX_DATA) & 0x01);
+
+	hdq_data->hdq_irqstatus = 0;
+	/* read comp_bit */
+	hdq_reg_merge(_hdq, OMAP_HDQ_CTRL_STATUS,
+		      ctrl | OMAP_HDQ_CTRL_STATUS_DIR, mask);
+	err = wait_event_timeout(hdq_wait_queue,
+				 (hdq_data->hdq_irqstatus
+				  & OMAP_HDQ_INT_STATUS_RXCOMPLETE),
+				 OMAP_HDQ_TIMEOUT);
+	if (err == 0) {
+		dev_dbg(hdq_data->dev, "RX wait elapsed\n");
+		goto out;
+	}
+	comp_bit = (hdq_reg_in(_hdq, OMAP_HDQ_RX_DATA) & 0x01);
+
+	if (id_bit && comp_bit) {
+		ret = 0x03;  /* no slaves responded */
+		goto out;
+	}
+	if (!id_bit && !comp_bit) {
+		/* Both bits are valid, take the direction given */
+		ret = bdir ? 0x04 : 0;
+	} else {
+		/* Only one bit is valid, take that direction */
+		bdir = id_bit;
+		ret = id_bit ? 0x05 : 0x02;
+	}
+
+	/* write bdir bit */
+	hdq_reg_out(_hdq, OMAP_HDQ_TX_DATA, bdir);
+	hdq_reg_merge(_hdq, OMAP_HDQ_CTRL_STATUS, ctrl, mask);
+	err = wait_event_timeout(hdq_wait_queue,
+				 (hdq_data->hdq_irqstatus
+				  & OMAP_HDQ_INT_STATUS_TXCOMPLETE),
+				 OMAP_HDQ_TIMEOUT);
+	if (err == 0) {
+		dev_dbg(hdq_data->dev, "TX wait elapsed\n");
+		goto out;
+	}
+
+	hdq_reg_merge(_hdq, OMAP_HDQ_CTRL_STATUS, 0,
+		      OMAP_HDQ_CTRL_STATUS_SINGLE);
+
+out:
+	mutex_unlock(&hdq_data->hdq_mutex);
+rtn:
+	omap_hdq_put(_hdq);
+	return ret;
+}
+
+/* reset callback */
+static u8 omap_w1_reset_bus(void *_hdq)
+{
+	omap_hdq_get(_hdq);
+	omap_hdq_break(_hdq);
+	omap_hdq_put(_hdq);
+	return 0;
+}
+
+/* Read a byte of data from the device */
+static u8 omap_w1_read_byte(void *_hdq)
+{
+	struct hdq_data *hdq_data = _hdq;
+	u8 val = 0;
+	int ret;
+
+	/* First write to initialize the transfer */
+	if (hdq_data->init_trans == 0)
+		omap_hdq_get(hdq_data);
+
+	ret = hdq_read_byte(hdq_data, &val);
+	if (ret) {
+		ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+		if (ret < 0) {
+			dev_dbg(hdq_data->dev, "Could not acquire mutex\n");
+			return -EINTR;
+		}
+		hdq_data->init_trans = 0;
+		mutex_unlock(&hdq_data->hdq_mutex);
+		omap_hdq_put(hdq_data);
+		return -1;
+	}
+
+	hdq_disable_interrupt(hdq_data, OMAP_HDQ_CTRL_STATUS,
+			      ~OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK);
+
+	/* Write followed by a read, release the module */
+	if (hdq_data->init_trans) {
+		ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+		if (ret < 0) {
+			dev_dbg(hdq_data->dev, "Could not acquire mutex\n");
+			return -EINTR;
+		}
+		hdq_data->init_trans = 0;
+		mutex_unlock(&hdq_data->hdq_mutex);
+		omap_hdq_put(hdq_data);
+	}
+
+	return val;
+}
+
+/* Write a byte of data to the device */
+static void omap_w1_write_byte(void *_hdq, u8 byte)
+{
+	struct hdq_data *hdq_data = _hdq;
+	int ret;
+	u8 status;
+
+	/* First write to initialize the transfer */
+	if (hdq_data->init_trans == 0)
+		omap_hdq_get(hdq_data);
+
+	/*
+	 * We need to reset the slave before
+	 * issuing the SKIP ROM command, else
+	 * the slave will not work.
+	 */
+	if (byte == W1_SKIP_ROM)
+		omap_hdq_break(hdq_data);
+
+	ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+	if (ret < 0) {
+		dev_dbg(hdq_data->dev, "Could not acquire mutex\n");
+		return;
+	}
+	hdq_data->init_trans++;
+	mutex_unlock(&hdq_data->hdq_mutex);
+
+	ret = hdq_write_byte(hdq_data, byte, &status);
+	if (ret < 0) {
+		dev_dbg(hdq_data->dev, "TX failure:Ctrl status %x\n", status);
+		return;
+	}
+
+	/* Second write, data transferred. Release the module */
+	if (hdq_data->init_trans > 1) {
+		omap_hdq_put(hdq_data);
+		ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
+		if (ret < 0) {
+			dev_dbg(hdq_data->dev, "Could not acquire mutex\n");
+			return;
+		}
+		hdq_data->init_trans = 0;
+		mutex_unlock(&hdq_data->hdq_mutex);
+	}
+}
+
+static struct w1_bus_master omap_w1_master = {
+	.read_byte	= omap_w1_read_byte,
+	.write_byte	= omap_w1_write_byte,
+	.reset_bus	= omap_w1_reset_bus,
+};
+
+static int omap_hdq_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hdq_data *hdq_data;
+	struct resource *res;
+	int ret, irq;
+	u8 rev;
+	const char *mode;
+
+	hdq_data = devm_kzalloc(dev, sizeof(*hdq_data), GFP_KERNEL);
+	if (!hdq_data) {
+		dev_dbg(&pdev->dev, "unable to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	hdq_data->dev = dev;
+	platform_set_drvdata(pdev, hdq_data);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hdq_data->hdq_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(hdq_data->hdq_base))
+		return PTR_ERR(hdq_data->hdq_base);
+
+	hdq_data->hdq_usecount = 0;
+	hdq_data->rrw = 0;
+	mutex_init(&hdq_data->hdq_mutex);
+
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		dev_dbg(&pdev->dev, "pm_runtime_get_sync failed\n");
+		goto err_w1;
+	}
+
+	ret = _omap_hdq_reset(hdq_data);
+	if (ret) {
+		dev_dbg(&pdev->dev, "reset failed\n");
+		goto err_irq;
+	}
+
+	rev = hdq_reg_in(hdq_data, OMAP_HDQ_REVISION);
+	dev_info(&pdev->dev, "OMAP HDQ Hardware Rev %c.%c. Driver in %s mode\n",
+		(rev >> 4) + '0', (rev & 0x0f) + '0', "Interrupt");
+
+	spin_lock_init(&hdq_data->hdq_spinlock);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq	< 0) {
+		dev_dbg(&pdev->dev, "Failed to get IRQ: %d\n", irq);
+		ret = irq;
+		goto err_irq;
+	}
+
+	ret = devm_request_irq(dev, irq, hdq_isr, 0, "omap_hdq", hdq_data);
+	if (ret < 0) {
+		dev_dbg(&pdev->dev, "could not request irq\n");
+		goto err_irq;
+	}
+
+	omap_hdq_break(hdq_data);
+
+	pm_runtime_put_sync(&pdev->dev);
+
+	ret = of_property_read_string(pdev->dev.of_node, "ti,mode", &mode);
+	if (ret < 0 || !strcmp(mode, "hdq")) {
+		hdq_data->mode = 0;
+		omap_w1_master.search = omap_w1_search_bus;
+	} else {
+		hdq_data->mode = 1;
+		omap_w1_master.triplet = omap_w1_triplet;
+	}
+
+	omap_w1_master.data = hdq_data;
+
+	ret = w1_add_master_device(&omap_w1_master);
+	if (ret) {
+		dev_dbg(&pdev->dev, "Failure in registering w1 master\n");
+		goto err_w1;
+	}
+
+	return 0;
+
+err_irq:
+	pm_runtime_put_sync(&pdev->dev);
+err_w1:
+	pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int omap_hdq_remove(struct platform_device *pdev)
+{
+	struct hdq_data *hdq_data = platform_get_drvdata(pdev);
+
+	mutex_lock(&hdq_data->hdq_mutex);
+
+	if (hdq_data->hdq_usecount) {
+		dev_dbg(&pdev->dev, "removed when use count is not zero\n");
+		mutex_unlock(&hdq_data->hdq_mutex);
+		return -EBUSY;
+	}
+
+	mutex_unlock(&hdq_data->hdq_mutex);
+
+	/* remove module dependency */
+	pm_runtime_disable(&pdev->dev);
+
+	w1_remove_master_device(&omap_w1_master);
+
+	return 0;
+}
+
+static const struct of_device_id omap_hdq_dt_ids[] = {
+	{ .compatible = "ti,omap3-1w" },
+	{ .compatible = "ti,am4372-hdq" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, omap_hdq_dt_ids);
+
+static struct platform_driver omap_hdq_driver = {
+	.probe = omap_hdq_probe,
+	.remove = omap_hdq_remove,
+	.driver = {
+		.name =	"omap_hdq",
+		.of_match_table = omap_hdq_dt_ids,
+	},
+};
+module_platform_driver(omap_hdq_driver);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("HDQ-1W driver Library");
+MODULE_LICENSE("GPL");
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
new file mode 100644
index 0000000..55e11bf
--- /dev/null
+++ b/drivers/w1/masters/w1-gpio.c
@@ -0,0 +1,209 @@
+/*
+ * w1-gpio - GPIO w1 bus master driver
+ *
+ * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/w1-gpio.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/w1.h>
+
+static u8 w1_gpio_set_pullup(void *data, int delay)
+{
+	struct w1_gpio_platform_data *pdata = data;
+
+	if (delay) {
+		pdata->pullup_duration = delay;
+	} else {
+		if (pdata->pullup_duration) {
+			/*
+			 * This will OVERRIDE open drain emulation and force-pull
+			 * the line high for some time.
+			 */
+			gpiod_set_raw_value(pdata->gpiod, 1);
+			msleep(pdata->pullup_duration);
+			/*
+			 * This will simply set the line as input since we are doing
+			 * open drain emulation in the GPIO library.
+			 */
+			gpiod_set_value(pdata->gpiod, 1);
+		}
+		pdata->pullup_duration = 0;
+	}
+
+	return 0;
+}
+
+static void w1_gpio_write_bit(void *data, u8 bit)
+{
+	struct w1_gpio_platform_data *pdata = data;
+
+	gpiod_set_value(pdata->gpiod, bit);
+}
+
+static u8 w1_gpio_read_bit(void *data)
+{
+	struct w1_gpio_platform_data *pdata = data;
+
+	return gpiod_get_value(pdata->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_platform_data *pdata;
+	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;
+
+	if (of_have_populated_dt()) {
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+
+		/*
+		 * This parameter means that something else than the gpiolib has
+		 * already set the line into open drain mode, so we should just
+		 * driver it high/low like we are in full control of the line and
+		 * open drain will happen transparently.
+		 */
+		if (of_get_property(np, "linux,open-drain", NULL))
+			gflags = GPIOD_OUT_LOW;
+
+		pdev->dev.platform_data = pdata;
+	}
+	pdata = dev_get_platdata(dev);
+
+	if (!pdata) {
+		dev_err(dev, "No configuration data\n");
+		return -ENXIO;
+	}
+
+	master = devm_kzalloc(dev, sizeof(struct w1_bus_master),
+			GFP_KERNEL);
+	if (!master) {
+		dev_err(dev, "Out of memory\n");
+		return -ENOMEM;
+	}
+
+	pdata->gpiod = devm_gpiod_get_index(dev, NULL, 0, gflags);
+	if (IS_ERR(pdata->gpiod)) {
+		dev_err(dev, "gpio_request (pin) failed\n");
+		return PTR_ERR(pdata->gpiod);
+	}
+
+	pdata->pullup_gpiod =
+		devm_gpiod_get_index_optional(dev, NULL, 1, GPIOD_OUT_LOW);
+	if (IS_ERR(pdata->pullup_gpiod)) {
+		dev_err(dev, "gpio_request_one "
+			"(ext_pullup_enable_pin) failed\n");
+		return PTR_ERR(pdata->pullup_gpiod);
+	}
+
+	master->data = pdata;
+	master->read_bit = w1_gpio_read_bit;
+	gpiod_direction_output(pdata->gpiod, 1);
+	master->write_bit = w1_gpio_write_bit;
+
+	/*
+	 * If we are using open drain emulation from the GPIO library,
+	 * we need to use this pullup function that hammers the line
+	 * high using a raw accessor to provide pull-up for the w1
+	 * line.
+	 */
+	if (gflags == GPIOD_OUT_LOW_OPEN_DRAIN)
+		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 (pdata->enable_external_pullup)
+		pdata->enable_external_pullup(1);
+
+	if (pdata->pullup_gpiod)
+		gpiod_set_value(pdata->pullup_gpiod, 1);
+
+	platform_set_drvdata(pdev, master);
+
+	return 0;
+}
+
+static int w1_gpio_remove(struct platform_device *pdev)
+{
+	struct w1_bus_master *master = platform_get_drvdata(pdev);
+	struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+
+	if (pdata->enable_external_pullup)
+		pdata->enable_external_pullup(0);
+
+	if (pdata->pullup_gpiod)
+		gpiod_set_value(pdata->pullup_gpiod, 0);
+
+	w1_remove_master_device(master);
+
+	return 0;
+}
+
+static int __maybe_unused w1_gpio_suspend(struct device *dev)
+{
+	struct w1_gpio_platform_data *pdata = dev_get_platdata(dev);
+
+	if (pdata->enable_external_pullup)
+		pdata->enable_external_pullup(0);
+
+	return 0;
+}
+
+static int __maybe_unused w1_gpio_resume(struct device *dev)
+{
+	struct w1_gpio_platform_data *pdata = dev_get_platdata(dev);
+
+	if (pdata->enable_external_pullup)
+		pdata->enable_external_pullup(1);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(w1_gpio_pm_ops, w1_gpio_suspend, w1_gpio_resume);
+
+static struct platform_driver w1_gpio_driver = {
+	.driver = {
+		.name	= "w1-gpio",
+		.pm	= &w1_gpio_pm_ops,
+		.of_match_table = of_match_ptr(w1_gpio_dt_ids),
+	},
+	.probe = w1_gpio_probe,
+	.remove = w1_gpio_remove,
+};
+
+module_platform_driver(w1_gpio_driver);
+
+MODULE_DESCRIPTION("GPIO w1 bus master driver");
+MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
+MODULE_LICENSE("GPL");