brcm2708: update linux 4.4 patches to latest version
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0045-Add-Chris-Boot-s-i2c-driver.patch
1 From b78bc1bb96c2db043c3be03c1bcccefa22621543 Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Wed, 17 Jun 2015 15:44:08 +0100
4 Subject: [PATCH] Add Chris Boot's i2c driver
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 i2c-bcm2708: fixed baudrate
10
11 Fixed issue where the wrong CDIV value was set for baudrates below 3815 Hz (for 250MHz bus clock).
12 In that case the computed CDIV value was more than 0xffff. However the CDIV register width is only 16 bits.
13 This resulted in incorrect setting of CDIV and higher baudrate than intended.
14 Example: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0x1704 -> 42430Hz
15 After correction: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0xffff -> 3815Hz
16 The correct baudrate is shown in the log after the cdiv > 0xffff correction.
17
18 Perform I2C combined transactions when possible
19
20 Perform I2C combined transactions whenever possible, within the
21 restrictions of the Broadcomm Serial Controller.
22
23 Disable DONE interrupt during TA poll
24
25 Prevent interrupt from being triggered if poll is missed and transfer
26 starts and finishes.
27
28 i2c: Make combined transactions optional and disabled by default
29
30 i2c: bcm2708: add device tree support
31
32 Add DT support to driver and add to .dtsi file.
33 Setup pins in .dts file.
34 i2c is disabled by default.
35
36 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
37
38 bcm2708: don't register i2c controllers when using DT
39
40 The devices for the i2c controllers are in the Device Tree.
41 Only register devices when not using DT.
42
43 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
44
45 I2C: Only register the I2C device for the current board revision
46
47 i2c_bcm2708: Fix clock reference counting
48
49 Fix grabbing lock from atomic context in i2c driver
50
51 2 main changes:
52 - check for timeouts in the bcm2708_bsc_setup function as indicated by this comment:
53 /* poll for transfer start bit (should only take 1-20 polls) */
54 This implies that the setup function can now fail so account for this everywhere it's called
55 - Removed the clk_get_rate call from inside the setup function as it locks a mutex and that's not ok since we call it from under a spin lock.
56
57 i2c-bcm2708: When using DT, leave the GPIO setup to pinctrl
58
59 i2c-bcm2708: Increase timeouts to allow larger transfers
60
61 Use the timeout value provided by the I2C_TIMEOUT ioctl when waiting
62 for completion. The default timeout is 1 second.
63
64 See: https://github.com/raspberrypi/linux/issues/260
65
66 i2c-bcm2708/BCM270X_DT: Add support for I2C2
67
68 The third I2C bus (I2C2) is normally reserved for HDMI use. Careless
69 use of this bus can break an attached display - use with caution.
70
71 It is recommended to disable accesses by VideoCore by setting
72 hdmi_ignore_edid=1 or hdmi_edid_file=1 in config.txt.
73
74 The interface is disabled by default - enable using the
75 i2c2_iknowwhatimdoing DT parameter.
76
77 bcm2708-spi: Don't use static pin configuration with DT
78
79 Also remove superfluous error checking - the SPI framework ensures the
80 validity of the chip_select value.
81
82 i2c-bcm2708: Remove non-DT support
83
84 Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
85 ---
86 drivers/i2c/busses/Kconfig | 21 +-
87 drivers/i2c/busses/Makefile | 2 +
88 drivers/i2c/busses/i2c-bcm2708.c | 493 +++++++++++++++++++++++++++++++++++++++
89 3 files changed, 515 insertions(+), 1 deletion(-)
90 create mode 100644 drivers/i2c/busses/i2c-bcm2708.c
91
92 --- a/drivers/i2c/busses/Kconfig
93 +++ b/drivers/i2c/busses/Kconfig
94 @@ -8,6 +8,25 @@ menu "I2C Hardware Bus support"
95 comment "PC SMBus host controller drivers"
96 depends on PCI
97
98 +config I2C_BCM2708
99 + tristate "BCM2708 BSC"
100 + depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835
101 + help
102 + Enabling this option will add BSC (Broadcom Serial Controller)
103 + support for the BCM2708. BSC is a Broadcom proprietary bus compatible
104 + with I2C/TWI/SMBus.
105 +
106 +config I2C_BCM2708_BAUDRATE
107 + prompt "BCM2708 I2C baudrate"
108 + depends on I2C_BCM2708
109 + int
110 + default 100000
111 + help
112 + Set the I2C baudrate. This will alter the default value. A
113 + different baudrate can be set by using a module parameter as well. If
114 + no parameter is provided when loading, this is the value that will be
115 + used.
116 +
117 config I2C_ALI1535
118 tristate "ALI 1535"
119 depends on PCI
120 @@ -365,7 +384,7 @@ config I2C_AXXIA
121
122 config I2C_BCM2835
123 tristate "Broadcom BCM2835 I2C controller"
124 - depends on ARCH_BCM2835
125 + depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709
126 help
127 If you say yes to this option, support will be included for the
128 BCM2835 I2C controller.
129 --- a/drivers/i2c/busses/Makefile
130 +++ b/drivers/i2c/busses/Makefile
131 @@ -2,6 +2,8 @@
132 # Makefile for the i2c bus drivers.
133 #
134
135 +obj-$(CONFIG_I2C_BCM2708) += i2c-bcm2708.o
136 +
137 # ACPI drivers
138 obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o
139
140 --- /dev/null
141 +++ b/drivers/i2c/busses/i2c-bcm2708.c
142 @@ -0,0 +1,493 @@
143 +/*
144 + * Driver for Broadcom BCM2708 BSC Controllers
145 + *
146 + * Copyright (C) 2012 Chris Boot & Frank Buss
147 + *
148 + * This driver is inspired by:
149 + * i2c-ocores.c, by Peter Korsgaard <jacmet@sunsite.dk>
150 + *
151 + * This program is free software; you can redistribute it and/or modify
152 + * it under the terms of the GNU General Public License as published by
153 + * the Free Software Foundation; either version 2 of the License, or
154 + * (at your option) any later version.
155 + *
156 + * This program is distributed in the hope that it will be useful,
157 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
158 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
159 + * GNU General Public License for more details.
160 + *
161 + * You should have received a copy of the GNU General Public License
162 + * along with this program; if not, write to the Free Software
163 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
164 + */
165 +
166 +#include <linux/kernel.h>
167 +#include <linux/module.h>
168 +#include <linux/spinlock.h>
169 +#include <linux/clk.h>
170 +#include <linux/err.h>
171 +#include <linux/of.h>
172 +#include <linux/platform_device.h>
173 +#include <linux/io.h>
174 +#include <linux/slab.h>
175 +#include <linux/i2c.h>
176 +#include <linux/interrupt.h>
177 +#include <linux/sched.h>
178 +#include <linux/wait.h>
179 +
180 +/* BSC register offsets */
181 +#define BSC_C 0x00
182 +#define BSC_S 0x04
183 +#define BSC_DLEN 0x08
184 +#define BSC_A 0x0c
185 +#define BSC_FIFO 0x10
186 +#define BSC_DIV 0x14
187 +#define BSC_DEL 0x18
188 +#define BSC_CLKT 0x1c
189 +
190 +/* Bitfields in BSC_C */
191 +#define BSC_C_I2CEN 0x00008000
192 +#define BSC_C_INTR 0x00000400
193 +#define BSC_C_INTT 0x00000200
194 +#define BSC_C_INTD 0x00000100
195 +#define BSC_C_ST 0x00000080
196 +#define BSC_C_CLEAR_1 0x00000020
197 +#define BSC_C_CLEAR_2 0x00000010
198 +#define BSC_C_READ 0x00000001
199 +
200 +/* Bitfields in BSC_S */
201 +#define BSC_S_CLKT 0x00000200
202 +#define BSC_S_ERR 0x00000100
203 +#define BSC_S_RXF 0x00000080
204 +#define BSC_S_TXE 0x00000040
205 +#define BSC_S_RXD 0x00000020
206 +#define BSC_S_TXD 0x00000010
207 +#define BSC_S_RXR 0x00000008
208 +#define BSC_S_TXW 0x00000004
209 +#define BSC_S_DONE 0x00000002
210 +#define BSC_S_TA 0x00000001
211 +
212 +#define I2C_WAIT_LOOP_COUNT 200
213 +
214 +#define DRV_NAME "bcm2708_i2c"
215 +
216 +static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE;
217 +module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
218 +MODULE_PARM_DESC(baudrate, "The I2C baudrate");
219 +
220 +static bool combined = false;
221 +module_param(combined, bool, 0644);
222 +MODULE_PARM_DESC(combined, "Use combined transactions");
223 +
224 +struct bcm2708_i2c {
225 + struct i2c_adapter adapter;
226 +
227 + spinlock_t lock;
228 + void __iomem *base;
229 + int irq;
230 + struct clk *clk;
231 + u32 cdiv;
232 +
233 + struct completion done;
234 +
235 + struct i2c_msg *msg;
236 + int pos;
237 + int nmsgs;
238 + bool error;
239 +};
240 +
241 +static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg)
242 +{
243 + return readl(bi->base + reg);
244 +}
245 +
246 +static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val)
247 +{
248 + writel(val, bi->base + reg);
249 +}
250 +
251 +static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi)
252 +{
253 + bcm2708_wr(bi, BSC_C, 0);
254 + bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE);
255 +}
256 +
257 +static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi)
258 +{
259 + while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len))
260 + bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO);
261 +}
262 +
263 +static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
264 +{
265 + while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len))
266 + bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
267 +}
268 +
269 +static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi)
270 +{
271 + u32 cdiv, s;
272 + u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
273 + int wait_loops = I2C_WAIT_LOOP_COUNT;
274 +
275 + /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked.
276 + * Use the value that we cached in the probe.
277 + */
278 + cdiv = bi->cdiv;
279 +
280 + if (bi->msg->flags & I2C_M_RD)
281 + c |= BSC_C_INTR | BSC_C_READ;
282 + else
283 + c |= BSC_C_INTT;
284 +
285 + bcm2708_wr(bi, BSC_DIV, cdiv);
286 + bcm2708_wr(bi, BSC_A, bi->msg->addr);
287 + bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
288 + if (combined)
289 + {
290 + /* Do the next two messages meet combined transaction criteria?
291 + - Current message is a write, next message is a read
292 + - Both messages to same slave address
293 + - Write message can fit inside FIFO (16 bytes or less) */
294 + if ( (bi->nmsgs > 1) &&
295 + !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) &&
296 + (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) {
297 + /* Fill FIFO with entire write message (16 byte FIFO) */
298 + while (bi->pos < bi->msg->len) {
299 + bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
300 + }
301 + /* Start write transfer (no interrupts, don't clear FIFO) */
302 + bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST);
303 +
304 + /* poll for transfer start bit (should only take 1-20 polls) */
305 + do {
306 + s = bcm2708_rd(bi, BSC_S);
307 + } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0);
308 +
309 + /* did we time out or some error occured? */
310 + if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) {
311 + return -1;
312 + }
313 +
314 + /* Send next read message before the write transfer finishes. */
315 + bi->nmsgs--;
316 + bi->msg++;
317 + bi->pos = 0;
318 + bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
319 + c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ;
320 + }
321 + }
322 + bcm2708_wr(bi, BSC_C, c);
323 +
324 + return 0;
325 +}
326 +
327 +static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id)
328 +{
329 + struct bcm2708_i2c *bi = dev_id;
330 + bool handled = true;
331 + u32 s;
332 + int ret;
333 +
334 + spin_lock(&bi->lock);
335 +
336 + /* we may see camera interrupts on the "other" I2C channel
337 + Just return if we've not sent anything */
338 + if (!bi->nmsgs || !bi->msg) {
339 + goto early_exit;
340 + }
341 +
342 + s = bcm2708_rd(bi, BSC_S);
343 +
344 + if (s & (BSC_S_CLKT | BSC_S_ERR)) {
345 + bcm2708_bsc_reset(bi);
346 + bi->error = true;
347 +
348 + bi->msg = 0; /* to inform the that all work is done */
349 + bi->nmsgs = 0;
350 + /* wake up our bh */
351 + complete(&bi->done);
352 + } else if (s & BSC_S_DONE) {
353 + bi->nmsgs--;
354 +
355 + if (bi->msg->flags & I2C_M_RD) {
356 + bcm2708_bsc_fifo_drain(bi);
357 + }
358 +
359 + bcm2708_bsc_reset(bi);
360 +
361 + if (bi->nmsgs) {
362 + /* advance to next message */
363 + bi->msg++;
364 + bi->pos = 0;
365 + ret = bcm2708_bsc_setup(bi);
366 + if (ret < 0) {
367 + bcm2708_bsc_reset(bi);
368 + bi->error = true;
369 + bi->msg = 0; /* to inform the that all work is done */
370 + bi->nmsgs = 0;
371 + /* wake up our bh */
372 + complete(&bi->done);
373 + goto early_exit;
374 + }
375 + } else {
376 + bi->msg = 0; /* to inform the that all work is done */
377 + bi->nmsgs = 0;
378 + /* wake up our bh */
379 + complete(&bi->done);
380 + }
381 + } else if (s & BSC_S_TXW) {
382 + bcm2708_bsc_fifo_fill(bi);
383 + } else if (s & BSC_S_RXR) {
384 + bcm2708_bsc_fifo_drain(bi);
385 + } else {
386 + handled = false;
387 + }
388 +
389 +early_exit:
390 + spin_unlock(&bi->lock);
391 +
392 + return handled ? IRQ_HANDLED : IRQ_NONE;
393 +}
394 +
395 +static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap,
396 + struct i2c_msg *msgs, int num)
397 +{
398 + struct bcm2708_i2c *bi = adap->algo_data;
399 + unsigned long flags;
400 + int ret;
401 +
402 + spin_lock_irqsave(&bi->lock, flags);
403 +
404 + reinit_completion(&bi->done);
405 + bi->msg = msgs;
406 + bi->pos = 0;
407 + bi->nmsgs = num;
408 + bi->error = false;
409 +
410 + ret = bcm2708_bsc_setup(bi);
411 +
412 + spin_unlock_irqrestore(&bi->lock, flags);
413 +
414 + /* check the result of the setup */
415 + if (ret < 0)
416 + {
417 + dev_err(&adap->dev, "transfer setup timed out\n");
418 + goto error_timeout;
419 + }
420 +
421 + ret = wait_for_completion_timeout(&bi->done, adap->timeout);
422 + if (ret == 0) {
423 + dev_err(&adap->dev, "transfer timed out\n");
424 + goto error_timeout;
425 + }
426 +
427 + ret = bi->error ? -EIO : num;
428 + return ret;
429 +
430 +error_timeout:
431 + spin_lock_irqsave(&bi->lock, flags);
432 + bcm2708_bsc_reset(bi);
433 + bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */
434 + bi->nmsgs = 0;
435 + spin_unlock_irqrestore(&bi->lock, flags);
436 + return -ETIMEDOUT;
437 +}
438 +
439 +static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap)
440 +{
441 + return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL;
442 +}
443 +
444 +static struct i2c_algorithm bcm2708_i2c_algorithm = {
445 + .master_xfer = bcm2708_i2c_master_xfer,
446 + .functionality = bcm2708_i2c_functionality,
447 +};
448 +
449 +static int bcm2708_i2c_probe(struct platform_device *pdev)
450 +{
451 + struct resource *regs;
452 + int irq, err = -ENOMEM;
453 + struct clk *clk;
454 + struct bcm2708_i2c *bi;
455 + struct i2c_adapter *adap;
456 + unsigned long bus_hz;
457 + u32 cdiv;
458 +
459 + if (pdev->dev.of_node) {
460 + u32 bus_clk_rate;
461 + pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c");
462 + if (pdev->id < 0) {
463 + dev_err(&pdev->dev, "alias is missing\n");
464 + return -EINVAL;
465 + }
466 + if (!of_property_read_u32(pdev->dev.of_node,
467 + "clock-frequency", &bus_clk_rate))
468 + baudrate = bus_clk_rate;
469 + else
470 + dev_warn(&pdev->dev,
471 + "Could not read clock-frequency property\n");
472 + }
473 +
474 + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
475 + if (!regs) {
476 + dev_err(&pdev->dev, "could not get IO memory\n");
477 + return -ENXIO;
478 + }
479 +
480 + irq = platform_get_irq(pdev, 0);
481 + if (irq < 0) {
482 + dev_err(&pdev->dev, "could not get IRQ\n");
483 + return irq;
484 + }
485 +
486 + clk = clk_get(&pdev->dev, NULL);
487 + if (IS_ERR(clk)) {
488 + dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
489 + return PTR_ERR(clk);
490 + }
491 +
492 + err = clk_prepare_enable(clk);
493 + if (err) {
494 + dev_err(&pdev->dev, "could not enable clk: %d\n", err);
495 + goto out_clk_put;
496 + }
497 +
498 + bi = kzalloc(sizeof(*bi), GFP_KERNEL);
499 + if (!bi)
500 + goto out_clk_disable;
501 +
502 + platform_set_drvdata(pdev, bi);
503 +
504 + adap = &bi->adapter;
505 + adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC;
506 + adap->algo = &bcm2708_i2c_algorithm;
507 + adap->algo_data = bi;
508 + adap->dev.parent = &pdev->dev;
509 + adap->nr = pdev->id;
510 + strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
511 + adap->dev.of_node = pdev->dev.of_node;
512 +
513 + switch (pdev->id) {
514 + case 0:
515 + adap->class = I2C_CLASS_HWMON;
516 + break;
517 + case 1:
518 + adap->class = I2C_CLASS_DDC;
519 + break;
520 + case 2:
521 + adap->class = I2C_CLASS_DDC;
522 + break;
523 + default:
524 + dev_err(&pdev->dev, "can only bind to BSC 0, 1 or 2\n");
525 + err = -ENXIO;
526 + goto out_free_bi;
527 + }
528 +
529 + spin_lock_init(&bi->lock);
530 + init_completion(&bi->done);
531 +
532 + bi->base = ioremap(regs->start, resource_size(regs));
533 + if (!bi->base) {
534 + dev_err(&pdev->dev, "could not remap memory\n");
535 + goto out_free_bi;
536 + }
537 +
538 + bi->irq = irq;
539 + bi->clk = clk;
540 +
541 + err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED,
542 + dev_name(&pdev->dev), bi);
543 + if (err) {
544 + dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
545 + goto out_iounmap;
546 + }
547 +
548 + bcm2708_bsc_reset(bi);
549 +
550 + err = i2c_add_numbered_adapter(adap);
551 + if (err < 0) {
552 + dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err);
553 + goto out_free_irq;
554 + }
555 +
556 + bus_hz = clk_get_rate(bi->clk);
557 + cdiv = bus_hz / baudrate;
558 + if (cdiv > 0xffff) {
559 + cdiv = 0xffff;
560 + baudrate = bus_hz / cdiv;
561 + }
562 + bi->cdiv = cdiv;
563 +
564 + dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n",
565 + pdev->id, (unsigned long)regs->start, irq, baudrate);
566 +
567 + return 0;
568 +
569 +out_free_irq:
570 + free_irq(bi->irq, bi);
571 +out_iounmap:
572 + iounmap(bi->base);
573 +out_free_bi:
574 + kfree(bi);
575 +out_clk_disable:
576 + clk_disable_unprepare(clk);
577 +out_clk_put:
578 + clk_put(clk);
579 + return err;
580 +}
581 +
582 +static int bcm2708_i2c_remove(struct platform_device *pdev)
583 +{
584 + struct bcm2708_i2c *bi = platform_get_drvdata(pdev);
585 +
586 + platform_set_drvdata(pdev, NULL);
587 +
588 + i2c_del_adapter(&bi->adapter);
589 + free_irq(bi->irq, bi);
590 + iounmap(bi->base);
591 + clk_disable_unprepare(bi->clk);
592 + clk_put(bi->clk);
593 + kfree(bi);
594 +
595 + return 0;
596 +}
597 +
598 +static const struct of_device_id bcm2708_i2c_of_match[] = {
599 + { .compatible = "brcm,bcm2708-i2c" },
600 + {},
601 +};
602 +MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match);
603 +
604 +static struct platform_driver bcm2708_i2c_driver = {
605 + .driver = {
606 + .name = DRV_NAME,
607 + .owner = THIS_MODULE,
608 + .of_match_table = bcm2708_i2c_of_match,
609 + },
610 + .probe = bcm2708_i2c_probe,
611 + .remove = bcm2708_i2c_remove,
612 +};
613 +
614 +// module_platform_driver(bcm2708_i2c_driver);
615 +
616 +
617 +static int __init bcm2708_i2c_init(void)
618 +{
619 + return platform_driver_register(&bcm2708_i2c_driver);
620 +}
621 +
622 +static void __exit bcm2708_i2c_exit(void)
623 +{
624 + platform_driver_unregister(&bcm2708_i2c_driver);
625 +}
626 +
627 +module_init(bcm2708_i2c_init);
628 +module_exit(bcm2708_i2c_exit);
629 +
630 +
631 +
632 +MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708");
633 +MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
634 +MODULE_LICENSE("GPL v2");
635 +MODULE_ALIAS("platform:" DRV_NAME);