[s3c24xx] bump to 2.6.30-rc6
[openwrt.git] / target / linux / s3c24xx / patches-2.6.30 / 100-udc-poll-vbus.patch
1 Index: linux-2.6.30-rc6/drivers/usb/gadget/s3c2410_udc.c
2 ===================================================================
3 --- linux-2.6.30-rc6.orig/drivers/usb/gadget/s3c2410_udc.c      2009-05-16 06:12:57.000000000 +0200
4 +++ linux-2.6.30-rc6/drivers/usb/gadget/s3c2410_udc.c   2009-05-18 19:08:35.000000000 +0200
5 @@ -74,6 +74,7 @@
6  static u64                     rsrc_start;
7  static u64                     rsrc_len;
8  static struct dentry           *s3c2410_udc_debugfs_root;
9 +static struct timer_list       vbus_poll_timer;
10  
11  static inline u32 udc_read(u32 reg)
12  {
13 @@ -134,6 +135,8 @@
14         return 0;
15  }
16  #endif
17 +
18 +#ifdef CONFIG_USB_GADGET_DEBUG_FS
19  static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p)
20  {
21         u32 addr_reg,pwr_reg,ep_int_reg,usb_int_reg;
22 @@ -197,6 +200,7 @@
23         .release        = single_release,
24         .owner          = THIS_MODULE,
25  };
26 +#endif
27  
28  /* io macros */
29  
30 @@ -843,6 +847,7 @@
31         u32                     ep_csr1;
32         u32                     idx;
33  
34 +handle_ep_again:
35         if (likely (!list_empty(&ep->queue)))
36                 req = list_entry(ep->queue.next,
37                                 struct s3c2410_request, queue);
38 @@ -882,6 +887,8 @@
39  
40                 if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
41                         s3c2410_udc_read_fifo(ep,req);
42 +                       if (s3c2410_udc_fifo_count_out())
43 +                               goto handle_ep_again;
44                 }
45         }
46  }
47 @@ -1520,6 +1527,20 @@
48         return IRQ_HANDLED;
49  }
50  
51 +static void s3c2410_udc_vbus_poll(unsigned long _data)
52 +{
53 +       struct s3c2410_udc      *data = (struct s3c2410_udc *)_data;
54 +       int                     v;
55 +
56 +       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
57 +       if (udc_info && udc_info->get_vbus_status) {
58 +               v = udc_info->get_vbus_status();
59 +               if ((v > -1) && (v != data->vbus))
60 +                       s3c2410_udc_vbus_session(&data->gadget, v);
61 +               mod_timer(&vbus_poll_timer, jiffies + msecs_to_jiffies(900));
62 +       }
63 +}
64 +
65  static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma)
66  {
67         dprintk(DEBUG_NORMAL, "%s()\n", __func__);
68 @@ -1677,6 +1698,11 @@
69                 goto register_error;
70         }
71  
72 +       if (udc_info && udc_info->get_vbus_status && !udc_info->vbus_pin) {
73 +               mod_timer(&vbus_poll_timer, jiffies + msecs_to_jiffies(50));
74 +               return 0; /* just return, vbus change will enable udc */
75 +       }
76 +
77         /* Enable udc */
78         s3c2410_udc_enable(udc);
79  
80 @@ -1707,6 +1733,7 @@
81         if (driver->disconnect)
82                 driver->disconnect(&udc->gadget);
83  
84 +       driver->unbind(&udc->gadget);
85         device_del(&udc->gadget.dev);
86         udc->driver = NULL;
87  
88 @@ -1893,10 +1920,16 @@
89                 }
90  
91                 dev_dbg(dev, "got irq %i\n", irq);
92 +       } else if (udc_info && udc_info->get_vbus_status) {
93 +               udc->vbus = 0;
94 +               init_timer(&vbus_poll_timer);
95 +               vbus_poll_timer.function = s3c2410_udc_vbus_poll;
96 +               vbus_poll_timer.data = (unsigned long) udc;
97         } else {
98                 udc->vbus = 1;
99         }
100  
101 +#ifdef CONFIG_USB_GADGET_DEBUG_FS
102         if (s3c2410_udc_debugfs_root) {
103                 udc->regs_info = debugfs_create_file("registers", S_IRUGO,
104                                 s3c2410_udc_debugfs_root,
105 @@ -1904,6 +1937,7 @@
106                 if (!udc->regs_info)
107                         dev_warn(dev, "debugfs file creation failed\n");
108         }
109 +#endif
110  
111         dev_dbg(dev, "probe ok\n");
112  
113 @@ -1939,6 +1973,8 @@
114         if (udc_info && udc_info->vbus_pin > 0) {
115                 irq = gpio_to_irq(udc_info->vbus_pin);
116                 free_irq(irq, udc);
117 +       } else if (udc_info && udc_info->get_vbus_status) {
118 +               del_timer_sync(&vbus_poll_timer);
119         }
120  
121         free_irq(IRQ_USBD, udc);
122 @@ -2013,12 +2049,14 @@
123  
124         dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION);
125  
126 +#ifdef CONFIG_USB_GADGET_DEBUG_FS
127         s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL);
128         if (IS_ERR(s3c2410_udc_debugfs_root)) {
129                 printk(KERN_ERR "%s: debugfs dir creation failed %ld\n",
130                         gadget_name, PTR_ERR(s3c2410_udc_debugfs_root));
131                 s3c2410_udc_debugfs_root = NULL;
132         }
133 +#endif
134  
135         retval = platform_driver_register(&udc_driver_2410);
136         if (retval)
137 Index: linux-2.6.30-rc6/drivers/usb/host/ohci-s3c2410.c
138 ===================================================================
139 --- linux-2.6.30-rc6.orig/drivers/usb/host/ohci-s3c2410.c       2009-05-16 06:12:57.000000000 +0200
140 +++ linux-2.6.30-rc6/drivers/usb/host/ohci-s3c2410.c    2009-05-18 19:08:35.000000000 +0200
141 @@ -21,6 +21,8 @@
142  
143  #include <linux/platform_device.h>
144  #include <linux/clk.h>
145 +#include <mach/hardware.h>
146 +#include <mach/regs-gpio.h>
147  #include <plat/usb-control.h>
148  
149  #define valid_port(idx) ((idx) == 1 || (idx) == 2)
150 @@ -306,6 +308,42 @@
151         local_irq_restore(flags);
152  }
153  
154 +/* switching of USB pads */
155 +static ssize_t show_usb_mode(struct device *dev, struct device_attribute *attr,
156 +                            char *buf)
157 +{
158 +       if (__raw_readl(S3C24XX_MISCCR) & S3C2410_MISCCR_USBHOST)
159 +               return sprintf(buf, "host\n");
160 +
161 +       return sprintf(buf, "device\n");
162 +}
163 +
164 +static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr,
165 +                           const char *buf, size_t count)
166 +{
167 +       if (!strncmp(buf, "host", 4)) {
168 +               printk(KERN_WARNING "s3c2410: changing usb to host\n");
169 +               s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST,
170 +                                     S3C2410_MISCCR_USBHOST);
171 +               /* FIXME:
172 +                * - call machine-specific disable-pullup function i
173 +                * - enable +Vbus (if hardware supports it)
174 +                */
175 +               s3c2410_gpio_setpin(S3C2410_GPB9, 0);
176 +       } else if (!strncmp(buf, "device", 6)) {
177 +               printk(KERN_WARNING "s3c2410: changing usb to device\n");
178 +               s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, 0);
179 +               s3c2410_gpio_setpin(S3C2410_GPB9, 1);
180 +       } else {
181 +               printk(KERN_WARNING "s3c2410: unknown mode\n");
182 +               return -EINVAL;
183 +       }
184 +
185 +       return count;
186 +}
187 +
188 +static DEVICE_ATTR(usb_mode, S_IRUGO | S_IWUSR, show_usb_mode, set_usb_mode);
189 +
190  /* may be called without controller electrically present */
191  /* may be called with controller, bus, and devices active */
192  
193 @@ -486,15 +524,23 @@
194         return 0;
195  }
196  
197 +static int ohci_hcd_s3c2410_drv_resume(struct platform_device *pdev)
198 +{
199 +       struct usb_hcd *hcd = platform_get_drvdata(pdev);
200 +
201 +       ohci_finish_controller_resume(hcd);
202 +       return 0;
203 +}
204 +
205  static struct platform_driver ohci_hcd_s3c2410_driver = {
206         .probe          = ohci_hcd_s3c2410_drv_probe,
207         .remove         = ohci_hcd_s3c2410_drv_remove,
208         .shutdown       = usb_hcd_platform_shutdown,
209         /*.suspend      = ohci_hcd_s3c2410_drv_suspend, */
210 -       /*.resume       = ohci_hcd_s3c2410_drv_resume, */
211 +       .resume         = ohci_hcd_s3c2410_drv_resume,
212         .driver         = {
213                 .owner  = THIS_MODULE,
214 -               .name   = "s3c2410-ohci",
215 +               .name   = "s3c-ohci",
216         },
217  };
218  
219 Index: linux-2.6.30-rc6/arch/arm/plat-s3c24xx/include/plat/udc.h
220 ===================================================================
221 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c24xx/include/plat/udc.h      2009-05-16 06:12:57.000000000 +0200
222 +++ linux-2.6.30-rc6/arch/arm/plat-s3c24xx/include/plat/udc.h   2009-05-18 19:08:35.000000000 +0200
223 @@ -27,6 +27,7 @@
224  struct s3c2410_udc_mach_info {
225         void    (*udc_command)(enum s3c2410_udc_cmd_e);
226         void    (*vbus_draw)(unsigned int ma);
227 +       int     (*get_vbus_status)(void);
228         unsigned int vbus_pin;
229         unsigned char vbus_pin_inverted;
230  };