Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: driver for the Synopsys DesignWare I2C controller

The i2c Linux driver for the DesignWare i2c block of Synopsys, which is meant
for AMBA Peripheral Bus. This i2c block is used on SoC chips like the ARM9
based PVG610.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>

authored by

Baruch Siach and committed by
Ben Dooks
1ab52cf9 d888a4c7

+634
+9
drivers/i2c/busses/Kconfig
··· 326 326 devices such as DaVinci NIC. 327 327 For details please see http://www.ti.com/davinci 328 328 329 + config I2C_DESIGNWARE 330 + tristate "Synopsys DesignWare" 331 + help 332 + If you say yes to this option, support will be included for the 333 + Synopsys DesignWare I2C adapter. Only master mode is supported. 334 + 335 + This driver can also be built as a module. If so, the module 336 + will be called i2c-designware. 337 + 329 338 config I2C_GPIO 330 339 tristate "GPIO-based bitbanging I2C" 331 340 depends on GENERIC_GPIO
+1
drivers/i2c/busses/Makefile
··· 30 30 obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o 31 31 obj-$(CONFIG_I2C_CPM) += i2c-cpm.o 32 32 obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o 33 + obj-$(CONFIG_I2C_DESIGNWARE) += i2c-designware.o 33 34 obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o 34 35 obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o 35 36 obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
+624
drivers/i2c/busses/i2c-designware.c
··· 1 + /* 2 + * Synopsys Designware I2C adapter driver (master only). 3 + * 4 + * Based on the TI DAVINCI I2C adapter driver. 5 + * 6 + * Copyright (C) 2006 Texas Instruments. 7 + * Copyright (C) 2007 MontaVista Software Inc. 8 + * Copyright (C) 2009 Provigent Ltd. 9 + * 10 + * ---------------------------------------------------------------------------- 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License as published by 14 + * the Free Software Foundation; either version 2 of the License, or 15 + * (at your option) any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + * 22 + * You should have received a copy of the GNU General Public License 23 + * along with this program; if not, write to the Free Software 24 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 + * ---------------------------------------------------------------------------- 26 + * 27 + */ 28 + #include <linux/kernel.h> 29 + #include <linux/module.h> 30 + #include <linux/delay.h> 31 + #include <linux/i2c.h> 32 + #include <linux/clk.h> 33 + #include <linux/errno.h> 34 + #include <linux/sched.h> 35 + #include <linux/err.h> 36 + #include <linux/interrupt.h> 37 + #include <linux/platform_device.h> 38 + #include <linux/io.h> 39 + 40 + /* 41 + * Registers offset 42 + */ 43 + #define DW_IC_CON 0x0 44 + #define DW_IC_TAR 0x4 45 + #define DW_IC_DATA_CMD 0x10 46 + #define DW_IC_SS_SCL_HCNT 0x14 47 + #define DW_IC_SS_SCL_LCNT 0x18 48 + #define DW_IC_FS_SCL_HCNT 0x1c 49 + #define DW_IC_FS_SCL_LCNT 0x20 50 + #define DW_IC_INTR_STAT 0x2c 51 + #define DW_IC_INTR_MASK 0x30 52 + #define DW_IC_CLR_INTR 0x40 53 + #define DW_IC_ENABLE 0x6c 54 + #define DW_IC_STATUS 0x70 55 + #define DW_IC_TXFLR 0x74 56 + #define DW_IC_RXFLR 0x78 57 + #define DW_IC_COMP_PARAM_1 0xf4 58 + #define DW_IC_TX_ABRT_SOURCE 0x80 59 + 60 + #define DW_IC_CON_MASTER 0x1 61 + #define DW_IC_CON_SPEED_STD 0x2 62 + #define DW_IC_CON_SPEED_FAST 0x4 63 + #define DW_IC_CON_10BITADDR_MASTER 0x10 64 + #define DW_IC_CON_RESTART_EN 0x20 65 + #define DW_IC_CON_SLAVE_DISABLE 0x40 66 + 67 + #define DW_IC_INTR_TX_EMPTY 0x10 68 + #define DW_IC_INTR_TX_ABRT 0x40 69 + #define DW_IC_INTR_STOP_DET 0x200 70 + 71 + #define DW_IC_STATUS_ACTIVITY 0x1 72 + 73 + #define DW_IC_ERR_TX_ABRT 0x1 74 + 75 + /* 76 + * status codes 77 + */ 78 + #define STATUS_IDLE 0x0 79 + #define STATUS_WRITE_IN_PROGRESS 0x1 80 + #define STATUS_READ_IN_PROGRESS 0x2 81 + 82 + #define TIMEOUT 20 /* ms */ 83 + 84 + /* 85 + * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register 86 + * 87 + * only expected abort codes are listed here 88 + * refer to the datasheet for the full list 89 + */ 90 + #define ABRT_7B_ADDR_NOACK 0 91 + #define ABRT_10ADDR1_NOACK 1 92 + #define ABRT_10ADDR2_NOACK 2 93 + #define ABRT_TXDATA_NOACK 3 94 + #define ABRT_GCALL_NOACK 4 95 + #define ABRT_GCALL_READ 5 96 + #define ABRT_SBYTE_ACKDET 7 97 + #define ABRT_SBYTE_NORSTRT 9 98 + #define ABRT_10B_RD_NORSTRT 10 99 + #define ARB_MASTER_DIS 11 100 + #define ARB_LOST 12 101 + 102 + static char *abort_sources[] = { 103 + [ABRT_7B_ADDR_NOACK] = 104 + "slave address not acknowledged (7bit mode)", 105 + [ABRT_10ADDR1_NOACK] = 106 + "first address byte not acknowledged (10bit mode)", 107 + [ABRT_10ADDR2_NOACK] = 108 + "second address byte not acknowledged (10bit mode)", 109 + [ABRT_TXDATA_NOACK] = 110 + "data not acknowledged", 111 + [ABRT_GCALL_NOACK] = 112 + "no acknowledgement for a general call", 113 + [ABRT_GCALL_READ] = 114 + "read after general call", 115 + [ABRT_SBYTE_ACKDET] = 116 + "start byte acknowledged", 117 + [ABRT_SBYTE_NORSTRT] = 118 + "trying to send start byte when restart is disabled", 119 + [ABRT_10B_RD_NORSTRT] = 120 + "trying to read when restart is disabled (10bit mode)", 121 + [ARB_MASTER_DIS] = 122 + "trying to use disabled adapter", 123 + [ARB_LOST] = 124 + "lost arbitration", 125 + }; 126 + 127 + /** 128 + * struct dw_i2c_dev - private i2c-designware data 129 + * @dev: driver model device node 130 + * @base: IO registers pointer 131 + * @cmd_complete: tx completion indicator 132 + * @pump_msg: continue in progress transfers 133 + * @lock: protect this struct and IO registers 134 + * @clk: input reference clock 135 + * @cmd_err: run time hadware error code 136 + * @msgs: points to an array of messages currently being transfered 137 + * @msgs_num: the number of elements in msgs 138 + * @msg_write_idx: the element index of the current tx message in the msgs 139 + * array 140 + * @tx_buf_len: the length of the current tx buffer 141 + * @tx_buf: the current tx buffer 142 + * @msg_read_idx: the element index of the current rx message in the msgs 143 + * array 144 + * @rx_buf_len: the length of the current rx buffer 145 + * @rx_buf: the current rx buffer 146 + * @msg_err: error status of the current transfer 147 + * @status: i2c master status, one of STATUS_* 148 + * @abort_source: copy of the TX_ABRT_SOURCE register 149 + * @irq: interrupt number for the i2c master 150 + * @adapter: i2c subsystem adapter node 151 + * @tx_fifo_depth: depth of the hardware tx fifo 152 + * @rx_fifo_depth: depth of the hardware rx fifo 153 + */ 154 + struct dw_i2c_dev { 155 + struct device *dev; 156 + void __iomem *base; 157 + struct completion cmd_complete; 158 + struct tasklet_struct pump_msg; 159 + struct mutex lock; 160 + struct clk *clk; 161 + int cmd_err; 162 + struct i2c_msg *msgs; 163 + int msgs_num; 164 + int msg_write_idx; 165 + u16 tx_buf_len; 166 + u8 *tx_buf; 167 + int msg_read_idx; 168 + u16 rx_buf_len; 169 + u8 *rx_buf; 170 + int msg_err; 171 + unsigned int status; 172 + u16 abort_source; 173 + int irq; 174 + struct i2c_adapter adapter; 175 + unsigned int tx_fifo_depth; 176 + unsigned int rx_fifo_depth; 177 + }; 178 + 179 + /** 180 + * i2c_dw_init() - initialize the designware i2c master hardware 181 + * @dev: device private data 182 + * 183 + * This functions configures and enables the I2C master. 184 + * This function is called during I2C init function, and in case of timeout at 185 + * run time. 186 + */ 187 + static void i2c_dw_init(struct dw_i2c_dev *dev) 188 + { 189 + u32 input_clock_khz = clk_get_rate(dev->clk) / 1000; 190 + u16 ic_con; 191 + 192 + /* Disable the adapter */ 193 + writeb(0, dev->base + DW_IC_ENABLE); 194 + 195 + /* set standard and fast speed deviders for high/low periods */ 196 + writew((input_clock_khz * 40 / 10000)+1, /* std speed high, 4us */ 197 + dev->base + DW_IC_SS_SCL_HCNT); 198 + writew((input_clock_khz * 47 / 10000)+1, /* std speed low, 4.7us */ 199 + dev->base + DW_IC_SS_SCL_LCNT); 200 + writew((input_clock_khz * 6 / 10000)+1, /* fast speed high, 0.6us */ 201 + dev->base + DW_IC_FS_SCL_HCNT); 202 + writew((input_clock_khz * 13 / 10000)+1, /* fast speed low, 1.3us */ 203 + dev->base + DW_IC_FS_SCL_LCNT); 204 + 205 + /* configure the i2c master */ 206 + ic_con = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | 207 + DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; 208 + writew(ic_con, dev->base + DW_IC_CON); 209 + } 210 + 211 + /* 212 + * Waiting for bus not busy 213 + */ 214 + static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) 215 + { 216 + int timeout = TIMEOUT; 217 + 218 + while (readb(dev->base + DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { 219 + if (timeout <= 0) { 220 + dev_warn(dev->dev, "timeout waiting for bus ready\n"); 221 + return -ETIMEDOUT; 222 + } 223 + timeout--; 224 + mdelay(1); 225 + } 226 + 227 + return 0; 228 + } 229 + 230 + /* 231 + * Initiate low level master read/write transaction. 232 + * This function is called from i2c_dw_xfer when starting a transfer. 233 + * This function is also called from dw_i2c_pump_msg to continue a transfer 234 + * that is longer than the size of the TX FIFO. 235 + */ 236 + static void 237 + i2c_dw_xfer_msg(struct i2c_adapter *adap) 238 + { 239 + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 240 + struct i2c_msg *msgs = dev->msgs; 241 + int num = dev->msgs_num; 242 + u16 ic_con, intr_mask; 243 + int tx_limit = dev->tx_fifo_depth - readb(dev->base + DW_IC_TXFLR); 244 + int rx_limit = dev->rx_fifo_depth - readb(dev->base + DW_IC_RXFLR); 245 + u16 addr = msgs[dev->msg_write_idx].addr; 246 + u16 buf_len = dev->tx_buf_len; 247 + 248 + if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { 249 + /* Disable the adapter */ 250 + writeb(0, dev->base + DW_IC_ENABLE); 251 + 252 + /* set the slave (target) address */ 253 + writew(msgs[dev->msg_write_idx].addr, dev->base + DW_IC_TAR); 254 + 255 + /* if the slave address is ten bit address, enable 10BITADDR */ 256 + ic_con = readw(dev->base + DW_IC_CON); 257 + if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) 258 + ic_con |= DW_IC_CON_10BITADDR_MASTER; 259 + else 260 + ic_con &= ~DW_IC_CON_10BITADDR_MASTER; 261 + writew(ic_con, dev->base + DW_IC_CON); 262 + 263 + /* Enable the adapter */ 264 + writeb(1, dev->base + DW_IC_ENABLE); 265 + } 266 + 267 + for (; dev->msg_write_idx < num; dev->msg_write_idx++) { 268 + /* if target address has changed, we need to 269 + * reprogram the target address in the i2c 270 + * adapter when we are done with this transfer 271 + */ 272 + if (msgs[dev->msg_write_idx].addr != addr) 273 + return; 274 + 275 + if (msgs[dev->msg_write_idx].len == 0) { 276 + dev_err(dev->dev, 277 + "%s: invalid message length\n", __func__); 278 + dev->msg_err = -EINVAL; 279 + return; 280 + } 281 + 282 + if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { 283 + /* new i2c_msg */ 284 + dev->tx_buf = msgs[dev->msg_write_idx].buf; 285 + buf_len = msgs[dev->msg_write_idx].len; 286 + } 287 + 288 + while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { 289 + if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { 290 + writew(0x100, dev->base + DW_IC_DATA_CMD); 291 + rx_limit--; 292 + } else 293 + writew(*(dev->tx_buf++), 294 + dev->base + DW_IC_DATA_CMD); 295 + tx_limit--; buf_len--; 296 + } 297 + } 298 + 299 + intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT; 300 + if (buf_len > 0) { /* more bytes to be written */ 301 + intr_mask |= DW_IC_INTR_TX_EMPTY; 302 + dev->status |= STATUS_WRITE_IN_PROGRESS; 303 + } else 304 + dev->status &= ~STATUS_WRITE_IN_PROGRESS; 305 + writew(intr_mask, dev->base + DW_IC_INTR_MASK); 306 + 307 + dev->tx_buf_len = buf_len; 308 + } 309 + 310 + static void 311 + i2c_dw_read(struct i2c_adapter *adap) 312 + { 313 + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 314 + struct i2c_msg *msgs = dev->msgs; 315 + int num = dev->msgs_num; 316 + u16 addr = msgs[dev->msg_read_idx].addr; 317 + int rx_valid = readw(dev->base + DW_IC_RXFLR); 318 + 319 + for (; dev->msg_read_idx < num; dev->msg_read_idx++) { 320 + u16 len; 321 + u8 *buf; 322 + 323 + if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) 324 + continue; 325 + 326 + /* different i2c client, reprogram the i2c adapter */ 327 + if (msgs[dev->msg_read_idx].addr != addr) 328 + return; 329 + 330 + if (!(dev->status & STATUS_READ_IN_PROGRESS)) { 331 + len = msgs[dev->msg_read_idx].len; 332 + buf = msgs[dev->msg_read_idx].buf; 333 + } else { 334 + len = dev->rx_buf_len; 335 + buf = dev->rx_buf; 336 + } 337 + 338 + for (; len > 0 && rx_valid > 0; len--, rx_valid--) 339 + *buf++ = readb(dev->base + DW_IC_DATA_CMD); 340 + 341 + if (len > 0) { 342 + dev->status |= STATUS_READ_IN_PROGRESS; 343 + dev->rx_buf_len = len; 344 + dev->rx_buf = buf; 345 + return; 346 + } else 347 + dev->status &= ~STATUS_READ_IN_PROGRESS; 348 + } 349 + } 350 + 351 + /* 352 + * Prepare controller for a transaction and call i2c_dw_xfer_msg 353 + */ 354 + static int 355 + i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) 356 + { 357 + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 358 + int ret; 359 + 360 + dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); 361 + 362 + mutex_lock(&dev->lock); 363 + 364 + INIT_COMPLETION(dev->cmd_complete); 365 + dev->msgs = msgs; 366 + dev->msgs_num = num; 367 + dev->cmd_err = 0; 368 + dev->msg_write_idx = 0; 369 + dev->msg_read_idx = 0; 370 + dev->msg_err = 0; 371 + dev->status = STATUS_IDLE; 372 + 373 + ret = i2c_dw_wait_bus_not_busy(dev); 374 + if (ret < 0) 375 + goto done; 376 + 377 + /* start the transfers */ 378 + i2c_dw_xfer_msg(adap); 379 + 380 + /* wait for tx to complete */ 381 + ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ); 382 + if (ret == 0) { 383 + dev_err(dev->dev, "controller timed out\n"); 384 + i2c_dw_init(dev); 385 + ret = -ETIMEDOUT; 386 + goto done; 387 + } else if (ret < 0) 388 + goto done; 389 + 390 + if (dev->msg_err) { 391 + ret = dev->msg_err; 392 + goto done; 393 + } 394 + 395 + /* no error */ 396 + if (likely(!dev->cmd_err)) { 397 + /* read rx fifo, and disable the adapter */ 398 + do { 399 + i2c_dw_read(adap); 400 + } while (dev->status & STATUS_READ_IN_PROGRESS); 401 + writeb(0, dev->base + DW_IC_ENABLE); 402 + ret = num; 403 + goto done; 404 + } 405 + 406 + /* We have an error */ 407 + if (dev->cmd_err == DW_IC_ERR_TX_ABRT) { 408 + unsigned long abort_source = dev->abort_source; 409 + int i; 410 + 411 + for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) { 412 + dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); 413 + } 414 + } 415 + ret = -EIO; 416 + 417 + done: 418 + mutex_unlock(&dev->lock); 419 + 420 + return ret; 421 + } 422 + 423 + static u32 i2c_dw_func(struct i2c_adapter *adap) 424 + { 425 + return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; 426 + } 427 + 428 + static void dw_i2c_pump_msg(unsigned long data) 429 + { 430 + struct dw_i2c_dev *dev = (struct dw_i2c_dev *) data; 431 + u16 intr_mask; 432 + 433 + i2c_dw_read(&dev->adapter); 434 + i2c_dw_xfer_msg(&dev->adapter); 435 + 436 + intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT; 437 + if (dev->status & STATUS_WRITE_IN_PROGRESS) 438 + intr_mask |= DW_IC_INTR_TX_EMPTY; 439 + writew(intr_mask, dev->base + DW_IC_INTR_MASK); 440 + } 441 + 442 + /* 443 + * Interrupt service routine. This gets called whenever an I2C interrupt 444 + * occurs. 445 + */ 446 + static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) 447 + { 448 + struct dw_i2c_dev *dev = dev_id; 449 + u16 stat; 450 + 451 + stat = readw(dev->base + DW_IC_INTR_STAT); 452 + dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat); 453 + if (stat & DW_IC_INTR_TX_ABRT) { 454 + dev->abort_source = readw(dev->base + DW_IC_TX_ABRT_SOURCE); 455 + dev->cmd_err |= DW_IC_ERR_TX_ABRT; 456 + dev->status = STATUS_IDLE; 457 + } else if (stat & DW_IC_INTR_TX_EMPTY) 458 + tasklet_schedule(&dev->pump_msg); 459 + 460 + readb(dev->base + DW_IC_CLR_INTR); /* clear interrupts */ 461 + writew(0, dev->base + DW_IC_INTR_MASK); /* disable interrupts */ 462 + if (stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) 463 + complete(&dev->cmd_complete); 464 + 465 + return IRQ_HANDLED; 466 + } 467 + 468 + static struct i2c_algorithm i2c_dw_algo = { 469 + .master_xfer = i2c_dw_xfer, 470 + .functionality = i2c_dw_func, 471 + }; 472 + 473 + static int __devinit dw_i2c_probe(struct platform_device *pdev) 474 + { 475 + struct dw_i2c_dev *dev; 476 + struct i2c_adapter *adap; 477 + struct resource *mem, *irq, *ioarea; 478 + int r; 479 + 480 + /* NOTE: driver uses the static register mapping */ 481 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 482 + if (!mem) { 483 + dev_err(&pdev->dev, "no mem resource?\n"); 484 + return -EINVAL; 485 + } 486 + 487 + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 488 + if (!irq) { 489 + dev_err(&pdev->dev, "no irq resource?\n"); 490 + return -EINVAL; 491 + } 492 + 493 + ioarea = request_mem_region(mem->start, resource_size(mem), 494 + pdev->name); 495 + if (!ioarea) { 496 + dev_err(&pdev->dev, "I2C region already claimed\n"); 497 + return -EBUSY; 498 + } 499 + 500 + dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL); 501 + if (!dev) { 502 + r = -ENOMEM; 503 + goto err_release_region; 504 + } 505 + 506 + init_completion(&dev->cmd_complete); 507 + tasklet_init(&dev->pump_msg, dw_i2c_pump_msg, (unsigned long) dev); 508 + mutex_init(&dev->lock); 509 + dev->dev = get_device(&pdev->dev); 510 + dev->irq = irq->start; 511 + platform_set_drvdata(pdev, dev); 512 + 513 + dev->clk = clk_get(&pdev->dev, NULL); 514 + if (IS_ERR(dev->clk)) { 515 + r = -ENODEV; 516 + goto err_free_mem; 517 + } 518 + clk_enable(dev->clk); 519 + 520 + dev->base = ioremap(mem->start, resource_size(mem)); 521 + if (dev->base == NULL) { 522 + dev_err(&pdev->dev, "failure mapping io resources\n"); 523 + r = -EBUSY; 524 + goto err_unuse_clocks; 525 + } 526 + { 527 + u32 param1 = readl(dev->base + DW_IC_COMP_PARAM_1); 528 + 529 + dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1; 530 + dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1; 531 + } 532 + i2c_dw_init(dev); 533 + 534 + writew(0, dev->base + DW_IC_INTR_MASK); /* disable IRQ */ 535 + r = request_irq(dev->irq, i2c_dw_isr, 0, pdev->name, dev); 536 + if (r) { 537 + dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); 538 + goto err_iounmap; 539 + } 540 + 541 + adap = &dev->adapter; 542 + i2c_set_adapdata(adap, dev); 543 + adap->owner = THIS_MODULE; 544 + adap->class = I2C_CLASS_HWMON; 545 + strlcpy(adap->name, "Synopsys DesignWare I2C adapter", 546 + sizeof(adap->name)); 547 + adap->algo = &i2c_dw_algo; 548 + adap->dev.parent = &pdev->dev; 549 + 550 + adap->nr = pdev->id; 551 + r = i2c_add_numbered_adapter(adap); 552 + if (r) { 553 + dev_err(&pdev->dev, "failure adding adapter\n"); 554 + goto err_free_irq; 555 + } 556 + 557 + return 0; 558 + 559 + err_free_irq: 560 + free_irq(dev->irq, dev); 561 + err_iounmap: 562 + iounmap(dev->base); 563 + err_unuse_clocks: 564 + clk_disable(dev->clk); 565 + clk_put(dev->clk); 566 + dev->clk = NULL; 567 + err_free_mem: 568 + platform_set_drvdata(pdev, NULL); 569 + put_device(&pdev->dev); 570 + kfree(dev); 571 + err_release_region: 572 + release_mem_region(mem->start, resource_size(mem)); 573 + 574 + return r; 575 + } 576 + 577 + static int __devexit dw_i2c_remove(struct platform_device *pdev) 578 + { 579 + struct dw_i2c_dev *dev = platform_get_drvdata(pdev); 580 + struct resource *mem; 581 + 582 + platform_set_drvdata(pdev, NULL); 583 + i2c_del_adapter(&dev->adapter); 584 + put_device(&pdev->dev); 585 + 586 + clk_disable(dev->clk); 587 + clk_put(dev->clk); 588 + dev->clk = NULL; 589 + 590 + writeb(0, dev->base + DW_IC_ENABLE); 591 + free_irq(dev->irq, dev); 592 + kfree(dev); 593 + 594 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 595 + release_mem_region(mem->start, resource_size(mem)); 596 + return 0; 597 + } 598 + 599 + /* work with hotplug and coldplug */ 600 + MODULE_ALIAS("platform:i2c_designware"); 601 + 602 + static struct platform_driver dw_i2c_driver = { 603 + .remove = __devexit_p(dw_i2c_remove), 604 + .driver = { 605 + .name = "i2c_designware", 606 + .owner = THIS_MODULE, 607 + }, 608 + }; 609 + 610 + static int __init dw_i2c_init_driver(void) 611 + { 612 + return platform_driver_probe(&dw_i2c_driver, dw_i2c_probe); 613 + } 614 + module_init(dw_i2c_init_driver); 615 + 616 + static void __exit dw_i2c_exit_driver(void) 617 + { 618 + platform_driver_unregister(&dw_i2c_driver); 619 + } 620 + module_exit(dw_i2c_exit_driver); 621 + 622 + MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); 623 + MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter"); 624 + MODULE_LICENSE("GPL");