]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/cbus/tahvo-usb.c
[PATCH] CBUS: Fix tahvo-usb omap_otg_remove
[linux-2.6-omap-h63xx.git] / drivers / cbus / tahvo-usb.c
1 /**
2  * drivers/cbus/tahvo-usb.c
3  *
4  * Tahvo USB transeiver
5  *
6  * Copyright (C) 2005 Nokia Corporation
7  *
8  * Written by Juha Yrjölä <juha.yrjola@nokia.com>,
9  *            Tony Lindgren <tony@atomide.com>, and
10  *            Timo Teräs <timo.teras@nokia.com>
11  *
12  * This file is subject to the terms and conditions of the GNU General
13  * Public License. See the file "COPYING" in the main directory of this
14  * archive for more details.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 #include <linux/config.h>
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/slab.h>
31 #include <linux/interrupt.h>
32 #include <linux/platform_device.h>
33 #include <linux/usb_ch9.h>
34 #include <linux/usb_gadget.h>
35 #include <linux/usb.h>
36 #include <linux/usb_otg.h>
37 #include <linux/i2c.h>
38 #include <linux/workqueue.h>
39 #include <linux/kobject.h>
40 #include <linux/clk.h>
41
42 #include <asm/irq.h>
43 #include <asm/semaphore.h>
44 #include <asm/arch/usb.h>
45
46 #include "cbus.h"
47 #include "tahvo.h"
48
49 #define DRIVER_NAME     "tahvo-usb"
50
51 #define USBR_SLAVE_CONTROL      (1 << 8)
52 #define USBR_VPPVIO_SW          (1 << 7)
53 #define USBR_SPEED              (1 << 6)
54 #define USBR_REGOUT             (1 << 5)
55 #define USBR_MASTER_SW2         (1 << 4)
56 #define USBR_MASTER_SW1         (1 << 3)
57 #define USBR_SLAVE_SW           (1 << 2)
58 #define USBR_NSUSPEND           (1 << 1)
59 #define USBR_SEMODE             (1 << 0)
60
61 /* bits in OTG_CTRL_REG */
62
63 /* Bits that are controlled by OMAP OTG and are read-only */
64 #define OTG_CTRL_OMAP_MASK      (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|\
65                                 OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID)
66 /* Bits that are controlled by transceiver */
67 #define OTG_CTRL_XCVR_MASK      (OTG_ASESSVLD|OTG_BSESSEND|\
68                                 OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID)
69 /* Bits that are controlled by system */
70 #define OTG_CTRL_SYS_MASK       (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|\
71                                 OTG_B_HNPEN|OTG_BUSDROP)
72
73 #if defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OTG)
74 #error tahvo-otg.c does not work with OCHI yet!
75 #endif
76
77 #define TAHVO_MODE_HOST         0
78 #define TAHVO_MODE_PERIPHERAL   1
79
80 #ifdef CONFIG_USB_OTG
81 #define TAHVO_MODE(tu)          (tu)->tahvo_mode
82 #elif defined(CONFIG_USB_GADGET_OMAP)
83 #define TAHVO_MODE(tu)          TAHVO_MODE_PERIPHERAL
84 #else
85 #define TAHVO_MODE(tu)          TAHVO_MODE_HOST
86 #endif
87
88 extern int ohci_omap_host_enable(struct usb_bus *host, int enable);
89
90 struct tahvo_usb {
91         struct platform_device *pt_dev;
92         struct otg_transceiver otg;
93         int vbus_state;
94         struct work_struct irq_work;
95         struct semaphore serialize;
96 #ifdef CONFIG_USB_OTG
97         int tahvo_mode;
98 #endif
99 };
100 static struct platform_device tahvo_usb_device;
101
102 /*
103  * ---------------------------------------------------------------------------
104  * OTG related functions
105  *
106  * These shoud be separated into omap-otg.c driver module, as they are used
107  * by various transceivers. These functions are needed in the UDC-only case 
108  * as well. These functions are copied from GPL isp1301_omap.c
109  * ---------------------------------------------------------------------------
110  */
111 static struct platform_device *tahvo_otg_dev;
112
113 static irqreturn_t omap_otg_irq(int irq, void *arg, struct pt_regs *regs)
114 {
115         struct platform_device *otg_dev = (struct platform_device *) arg;
116         struct tahvo_usb *tu = (struct tahvo_usb *) otg_dev->dev.driver_data;
117         u16 otg_irq;
118
119         otg_irq = OTG_IRQ_SRC_REG;
120         if (otg_irq & OPRT_CHG) {
121                 OTG_IRQ_SRC_REG = OPRT_CHG;
122         } else if (otg_irq & B_SRP_TMROUT) {
123                 OTG_IRQ_SRC_REG = B_SRP_TMROUT;
124         } else if (otg_irq & B_HNP_FAIL) {
125                 OTG_IRQ_SRC_REG = B_HNP_FAIL;
126         } else if (otg_irq & A_SRP_DETECT) {
127                 OTG_IRQ_SRC_REG = A_SRP_DETECT;
128         } else if (otg_irq & A_REQ_TMROUT) {
129                 OTG_IRQ_SRC_REG = A_REQ_TMROUT;
130         } else if (otg_irq & A_VBUS_ERR) {
131                 OTG_IRQ_SRC_REG = A_VBUS_ERR;
132         } else if (otg_irq & DRIVER_SWITCH) {
133
134                 if ((!(OTG_CTRL_REG & OTG_DRIVER_SEL)) &&
135                    tu->otg.host && tu->otg.state == OTG_STATE_A_HOST) {
136                         /* role is host */
137                         usb_bus_start_enum(tu->otg.host,
138                                            tu->otg.host->otg_port);
139                 }
140
141                 OTG_IRQ_SRC_REG = DRIVER_SWITCH;
142         } else
143                 return IRQ_NONE;
144
145         return IRQ_HANDLED;
146
147 }
148
149 static int omap_otg_init(void)
150 {
151
152 #ifdef CONFIG_USB_OTG
153         if (!tahvo_otg_dev) {
154                 printk("tahvo-usb: no tahvo_otg_dev\n");
155                 return -ENODEV;
156         }
157 #endif
158
159         /* some of these values are board-specific... */
160         OTG_SYSCON_2_REG |= OTG_EN
161                 /* for B-device: */
162                 | SRP_GPDATA            /* 9msec Bdev D+ pulse */
163                 | SRP_GPDVBUS           /* discharge after VBUS pulse */
164                 // | (3 << 24)          /* 2msec VBUS pulse */
165                 /* for A-device: */
166                 | (0 << 20)             /* 200ms nominal A_WAIT_VRISE timer */
167                 | SRP_DPW               /* detect 167+ns SRP pulses */
168                 | SRP_DATA | SRP_VBUS;  /* accept both kinds of SRP pulse */
169
170         OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG
171                         | B_SRP_TMROUT | B_HNP_FAIL
172                         | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT;
173         OTG_SYSCON_2_REG |= OTG_EN;
174
175         return 0;
176 }
177
178 static int omap_otg_probe(struct device *dev)
179 {
180         int ret;
181
182         tahvo_otg_dev = to_platform_device(dev);
183         ret = omap_otg_init();
184         if (ret != 0) {
185                 printk(KERN_ERR "tahvo-usb: omap_otg_init failed\n");
186                 return ret;
187         }
188
189         return request_irq(tahvo_otg_dev->resource[1].start,
190                            omap_otg_irq, SA_INTERRUPT, DRIVER_NAME,
191                            &tahvo_usb_device);
192 }
193
194 static int omap_otg_remove(struct device *dev)
195 {
196         free_irq(tahvo_otg_dev->resource[1].start, &tahvo_usb_device);
197         tahvo_otg_dev = NULL;
198
199         return 0;
200 }
201
202 struct device_driver omap_otg_driver = {
203         .name           = "omap_otg",
204         .bus            = &platform_bus_type,
205         .probe          = omap_otg_probe,
206         .remove         = omap_otg_remove,
207 };
208
209 /*
210  * ---------------------------------------------------------------------------
211  * Tahvo related functions
212  * These are Nokia proprietary code, except for the OTG register settings,
213  * which are copied from isp1301.c
214  * ---------------------------------------------------------------------------
215  */
216 static ssize_t vbus_state_show(struct device *device,
217                                struct device_attribute *attr, char *buf)
218 {
219         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
220         return sprintf(buf, "%d\n", tu->vbus_state);
221 }
222 static DEVICE_ATTR(vbus_state, 0444, vbus_state_show, NULL);
223
224 int vbus_active = 0;
225
226 static void check_vbus_state(struct tahvo_usb *tu)
227 {
228         int reg, prev_state;
229
230         reg = tahvo_read_reg(TAHVO_REG_IDSR);
231         if (reg & 0x01) {
232                 vbus_active = 1;
233                 switch (tu->otg.state) {
234                 case OTG_STATE_B_IDLE:
235                         /* Enable the gadget driver */
236                         if (tu->otg.gadget)
237                                 usb_gadget_vbus_connect(tu->otg.gadget);
238                         /* Set B-session valid and not B-sessio ended to indicate
239                          * Vbus to be ok. */
240                         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSEND) | OTG_BSESSVLD;
241
242                         tu->otg.state = OTG_STATE_B_PERIPHERAL;
243                         break;
244                 case OTG_STATE_A_IDLE:
245                         /* Session is now valid assuming the USB hub is driving Vbus */
246                         tu->otg.state = OTG_STATE_A_HOST;
247                         if (tu->otg.host)
248                                 ohci_omap_host_enable(tu->otg.host, 1);
249                         break;
250                 default:
251                         break;
252                 }
253                 printk("USB cable connected\n");
254         } else {
255                 vbus_active = 0;
256                 switch (tu->otg.state) {
257                 case OTG_STATE_B_PERIPHERAL:
258                         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND;
259                         if (tu->otg.gadget)
260                                 usb_gadget_vbus_disconnect(tu->otg.gadget);
261                         tu->otg.state = OTG_STATE_B_IDLE;
262                         break;
263                 case OTG_STATE_A_HOST:
264                         tu->otg.state = OTG_STATE_A_IDLE;
265                         if (tu->otg.host)
266                                 ohci_omap_host_enable(tu->otg.host, 0);
267
268                         break;
269                 default:
270                         break;
271                 }
272                 printk("USB cable disconnected\n");
273         }
274
275         prev_state = tu->vbus_state;
276         tu->vbus_state = reg & 0x01;
277         if (prev_state != tu->vbus_state)
278                 kobject_uevent(&tu->pt_dev->dev.kobj, KOBJ_CHANGE);
279 }
280
281 static void tahvo_usb_become_host(struct tahvo_usb *tu)
282 {
283         /* Clear system and transceiver controlled bits
284          * also mark the A-session is always valid */
285         omap_otg_init();
286         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK))
287                 | OTG_ASESSVLD;
288
289         /* Power up the transceiver in USB host mode */
290         tahvo_write_reg(TAHVO_REG_USBR, USBR_REGOUT | USBR_NSUSPEND |
291                         USBR_MASTER_SW2 | USBR_MASTER_SW1);
292         tu->otg.state = OTG_STATE_A_IDLE;
293
294         check_vbus_state(tu);
295 }
296
297 static void tahvo_usb_stop_host(struct tahvo_usb *tu)
298 {
299         if (tu->otg.host)
300                 ohci_omap_host_enable(tu->otg.host, 0);
301         tu->otg.state = OTG_STATE_A_IDLE;
302 }
303
304 static void tahvo_usb_become_peripheral(struct tahvo_usb *tu)
305 {
306         /* Clear system and transceiver controlled bits
307          * and enable ID to mark peripheral mode and
308          * BSESSEND to mark no Vbus */
309         omap_otg_init();
310         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK))
311                 | OTG_ID | OTG_BSESSEND;
312
313         /* Power up transceiver and set it in USB perhiperal mode */
314         tahvo_write_reg(TAHVO_REG_USBR, USBR_SLAVE_CONTROL | USBR_REGOUT | USBR_NSUSPEND | USBR_SLAVE_SW);
315         tu->otg.state = OTG_STATE_B_IDLE;
316
317         check_vbus_state(tu);
318 }
319
320 static void tahvo_usb_stop_peripheral(struct tahvo_usb *tu)
321 {
322         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND;
323         if (tu->otg.gadget)
324                 usb_gadget_vbus_disconnect(tu->otg.gadget);
325         tu->otg.state = OTG_STATE_B_IDLE;
326
327 }
328
329 static void tahvo_usb_power_off(struct tahvo_usb *tu)
330 {
331         int id;
332
333         /* Disable gadget controller if any */
334         if (tu->otg.gadget)
335                 usb_gadget_vbus_disconnect(tu->otg.gadget);
336
337         if (tu->otg.host)
338                 ohci_omap_host_enable(tu->otg.host, 0);
339
340         /* Disable OTG and interrupts */
341         if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
342                 id = OTG_ID;
343         else    id = 0;
344         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK)) | id;
345         OTG_IRQ_EN_REG = 0;
346 #if 0
347         OTG_SYSCON_2_REG &= ~OTG_EN;
348 #endif
349
350         /* Power off transceiver */
351         tahvo_write_reg(TAHVO_REG_USBR, 0);
352         tu->otg.state = OTG_STATE_UNDEFINED;
353 }
354
355
356 static int tahvo_usb_set_power(struct otg_transceiver *dev, unsigned mA)
357 {
358         if (dev->state == OTG_STATE_B_PERIPHERAL) {
359                 /* REVISIT: Can Tahvo charge battery from VBUS? */
360         }
361         return 0;
362 }
363
364 static int tahvo_usb_set_suspend(struct otg_transceiver *dev, int suspend)
365 {
366         u16 w;
367
368         w = tahvo_read_reg(TAHVO_REG_USBR);
369         if (suspend)
370                 w &= ~USBR_NSUSPEND;
371         else
372                 w |= USBR_NSUSPEND;
373         tahvo_write_reg(TAHVO_REG_USBR, w);
374
375         return 0;
376 }
377
378 static int tahvo_usb_start_srp(struct otg_transceiver *dev)
379 {
380         struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
381         u32 otg_ctrl;
382
383         if (!dev || tu->otg.state != OTG_STATE_B_IDLE)
384                 return -ENODEV;
385
386         otg_ctrl = OTG_CTRL_REG;
387         if (!(otg_ctrl & OTG_BSESSEND))
388                 return -EINVAL;
389
390         otg_ctrl |= OTG_B_BUSREQ;
391         otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_SYS_MASK;
392         OTG_CTRL_REG = otg_ctrl;
393         tu->otg.state = OTG_STATE_B_SRP_INIT;
394
395         pr_debug("otg: SRP, %s ... %06x\n", state_name(tu), OTG_CTRL_REG);
396
397         return 0;
398 }
399
400 static int tahvo_usb_start_hnp(struct otg_transceiver *dev)
401 {
402 #ifdef CONFIG_USB_OTG
403         /* REVISIT: Add this for OTG */
404 #endif
405         return -EINVAL;
406 }
407
408 static int tahvo_usb_set_host(struct otg_transceiver *otg, struct usb_bus *host)
409 {
410         struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
411
412         if (!otg)
413                 return -ENODEV;
414
415 #if defined(CONFIG_USB_OTG) || !defined(CONFIG_USB_GADGET_OMAP)
416
417         down(&tu->serialize);
418
419         if (!host) {
420                 if (TAHVO_MODE(tu) == TAHVO_MODE_HOST)
421                         tahvo_usb_power_off(tu);
422                 tu->otg.host = 0;
423                 up(&tu->serialize);
424                 return 0;
425         }
426
427         if (TAHVO_MODE(tu) == TAHVO_MODE_HOST) {
428                 tu->otg.host = 0;
429                 tahvo_usb_become_host(tu);
430         } else
431                 ohci_omap_host_enable(host, 0);
432
433         tu->otg.host = host;
434
435         up(&tu->serialize);
436 #else
437         /* No host mode configured, so do not allow host controlled to be set */
438         return -EINVAL;
439 #endif
440
441         return 0;
442 }
443
444 static int tahvo_usb_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
445 {
446         struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
447
448         if (!otg)
449                 return -ENODEV;
450
451 #if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_GADGET_OMAP)
452
453         down(&tu->serialize);
454
455         if (!gadget) {
456                 if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
457                         tahvo_usb_power_off(tu);
458                 tu->otg.gadget = 0;
459                 up(&tu->serialize);
460                 return 0;
461         }
462
463         tu->otg.gadget = gadget;
464         if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
465                 tahvo_usb_become_peripheral(tu);
466
467         up(&tu->serialize);
468 #else
469         /* No gadget mode configured, so do not allow host controlled to be set */
470         return -EINVAL;
471 #endif
472
473         return 0;
474 }
475
476 static void tahvo_usb_irq_work(void *data)
477 {
478         struct tahvo_usb *tu = (struct tahvo_usb *)data;
479
480         down(&tu->serialize);
481         check_vbus_state(tu);
482         up(&tu->serialize);
483 }
484
485 static void tahvo_usb_vbus_interrupt(unsigned long arg)
486 {
487         struct tahvo_usb *tu = (struct tahvo_usb *) arg;
488
489         tahvo_ack_irq(TAHVO_INT_VBUSON);
490         /* Seems we need this to acknowledge the interrupt */
491         tahvo_read_reg(TAHVO_REG_IDSR);
492         schedule_work(&tu->irq_work);
493 }
494
495 #ifdef CONFIG_USB_OTG
496 static ssize_t otg_mode_show(struct device *device,
497                              struct device_attribute *attr, char *buf)
498 {
499         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
500         switch (tu->tahvo_mode) {
501         case TAHVO_MODE_HOST:
502                 return sprintf(buf, "host\n");
503         case TAHVO_MODE_PERIPHERAL:
504                 return sprintf(buf, "peripheral\n");
505         }
506         return sprintf(buf, "unknown\n");
507 }
508
509 static ssize_t otg_mode_store(struct device *device,
510                               struct device_attribute *attr,
511                               const char *buf, size_t count)
512 {
513         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
514         int r;
515
516         r = strlen(buf);
517         down(&tu->serialize);
518         if (strncmp(buf, "host", 4) == 0) {
519                 if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL)
520                         tahvo_usb_stop_peripheral(tu);
521                 tu->tahvo_mode = TAHVO_MODE_HOST;
522                 if (tu->otg.host) {
523                         printk(KERN_INFO "Selected HOST mode: host controller present.\n");
524                         tahvo_usb_become_host(tu);
525                 } else {
526                         printk(KERN_INFO "Selected HOST mode: no host controller, powering off.\n");
527                         tahvo_usb_power_off(tu);
528                 }
529         } else if (strncmp(buf, "peripheral", 10) == 0) {
530                 if (tu->tahvo_mode == TAHVO_MODE_HOST)
531                         tahvo_usb_stop_host(tu);
532                 tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
533                 if (tu->otg.gadget) {
534                         printk(KERN_INFO "Selected PERIPHERAL mode: gadget driver present.\n");
535                         tahvo_usb_become_peripheral(tu);
536                 } else {
537                         printk(KERN_INFO "Selected PERIPHERAL mode: no gadget driver, powering off.\n");
538                         tahvo_usb_power_off(tu);
539                 }
540         } else
541                 r = -EINVAL;
542
543         up(&tu->serialize);
544         return r;
545 }
546
547 static DEVICE_ATTR(otg_mode, 0644, otg_mode_show, otg_mode_store);
548 #endif
549
550 static int tahvo_usb_probe(struct device *dev)
551 {
552         struct tahvo_usb *tu;
553         int ret;
554
555         /* Create driver data */
556         tu = kmalloc(sizeof(*tu), GFP_KERNEL);
557         if (!tu)
558                 return -ENOMEM;
559         memset(tu, 0, sizeof(*tu));
560         tu->pt_dev = container_of(dev, struct platform_device, dev);
561 #ifdef CONFIG_USB_OTG
562         /* Default mode */
563 #ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT
564         tu->tahvo_mode = TAHVO_MODE_HOST;
565 #else
566         tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
567 #endif
568 #endif
569
570         INIT_WORK(&tu->irq_work, tahvo_usb_irq_work, tu);
571         init_MUTEX(&tu->serialize);
572
573         /* Set initial state, so that we generate kevents only on
574          * state changes */
575         tu->vbus_state = tahvo_read_reg(TAHVO_REG_IDSR) & 0x01;
576
577         /* We cannot enable interrupt until omap_udc is initialized */
578         ret = tahvo_request_irq(TAHVO_INT_VBUSON, tahvo_usb_vbus_interrupt,
579                                 (unsigned long) tu, "vbus_interrupt");
580         if (ret != 0) {
581                 kfree(tu);
582                 printk(KERN_ERR "Could not register Tahvo interrupt for VBUS\n");
583                 return ret;
584         }
585
586         /* Attributes */
587         device_create_file(dev, &dev_attr_vbus_state);
588 #ifdef CONFIG_USB_OTG
589         device_create_file(dev, &dev_attr_otg_mode);
590 #endif
591
592         /* Create OTG interface */
593         tahvo_usb_power_off(tu);
594         tu->otg.state = OTG_STATE_UNDEFINED;
595         tu->otg.label = DRIVER_NAME;
596         tu->otg.set_host = tahvo_usb_set_host;
597         tu->otg.set_peripheral = tahvo_usb_set_peripheral;
598         tu->otg.set_power = tahvo_usb_set_power;
599         tu->otg.set_suspend = tahvo_usb_set_suspend;
600         tu->otg.start_srp = tahvo_usb_start_srp;
601         tu->otg.start_hnp = tahvo_usb_start_hnp;
602
603         ret = otg_set_transceiver(&tu->otg);
604         if (ret < 0) {
605                 printk(KERN_ERR "Cannot register USB transceiver\n");
606                 kfree(tu);
607                 tahvo_free_irq(TAHVO_INT_VBUSON);
608                 return ret;
609         }
610
611         dev->driver_data = tu;
612
613         /* Act upon current vbus state once at startup. A vbus state irq may or
614          * may not be generated in addition to this. */
615         schedule_work(&tu->irq_work);
616         return 0;
617 }
618
619 static int tahvo_usb_remove(struct device *dev)
620 {
621         tahvo_free_irq(TAHVO_INT_VBUSON);
622         flush_scheduled_work();
623         otg_set_transceiver(0);
624         device_remove_file(dev, &dev_attr_vbus_state);
625 #ifdef CONFIG_USB_OTG
626         device_remove_file(dev, &dev_attr_otg_mode);
627 #endif
628         return 0;
629 }
630
631 static struct device_driver tahvo_usb_driver = {
632         .name           = "tahvo-usb",
633         .bus            = &platform_bus_type,
634         .probe          = tahvo_usb_probe,
635         .remove         = tahvo_usb_remove,
636 };
637
638 static struct platform_device tahvo_usb_device = {
639         .name           = "tahvo-usb",
640         .id             = -1,
641 };
642
643 static int __init tahvo_usb_init(void)
644 {
645         int ret = 0;
646
647         printk(KERN_INFO "Tahvo USB transceiver driver initializing\n");
648         ret = driver_register(&tahvo_usb_driver);
649         if (ret)
650                 return ret;
651         ret = platform_device_register(&tahvo_usb_device);
652         if (ret < 0) {
653                 driver_unregister(&tahvo_usb_driver);
654                 return ret;
655         }
656         ret = driver_register(&omap_otg_driver);
657         if (ret) {
658                 platform_device_unregister(&tahvo_usb_device);
659                 driver_unregister(&tahvo_usb_driver);
660                 return ret;
661         }
662         return 0;
663 }
664
665 subsys_initcall(tahvo_usb_init);
666
667 static void __exit tahvo_usb_exit(void)
668 {
669         driver_unregister(&omap_otg_driver);
670         platform_device_unregister(&tahvo_usb_device);
671         driver_unregister(&tahvo_usb_driver);
672 }
673 module_exit(tahvo_usb_exit);
674
675 MODULE_DESCRIPTION("Tahvo USB OTG Transceiver Driver");
676 MODULE_LICENSE("GPL");
677 MODULE_AUTHOR("Juha Yrjölä, Tony Lindgren, and Timo Teräs");