disable IMQ on 2.6.28 as well -- people should use IFB..
[openwrt.git] / target / linux / s3c24xx / patches / 0051-s3c2410-usb-switch.patch.patch
1 From 7cb1e9a0797dd5d372f943f0ed971a5b432d16aa Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Fri, 25 Jul 2008 22:21:23 +0100
4 Subject: [PATCH] s3c2410-usb-switch.patch
5
6 ---
7  drivers/usb/host/ohci-s3c2410.c |   43 +++++++++++++++++++++++++++++++++++++++
8  1 files changed, 43 insertions(+), 0 deletions(-)
9
10 diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
11 index 3c7a740..5877fc9 100644
12 --- a/drivers/usb/host/ohci-s3c2410.c
13 +++ b/drivers/usb/host/ohci-s3c2410.c
14 @@ -24,6 +24,7 @@
15  
16  #include <asm/hardware.h>
17  #include <asm/arch/usb-control.h>
18 +#include <asm/arch/regs-gpio.h>
19  
20  #define valid_port(idx) ((idx) == 1 || (idx) == 2)
21  
22 @@ -308,6 +309,40 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc)
23         local_irq_restore(flags);
24  }
25  
26 +/* switching of USB pads */
27 +static ssize_t show_usb_mode(struct device *dev, struct device_attribute *attr,
28 +                            char *buf)
29 +{
30 +       if (__raw_readl(S3C24XX_MISCCR) & S3C2410_MISCCR_USBHOST)
31 +               return sprintf(buf, "host\n");
32 +
33 +       return sprintf(buf, "device\n");
34 +}
35 +
36 +static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr,
37 +                           const char *buf, size_t count)
38 +{
39 +       if (!strncmp(buf, "host", 4)) {
40 +               printk("s3c2410: changing usb to host\n");
41 +               s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST,
42 +                                     S3C2410_MISCCR_USBHOST);
43 +               /* FIXME:
44 +                * - call machine-specific disable-pullup function i
45 +                * - enable +Vbus (if hardware supports it)
46 +                */
47 +               s3c2410_gpio_setpin(S3C2410_GPB9, 0);
48 +       } else if (!strncmp(buf, "device", 6)) {
49 +               printk("s3c2410: changing usb to device\n");
50 +               s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, 0);
51 +               s3c2410_gpio_setpin(S3C2410_GPB9, 1);
52 +       } else
53 +               printk("s3c2410: unknown mode\n");
54 +               return -EINVAL;
55 +       return count;
56 +}
57 +
58 +static DEVICE_ATTR(usb_mode, S_IRUGO | S_IWUSR, show_usb_mode, set_usb_mode);
59 +
60  /* may be called without controller electrically present */
61  /* may be called with controller, bus, and devices active */
62  
63 @@ -325,6 +360,7 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc)
64  static void
65  usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev)
66  {
67 +       device_remove_file(&dev->dev, &dev_attr_usb_mode);
68         usb_remove_hcd(hcd);
69         s3c2410_stop_hc(dev);
70         iounmap(hcd->regs);
71 @@ -392,8 +428,15 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
72         if (retval != 0)
73                 goto err_ioremap;
74  
75 +       retval = device_create_file(&dev->dev, &dev_attr_usb_mode);
76 +       if (retval != 0)
77 +               goto err_hcd;
78 +
79         return 0;
80  
81 + err_hcd:
82 +       usb_remove_hcd(hcd);
83 +
84   err_ioremap:
85         s3c2410_stop_hc(dev);
86         iounmap(hcd->regs);
87 -- 
88 1.5.6.3
89