Root/target/linux/s3c24xx/patches-2.6.30/100-udc-poll-vbus.patch

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

Archive Download this file



interactive