diff options
Diffstat (limited to 'drivers/w1/masters')
| -rw-r--r-- | drivers/w1/masters/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/w1/masters/ds1wm.c | 14 | ||||
| -rw-r--r-- | drivers/w1/masters/ds2490.c | 155 | ||||
| -rw-r--r-- | drivers/w1/masters/mxc_w1.c | 72 | ||||
| -rw-r--r-- | drivers/w1/masters/omap_hdq.c | 3 | ||||
| -rw-r--r-- | drivers/w1/masters/w1-gpio.c | 84 | 
6 files changed, 221 insertions, 110 deletions
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index efc7f075fcb..1708b2300c7 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig @@ -36,13 +36,12 @@ config W1_MASTER_DS2482  config W1_MASTER_MXC  	tristate "Freescale MXC 1-wire busmaster" -	depends on W1 && ARCH_MXC +	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" -	depends on W1  	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 diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index 96cab6ac2b4..02df3b1381d 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c @@ -255,17 +255,17 @@ static int ds1wm_find_divisor(int gclk)  static void ds1wm_up(struct ds1wm_data *ds1wm_data)  {  	int divisor; -	struct ds1wm_driver_data *plat = ds1wm_data->pdev->dev.platform_data; +	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(&ds1wm_data->pdev->dev, -		"found divisor 0x%x for clock %d\n", divisor, plat->clock_rate); +	dev_dbg(dev, "found divisor 0x%x for clock %d\n", +		divisor, plat->clock_rate);  	if (divisor == 0) { -		dev_err(&ds1wm_data->pdev->dev, -			"no suitable divisor for %dHz clock\n", +		dev_err(dev, "no suitable divisor for %dHz clock\n",  			plat->clock_rate);  		return;  	} @@ -481,7 +481,7 @@ static int ds1wm_probe(struct platform_device *pdev)  	ds1wm_data->cell = mfd_get_cell(pdev);  	if (!ds1wm_data->cell)  		return -ENODEV; -	plat = pdev->dev.platform_data; +	plat = dev_get_platdata(&pdev->dev);  	if (!plat)  		return -ENODEV; @@ -498,7 +498,7 @@ static int ds1wm_probe(struct platform_device *pdev)  		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);  	ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr, -			IRQF_DISABLED | IRQF_SHARED, "ds1wm", ds1wm_data); +			IRQF_SHARED, "ds1wm", ds1wm_data);  	if (ret)  		return ret; diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index 4f7e1d770f8..7404ad3062b 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c @@ -1,5 +1,5 @@  /* - *	dscore.c + *	ds2490.c  USB to one wire bridge   *   * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>   * @@ -28,6 +28,10 @@  #include "../w1_int.h"  #include "../w1.h" +/* USB Standard */ +/* USB Control request vendor type */ +#define VENDOR				0x40 +  /* COMMAND TYPE CODES */  #define CONTROL_CMD			0x00  #define COMM_CMD			0x01 @@ -107,6 +111,8 @@  #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 */ @@ -198,7 +204,7 @@ 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, 0x40, value, index, NULL, 0, 1000); +			CONTROL_CMD, VENDOR, value, index, NULL, 0, 1000);  	if (err < 0) {  		printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n",  				value, index, err); @@ -213,7 +219,7 @@ 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, 0x40, value, index, NULL, 0, 1000); +			MODE_CMD, VENDOR, value, index, NULL, 0, 1000);  	if (err < 0) {  		printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n",  				value, index, err); @@ -228,7 +234,7 @@ 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, 0x40, value, index, NULL, 0, 1000); +			COMM_CMD, VENDOR, value, index, NULL, 0, 1000);  	if (err < 0) {  		printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n",  				value, index, err); @@ -246,7 +252,8 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,  	memset(st, 0, sizeof(*st));  	count = 0; -	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); +	err = usb_interrupt_msg(dev->udev, usb_rcvintpipe(dev->udev, +		dev->ep[EP_STATUS]), buf, size, &count, 100);  	if (err < 0) {  		printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err);  		return err; @@ -353,7 +360,7 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)  	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),  				buf, size, &count, 1000);  	if (err < 0) { -		u8 buf[0x20]; +		u8 buf[ST_SIZE];  		int count;  		printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); @@ -398,7 +405,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit)  {  	struct ds_status st;  	int count = 0, err = 0; -	u8 buf[0x20]; +	u8 buf[ST_SIZE];  	do {  		err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); @@ -450,10 +457,11 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)  static int ds_wait_status(struct ds_device *dev, struct ds_status *st)  { -	u8 buf[0x20]; +	u8 buf[ST_SIZE];  	int err, count = 0;  	do { +		st->status = 0;  		err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));  #if 0  		if (err >= 0) { @@ -464,7 +472,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)  			printk("\n");  		}  #endif -	} while (!(buf[0x08] & ST_IDLE) && !(err < 0) && ++count < 100); +	} while (!(st->status & ST_IDLE) && !(err < 0) && ++count < 100);  	if (err >= 16 && st->status & ST_EPOF) {  		printk(KERN_INFO "Resetting device after ST_EPOF.\n"); @@ -690,37 +698,106 @@ static int ds_write_block(struct ds_device *dev, u8 *buf, int len)  	return !(err == len);  } -#if 0 - -static int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) +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; +	u8 st_buf[ST_SIZE]; +	int search_limit; +	int found = 0; +	int i; -	memset(buf, 0, sizeof(buf)); +	/* 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. +	 */ +	u64 buf[2*64/8]; -	err = ds_send_data(ds_dev, (unsigned char *)&init, 8); -	if (err) -		return err; +	mutex_lock(&master->bus_mutex); -	ds_wait_status(ds_dev, &st); +	/* 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_SM | COMM_F | COMM_RTS; -	index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8); -	err = ds_send_control(ds_dev, value, index); -	if (err) -		return err; +	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; -	ds_wait_status(ds_dev, &st); +	do { +		schedule_timeout(jtime); -	err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number); -	if (err < 0) -		return err; +		if (ds_recv_status_nodump(dev, &st, st_buf, sizeof(st_buf)) < +			sizeof(st)) { +			break; +		} -	return err/8; +		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, sizeof(buf)); +			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);  } +#if 0  static int ds_match_access(struct ds_device *dev, u64 init)  {  	int err; @@ -894,6 +971,7 @@ static int ds_w1_init(struct ds_device *dev)  	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);  } @@ -910,15 +988,13 @@ static int ds_probe(struct usb_interface *intf,  	struct usb_endpoint_descriptor *endpoint;  	struct usb_host_interface *iface_desc;  	struct ds_device *dev; -	int i, err; +	int i, err, alt; -	dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); +	dev = kzalloc(sizeof(struct ds_device), GFP_KERNEL);  	if (!dev) {  		printk(KERN_INFO "Failed to allocate new DS9490R structure.\n");  		return -ENOMEM;  	} -	dev->spu_sleep = 0; -	dev->spu_bit = 0;  	dev->udev = usb_get_dev(udev);  	if (!dev->udev) {  		err = -ENOMEM; @@ -928,20 +1004,25 @@ static int ds_probe(struct usb_interface *intf,  	usb_set_intfdata(intf, dev); -	err = usb_set_interface(dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); +	err = usb_reset_configuration(dev->udev);  	if (err) { -		printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", -				intf->altsetting[0].desc.bInterfaceNumber, err); +		dev_err(&dev->udev->dev, +			"Failed to reset configuration: err=%d.\n", err);  		goto err_out_clear;  	} -	err = usb_reset_configuration(dev->udev); +	/* 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) { -		printk(KERN_ERR "Failed to reset configuration: err=%d.\n", 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[0]; +	iface_desc = &intf->altsetting[alt];  	if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {  		printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints);  		err = -EINVAL; diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index 15c7251b055..a5df5e89d45 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -10,24 +10,16 @@   * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. - *   */ -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h>  #include <linux/clk.h> -#include <linux/slab.h>  #include <linux/delay.h>  #include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h>  #include "../w1.h"  #include "../w1_int.h" -#include "../w1_log.h"  /* According to the mx27 Datasheet the reset procedure should take up to about   * 1350us. We set the timeout to 500*100us = 50ms for sure */ @@ -36,17 +28,16 @@  /*   * MXC W1 Register offsets   */ -#define MXC_W1_CONTROL          0x00 -#define MXC_W1_TIME_DIVIDER     0x02 -#define MXC_W1_RESET            0x04 -#define MXC_W1_COMMAND          0x06 -#define MXC_W1_TXRX             0x08 -#define MXC_W1_INTERRUPT        0x0A -#define MXC_W1_INTERRUPT_EN     0x0C +#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  struct mxc_w1_device {  	void __iomem *regs; -	unsigned int clkdiv;  	struct clk *clk;  	struct w1_bus_master bus_master;  }; @@ -62,12 +53,12 @@ static u8 mxc_w1_ds2_reset_bus(void *data)  	unsigned int timeout_cnt = 0;  	struct mxc_w1_device *dev = data; -	__raw_writeb(0x80, (dev->regs + MXC_W1_CONTROL)); +	writeb(MXC_W1_CONTROL_RPP, (dev->regs + MXC_W1_CONTROL));  	while (1) { -		reg_val = __raw_readb(dev->regs + MXC_W1_CONTROL); +		reg_val = readb(dev->regs + MXC_W1_CONTROL); -		if (((reg_val >> 7) & 0x1) == 0 || +		if (!(reg_val & MXC_W1_CONTROL_RPP) ||  		    timeout_cnt > MXC_W1_RESET_TIMEOUT)  			break;  		else @@ -75,7 +66,7 @@ static u8 mxc_w1_ds2_reset_bus(void *data)  		udelay(100);  	} -	return (reg_val >> 7) & 0x1; +	return !(reg_val & MXC_W1_CONTROL_PST);  }  /* @@ -91,23 +82,25 @@ static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)  					 * datasheet.  					 */ -	__raw_writeb((1 << (5 - bit)), ctrl_addr); +	writeb(MXC_W1_CONTROL_WR(bit), ctrl_addr);  	while (timeout_cnt--) { -		if (!((__raw_readb(ctrl_addr) >> (5 - bit)) & 0x1)) +		if (!(readb(ctrl_addr) & MXC_W1_CONTROL_WR(bit)))  			break;  		udelay(1);  	} -	return ((__raw_readb(ctrl_addr)) >> 3) & 0x1; +	return !!(readb(ctrl_addr) & MXC_W1_CONTROL_RDST);  }  static int mxc_w1_probe(struct platform_device *pdev)  {  	struct mxc_w1_device *mdev; +	unsigned long clkrate;  	struct resource *res; -	int err = 0; +	unsigned int clkdiv; +	int err;  	mdev = devm_kzalloc(&pdev->dev, sizeof(struct mxc_w1_device),  			    GFP_KERNEL); @@ -118,27 +111,39 @@ static int mxc_w1_probe(struct platform_device *pdev)  	if (IS_ERR(mdev->clk))  		return PTR_ERR(mdev->clk); -	mdev->clkdiv = (clk_get_rate(mdev->clk) / 1000000) - 1; +	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))  		return PTR_ERR(mdev->regs); -	clk_prepare_enable(mdev->clk); -	__raw_writeb(mdev->clkdiv, mdev->regs + MXC_W1_TIME_DIVIDER); +	err = clk_prepare_enable(mdev->clk); +	if (err) +		return err; + +	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; -	err = w1_add_master_device(&mdev->bus_master); +	platform_set_drvdata(pdev, mdev); +	err = w1_add_master_device(&mdev->bus_master);  	if (err) -		return err; +		clk_disable_unprepare(mdev->clk); -	platform_set_drvdata(pdev, mdev); -	return 0; +	return err;  }  /* @@ -164,6 +169,7 @@ MODULE_DEVICE_TABLE(of, mxc_w1_dt_ids);  static struct platform_driver mxc_w1_driver = {  	.driver = {  		.name = "mxc_w1", +		.owner = THIS_MODULE,  		.of_match_table = mxc_w1_dt_ids,  	},  	.probe = mxc_w1_probe, diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 6e94d8dd3d0..9900e8ec739 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -577,8 +577,7 @@ static int omap_hdq_probe(struct platform_device *pdev)  		goto err_irq;  	} -	ret = devm_request_irq(dev, irq, hdq_isr, IRQF_DISABLED, -			"omap_hdq", hdq_data); +	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; diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index f54ece268c9..1d111e56c8c 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -18,10 +18,31 @@  #include <linux/of_gpio.h>  #include <linux/err.h>  #include <linux/of.h> +#include <linux/delay.h>  #include "../w1.h"  #include "../w1_int.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) { +			gpio_direction_output(pdata->pin, 1); + +			msleep(pdata->pullup_duration); + +			gpio_direction_input(pdata->pin); +		} +		pdata->pullup_duration = 0; +	} + +	return 0; +} +  static void w1_gpio_write_bit_dir(void *data, u8 bit)  {  	struct w1_gpio_platform_data *pdata = data; @@ -56,8 +77,9 @@ MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);  static int w1_gpio_probe_dt(struct platform_device *pdev)  { -	struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; +	struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);  	struct device_node *np = pdev->dev.of_node; +	int gpio;  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);  	if (!pdata) @@ -66,8 +88,23 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)  	if (of_get_property(np, "linux,open-drain", NULL))  		pdata->is_open_drain = 1; -	pdata->pin = of_get_gpio(np, 0); -	pdata->ext_pullup_enable_pin = of_get_gpio(np, 1); +	gpio = of_get_gpio(np, 0); +	if (gpio < 0) { +		if (gpio != -EPROBE_DEFER) +			dev_err(&pdev->dev, +					"Failed to parse gpio property for data pin (%d)\n", +					gpio); + +		return gpio; +	} +	pdata->pin = gpio; + +	gpio = of_get_gpio(np, 1); +	if (gpio == -EPROBE_DEFER) +		return gpio; +	/* ignore other errors as the pullup gpio is optional */ +	pdata->ext_pullup_enable_pin = gpio; +  	pdev->dev.platform_data = pdata;  	return 0; @@ -81,38 +118,38 @@ static int w1_gpio_probe(struct platform_device *pdev)  	if (of_have_populated_dt()) {  		err = w1_gpio_probe_dt(pdev); -		if (err < 0) { -			dev_err(&pdev->dev, "Failed to parse DT\n"); +		if (err < 0)  			return err; -		}  	} -	pdata = pdev->dev.platform_data; +	pdata = dev_get_platdata(&pdev->dev);  	if (!pdata) {  		dev_err(&pdev->dev, "No configuration data\n");  		return -ENXIO;  	} -	master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL); +	master = devm_kzalloc(&pdev->dev, sizeof(struct w1_bus_master), +			GFP_KERNEL);  	if (!master) {  		dev_err(&pdev->dev, "Out of memory\n");  		return -ENOMEM;  	} -	err = gpio_request(pdata->pin, "w1"); +	err = devm_gpio_request(&pdev->dev, pdata->pin, "w1");  	if (err) {  		dev_err(&pdev->dev, "gpio_request (pin) failed\n"); -		goto free_master; +		return err;  	}  	if (gpio_is_valid(pdata->ext_pullup_enable_pin)) { -		err = gpio_request_one(pdata->ext_pullup_enable_pin, -				       GPIOF_INIT_LOW, "w1 pullup"); +		err = devm_gpio_request_one(&pdev->dev, +				pdata->ext_pullup_enable_pin, GPIOF_INIT_LOW, +				"w1 pullup");  		if (err < 0) {  			dev_err(&pdev->dev, "gpio_request_one "  					"(ext_pullup_enable_pin) failed\n"); -			goto free_gpio; +			return err;  		}  	} @@ -125,12 +162,13 @@ static int w1_gpio_probe(struct platform_device *pdev)  	} else {  		gpio_direction_input(pdata->pin);  		master->write_bit = w1_gpio_write_bit_dir; +		master->set_pullup = w1_gpio_set_pullup;  	}  	err = w1_add_master_device(master);  	if (err) {  		dev_err(&pdev->dev, "w1_add_master device failed\n"); -		goto free_gpio_ext_pu; +		return err;  	}  	if (pdata->enable_external_pullup) @@ -142,22 +180,12 @@ static int w1_gpio_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, master);  	return 0; - - free_gpio_ext_pu: -	if (gpio_is_valid(pdata->ext_pullup_enable_pin)) -		gpio_free(pdata->ext_pullup_enable_pin); - free_gpio: -	gpio_free(pdata->pin); - free_master: -	kfree(master); - -	return err;  }  static int w1_gpio_remove(struct platform_device *pdev)  {  	struct w1_bus_master *master = platform_get_drvdata(pdev); -	struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; +	struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);  	if (pdata->enable_external_pullup)  		pdata->enable_external_pullup(0); @@ -166,8 +194,6 @@ static int w1_gpio_remove(struct platform_device *pdev)  		gpio_set_value(pdata->ext_pullup_enable_pin, 0);  	w1_remove_master_device(master); -	gpio_free(pdata->pin); -	kfree(master);  	return 0;  } @@ -176,7 +202,7 @@ static int w1_gpio_remove(struct platform_device *pdev)  static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state)  { -	struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; +	struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);  	if (pdata->enable_external_pullup)  		pdata->enable_external_pullup(0); @@ -186,7 +212,7 @@ static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state)  static int w1_gpio_resume(struct platform_device *pdev)  { -	struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; +	struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);  	if (pdata->enable_external_pullup)  		pdata->enable_external_pullup(1);  | 
