cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ds1wm.c (18080B)


      1/*
      2 * 1-wire busmaster driver for DS1WM and ASICs with embedded DS1WMs
      3 * such as HP iPAQs (including h5xxx, h2200, and devices with ASIC3
      4 * like hx4700).
      5 *
      6 * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
      7 * Copyright (c) 2004-2007, Matt Reimer <mreimer@vpop.net>
      8 *
      9 * Use consistent with the GNU GPL is permitted,
     10 * provided that this copyright notice is
     11 * preserved in its entirety in all copies and derived works.
     12 */
     13
     14#include <linux/module.h>
     15#include <linux/interrupt.h>
     16#include <linux/io.h>
     17#include <linux/irq.h>
     18#include <linux/pm.h>
     19#include <linux/platform_device.h>
     20#include <linux/err.h>
     21#include <linux/delay.h>
     22#include <linux/mfd/core.h>
     23#include <linux/mfd/ds1wm.h>
     24#include <linux/slab.h>
     25
     26#include <asm/io.h>
     27
     28#include <linux/w1.h>
     29
     30
     31#define DS1WM_CMD	0x00	/* R/W 4 bits command */
     32#define DS1WM_DATA	0x01	/* R/W 8 bits, transmit/receive buffer */
     33#define DS1WM_INT	0x02	/* R/W interrupt status */
     34#define DS1WM_INT_EN	0x03	/* R/W interrupt enable */
     35#define DS1WM_CLKDIV	0x04	/* R/W 5 bits of divisor and pre-scale */
     36#define DS1WM_CNTRL	0x05	/* R/W master control register (not used yet) */
     37
     38#define DS1WM_CMD_1W_RESET  (1 << 0)	/* force reset on 1-wire bus */
     39#define DS1WM_CMD_SRA	    (1 << 1)	/* enable Search ROM accelerator mode */
     40#define DS1WM_CMD_DQ_OUTPUT (1 << 2)	/* write only - forces bus low */
     41#define DS1WM_CMD_DQ_INPUT  (1 << 3)	/* read only - reflects state of bus */
     42#define DS1WM_CMD_RST	    (1 << 5)	/* software reset */
     43#define DS1WM_CMD_OD	    (1 << 7)	/* overdrive */
     44
     45#define DS1WM_INT_PD	    (1 << 0)	/* presence detect */
     46#define DS1WM_INT_PDR	    (1 << 1)	/* presence detect result */
     47#define DS1WM_INT_TBE	    (1 << 2)	/* tx buffer empty */
     48#define DS1WM_INT_TSRE	    (1 << 3)	/* tx shift register empty */
     49#define DS1WM_INT_RBF	    (1 << 4)	/* rx buffer full */
     50#define DS1WM_INT_RSRF	    (1 << 5)	/* rx shift register full */
     51
     52#define DS1WM_INTEN_EPD	    (1 << 0)	/* enable presence detect int */
     53#define DS1WM_INTEN_IAS	    (1 << 1)	/* INTR active state */
     54#define DS1WM_INTEN_ETBE    (1 << 2)	/* enable tx buffer empty int */
     55#define DS1WM_INTEN_ETMT    (1 << 3)	/* enable tx shift register empty int */
     56#define DS1WM_INTEN_ERBF    (1 << 4)	/* enable rx buffer full int */
     57#define DS1WM_INTEN_ERSRF   (1 << 5)	/* enable rx shift register full int */
     58#define DS1WM_INTEN_DQO	    (1 << 6)	/* enable direct bus driving ops */
     59
     60#define DS1WM_INTEN_NOT_IAS (~DS1WM_INTEN_IAS)	/* all but INTR active state */
     61
     62#define DS1WM_TIMEOUT (HZ * 5)
     63
     64static struct {
     65	unsigned long freq;
     66	unsigned long divisor;
     67} freq[] = {
     68	{   1000000, 0x80 },
     69	{   2000000, 0x84 },
     70	{   3000000, 0x81 },
     71	{   4000000, 0x88 },
     72	{   5000000, 0x82 },
     73	{   6000000, 0x85 },
     74	{   7000000, 0x83 },
     75	{   8000000, 0x8c },
     76	{  10000000, 0x86 },
     77	{  12000000, 0x89 },
     78	{  14000000, 0x87 },
     79	{  16000000, 0x90 },
     80	{  20000000, 0x8a },
     81	{  24000000, 0x8d },
     82	{  28000000, 0x8b },
     83	{  32000000, 0x94 },
     84	{  40000000, 0x8e },
     85	{  48000000, 0x91 },
     86	{  56000000, 0x8f },
     87	{  64000000, 0x98 },
     88	{  80000000, 0x92 },
     89	{  96000000, 0x95 },
     90	{ 112000000, 0x93 },
     91	{ 128000000, 0x9c },
     92/* you can continue this table, consult the OPERATION - CLOCK DIVISOR
     93   section of the ds1wm spec sheet. */
     94};
     95
     96struct ds1wm_data {
     97	void     __iomem *map;
     98	unsigned int      bus_shift; /* # of shifts to calc register offsets */
     99	bool      is_hw_big_endian;
    100	struct platform_device *pdev;
    101	const struct mfd_cell   *cell;
    102	int      irq;
    103	int      slave_present;
    104	void     *reset_complete;
    105	void     *read_complete;
    106	void     *write_complete;
    107	int      read_error;
    108	/* last byte received */
    109	u8       read_byte;
    110	/* byte to write that makes all intr disabled, */
    111	/* considering active_state (IAS) (optimization) */
    112	u8       int_en_reg_none;
    113	unsigned int reset_recover_delay; /* see ds1wm.h */
    114};
    115
    116static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
    117					u8 val)
    118{
    119	if (ds1wm_data->is_hw_big_endian) {
    120		switch (ds1wm_data->bus_shift) {
    121		case 0:
    122			iowrite8(val, ds1wm_data->map + (reg << 0));
    123			break;
    124		case 1:
    125			iowrite16be((u16)val, ds1wm_data->map + (reg << 1));
    126			break;
    127		case 2:
    128			iowrite32be((u32)val, ds1wm_data->map + (reg << 2));
    129			break;
    130		}
    131	} else {
    132		switch (ds1wm_data->bus_shift) {
    133		case 0:
    134			iowrite8(val, ds1wm_data->map + (reg << 0));
    135			break;
    136		case 1:
    137			iowrite16((u16)val, ds1wm_data->map + (reg << 1));
    138			break;
    139		case 2:
    140			iowrite32((u32)val, ds1wm_data->map + (reg << 2));
    141			break;
    142		}
    143	}
    144}
    145
    146static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg)
    147{
    148	u32 val = 0;
    149
    150	if (ds1wm_data->is_hw_big_endian) {
    151		switch (ds1wm_data->bus_shift) {
    152		case 0:
    153			val = ioread8(ds1wm_data->map + (reg << 0));
    154			break;
    155		case 1:
    156			val = ioread16be(ds1wm_data->map + (reg << 1));
    157			break;
    158		case 2:
    159			val = ioread32be(ds1wm_data->map + (reg << 2));
    160			break;
    161		}
    162	} else {
    163		switch (ds1wm_data->bus_shift) {
    164		case 0:
    165			val = ioread8(ds1wm_data->map + (reg << 0));
    166			break;
    167		case 1:
    168			val = ioread16(ds1wm_data->map + (reg << 1));
    169			break;
    170		case 2:
    171			val = ioread32(ds1wm_data->map + (reg << 2));
    172			break;
    173		}
    174	}
    175	dev_dbg(&ds1wm_data->pdev->dev,
    176		"ds1wm_read_register reg: %d, 32 bit val:%x\n", reg, val);
    177	return (u8)val;
    178}
    179
    180
    181static irqreturn_t ds1wm_isr(int isr, void *data)
    182{
    183	struct ds1wm_data *ds1wm_data = data;
    184	u8 intr;
    185	u8 inten = ds1wm_read_register(ds1wm_data, DS1WM_INT_EN);
    186	/* if no bits are set in int enable register (except the IAS)
    187	than go no further, reading the regs below has side effects */
    188	if (!(inten & DS1WM_INTEN_NOT_IAS))
    189		return IRQ_NONE;
    190
    191	ds1wm_write_register(ds1wm_data,
    192		DS1WM_INT_EN, ds1wm_data->int_en_reg_none);
    193
    194	/* this read action clears the INTR and certain flags in ds1wm */
    195	intr = ds1wm_read_register(ds1wm_data, DS1WM_INT);
    196
    197	ds1wm_data->slave_present = (intr & DS1WM_INT_PDR) ? 0 : 1;
    198
    199	if ((intr & DS1WM_INT_TSRE) && ds1wm_data->write_complete) {
    200		inten &= ~DS1WM_INTEN_ETMT;
    201		complete(ds1wm_data->write_complete);
    202	}
    203	if (intr & DS1WM_INT_RBF) {
    204		/* this read clears the RBF flag */
    205		ds1wm_data->read_byte = ds1wm_read_register(ds1wm_data,
    206		DS1WM_DATA);
    207		inten &= ~DS1WM_INTEN_ERBF;
    208		if (ds1wm_data->read_complete)
    209			complete(ds1wm_data->read_complete);
    210	}
    211	if ((intr & DS1WM_INT_PD) && ds1wm_data->reset_complete) {
    212		inten &= ~DS1WM_INTEN_EPD;
    213		complete(ds1wm_data->reset_complete);
    214	}
    215
    216	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, inten);
    217	return IRQ_HANDLED;
    218}
    219
    220static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
    221{
    222	unsigned long timeleft;
    223	DECLARE_COMPLETION_ONSTACK(reset_done);
    224
    225	ds1wm_data->reset_complete = &reset_done;
    226
    227	/* enable Presence detect only */
    228	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, DS1WM_INTEN_EPD |
    229	ds1wm_data->int_en_reg_none);
    230
    231	ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_1W_RESET);
    232
    233	timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT);
    234	ds1wm_data->reset_complete = NULL;
    235	if (!timeleft) {
    236		dev_err(&ds1wm_data->pdev->dev, "reset failed, timed out\n");
    237		return 1;
    238	}
    239
    240	if (!ds1wm_data->slave_present) {
    241		dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n");
    242		return 1;
    243	}
    244
    245	if (ds1wm_data->reset_recover_delay)
    246		msleep(ds1wm_data->reset_recover_delay);
    247
    248	return 0;
    249}
    250
    251static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data)
    252{
    253	unsigned long timeleft;
    254	DECLARE_COMPLETION_ONSTACK(write_done);
    255	ds1wm_data->write_complete = &write_done;
    256
    257	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
    258	ds1wm_data->int_en_reg_none | DS1WM_INTEN_ETMT);
    259
    260	ds1wm_write_register(ds1wm_data, DS1WM_DATA, data);
    261
    262	timeleft = wait_for_completion_timeout(&write_done, DS1WM_TIMEOUT);
    263
    264	ds1wm_data->write_complete = NULL;
    265	if (!timeleft) {
    266		dev_err(&ds1wm_data->pdev->dev, "write failed, timed out\n");
    267		return -ETIMEDOUT;
    268	}
    269
    270	return 0;
    271}
    272
    273static u8 ds1wm_read(struct ds1wm_data *ds1wm_data, unsigned char write_data)
    274{
    275	unsigned long timeleft;
    276	u8 intEnable = DS1WM_INTEN_ERBF | ds1wm_data->int_en_reg_none;
    277	DECLARE_COMPLETION_ONSTACK(read_done);
    278
    279	ds1wm_read_register(ds1wm_data, DS1WM_DATA);
    280
    281	ds1wm_data->read_complete = &read_done;
    282	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, intEnable);
    283
    284	ds1wm_write_register(ds1wm_data, DS1WM_DATA, write_data);
    285	timeleft = wait_for_completion_timeout(&read_done, DS1WM_TIMEOUT);
    286
    287	ds1wm_data->read_complete = NULL;
    288	if (!timeleft) {
    289		dev_err(&ds1wm_data->pdev->dev, "read failed, timed out\n");
    290		ds1wm_data->read_error = -ETIMEDOUT;
    291		return 0xFF;
    292	}
    293	ds1wm_data->read_error = 0;
    294	return ds1wm_data->read_byte;
    295}
    296
    297static int ds1wm_find_divisor(int gclk)
    298{
    299	int i;
    300
    301	for (i = ARRAY_SIZE(freq)-1; i >= 0; --i)
    302		if (gclk >= freq[i].freq)
    303			return freq[i].divisor;
    304
    305	return 0;
    306}
    307
    308static void ds1wm_up(struct ds1wm_data *ds1wm_data)
    309{
    310	int divisor;
    311	struct device *dev = &ds1wm_data->pdev->dev;
    312	struct ds1wm_driver_data *plat = dev_get_platdata(dev);
    313
    314	if (ds1wm_data->cell->enable)
    315		ds1wm_data->cell->enable(ds1wm_data->pdev);
    316
    317	divisor = ds1wm_find_divisor(plat->clock_rate);
    318	dev_dbg(dev, "found divisor 0x%x for clock %d\n",
    319		divisor, plat->clock_rate);
    320	if (divisor == 0) {
    321		dev_err(dev, "no suitable divisor for %dHz clock\n",
    322			plat->clock_rate);
    323		return;
    324	}
    325	ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
    326
    327	/* Let the w1 clock stabilize. */
    328	msleep(1);
    329
    330	ds1wm_reset(ds1wm_data);
    331}
    332
    333static void ds1wm_down(struct ds1wm_data *ds1wm_data)
    334{
    335	ds1wm_reset(ds1wm_data);
    336
    337	/* Disable interrupts. */
    338	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
    339		ds1wm_data->int_en_reg_none);
    340
    341	if (ds1wm_data->cell->disable)
    342		ds1wm_data->cell->disable(ds1wm_data->pdev);
    343}
    344
    345/* --------------------------------------------------------------------- */
    346/* w1 methods */
    347
    348static u8 ds1wm_read_byte(void *data)
    349{
    350	struct ds1wm_data *ds1wm_data = data;
    351
    352	return ds1wm_read(ds1wm_data, 0xff);
    353}
    354
    355static void ds1wm_write_byte(void *data, u8 byte)
    356{
    357	struct ds1wm_data *ds1wm_data = data;
    358
    359	ds1wm_write(ds1wm_data, byte);
    360}
    361
    362static u8 ds1wm_reset_bus(void *data)
    363{
    364	struct ds1wm_data *ds1wm_data = data;
    365
    366	ds1wm_reset(ds1wm_data);
    367
    368	return 0;
    369}
    370
    371static void ds1wm_search(void *data, struct w1_master *master_dev,
    372			u8 search_type, w1_slave_found_callback slave_found)
    373{
    374	struct ds1wm_data *ds1wm_data = data;
    375	int i;
    376	int ms_discrep_bit = -1;
    377	u64 r = 0; /* holds the progress of the search */
    378	u64 r_prime, d;
    379	unsigned slaves_found = 0;
    380	unsigned int pass = 0;
    381
    382	dev_dbg(&ds1wm_data->pdev->dev, "search begin\n");
    383	while (true) {
    384		++pass;
    385		if (pass > 100) {
    386			dev_dbg(&ds1wm_data->pdev->dev,
    387				"too many attempts (100), search aborted\n");
    388			return;
    389		}
    390
    391		mutex_lock(&master_dev->bus_mutex);
    392		if (ds1wm_reset(ds1wm_data)) {
    393			mutex_unlock(&master_dev->bus_mutex);
    394			dev_dbg(&ds1wm_data->pdev->dev,
    395				"pass: %d reset error (or no slaves)\n", pass);
    396			break;
    397		}
    398
    399		dev_dbg(&ds1wm_data->pdev->dev,
    400			"pass: %d r : %0#18llx writing SEARCH_ROM\n", pass, r);
    401		ds1wm_write(ds1wm_data, search_type);
    402		dev_dbg(&ds1wm_data->pdev->dev,
    403			"pass: %d entering ASM\n", pass);
    404		ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_SRA);
    405		dev_dbg(&ds1wm_data->pdev->dev,
    406			"pass: %d beginning nibble loop\n", pass);
    407
    408		r_prime = 0;
    409		d = 0;
    410		/* we work one nibble at a time */
    411		/* each nibble is interleaved to form a byte */
    412		for (i = 0; i < 16; i++) {
    413
    414			unsigned char resp, _r, _r_prime, _d;
    415
    416			_r = (r >> (4*i)) & 0xf;
    417			_r = ((_r & 0x1) << 1) |
    418			((_r & 0x2) << 2) |
    419			((_r & 0x4) << 3) |
    420			((_r & 0x8) << 4);
    421
    422			/* writes _r, then reads back: */
    423			resp = ds1wm_read(ds1wm_data, _r);
    424
    425			if (ds1wm_data->read_error) {
    426				dev_err(&ds1wm_data->pdev->dev,
    427				"pass: %d nibble: %d read error\n", pass, i);
    428				break;
    429			}
    430
    431			_r_prime = ((resp & 0x02) >> 1) |
    432			((resp & 0x08) >> 2) |
    433			((resp & 0x20) >> 3) |
    434			((resp & 0x80) >> 4);
    435
    436			_d = ((resp & 0x01) >> 0) |
    437			((resp & 0x04) >> 1) |
    438			((resp & 0x10) >> 2) |
    439			((resp & 0x40) >> 3);
    440
    441			r_prime |= (unsigned long long) _r_prime << (i * 4);
    442			d |= (unsigned long long) _d << (i * 4);
    443
    444		}
    445		if (ds1wm_data->read_error) {
    446			mutex_unlock(&master_dev->bus_mutex);
    447			dev_err(&ds1wm_data->pdev->dev,
    448				"pass: %d read error, retrying\n", pass);
    449			break;
    450		}
    451		dev_dbg(&ds1wm_data->pdev->dev,
    452			"pass: %d r\': %0#18llx d:%0#18llx\n",
    453			pass, r_prime, d);
    454		dev_dbg(&ds1wm_data->pdev->dev,
    455			"pass: %d nibble loop complete, exiting ASM\n", pass);
    456		ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
    457		dev_dbg(&ds1wm_data->pdev->dev,
    458			"pass: %d resetting bus\n", pass);
    459		ds1wm_reset(ds1wm_data);
    460		mutex_unlock(&master_dev->bus_mutex);
    461		if ((r_prime & ((u64)1 << 63)) && (d & ((u64)1 << 63))) {
    462			dev_err(&ds1wm_data->pdev->dev,
    463				"pass: %d bus error, retrying\n", pass);
    464			continue; /* start over */
    465		}
    466
    467
    468		dev_dbg(&ds1wm_data->pdev->dev,
    469			"pass: %d found %0#18llx\n", pass, r_prime);
    470		slave_found(master_dev, r_prime);
    471		++slaves_found;
    472		dev_dbg(&ds1wm_data->pdev->dev,
    473			"pass: %d complete, preparing next pass\n", pass);
    474
    475		/* any discrepency found which we already choose the
    476		   '1' branch is now is now irrelevant we reveal the
    477		   next branch with this: */
    478		d &= ~r;
    479		/* find last bit set, i.e. the most signif. bit set */
    480		ms_discrep_bit = fls64(d) - 1;
    481		dev_dbg(&ds1wm_data->pdev->dev,
    482			"pass: %d new d:%0#18llx MS discrep bit:%d\n",
    483			pass, d, ms_discrep_bit);
    484
    485		/* prev_ms_discrep_bit = ms_discrep_bit;
    486		   prepare for next ROM search:		    */
    487		if (ms_discrep_bit == -1)
    488			break;
    489
    490		r = (r &  ~(~0ull << (ms_discrep_bit))) | 1 << ms_discrep_bit;
    491	} /* end while true */
    492	dev_dbg(&ds1wm_data->pdev->dev,
    493		"pass: %d total: %d search done ms d bit pos: %d\n", pass,
    494		slaves_found, ms_discrep_bit);
    495}
    496
    497/* --------------------------------------------------------------------- */
    498
    499static struct w1_bus_master ds1wm_master = {
    500	.read_byte  = ds1wm_read_byte,
    501	.write_byte = ds1wm_write_byte,
    502	.reset_bus  = ds1wm_reset_bus,
    503	.search	    = ds1wm_search,
    504};
    505
    506static int ds1wm_probe(struct platform_device *pdev)
    507{
    508	struct ds1wm_data *ds1wm_data;
    509	struct ds1wm_driver_data *plat;
    510	struct resource *res;
    511	int ret;
    512	u8 inten;
    513
    514	if (!pdev)
    515		return -ENODEV;
    516
    517	ds1wm_data = devm_kzalloc(&pdev->dev, sizeof(*ds1wm_data), GFP_KERNEL);
    518	if (!ds1wm_data)
    519		return -ENOMEM;
    520
    521	platform_set_drvdata(pdev, ds1wm_data);
    522
    523	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    524	if (!res)
    525		return -ENXIO;
    526	ds1wm_data->map = devm_ioremap(&pdev->dev, res->start,
    527				       resource_size(res));
    528	if (!ds1wm_data->map)
    529		return -ENOMEM;
    530
    531	ds1wm_data->pdev = pdev;
    532	ds1wm_data->cell = mfd_get_cell(pdev);
    533	if (!ds1wm_data->cell)
    534		return -ENODEV;
    535	plat = dev_get_platdata(&pdev->dev);
    536	if (!plat)
    537		return -ENODEV;
    538
    539	/* how many bits to shift register number to get register offset */
    540	if (plat->bus_shift > 2) {
    541		dev_err(&ds1wm_data->pdev->dev,
    542			"illegal bus shift %d, not written",
    543			ds1wm_data->bus_shift);
    544		return -EINVAL;
    545	}
    546
    547	ds1wm_data->bus_shift = plat->bus_shift;
    548	/* make sure resource has space for 8 registers */
    549	if ((8 << ds1wm_data->bus_shift) > resource_size(res)) {
    550		dev_err(&ds1wm_data->pdev->dev,
    551			"memory resource size %d to small, should be %d\n",
    552			(int)resource_size(res),
    553			8 << ds1wm_data->bus_shift);
    554		return -EINVAL;
    555	}
    556
    557	ds1wm_data->is_hw_big_endian = plat->is_hw_big_endian;
    558
    559	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    560	if (!res)
    561		return -ENXIO;
    562	ds1wm_data->irq = res->start;
    563	ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0);
    564	ds1wm_data->reset_recover_delay = plat->reset_recover_delay;
    565
    566	/* Mask interrupts, set IAS before claiming interrupt */
    567	inten = ds1wm_read_register(ds1wm_data, DS1WM_INT_EN);
    568	ds1wm_write_register(ds1wm_data,
    569		DS1WM_INT_EN, ds1wm_data->int_en_reg_none);
    570
    571	if (res->flags & IORESOURCE_IRQ_HIGHEDGE)
    572		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING);
    573	if (res->flags & IORESOURCE_IRQ_LOWEDGE)
    574		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
    575	if (res->flags & IORESOURCE_IRQ_HIGHLEVEL)
    576		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_HIGH);
    577	if (res->flags & IORESOURCE_IRQ_LOWLEVEL)
    578		irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_LOW);
    579
    580	ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr,
    581			IRQF_SHARED, "ds1wm", ds1wm_data);
    582	if (ret) {
    583		dev_err(&ds1wm_data->pdev->dev,
    584			"devm_request_irq %d failed with errno %d\n",
    585			ds1wm_data->irq,
    586			ret);
    587
    588		return ret;
    589	}
    590
    591	ds1wm_up(ds1wm_data);
    592
    593	ds1wm_master.data = (void *)ds1wm_data;
    594
    595	ret = w1_add_master_device(&ds1wm_master);
    596	if (ret)
    597		goto err;
    598
    599	dev_dbg(&ds1wm_data->pdev->dev,
    600		"ds1wm: probe successful, IAS: %d, rec.delay: %d, clockrate: %d, bus-shift: %d, is Hw Big Endian: %d\n",
    601		plat->active_high,
    602		plat->reset_recover_delay,
    603		plat->clock_rate,
    604		ds1wm_data->bus_shift,
    605		ds1wm_data->is_hw_big_endian);
    606	return 0;
    607
    608err:
    609	ds1wm_down(ds1wm_data);
    610
    611	return ret;
    612}
    613
    614#ifdef CONFIG_PM
    615static int ds1wm_suspend(struct platform_device *pdev, pm_message_t state)
    616{
    617	struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
    618
    619	ds1wm_down(ds1wm_data);
    620
    621	return 0;
    622}
    623
    624static int ds1wm_resume(struct platform_device *pdev)
    625{
    626	struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
    627
    628	ds1wm_up(ds1wm_data);
    629
    630	return 0;
    631}
    632#else
    633#define ds1wm_suspend NULL
    634#define ds1wm_resume NULL
    635#endif
    636
    637static int ds1wm_remove(struct platform_device *pdev)
    638{
    639	struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
    640
    641	w1_remove_master_device(&ds1wm_master);
    642	ds1wm_down(ds1wm_data);
    643
    644	return 0;
    645}
    646
    647static struct platform_driver ds1wm_driver = {
    648	.driver   = {
    649		.name = "ds1wm",
    650	},
    651	.probe    = ds1wm_probe,
    652	.remove   = ds1wm_remove,
    653	.suspend  = ds1wm_suspend,
    654	.resume   = ds1wm_resume
    655};
    656
    657static int __init ds1wm_init(void)
    658{
    659	pr_info("DS1WM w1 busmaster driver - (c) 2004 Szabolcs Gyurko\n");
    660	return platform_driver_register(&ds1wm_driver);
    661}
    662
    663static void __exit ds1wm_exit(void)
    664{
    665	platform_driver_unregister(&ds1wm_driver);
    666}
    667
    668module_init(ds1wm_init);
    669module_exit(ds1wm_exit);
    670
    671MODULE_LICENSE("GPL");
    672MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
    673	"Matt Reimer <mreimer@vpop.net>,"
    674	"Jean-Francois Dagenais <dagenaisj@sonatest.com>");
    675MODULE_DESCRIPTION("DS1WM w1 busmaster driver");