~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to drivers/usb/host/ehci-au1xxx.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#include <linux/platform_device.h>
15
15
#include <asm/mach-au1x00/au1000.h>
16
16
 
17
 
#define USB_HOST_CONFIG   (USB_MSR_BASE + USB_MSR_MCFG)
18
 
#define USB_MCFG_PFEN     (1<<31)
19
 
#define USB_MCFG_RDCOMB   (1<<30)
20
 
#define USB_MCFG_SSDEN    (1<<23)
21
 
#define USB_MCFG_PHYPLLEN (1<<19)
22
 
#define USB_MCFG_UCECLKEN (1<<18)
23
 
#define USB_MCFG_EHCCLKEN (1<<17)
24
 
#ifdef CONFIG_DMA_COHERENT
25
 
#define USB_MCFG_UCAM     (1<<7)
26
 
#else
27
 
#define USB_MCFG_UCAM     (0)
28
 
#endif
29
 
#define USB_MCFG_EBMEN    (1<<3)
30
 
#define USB_MCFG_EMEMEN   (1<<2)
31
 
 
32
 
#define USBH_ENABLE_CE  (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN)
33
 
#define USBH_ENABLE_INIT (USB_MCFG_PFEN  | USB_MCFG_RDCOMB |    \
34
 
                          USBH_ENABLE_CE | USB_MCFG_SSDEN  |    \
35
 
                          USB_MCFG_UCAM  | USB_MCFG_EBMEN  |    \
36
 
                          USB_MCFG_EMEMEN)
37
 
 
38
 
#define USBH_DISABLE      (USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
39
17
 
40
18
extern int usb_disabled(void);
41
19
 
42
 
static void au1xxx_start_ehc(void)
43
 
{
44
 
        /* enable clock to EHCI block and HS PHY PLL*/
45
 
        au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG);
46
 
        au_sync();
47
 
        udelay(1000);
48
 
 
49
 
        /* enable EHCI mmio */
50
 
        au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG);
51
 
        au_sync();
52
 
        udelay(1000);
53
 
}
54
 
 
55
 
static void au1xxx_stop_ehc(void)
56
 
{
57
 
        unsigned long c;
58
 
 
59
 
        /* Disable mem */
60
 
        au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG);
61
 
        au_sync();
62
 
        udelay(1000);
63
 
 
64
 
        /* Disable EHC clock. If the HS PHY is unused disable it too. */
65
 
        c = au_readl(USB_HOST_CONFIG) & ~USB_MCFG_EHCCLKEN;
66
 
        if (!(c & USB_MCFG_UCECLKEN))           /* UDC disabled? */
67
 
                c &= ~USB_MCFG_PHYPLLEN;        /* yes: disable HS PHY PLL */
68
 
        au_writel(c, USB_HOST_CONFIG);
69
 
        au_sync();
70
 
}
71
 
 
72
20
static int au1xxx_ehci_setup(struct usb_hcd *hcd)
73
21
{
74
22
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
136
84
        if (usb_disabled())
137
85
                return -ENODEV;
138
86
 
139
 
#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
140
 
        /* Au1200 AB USB does not support coherent memory */
141
 
        if (!(read_c0_prid() & 0xff)) {
142
 
                printk(KERN_INFO "%s: this is chip revision AB!\n", pdev->name);
143
 
                printk(KERN_INFO "%s: update your board or re-configure"
144
 
                                 " the kernel\n", pdev->name);
145
 
                return -ENODEV;
146
 
        }
147
 
#endif
148
 
 
149
87
        if (pdev->resource[1].flags != IORESOURCE_IRQ) {
150
88
                pr_debug("resource[1] is not IORESOURCE_IRQ");
151
89
                return -ENOMEM;
171
109
                goto err2;
172
110
        }
173
111
 
174
 
        au1xxx_start_ehc();
 
112
        if (alchemy_usb_control(ALCHEMY_USB_EHCI0, 1)) {
 
113
                printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
 
114
                ret = -ENODEV;
 
115
                goto err3;
 
116
        }
175
117
 
176
118
        ehci = hcd_to_ehci(hcd);
177
119
        ehci->caps = hcd->regs;
181
123
        ehci->hcs_params = readl(&ehci->caps->hcs_params);
182
124
 
183
125
        ret = usb_add_hcd(hcd, pdev->resource[1].start,
184
 
                          IRQF_DISABLED | IRQF_SHARED);
 
126
                          IRQF_SHARED);
185
127
        if (ret == 0) {
186
128
                platform_set_drvdata(pdev, hcd);
187
129
                return ret;
188
130
        }
189
131
 
190
 
        au1xxx_stop_ehc();
 
132
        alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
 
133
err3:
191
134
        iounmap(hcd->regs);
192
135
err2:
193
136
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
201
144
        struct usb_hcd *hcd = platform_get_drvdata(pdev);
202
145
 
203
146
        usb_remove_hcd(hcd);
 
147
        alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
204
148
        iounmap(hcd->regs);
205
149
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
206
150
        usb_put_hcd(hcd);
207
 
        au1xxx_stop_ehc();
208
151
        platform_set_drvdata(pdev, NULL);
209
152
 
210
153
        return 0;
236
179
        // could save FLADJ in case of Vaux power loss
237
180
        // ... we'd only use it to handle clock skew
238
181
 
239
 
        au1xxx_stop_ehc();
 
182
        alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
240
183
 
241
184
        return rc;
242
185
}
246
189
        struct usb_hcd *hcd = dev_get_drvdata(dev);
247
190
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
248
191
 
249
 
        au1xxx_start_ehc();
 
192
        alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
250
193
 
251
194
        // maybe restore FLADJ
252
195
 
293
236
        /* here we "know" root ports should always stay powered */
294
237
        ehci_port_power(ehci, 1);
295
238
 
296
 
        hcd->state = HC_STATE_SUSPENDED;
 
239
        ehci->rh_state = EHCI_RH_SUSPENDED;
297
240
 
298
241
        return 0;
299
242
}