diff options
-rw-r--r-- | arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h | 50 | ||||
-rw-r--r-- | arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h | 377 | ||||
-rw-r--r-- | drivers/usb/gadget/Kconfig | 14 | ||||
-rw-r--r-- | drivers/usb/gadget/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 3269 |
5 files changed, 3711 insertions, 0 deletions
diff --git a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h new file mode 100644 index 000000000000..36a85f5000c8 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C - USB2.0 Highspeed/OtG device PHY registers | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | /* Note, this is a seperate header file as some of the clock framework | ||
16 | * needs to touch this if the clk_48m is used as the USB OHCI or other | ||
17 | * peripheral source. | ||
18 | */ | ||
19 | |||
20 | #ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H | ||
21 | #define __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H __FILE__ | ||
22 | |||
23 | /* S3C64XX_PA_USB_HSPHY */ | ||
24 | |||
25 | #define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY) | ||
26 | |||
27 | #define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00) | ||
28 | #define SRC_PHYPWR_OTG_DISABLE (1 << 4) | ||
29 | #define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3) | ||
30 | #define SRC_PHYPWR_FORCE_SUSPEND (1 << 1) | ||
31 | |||
32 | #define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04) | ||
33 | #define S3C_PHYCLK_MODE_USB11 (1 << 6) | ||
34 | #define S3C_PHYCLK_EXT_OSC (1 << 5) | ||
35 | #define S3C_PHYCLK_CLK_FORCE (1 << 4) | ||
36 | #define S3C_PHYCLK_ID_PULL (1 << 2) | ||
37 | #define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0) | ||
38 | #define S3C_PHYCLK_CLKSEL_SHIFT (0) | ||
39 | #define S3C_PHYCLK_CLKSEL_48M (0x0 << 0) | ||
40 | #define S3C_PHYCLK_CLKSEL_12M (0x2 << 0) | ||
41 | #define S3C_PHYCLK_CLKSEL_24M (0x3 << 0) | ||
42 | |||
43 | #define S3C_RSTCON S3C_HSOTG_PHYREG(0x08) | ||
44 | #define S3C_RSTCON_PHYCLK (1 << 2) | ||
45 | #define S3C_RSTCON_HCLK (1 << 2) | ||
46 | #define S3C_RSTCON_PHY (1 << 0) | ||
47 | |||
48 | #define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20) | ||
49 | |||
50 | #endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H */ | ||
diff --git a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h b/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h new file mode 100644 index 000000000000..8d18d9d4d148 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h | |||
@@ -0,0 +1,377 @@ | |||
1 | /* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C - USB2.0 Highspeed/OtG device block registers | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_H | ||
16 | #define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__ | ||
17 | |||
18 | #define S3C_HSOTG_REG(x) (x) | ||
19 | |||
20 | #define S3C_GOTGCTL S3C_HSOTG_REG(0x000) | ||
21 | #define S3C_GOTGCTL_BSESVLD (1 << 19) | ||
22 | #define S3C_GOTGCTL_ASESVLD (1 << 18) | ||
23 | #define S3C_GOTGCTL_DBNC_SHORT (1 << 17) | ||
24 | #define S3C_GOTGCTL_CONID_B (1 << 16) | ||
25 | #define S3C_GOTGCTL_DEVHNPEN (1 << 11) | ||
26 | #define S3C_GOTGCTL_HSSETHNPEN (1 << 10) | ||
27 | #define S3C_GOTGCTL_HNPREQ (1 << 9) | ||
28 | #define S3C_GOTGCTL_HSTNEGSCS (1 << 8) | ||
29 | #define S3C_GOTGCTL_SESREQ (1 << 1) | ||
30 | #define S3C_GOTGCTL_SESREQSCS (1 << 0) | ||
31 | |||
32 | #define S3C_GOTGINT S3C_HSOTG_REG(0x004) | ||
33 | #define S3C_GOTGINT_DbnceDone (1 << 19) | ||
34 | #define S3C_GOTGINT_ADevTOUTChg (1 << 18) | ||
35 | #define S3C_GOTGINT_HstNegDet (1 << 17) | ||
36 | #define S3C_GOTGINT_HstnegSucStsChng (1 << 9) | ||
37 | #define S3C_GOTGINT_SesReqSucStsChng (1 << 8) | ||
38 | #define S3C_GOTGINT_SesEndDet (1 << 2) | ||
39 | |||
40 | #define S3C_GAHBCFG S3C_HSOTG_REG(0x008) | ||
41 | #define S3C_GAHBCFG_PTxFEmpLvl (1 << 8) | ||
42 | #define S3C_GAHBCFG_NPTxFEmpLvl (1 << 7) | ||
43 | #define S3C_GAHBCFG_DMAEn (1 << 5) | ||
44 | #define S3C_GAHBCFG_HBstLen_MASK (0xf << 1) | ||
45 | #define S3C_GAHBCFG_HBstLen_SHIFT (1) | ||
46 | #define S3C_GAHBCFG_HBstLen_Single (0x0 << 1) | ||
47 | #define S3C_GAHBCFG_HBstLen_Incr (0x1 << 1) | ||
48 | #define S3C_GAHBCFG_HBstLen_Incr4 (0x3 << 1) | ||
49 | #define S3C_GAHBCFG_HBstLen_Incr8 (0x5 << 1) | ||
50 | #define S3C_GAHBCFG_HBstLen_Incr16 (0x7 << 1) | ||
51 | #define S3C_GAHBCFG_GlblIntrEn (1 << 0) | ||
52 | |||
53 | #define S3C_GUSBCFG S3C_HSOTG_REG(0x00C) | ||
54 | #define S3C_GUSBCFG_PHYLPClkSel (1 << 15) | ||
55 | #define S3C_GUSBCFG_HNPCap (1 << 9) | ||
56 | #define S3C_GUSBCFG_SRPCap (1 << 8) | ||
57 | #define S3C_GUSBCFG_PHYIf16 (1 << 3) | ||
58 | #define S3C_GUSBCFG_TOutCal_MASK (0x7 << 0) | ||
59 | #define S3C_GUSBCFG_TOutCal_SHIFT (0) | ||
60 | #define S3C_GUSBCFG_TOutCal_LIMIT (0x7) | ||
61 | #define S3C_GUSBCFG_TOutCal(_x) ((_x) << 0) | ||
62 | |||
63 | #define S3C_GRSTCTL S3C_HSOTG_REG(0x010) | ||
64 | |||
65 | #define S3C_GRSTCTL_AHBIdle (1 << 31) | ||
66 | #define S3C_GRSTCTL_DMAReq (1 << 30) | ||
67 | #define S3C_GRSTCTL_TxFNum_MASK (0x1f << 6) | ||
68 | #define S3C_GRSTCTL_TxFNum_SHIFT (6) | ||
69 | #define S3C_GRSTCTL_TxFNum_LIMIT (0x1f) | ||
70 | #define S3C_GRSTCTL_TxFNum(_x) ((_x) << 6) | ||
71 | #define S3C_GRSTCTL_TxFFlsh (1 << 5) | ||
72 | #define S3C_GRSTCTL_RxFFlsh (1 << 4) | ||
73 | #define S3C_GRSTCTL_INTknQFlsh (1 << 3) | ||
74 | #define S3C_GRSTCTL_FrmCntrRst (1 << 2) | ||
75 | #define S3C_GRSTCTL_HSftRst (1 << 1) | ||
76 | #define S3C_GRSTCTL_CSftRst (1 << 0) | ||
77 | |||
78 | #define S3C_GINTSTS S3C_HSOTG_REG(0x014) | ||
79 | #define S3C_GINTMSK S3C_HSOTG_REG(0x018) | ||
80 | |||
81 | #define S3C_GINTSTS_WkUpInt (1 << 31) | ||
82 | #define S3C_GINTSTS_SessReqInt (1 << 30) | ||
83 | #define S3C_GINTSTS_DisconnInt (1 << 29) | ||
84 | #define S3C_GINTSTS_ConIDStsChng (1 << 28) | ||
85 | #define S3C_GINTSTS_PTxFEmp (1 << 26) | ||
86 | #define S3C_GINTSTS_HChInt (1 << 25) | ||
87 | #define S3C_GINTSTS_PrtInt (1 << 24) | ||
88 | #define S3C_GINTSTS_FetSusp (1 << 22) | ||
89 | #define S3C_GINTSTS_incompIP (1 << 21) | ||
90 | #define S3C_GINTSTS_IncomplSOIN (1 << 20) | ||
91 | #define S3C_GINTSTS_OEPInt (1 << 19) | ||
92 | #define S3C_GINTSTS_IEPInt (1 << 18) | ||
93 | #define S3C_GINTSTS_EPMis (1 << 17) | ||
94 | #define S3C_GINTSTS_EOPF (1 << 15) | ||
95 | #define S3C_GINTSTS_ISOutDrop (1 << 14) | ||
96 | #define S3C_GINTSTS_EnumDone (1 << 13) | ||
97 | #define S3C_GINTSTS_USBRst (1 << 12) | ||
98 | #define S3C_GINTSTS_USBSusp (1 << 11) | ||
99 | #define S3C_GINTSTS_ErlySusp (1 << 10) | ||
100 | #define S3C_GINTSTS_GOUTNakEff (1 << 7) | ||
101 | #define S3C_GINTSTS_GINNakEff (1 << 6) | ||
102 | #define S3C_GINTSTS_NPTxFEmp (1 << 5) | ||
103 | #define S3C_GINTSTS_RxFLvl (1 << 4) | ||
104 | #define S3C_GINTSTS_SOF (1 << 3) | ||
105 | #define S3C_GINTSTS_OTGInt (1 << 2) | ||
106 | #define S3C_GINTSTS_ModeMis (1 << 1) | ||
107 | #define S3C_GINTSTS_CurMod_Host (1 << 0) | ||
108 | |||
109 | #define S3C_GRXSTSR S3C_HSOTG_REG(0x01C) | ||
110 | #define S3C_GRXSTSP S3C_HSOTG_REG(0x020) | ||
111 | |||
112 | #define S3C_GRXSTS_FN_MASK (0x7f << 25) | ||
113 | #define S3C_GRXSTS_FN_SHIFT (25) | ||
114 | |||
115 | #define S3C_GRXSTS_PktSts_MASK (0xf << 17) | ||
116 | #define S3C_GRXSTS_PktSts_SHIFT (17) | ||
117 | #define S3C_GRXSTS_PktSts_GlobalOutNAK (0x1 << 17) | ||
118 | #define S3C_GRXSTS_PktSts_OutRX (0x2 << 17) | ||
119 | #define S3C_GRXSTS_PktSts_OutDone (0x3 << 17) | ||
120 | #define S3C_GRXSTS_PktSts_SetupDone (0x4 << 17) | ||
121 | #define S3C_GRXSTS_PktSts_SetupRX (0x6 << 17) | ||
122 | |||
123 | #define S3C_GRXSTS_DPID_MASK (0x3 << 15) | ||
124 | #define S3C_GRXSTS_DPID_SHIFT (15) | ||
125 | #define S3C_GRXSTS_ByteCnt_MASK (0x7ff << 4) | ||
126 | #define S3C_GRXSTS_ByteCnt_SHIFT (4) | ||
127 | #define S3C_GRXSTS_EPNum_MASK (0xf << 0) | ||
128 | #define S3C_GRXSTS_EPNum_SHIFT (0) | ||
129 | |||
130 | #define S3C_GRXFSIZ S3C_HSOTG_REG(0x024) | ||
131 | |||
132 | #define S3C_GNPTXFSIZ S3C_HSOTG_REG(0x028) | ||
133 | |||
134 | #define S3C_GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16) | ||
135 | #define S3C_GNPTXFSIZ_NPTxFDep_SHIFT (16) | ||
136 | #define S3C_GNPTXFSIZ_NPTxFDep_LIMIT (0xffff) | ||
137 | #define S3C_GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16) | ||
138 | #define S3C_GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0) | ||
139 | #define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT (0) | ||
140 | #define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff) | ||
141 | #define S3C_GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0) | ||
142 | |||
143 | #define S3C_GNPTXSTS S3C_HSOTG_REG(0x02C) | ||
144 | |||
145 | #define S3C_GNPTXSTS_NPtxQTop_MASK (0x7f << 24) | ||
146 | #define S3C_GNPTXSTS_NPtxQTop_SHIFT (24) | ||
147 | |||
148 | #define S3C_GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16) | ||
149 | #define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT (16) | ||
150 | #define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff) | ||
151 | |||
152 | #define S3C_GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0) | ||
153 | #define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT (0) | ||
154 | #define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff) | ||
155 | |||
156 | |||
157 | #define S3C_HPTXFSIZ S3C_HSOTG_REG(0x100) | ||
158 | |||
159 | #define S3C_DPTXFSIZn(_a) S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4)) | ||
160 | |||
161 | #define S3C_DPTXFSIZn_DPTxFSize_MASK (0xffff << 16) | ||
162 | #define S3C_DPTXFSIZn_DPTxFSize_SHIFT (16) | ||
163 | #define S3C_DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff) | ||
164 | #define S3C_DPTXFSIZn_DPTxFSize_LIMIT (0xffff) | ||
165 | #define S3C_DPTXFSIZn_DPTxFSize(_x) ((_x) << 16) | ||
166 | |||
167 | #define S3C_DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0) | ||
168 | #define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT (0) | ||
169 | |||
170 | /* Device mode registers */ | ||
171 | #define S3C_DCFG S3C_HSOTG_REG(0x800) | ||
172 | |||
173 | #define S3C_DCFG_EPMisCnt_MASK (0x1f << 18) | ||
174 | #define S3C_DCFG_EPMisCnt_SHIFT (18) | ||
175 | #define S3C_DCFG_EPMisCnt_LIMIT (0x1f) | ||
176 | #define S3C_DCFG_EPMisCnt(_x) ((_x) << 18) | ||
177 | |||
178 | #define S3C_DCFG_PerFrInt_MASK (0x3 << 11) | ||
179 | #define S3C_DCFG_PerFrInt_SHIFT (11) | ||
180 | #define S3C_DCFG_PerFrInt_LIMIT (0x3) | ||
181 | #define S3C_DCFG_PerFrInt(_x) ((_x) << 11) | ||
182 | |||
183 | #define S3C_DCFG_DevAddr_MASK (0x7f << 4) | ||
184 | #define S3C_DCFG_DevAddr_SHIFT (4) | ||
185 | #define S3C_DCFG_DevAddr_LIMIT (0x7f) | ||
186 | #define S3C_DCFG_DevAddr(_x) ((_x) << 4) | ||
187 | |||
188 | #define S3C_DCFG_NZStsOUTHShk (1 << 2) | ||
189 | |||
190 | #define S3C_DCFG_DevSpd_MASK (0x3 << 0) | ||
191 | #define S3C_DCFG_DevSpd_SHIFT (0) | ||
192 | #define S3C_DCFG_DevSpd_HS (0x0 << 0) | ||
193 | #define S3C_DCFG_DevSpd_FS (0x1 << 0) | ||
194 | #define S3C_DCFG_DevSpd_LS (0x2 << 0) | ||
195 | #define S3C_DCFG_DevSpd_FS48 (0x3 << 0) | ||
196 | |||
197 | #define S3C_DCTL S3C_HSOTG_REG(0x804) | ||
198 | |||
199 | #define S3C_DCTL_PWROnPrgDone (1 << 11) | ||
200 | #define S3C_DCTL_CGOUTNak (1 << 10) | ||
201 | #define S3C_DCTL_SGOUTNak (1 << 9) | ||
202 | #define S3C_DCTL_CGNPInNAK (1 << 8) | ||
203 | #define S3C_DCTL_SGNPInNAK (1 << 7) | ||
204 | #define S3C_DCTL_TstCtl_MASK (0x7 << 4) | ||
205 | #define S3C_DCTL_TstCtl_SHIFT (4) | ||
206 | #define S3C_DCTL_GOUTNakSts (1 << 3) | ||
207 | #define S3C_DCTL_GNPINNakSts (1 << 2) | ||
208 | #define S3C_DCTL_SftDiscon (1 << 1) | ||
209 | #define S3C_DCTL_RmtWkUpSig (1 << 0) | ||
210 | |||
211 | #define S3C_DSTS S3C_HSOTG_REG(0x808) | ||
212 | |||
213 | #define S3C_DSTS_SOFFN_MASK (0x3fff << 8) | ||
214 | #define S3C_DSTS_SOFFN_SHIFT (8) | ||
215 | #define S3C_DSTS_SOFFN_LIMIT (0x3fff) | ||
216 | #define S3C_DSTS_SOFFN(_x) ((_x) << 8) | ||
217 | #define S3C_DSTS_ErraticErr (1 << 3) | ||
218 | #define S3C_DSTS_EnumSpd_MASK (0x3 << 1) | ||
219 | #define S3C_DSTS_EnumSpd_SHIFT (1) | ||
220 | #define S3C_DSTS_EnumSpd_HS (0x0 << 1) | ||
221 | #define S3C_DSTS_EnumSpd_FS (0x1 << 1) | ||
222 | #define S3C_DSTS_EnumSpd_LS (0x2 << 1) | ||
223 | #define S3C_DSTS_EnumSpd_FS48 (0x3 << 1) | ||
224 | |||
225 | #define S3C_DSTS_SuspSts (1 << 0) | ||
226 | |||
227 | #define S3C_DIEPMSK S3C_HSOTG_REG(0x810) | ||
228 | |||
229 | #define S3C_DIEPMSK_INEPNakEffMsk (1 << 6) | ||
230 | #define S3C_DIEPMSK_INTknEPMisMsk (1 << 5) | ||
231 | #define S3C_DIEPMSK_INTknTXFEmpMsk (1 << 4) | ||
232 | #define S3C_DIEPMSK_TimeOUTMsk (1 << 3) | ||
233 | #define S3C_DIEPMSK_AHBErrMsk (1 << 2) | ||
234 | #define S3C_DIEPMSK_EPDisbldMsk (1 << 1) | ||
235 | #define S3C_DIEPMSK_XferComplMsk (1 << 0) | ||
236 | |||
237 | #define S3C_DOEPMSK S3C_HSOTG_REG(0x814) | ||
238 | |||
239 | #define S3C_DOEPMSK_Back2BackSetup (1 << 6) | ||
240 | #define S3C_DOEPMSK_OUTTknEPdisMsk (1 << 4) | ||
241 | #define S3C_DOEPMSK_SetupMsk (1 << 3) | ||
242 | #define S3C_DOEPMSK_AHBErrMsk (1 << 2) | ||
243 | #define S3C_DOEPMSK_EPDisbldMsk (1 << 1) | ||
244 | #define S3C_DOEPMSK_XferComplMsk (1 << 0) | ||
245 | |||
246 | #define S3C_DAINT S3C_HSOTG_REG(0x818) | ||
247 | #define S3C_DAINTMSK S3C_HSOTG_REG(0x81C) | ||
248 | |||
249 | #define S3C_DAINT_OutEP_SHIFT (16) | ||
250 | #define S3C_DAINT_OutEP(x) (1 << ((x) + 16)) | ||
251 | #define S3C_DAINT_InEP(x) (1 << (x)) | ||
252 | |||
253 | #define S3C_DTKNQR1 S3C_HSOTG_REG(0x820) | ||
254 | #define S3C_DTKNQR2 S3C_HSOTG_REG(0x824) | ||
255 | #define S3C_DTKNQR3 S3C_HSOTG_REG(0x830) | ||
256 | #define S3C_DTKNQR4 S3C_HSOTG_REG(0x834) | ||
257 | |||
258 | #define S3C_DVBUSDIS S3C_HSOTG_REG(0x828) | ||
259 | #define S3C_DVBUSPULSE S3C_HSOTG_REG(0x82C) | ||
260 | |||
261 | #define S3C_DIEPCTL0 S3C_HSOTG_REG(0x900) | ||
262 | #define S3C_DOEPCTL0 S3C_HSOTG_REG(0xB00) | ||
263 | #define S3C_DIEPCTL(_a) S3C_HSOTG_REG(0x900 + ((_a) * 0x20)) | ||
264 | #define S3C_DOEPCTL(_a) S3C_HSOTG_REG(0xB00 + ((_a) * 0x20)) | ||
265 | |||
266 | /* EP0 specialness: | ||
267 | * bits[29..28] - reserved (no SetD0PID, SetD1PID) | ||
268 | * bits[25..22] - should always be zero, this isn't a periodic endpoint | ||
269 | * bits[10..0] - MPS setting differenct for EP0 | ||
270 | */ | ||
271 | #define S3C_D0EPCTL_MPS_MASK (0x3 << 0) | ||
272 | #define S3C_D0EPCTL_MPS_SHIFT (0) | ||
273 | #define S3C_D0EPCTL_MPS_64 (0x0 << 0) | ||
274 | #define S3C_D0EPCTL_MPS_32 (0x1 << 0) | ||
275 | #define S3C_D0EPCTL_MPS_16 (0x2 << 0) | ||
276 | #define S3C_D0EPCTL_MPS_8 (0x3 << 0) | ||
277 | |||
278 | #define S3C_DxEPCTL_EPEna (1 << 31) | ||
279 | #define S3C_DxEPCTL_EPDis (1 << 30) | ||
280 | #define S3C_DxEPCTL_SetD1PID (1 << 29) | ||
281 | #define S3C_DxEPCTL_SetOddFr (1 << 29) | ||
282 | #define S3C_DxEPCTL_SetD0PID (1 << 28) | ||
283 | #define S3C_DxEPCTL_SetEvenFr (1 << 28) | ||
284 | #define S3C_DxEPCTL_SNAK (1 << 27) | ||
285 | #define S3C_DxEPCTL_CNAK (1 << 26) | ||
286 | #define S3C_DxEPCTL_TxFNum_MASK (0xf << 22) | ||
287 | #define S3C_DxEPCTL_TxFNum_SHIFT (22) | ||
288 | #define S3C_DxEPCTL_TxFNum_LIMIT (0xf) | ||
289 | #define S3C_DxEPCTL_TxFNum(_x) ((_x) << 22) | ||
290 | |||
291 | #define S3C_DxEPCTL_Stall (1 << 21) | ||
292 | #define S3C_DxEPCTL_Snp (1 << 20) | ||
293 | #define S3C_DxEPCTL_EPType_MASK (0x3 << 18) | ||
294 | #define S3C_DxEPCTL_EPType_SHIFT (18) | ||
295 | #define S3C_DxEPCTL_EPType_Control (0x0 << 18) | ||
296 | #define S3C_DxEPCTL_EPType_Iso (0x1 << 18) | ||
297 | #define S3C_DxEPCTL_EPType_Bulk (0x2 << 18) | ||
298 | #define S3C_DxEPCTL_EPType_Intterupt (0x3 << 18) | ||
299 | |||
300 | #define S3C_DxEPCTL_NAKsts (1 << 17) | ||
301 | #define S3C_DxEPCTL_DPID (1 << 16) | ||
302 | #define S3C_DxEPCTL_EOFrNum (1 << 16) | ||
303 | #define S3C_DxEPCTL_USBActEp (1 << 15) | ||
304 | #define S3C_DxEPCTL_NextEp_MASK (0xf << 11) | ||
305 | #define S3C_DxEPCTL_NextEp_SHIFT (11) | ||
306 | #define S3C_DxEPCTL_NextEp_LIMIT (0xf) | ||
307 | #define S3C_DxEPCTL_NextEp(_x) ((_x) << 11) | ||
308 | |||
309 | #define S3C_DxEPCTL_MPS_MASK (0x7ff << 0) | ||
310 | #define S3C_DxEPCTL_MPS_SHIFT (0) | ||
311 | #define S3C_DxEPCTL_MPS_LIMIT (0x7ff) | ||
312 | #define S3C_DxEPCTL_MPS(_x) ((_x) << 0) | ||
313 | |||
314 | #define S3C_DIEPINT(_a) S3C_HSOTG_REG(0x908 + ((_a) * 0x20)) | ||
315 | #define S3C_DOEPINT(_a) S3C_HSOTG_REG(0xB08 + ((_a) * 0x20)) | ||
316 | |||
317 | #define S3C_DxEPINT_INEPNakEff (1 << 6) | ||
318 | #define S3C_DxEPINT_Back2BackSetup (1 << 6) | ||
319 | #define S3C_DxEPINT_INTknEPMis (1 << 5) | ||
320 | #define S3C_DxEPINT_INTknTXFEmp (1 << 4) | ||
321 | #define S3C_DxEPINT_OUTTknEPdis (1 << 4) | ||
322 | #define S3C_DxEPINT_Timeout (1 << 3) | ||
323 | #define S3C_DxEPINT_Setup (1 << 3) | ||
324 | #define S3C_DxEPINT_AHBErr (1 << 2) | ||
325 | #define S3C_DxEPINT_EPDisbld (1 << 1) | ||
326 | #define S3C_DxEPINT_XferCompl (1 << 0) | ||
327 | |||
328 | #define S3C_DIEPTSIZ0 S3C_HSOTG_REG(0x910) | ||
329 | |||
330 | #define S3C_DIEPTSIZ0_PktCnt_MASK (0x3 << 19) | ||
331 | #define S3C_DIEPTSIZ0_PktCnt_SHIFT (19) | ||
332 | #define S3C_DIEPTSIZ0_PktCnt_LIMIT (0x3) | ||
333 | #define S3C_DIEPTSIZ0_PktCnt(_x) ((_x) << 19) | ||
334 | |||
335 | #define S3C_DIEPTSIZ0_XferSize_MASK (0x7f << 0) | ||
336 | #define S3C_DIEPTSIZ0_XferSize_SHIFT (0) | ||
337 | #define S3C_DIEPTSIZ0_XferSize_LIMIT (0x7f) | ||
338 | #define S3C_DIEPTSIZ0_XferSize(_x) ((_x) << 0) | ||
339 | |||
340 | |||
341 | #define DOEPTSIZ0 S3C_HSOTG_REG(0xB10) | ||
342 | #define S3C_DOEPTSIZ0_SUPCnt_MASK (0x3 << 29) | ||
343 | #define S3C_DOEPTSIZ0_SUPCnt_SHIFT (29) | ||
344 | #define S3C_DOEPTSIZ0_SUPCnt_LIMIT (0x3) | ||
345 | #define S3C_DOEPTSIZ0_SUPCnt(_x) ((_x) << 29) | ||
346 | |||
347 | #define S3C_DOEPTSIZ0_PktCnt (1 << 19) | ||
348 | #define S3C_DOEPTSIZ0_XferSize_MASK (0x7f << 0) | ||
349 | #define S3C_DOEPTSIZ0_XferSize_SHIFT (0) | ||
350 | |||
351 | #define S3C_DIEPTSIZ(_a) S3C_HSOTG_REG(0x910 + ((_a) * 0x20)) | ||
352 | #define S3C_DOEPTSIZ(_a) S3C_HSOTG_REG(0xB10 + ((_a) * 0x20)) | ||
353 | |||
354 | #define S3C_DxEPTSIZ_MC_MASK (0x3 << 29) | ||
355 | #define S3C_DxEPTSIZ_MC_SHIFT (29) | ||
356 | #define S3C_DxEPTSIZ_MC_LIMIT (0x3) | ||
357 | #define S3C_DxEPTSIZ_MC(_x) ((_x) << 29) | ||
358 | |||
359 | #define S3C_DxEPTSIZ_PktCnt_MASK (0x3ff << 19) | ||
360 | #define S3C_DxEPTSIZ_PktCnt_SHIFT (19) | ||
361 | #define S3C_DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff) | ||
362 | #define S3C_DxEPTSIZ_PktCnt_LIMIT (0x3ff) | ||
363 | #define S3C_DxEPTSIZ_PktCnt(_x) ((_x) << 19) | ||
364 | |||
365 | #define S3C_DxEPTSIZ_XferSize_MASK (0x7ffff << 0) | ||
366 | #define S3C_DxEPTSIZ_XferSize_SHIFT (0) | ||
367 | #define S3C_DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff) | ||
368 | #define S3C_DxEPTSIZ_XferSize_LIMIT (0x7ffff) | ||
369 | #define S3C_DxEPTSIZ_XferSize(_x) ((_x) << 0) | ||
370 | |||
371 | |||
372 | #define S3C_DIEPDMA(_a) S3C_HSOTG_REG(0x914 + ((_a) * 0x20)) | ||
373 | #define S3C_DOEPDMA(_a) S3C_HSOTG_REG(0xB14 + ((_a) * 0x20)) | ||
374 | |||
375 | #define S3C_EPFIFO(_a) S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000)) | ||
376 | |||
377 | #endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */ | ||
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 5de9b4f21713..924bb7a1cecf 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -272,6 +272,20 @@ config USB_PXA27X | |||
272 | default USB_GADGET | 272 | default USB_GADGET |
273 | select USB_GADGET_SELECTED | 273 | select USB_GADGET_SELECTED |
274 | 274 | ||
275 | config USB_GADGET_S3C_HSOTG | ||
276 | boolean "S3C HS/OtG USB Device controller" | ||
277 | depends on S3C_DEV_USB_HSOTG | ||
278 | select USB_GADGET_S3C_HSOTG_PIO | ||
279 | help | ||
280 | The Samsung S3C64XX USB2.0 high-speed gadget controller | ||
281 | integrated into the S3C64XX series SoC. | ||
282 | |||
283 | config USB_S3C_HSOTG | ||
284 | tristate | ||
285 | depends on USB_GADGET_S3C_HSOTG | ||
286 | default USB_GADGET | ||
287 | select USB_GADGET_SELECTED | ||
288 | |||
275 | config USB_GADGET_S3C2410 | 289 | config USB_GADGET_S3C2410 |
276 | boolean "S3C2410 USB Device Controller" | 290 | boolean "S3C2410 USB Device Controller" |
277 | depends on ARCH_S3C2410 | 291 | depends on ARCH_S3C2410 |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index c3fe06396b74..9be2fbd6f5c2 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -25,6 +25,7 @@ endif | |||
25 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | 25 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
26 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | 26 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o |
27 | obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o | 27 | obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o |
28 | obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o | ||
28 | 29 | ||
29 | # | 30 | # |
30 | # USB gadget drivers | 31 | # USB gadget drivers |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c new file mode 100644 index 000000000000..50c71aae2cc2 --- /dev/null +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -0,0 +1,3269 @@ | |||
1 | /* linux/drivers/usb/gadget/s3c-hsotg.c | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * S3C USB2.0 High-speed / OtG driver | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/dma-mapping.h> | ||
21 | #include <linux/debugfs.h> | ||
22 | #include <linux/seq_file.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #include <linux/usb/ch9.h> | ||
27 | #include <linux/usb/gadget.h> | ||
28 | |||
29 | #include <mach/map.h> | ||
30 | |||
31 | #include <plat/regs-usb-hsotg-phy.h> | ||
32 | #include <plat/regs-usb-hsotg.h> | ||
33 | #include <plat/regs-sys.h> | ||
34 | #include <plat/udc-hs.h> | ||
35 | |||
36 | #define DMA_ADDR_INVALID (~((dma_addr_t)0)) | ||
37 | |||
38 | /* EP0_MPS_LIMIT | ||
39 | * | ||
40 | * Unfortunately there seems to be a limit of the amount of data that can | ||
41 | * be transfered by IN transactions on EP0. This is either 127 bytes or 3 | ||
42 | * packets (which practially means 1 packet and 63 bytes of data) when the | ||
43 | * MPS is set to 64. | ||
44 | * | ||
45 | * This means if we are wanting to move >127 bytes of data, we need to | ||
46 | * split the transactions up, but just doing one packet at a time does | ||
47 | * not work (this may be an implicit DATA0 PID on first packet of the | ||
48 | * transaction) and doing 2 packets is outside the controller's limits. | ||
49 | * | ||
50 | * If we try to lower the MPS size for EP0, then no transfers work properly | ||
51 | * for EP0, and the system will fail basic enumeration. As no cause for this | ||
52 | * has currently been found, we cannot support any large IN transfers for | ||
53 | * EP0. | ||
54 | */ | ||
55 | #define EP0_MPS_LIMIT 64 | ||
56 | |||
57 | struct s3c_hsotg; | ||
58 | struct s3c_hsotg_req; | ||
59 | |||
60 | /** | ||
61 | * struct s3c_hsotg_ep - driver endpoint definition. | ||
62 | * @ep: The gadget layer representation of the endpoint. | ||
63 | * @name: The driver generated name for the endpoint. | ||
64 | * @queue: Queue of requests for this endpoint. | ||
65 | * @parent: Reference back to the parent device structure. | ||
66 | * @req: The current request that the endpoint is processing. This is | ||
67 | * used to indicate an request has been loaded onto the endpoint | ||
68 | * and has yet to be completed (maybe due to data move, or simply | ||
69 | * awaiting an ack from the core all the data has been completed). | ||
70 | * @debugfs: File entry for debugfs file for this endpoint. | ||
71 | * @lock: State lock to protect contents of endpoint. | ||
72 | * @dir_in: Set to true if this endpoint is of the IN direction, which | ||
73 | * means that it is sending data to the Host. | ||
74 | * @index: The index for the endpoint registers. | ||
75 | * @name: The name array passed to the USB core. | ||
76 | * @halted: Set if the endpoint has been halted. | ||
77 | * @periodic: Set if this is a periodic ep, such as Interrupt | ||
78 | * @sent_zlp: Set if we've sent a zero-length packet. | ||
79 | * @total_data: The total number of data bytes done. | ||
80 | * @fifo_size: The size of the FIFO (for periodic IN endpoints) | ||
81 | * @fifo_load: The amount of data loaded into the FIFO (periodic IN) | ||
82 | * @last_load: The offset of data for the last start of request. | ||
83 | * @size_loaded: The last loaded size for DxEPTSIZE for periodic IN | ||
84 | * | ||
85 | * This is the driver's state for each registered enpoint, allowing it | ||
86 | * to keep track of transactions that need doing. Each endpoint has a | ||
87 | * lock to protect the state, to try and avoid using an overall lock | ||
88 | * for the host controller as much as possible. | ||
89 | * | ||
90 | * For periodic IN endpoints, we have fifo_size and fifo_load to try | ||
91 | * and keep track of the amount of data in the periodic FIFO for each | ||
92 | * of these as we don't have a status register that tells us how much | ||
93 | * is in each of them. | ||
94 | */ | ||
95 | struct s3c_hsotg_ep { | ||
96 | struct usb_ep ep; | ||
97 | struct list_head queue; | ||
98 | struct s3c_hsotg *parent; | ||
99 | struct s3c_hsotg_req *req; | ||
100 | struct dentry *debugfs; | ||
101 | |||
102 | spinlock_t lock; | ||
103 | |||
104 | unsigned long total_data; | ||
105 | unsigned int size_loaded; | ||
106 | unsigned int last_load; | ||
107 | unsigned int fifo_load; | ||
108 | unsigned short fifo_size; | ||
109 | |||
110 | unsigned char dir_in; | ||
111 | unsigned char index; | ||
112 | |||
113 | unsigned int halted:1; | ||
114 | unsigned int periodic:1; | ||
115 | unsigned int sent_zlp:1; | ||
116 | |||
117 | char name[10]; | ||
118 | }; | ||
119 | |||
120 | #define S3C_HSOTG_EPS (8+1) /* limit to 9 for the moment */ | ||
121 | |||
122 | /** | ||
123 | * struct s3c_hsotg - driver state. | ||
124 | * @dev: The parent device supplied to the probe function | ||
125 | * @driver: USB gadget driver | ||
126 | * @plat: The platform specific configuration data. | ||
127 | * @regs: The memory area mapped for accessing registers. | ||
128 | * @regs_res: The resource that was allocated when claiming register space. | ||
129 | * @irq: The IRQ number we are using | ||
130 | * @debug_root: root directrory for debugfs. | ||
131 | * @debug_file: main status file for debugfs. | ||
132 | * @debug_fifo: FIFO status file for debugfs. | ||
133 | * @ep0_reply: Request used for ep0 reply. | ||
134 | * @ep0_buff: Buffer for EP0 reply data, if needed. | ||
135 | * @ctrl_buff: Buffer for EP0 control requests. | ||
136 | * @ctrl_req: Request for EP0 control packets. | ||
137 | * @eps: The endpoints being supplied to the gadget framework | ||
138 | */ | ||
139 | struct s3c_hsotg { | ||
140 | struct device *dev; | ||
141 | struct usb_gadget_driver *driver; | ||
142 | struct s3c_hsotg_plat *plat; | ||
143 | |||
144 | void __iomem *regs; | ||
145 | struct resource *regs_res; | ||
146 | int irq; | ||
147 | |||
148 | struct dentry *debug_root; | ||
149 | struct dentry *debug_file; | ||
150 | struct dentry *debug_fifo; | ||
151 | |||
152 | struct usb_request *ep0_reply; | ||
153 | struct usb_request *ctrl_req; | ||
154 | u8 ep0_buff[8]; | ||
155 | u8 ctrl_buff[8]; | ||
156 | |||
157 | struct usb_gadget gadget; | ||
158 | struct s3c_hsotg_ep eps[]; | ||
159 | }; | ||
160 | |||
161 | /** | ||
162 | * struct s3c_hsotg_req - data transfer request | ||
163 | * @req: The USB gadget request | ||
164 | * @queue: The list of requests for the endpoint this is queued for. | ||
165 | * @in_progress: Has already had size/packets written to core | ||
166 | * @mapped: DMA buffer for this request has been mapped via dma_map_single(). | ||
167 | */ | ||
168 | struct s3c_hsotg_req { | ||
169 | struct usb_request req; | ||
170 | struct list_head queue; | ||
171 | unsigned char in_progress; | ||
172 | unsigned char mapped; | ||
173 | }; | ||
174 | |||
175 | /* conversion functions */ | ||
176 | static inline struct s3c_hsotg_req *our_req(struct usb_request *req) | ||
177 | { | ||
178 | return container_of(req, struct s3c_hsotg_req, req); | ||
179 | } | ||
180 | |||
181 | static inline struct s3c_hsotg_ep *our_ep(struct usb_ep *ep) | ||
182 | { | ||
183 | return container_of(ep, struct s3c_hsotg_ep, ep); | ||
184 | } | ||
185 | |||
186 | static inline struct s3c_hsotg *to_hsotg(struct usb_gadget *gadget) | ||
187 | { | ||
188 | return container_of(gadget, struct s3c_hsotg, gadget); | ||
189 | } | ||
190 | |||
191 | static inline void __orr32(void __iomem *ptr, u32 val) | ||
192 | { | ||
193 | writel(readl(ptr) | val, ptr); | ||
194 | } | ||
195 | |||
196 | static inline void __bic32(void __iomem *ptr, u32 val) | ||
197 | { | ||
198 | writel(readl(ptr) & ~val, ptr); | ||
199 | } | ||
200 | |||
201 | /* forward decleration of functions */ | ||
202 | static void s3c_hsotg_dump(struct s3c_hsotg *hsotg); | ||
203 | |||
204 | /** | ||
205 | * using_dma - return the DMA status of the driver. | ||
206 | * @hsotg: The driver state. | ||
207 | * | ||
208 | * Return true if we're using DMA. | ||
209 | * | ||
210 | * Currently, we have the DMA support code worked into everywhere | ||
211 | * that needs it, but the AMBA DMA implementation in the hardware can | ||
212 | * only DMA from 32bit aligned addresses. This means that gadgets such | ||
213 | * as the CDC Ethernet cannot work as they often pass packets which are | ||
214 | * not 32bit aligned. | ||
215 | * | ||
216 | * Unfortunately the choice to use DMA or not is global to the controller | ||
217 | * and seems to be only settable when the controller is being put through | ||
218 | * a core reset. This means we either need to fix the gadgets to take | ||
219 | * account of DMA alignment, or add bounce buffers (yuerk). | ||
220 | * | ||
221 | * Until this issue is sorted out, we always return 'false'. | ||
222 | */ | ||
223 | static inline bool using_dma(struct s3c_hsotg *hsotg) | ||
224 | { | ||
225 | return false; /* support is not complete */ | ||
226 | } | ||
227 | |||
228 | /** | ||
229 | * s3c_hsotg_en_gsint - enable one or more of the general interrupt | ||
230 | * @hsotg: The device state | ||
231 | * @ints: A bitmask of the interrupts to enable | ||
232 | */ | ||
233 | static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints) | ||
234 | { | ||
235 | u32 gsintmsk = readl(hsotg->regs + S3C_GINTMSK); | ||
236 | u32 new_gsintmsk; | ||
237 | |||
238 | new_gsintmsk = gsintmsk | ints; | ||
239 | |||
240 | if (new_gsintmsk != gsintmsk) { | ||
241 | dev_dbg(hsotg->dev, "gsintmsk now 0x%08x\n", new_gsintmsk); | ||
242 | writel(new_gsintmsk, hsotg->regs + S3C_GINTMSK); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * s3c_hsotg_disable_gsint - disable one or more of the general interrupt | ||
248 | * @hsotg: The device state | ||
249 | * @ints: A bitmask of the interrupts to enable | ||
250 | */ | ||
251 | static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints) | ||
252 | { | ||
253 | u32 gsintmsk = readl(hsotg->regs + S3C_GINTMSK); | ||
254 | u32 new_gsintmsk; | ||
255 | |||
256 | new_gsintmsk = gsintmsk & ~ints; | ||
257 | |||
258 | if (new_gsintmsk != gsintmsk) | ||
259 | writel(new_gsintmsk, hsotg->regs + S3C_GINTMSK); | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * s3c_hsotg_ctrl_epint - enable/disable an endpoint irq | ||
264 | * @hsotg: The device state | ||
265 | * @ep: The endpoint index | ||
266 | * @dir_in: True if direction is in. | ||
267 | * @en: The enable value, true to enable | ||
268 | * | ||
269 | * Set or clear the mask for an individual endpoint's interrupt | ||
270 | * request. | ||
271 | */ | ||
272 | static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg, | ||
273 | unsigned int ep, unsigned int dir_in, | ||
274 | unsigned int en) | ||
275 | { | ||
276 | unsigned long flags; | ||
277 | u32 bit = 1 << ep; | ||
278 | u32 daint; | ||
279 | |||
280 | if (!dir_in) | ||
281 | bit <<= 16; | ||
282 | |||
283 | local_irq_save(flags); | ||
284 | daint = readl(hsotg->regs + S3C_DAINTMSK); | ||
285 | if (en) | ||
286 | daint |= bit; | ||
287 | else | ||
288 | daint &= ~bit; | ||
289 | writel(daint, hsotg->regs + S3C_DAINTMSK); | ||
290 | local_irq_restore(flags); | ||
291 | } | ||
292 | |||
293 | /** | ||
294 | * s3c_hsotg_init_fifo - initialise non-periodic FIFOs | ||
295 | * @hsotg: The device instance. | ||
296 | */ | ||
297 | static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) | ||
298 | { | ||
299 | /* the ryu 2.6.24 release ahs | ||
300 | writel(0x1C0, hsotg->regs + S3C_GRXFSIZ); | ||
301 | writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) | | ||
302 | S3C_GNPTXFSIZ_NPTxFDep(0x1C0), | ||
303 | hsotg->regs + S3C_GNPTXFSIZ); | ||
304 | */ | ||
305 | |||
306 | /* set FIFO sizes to 2048/0x1C0 */ | ||
307 | |||
308 | writel(2048, hsotg->regs + S3C_GRXFSIZ); | ||
309 | writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) | | ||
310 | S3C_GNPTXFSIZ_NPTxFDep(0x1C0), | ||
311 | hsotg->regs + S3C_GNPTXFSIZ); | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * @ep: USB endpoint to allocate request for. | ||
316 | * @flags: Allocation flags | ||
317 | * | ||
318 | * Allocate a new USB request structure appropriate for the specified endpoint | ||
319 | */ | ||
320 | struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep, gfp_t flags) | ||
321 | { | ||
322 | struct s3c_hsotg_req *req; | ||
323 | |||
324 | req = kzalloc(sizeof(struct s3c_hsotg_req), flags); | ||
325 | if (!req) | ||
326 | return NULL; | ||
327 | |||
328 | INIT_LIST_HEAD(&req->queue); | ||
329 | |||
330 | req->req.dma = DMA_ADDR_INVALID; | ||
331 | return &req->req; | ||
332 | } | ||
333 | |||
334 | /** | ||
335 | * is_ep_periodic - return true if the endpoint is in periodic mode. | ||
336 | * @hs_ep: The endpoint to query. | ||
337 | * | ||
338 | * Returns true if the endpoint is in periodic mode, meaning it is being | ||
339 | * used for an Interrupt or ISO transfer. | ||
340 | */ | ||
341 | static inline int is_ep_periodic(struct s3c_hsotg_ep *hs_ep) | ||
342 | { | ||
343 | return hs_ep->periodic; | ||
344 | } | ||
345 | |||
346 | /** | ||
347 | * s3c_hsotg_unmap_dma - unmap the DMA memory being used for the request | ||
348 | * @hsotg: The device state. | ||
349 | * @hs_ep: The endpoint for the request | ||
350 | * @hs_req: The request being processed. | ||
351 | * | ||
352 | * This is the reverse of s3c_hsotg_map_dma(), called for the completion | ||
353 | * of a request to ensure the buffer is ready for access by the caller. | ||
354 | */ | ||
355 | static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg, | ||
356 | struct s3c_hsotg_ep *hs_ep, | ||
357 | struct s3c_hsotg_req *hs_req) | ||
358 | { | ||
359 | struct usb_request *req = &hs_req->req; | ||
360 | enum dma_data_direction dir; | ||
361 | |||
362 | dir = hs_ep->dir_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | ||
363 | |||
364 | /* ignore this if we're not moving any data */ | ||
365 | if (hs_req->req.length == 0) | ||
366 | return; | ||
367 | |||
368 | if (hs_req->mapped) { | ||
369 | /* we mapped this, so unmap and remove the dma */ | ||
370 | |||
371 | dma_unmap_single(hsotg->dev, req->dma, req->length, dir); | ||
372 | |||
373 | req->dma = DMA_ADDR_INVALID; | ||
374 | hs_req->mapped = 0; | ||
375 | } else { | ||
376 | dma_sync_single(hsotg->dev, req->dma, req->length, dir); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | /** | ||
381 | * s3c_hsotg_write_fifo - write packet Data to the TxFIFO | ||
382 | * @hsotg: The controller state. | ||
383 | * @hs_ep: The endpoint we're going to write for. | ||
384 | * @hs_req: The request to write data for. | ||
385 | * | ||
386 | * This is called when the TxFIFO has some space in it to hold a new | ||
387 | * transmission and we have something to give it. The actual setup of | ||
388 | * the data size is done elsewhere, so all we have to do is to actually | ||
389 | * write the data. | ||
390 | * | ||
391 | * The return value is zero if there is more space (or nothing was done) | ||
392 | * otherwise -ENOSPC is returned if the FIFO space was used up. | ||
393 | * | ||
394 | * This routine is only needed for PIO | ||
395 | */ | ||
396 | static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg, | ||
397 | struct s3c_hsotg_ep *hs_ep, | ||
398 | struct s3c_hsotg_req *hs_req) | ||
399 | { | ||
400 | bool periodic = is_ep_periodic(hs_ep); | ||
401 | u32 gnptxsts = readl(hsotg->regs + S3C_GNPTXSTS); | ||
402 | int buf_pos = hs_req->req.actual; | ||
403 | int to_write = hs_ep->size_loaded; | ||
404 | void *data; | ||
405 | int can_write; | ||
406 | int pkt_round; | ||
407 | |||
408 | to_write -= (buf_pos - hs_ep->last_load); | ||
409 | |||
410 | /* if there's nothing to write, get out early */ | ||
411 | if (to_write == 0) | ||
412 | return 0; | ||
413 | |||
414 | if (periodic) { | ||
415 | u32 epsize = readl(hsotg->regs + S3C_DIEPTSIZ(hs_ep->index)); | ||
416 | int size_left; | ||
417 | int size_done; | ||
418 | |||
419 | /* work out how much data was loaded so we can calculate | ||
420 | * how much data is left in the fifo. */ | ||
421 | |||
422 | size_left = S3C_DxEPTSIZ_XferSize_GET(epsize); | ||
423 | |||
424 | dev_dbg(hsotg->dev, "%s: left=%d, load=%d, fifo=%d, size %d\n", | ||
425 | __func__, size_left, | ||
426 | hs_ep->size_loaded, hs_ep->fifo_load, hs_ep->fifo_size); | ||
427 | |||
428 | /* how much of the data has moved */ | ||
429 | size_done = hs_ep->size_loaded - size_left; | ||
430 | |||
431 | /* how much data is left in the fifo */ | ||
432 | can_write = hs_ep->fifo_load - size_done; | ||
433 | dev_dbg(hsotg->dev, "%s: => can_write1=%d\n", | ||
434 | __func__, can_write); | ||
435 | |||
436 | can_write = hs_ep->fifo_size - can_write; | ||
437 | dev_dbg(hsotg->dev, "%s: => can_write2=%d\n", | ||
438 | __func__, can_write); | ||
439 | |||
440 | if (can_write <= 0) { | ||
441 | s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_PTxFEmp); | ||
442 | return -ENOSPC; | ||
443 | } | ||
444 | } else { | ||
445 | if (S3C_GNPTXSTS_NPTxQSpcAvail_GET(gnptxsts) == 0) { | ||
446 | dev_dbg(hsotg->dev, | ||
447 | "%s: no queue slots available (0x%08x)\n", | ||
448 | __func__, gnptxsts); | ||
449 | |||
450 | s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_NPTxFEmp); | ||
451 | return -ENOSPC; | ||
452 | } | ||
453 | |||
454 | can_write = S3C_GNPTXSTS_NPTxFSpcAvail_GET(gnptxsts); | ||
455 | } | ||
456 | |||
457 | dev_dbg(hsotg->dev, "%s: GNPTXSTS=%08x, can=%d, to=%d, mps %d\n", | ||
458 | __func__, gnptxsts, can_write, to_write, hs_ep->ep.maxpacket); | ||
459 | |||
460 | /* limit to 512 bytes of data, it seems at least on the non-periodic | ||
461 | * FIFO, requests of >512 cause the endpoint to get stuck with a | ||
462 | * fragment of the end of the transfer in it. | ||
463 | */ | ||
464 | if (can_write > 512) | ||
465 | can_write = 512; | ||
466 | |||
467 | /* see if we can write data */ | ||
468 | |||
469 | if (to_write > can_write) { | ||
470 | to_write = can_write; | ||
471 | pkt_round = to_write % hs_ep->ep.maxpacket; | ||
472 | |||
473 | /* Not sure, but we probably shouldn't be writing partial | ||
474 | * packets into the FIFO, so round the write down to an | ||
475 | * exact number of packets. | ||
476 | * | ||
477 | * Note, we do not currently check to see if we can ever | ||
478 | * write a full packet or not to the FIFO. | ||
479 | */ | ||
480 | |||
481 | if (pkt_round) | ||
482 | to_write -= pkt_round; | ||
483 | |||
484 | /* enable correct FIFO interrupt to alert us when there | ||
485 | * is more room left. */ | ||
486 | |||
487 | s3c_hsotg_en_gsint(hsotg, | ||
488 | periodic ? S3C_GINTSTS_PTxFEmp : | ||
489 | S3C_GINTSTS_NPTxFEmp); | ||
490 | } | ||
491 | |||
492 | dev_dbg(hsotg->dev, "write %d/%d, can_write %d, done %d\n", | ||
493 | to_write, hs_req->req.length, can_write, buf_pos); | ||
494 | |||
495 | if (to_write <= 0) | ||
496 | return -ENOSPC; | ||
497 | |||
498 | hs_req->req.actual = buf_pos + to_write; | ||
499 | hs_ep->total_data += to_write; | ||
500 | |||
501 | if (periodic) | ||
502 | hs_ep->fifo_load += to_write; | ||
503 | |||
504 | to_write = DIV_ROUND_UP(to_write, 4); | ||
505 | data = hs_req->req.buf + buf_pos; | ||
506 | |||
507 | writesl(hsotg->regs + S3C_EPFIFO(hs_ep->index), data, to_write); | ||
508 | |||
509 | return (to_write >= can_write) ? -ENOSPC : 0; | ||
510 | } | ||
511 | |||
512 | /** | ||
513 | * get_ep_limit - get the maximum data legnth for this endpoint | ||
514 | * @hs_ep: The endpoint | ||
515 | * | ||
516 | * Return the maximum data that can be queued in one go on a given endpoint | ||
517 | * so that transfers that are too long can be split. | ||
518 | */ | ||
519 | static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep) | ||
520 | { | ||
521 | int index = hs_ep->index; | ||
522 | unsigned maxsize; | ||
523 | unsigned maxpkt; | ||
524 | |||
525 | if (index != 0) { | ||
526 | maxsize = S3C_DxEPTSIZ_XferSize_LIMIT + 1; | ||
527 | maxpkt = S3C_DxEPTSIZ_PktCnt_LIMIT + 1; | ||
528 | } else { | ||
529 | if (hs_ep->dir_in) { | ||
530 | /* maxsize = S3C_DIEPTSIZ0_XferSize_LIMIT + 1; */ | ||
531 | maxsize = 64+64+1; | ||
532 | maxpkt = S3C_DIEPTSIZ0_PktCnt_LIMIT + 1; | ||
533 | } else { | ||
534 | maxsize = 0x3f; | ||
535 | maxpkt = 2; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | /* we made the constant loading easier above by using +1 */ | ||
540 | maxpkt--; | ||
541 | maxsize--; | ||
542 | |||
543 | /* constrain by packet count if maxpkts*pktsize is greater | ||
544 | * than the length register size. */ | ||
545 | |||
546 | if ((maxpkt * hs_ep->ep.maxpacket) < maxsize) | ||
547 | maxsize = maxpkt * hs_ep->ep.maxpacket; | ||
548 | |||
549 | return maxsize; | ||
550 | } | ||
551 | |||
552 | /** | ||
553 | * s3c_hsotg_start_req - start a USB request from an endpoint's queue | ||
554 | * @hsotg: The controller state. | ||
555 | * @hs_ep: The endpoint to process a request for | ||
556 | * @hs_req: The request to start. | ||
557 | * @continuing: True if we are doing more for the current request. | ||
558 | * | ||
559 | * Start the given request running by setting the endpoint registers | ||
560 | * appropriately, and writing any data to the FIFOs. | ||
561 | */ | ||
562 | static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, | ||
563 | struct s3c_hsotg_ep *hs_ep, | ||
564 | struct s3c_hsotg_req *hs_req, | ||
565 | bool continuing) | ||
566 | { | ||
567 | struct usb_request *ureq = &hs_req->req; | ||
568 | int index = hs_ep->index; | ||
569 | int dir_in = hs_ep->dir_in; | ||
570 | u32 epctrl_reg; | ||
571 | u32 epsize_reg; | ||
572 | u32 epsize; | ||
573 | u32 ctrl; | ||
574 | unsigned length; | ||
575 | unsigned packets; | ||
576 | unsigned maxreq; | ||
577 | |||
578 | if (index != 0) { | ||
579 | if (hs_ep->req && !continuing) { | ||
580 | dev_err(hsotg->dev, "%s: active request\n", __func__); | ||
581 | WARN_ON(1); | ||
582 | return; | ||
583 | } else if (hs_ep->req != hs_req && continuing) { | ||
584 | dev_err(hsotg->dev, | ||
585 | "%s: continue different req\n", __func__); | ||
586 | WARN_ON(1); | ||
587 | return; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | epctrl_reg = dir_in ? S3C_DIEPCTL(index) : S3C_DOEPCTL(index); | ||
592 | epsize_reg = dir_in ? S3C_DIEPTSIZ(index) : S3C_DOEPTSIZ(index); | ||
593 | |||
594 | dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x, ep %d, dir %s\n", | ||
595 | __func__, readl(hsotg->regs + epctrl_reg), index, | ||
596 | hs_ep->dir_in ? "in" : "out"); | ||
597 | |||
598 | length = ureq->length - ureq->actual; | ||
599 | |||
600 | if (0) | ||
601 | dev_dbg(hsotg->dev, | ||
602 | "REQ buf %p len %d dma 0x%08x noi=%d zp=%d snok=%d\n", | ||
603 | ureq->buf, length, ureq->dma, | ||
604 | ureq->no_interrupt, ureq->zero, ureq->short_not_ok); | ||
605 | |||
606 | maxreq = get_ep_limit(hs_ep); | ||
607 | if (length > maxreq) { | ||
608 | int round = maxreq % hs_ep->ep.maxpacket; | ||
609 | |||
610 | dev_dbg(hsotg->dev, "%s: length %d, max-req %d, r %d\n", | ||
611 | __func__, length, maxreq, round); | ||
612 | |||
613 | /* round down to multiple of packets */ | ||
614 | if (round) | ||
615 | maxreq -= round; | ||
616 | |||
617 | length = maxreq; | ||
618 | } | ||
619 | |||
620 | if (length) | ||
621 | packets = DIV_ROUND_UP(length, hs_ep->ep.maxpacket); | ||
622 | else | ||
623 | packets = 1; /* send one packet if length is zero. */ | ||
624 | |||
625 | if (dir_in && index != 0) | ||
626 | epsize = S3C_DxEPTSIZ_MC(1); | ||
627 | else | ||
628 | epsize = 0; | ||
629 | |||
630 | if (index != 0 && ureq->zero) { | ||
631 | /* test for the packets being exactly right for the | ||
632 | * transfer */ | ||
633 | |||
634 | if (length == (packets * hs_ep->ep.maxpacket)) | ||
635 | packets++; | ||
636 | } | ||
637 | |||
638 | epsize |= S3C_DxEPTSIZ_PktCnt(packets); | ||
639 | epsize |= S3C_DxEPTSIZ_XferSize(length); | ||
640 | |||
641 | dev_dbg(hsotg->dev, "%s: %d@%d/%d, 0x%08x => 0x%08x\n", | ||
642 | __func__, packets, length, ureq->length, epsize, epsize_reg); | ||
643 | |||
644 | /* store the request as the current one we're doing */ | ||
645 | hs_ep->req = hs_req; | ||
646 | |||
647 | /* write size / packets */ | ||
648 | writel(epsize, hsotg->regs + epsize_reg); | ||
649 | |||
650 | ctrl = readl(hsotg->regs + epctrl_reg); | ||
651 | |||
652 | if (ctrl & S3C_DxEPCTL_Stall) { | ||
653 | dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index); | ||
654 | |||
655 | /* not sure what we can do here, if it is EP0 then we should | ||
656 | * get this cleared once the endpoint has transmitted the | ||
657 | * STALL packet, otherwise it needs to be cleared by the | ||
658 | * host. | ||
659 | */ | ||
660 | } | ||
661 | |||
662 | if (using_dma(hsotg)) { | ||
663 | unsigned int dma_reg; | ||
664 | |||
665 | /* write DMA address to control register, buffer already | ||
666 | * synced by s3c_hsotg_ep_queue(). */ | ||
667 | |||
668 | dma_reg = dir_in ? S3C_DIEPDMA(index) : S3C_DOEPDMA(index); | ||
669 | writel(ureq->dma, hsotg->regs + dma_reg); | ||
670 | |||
671 | dev_dbg(hsotg->dev, "%s: 0x%08x => 0x%08x\n", | ||
672 | __func__, ureq->dma, dma_reg); | ||
673 | } | ||
674 | |||
675 | ctrl |= S3C_DxEPCTL_EPEna; /* ensure ep enabled */ | ||
676 | ctrl |= S3C_DxEPCTL_USBActEp; | ||
677 | ctrl |= S3C_DxEPCTL_CNAK; /* clear NAK set by core */ | ||
678 | |||
679 | dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl); | ||
680 | writel(ctrl, hsotg->regs + epctrl_reg); | ||
681 | |||
682 | /* set these, it seems that DMA support increments past the end | ||
683 | * of the packet buffer so we need to calculate the length from | ||
684 | * this information. */ | ||
685 | hs_ep->size_loaded = length; | ||
686 | hs_ep->last_load = ureq->actual; | ||
687 | |||
688 | if (dir_in && !using_dma(hsotg)) { | ||
689 | /* set these anyway, we may need them for non-periodic in */ | ||
690 | hs_ep->fifo_load = 0; | ||
691 | |||
692 | s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req); | ||
693 | } | ||
694 | |||
695 | /* clear the INTknTXFEmpMsk when we start request, more as a aide | ||
696 | * to debugging to see what is going on. */ | ||
697 | if (dir_in) | ||
698 | writel(S3C_DIEPMSK_INTknTXFEmpMsk, | ||
699 | hsotg->regs + S3C_DIEPINT(index)); | ||
700 | |||
701 | /* Note, trying to clear the NAK here causes problems with transmit | ||
702 | * on the S3C6400 ending up with the TXFIFO becomming full. */ | ||
703 | |||
704 | /* check ep is enabled */ | ||
705 | if (!(readl(hsotg->regs + epctrl_reg) & S3C_DxEPCTL_EPEna)) | ||
706 | dev_warn(hsotg->dev, | ||
707 | "ep%d: failed to become enabled (DxEPCTL=0x%08x)?\n", | ||
708 | index, readl(hsotg->regs + epctrl_reg)); | ||
709 | |||
710 | dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", | ||
711 | __func__, readl(hsotg->regs + epctrl_reg)); | ||
712 | } | ||
713 | |||
714 | /** | ||
715 | * s3c_hsotg_map_dma - map the DMA memory being used for the request | ||
716 | * @hsotg: The device state. | ||
717 | * @hs_ep: The endpoint the request is on. | ||
718 | * @req: The request being processed. | ||
719 | * | ||
720 | * We've been asked to queue a request, so ensure that the memory buffer | ||
721 | * is correctly setup for DMA. If we've been passed an extant DMA address | ||
722 | * then ensure the buffer has been synced to memory. If our buffer has no | ||
723 | * DMA memory, then we map the memory and mark our request to allow us to | ||
724 | * cleanup on completion. | ||
725 | */ | ||
726 | static int s3c_hsotg_map_dma(struct s3c_hsotg *hsotg, | ||
727 | struct s3c_hsotg_ep *hs_ep, | ||
728 | struct usb_request *req) | ||
729 | { | ||
730 | enum dma_data_direction dir; | ||
731 | struct s3c_hsotg_req *hs_req = our_req(req); | ||
732 | |||
733 | dir = hs_ep->dir_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | ||
734 | |||
735 | /* if the length is zero, ignore the DMA data */ | ||
736 | if (hs_req->req.length == 0) | ||
737 | return 0; | ||
738 | |||
739 | if (req->dma == DMA_ADDR_INVALID) { | ||
740 | dma_addr_t dma; | ||
741 | |||
742 | dma = dma_map_single(hsotg->dev, req->buf, req->length, dir); | ||
743 | |||
744 | if (unlikely(dma_mapping_error(hsotg->dev, dma))) | ||
745 | goto dma_error; | ||
746 | |||
747 | if (dma & 3) { | ||
748 | dev_err(hsotg->dev, "%s: unaligned dma buffer\n", | ||
749 | __func__); | ||
750 | |||
751 | dma_unmap_single(hsotg->dev, dma, req->length, dir); | ||
752 | return -EINVAL; | ||
753 | } | ||
754 | |||
755 | hs_req->mapped = 1; | ||
756 | req->dma = dma; | ||
757 | } else { | ||
758 | dma_sync_single(hsotg->dev, req->dma, req->length, dir); | ||
759 | hs_req->mapped = 0; | ||
760 | } | ||
761 | |||
762 | return 0; | ||
763 | |||
764 | dma_error: | ||
765 | dev_err(hsotg->dev, "%s: failed to map buffer %p, %d bytes\n", | ||
766 | __func__, req->buf, req->length); | ||
767 | |||
768 | return -EIO; | ||
769 | } | ||
770 | |||
771 | static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | ||
772 | gfp_t gfp_flags) | ||
773 | { | ||
774 | struct s3c_hsotg_req *hs_req = our_req(req); | ||
775 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
776 | struct s3c_hsotg *hs = hs_ep->parent; | ||
777 | unsigned long irqflags; | ||
778 | bool first; | ||
779 | |||
780 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", | ||
781 | ep->name, req, req->length, req->buf, req->no_interrupt, | ||
782 | req->zero, req->short_not_ok); | ||
783 | |||
784 | /* initialise status of the request */ | ||
785 | INIT_LIST_HEAD(&hs_req->queue); | ||
786 | req->actual = 0; | ||
787 | req->status = -EINPROGRESS; | ||
788 | |||
789 | /* if we're using DMA, sync the buffers as necessary */ | ||
790 | if (using_dma(hs)) { | ||
791 | int ret = s3c_hsotg_map_dma(hs, hs_ep, req); | ||
792 | if (ret) | ||
793 | return ret; | ||
794 | } | ||
795 | |||
796 | spin_lock_irqsave(&hs_ep->lock, irqflags); | ||
797 | |||
798 | first = list_empty(&hs_ep->queue); | ||
799 | list_add_tail(&hs_req->queue, &hs_ep->queue); | ||
800 | |||
801 | if (first) | ||
802 | s3c_hsotg_start_req(hs, hs_ep, hs_req, false); | ||
803 | |||
804 | spin_unlock_irqrestore(&hs_ep->lock, irqflags); | ||
805 | |||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | static void s3c_hsotg_ep_free_request(struct usb_ep *ep, | ||
810 | struct usb_request *req) | ||
811 | { | ||
812 | struct s3c_hsotg_req *hs_req = our_req(req); | ||
813 | |||
814 | kfree(hs_req); | ||
815 | } | ||
816 | |||
817 | /** | ||
818 | * s3c_hsotg_complete_oursetup - setup completion callback | ||
819 | * @ep: The endpoint the request was on. | ||
820 | * @req: The request completed. | ||
821 | * | ||
822 | * Called on completion of any requests the driver itself | ||
823 | * submitted that need cleaning up. | ||
824 | */ | ||
825 | static void s3c_hsotg_complete_oursetup(struct usb_ep *ep, | ||
826 | struct usb_request *req) | ||
827 | { | ||
828 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
829 | struct s3c_hsotg *hsotg = hs_ep->parent; | ||
830 | |||
831 | dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req); | ||
832 | |||
833 | s3c_hsotg_ep_free_request(ep, req); | ||
834 | } | ||
835 | |||
836 | /** | ||
837 | * ep_from_windex - convert control wIndex value to endpoint | ||
838 | * @hsotg: The driver state. | ||
839 | * @windex: The control request wIndex field (in host order). | ||
840 | * | ||
841 | * Convert the given wIndex into a pointer to an driver endpoint | ||
842 | * structure, or return NULL if it is not a valid endpoint. | ||
843 | */ | ||
844 | static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg, | ||
845 | u32 windex) | ||
846 | { | ||
847 | struct s3c_hsotg_ep *ep = &hsotg->eps[windex & 0x7F]; | ||
848 | int dir = (windex & USB_DIR_IN) ? 1 : 0; | ||
849 | int idx = windex & 0x7F; | ||
850 | |||
851 | if (windex >= 0x100) | ||
852 | return NULL; | ||
853 | |||
854 | if (idx > S3C_HSOTG_EPS) | ||
855 | return NULL; | ||
856 | |||
857 | if (idx && ep->dir_in != dir) | ||
858 | return NULL; | ||
859 | |||
860 | return ep; | ||
861 | } | ||
862 | |||
863 | /** | ||
864 | * s3c_hsotg_send_reply - send reply to control request | ||
865 | * @hsotg: The device state | ||
866 | * @ep: Endpoint 0 | ||
867 | * @buff: Buffer for request | ||
868 | * @length: Length of reply. | ||
869 | * | ||
870 | * Create a request and queue it on the given endpoint. This is useful as | ||
871 | * an internal method of sending replies to certain control requests, etc. | ||
872 | */ | ||
873 | static int s3c_hsotg_send_reply(struct s3c_hsotg *hsotg, | ||
874 | struct s3c_hsotg_ep *ep, | ||
875 | void *buff, | ||
876 | int length) | ||
877 | { | ||
878 | struct usb_request *req; | ||
879 | int ret; | ||
880 | |||
881 | dev_dbg(hsotg->dev, "%s: buff %p, len %d\n", __func__, buff, length); | ||
882 | |||
883 | req = s3c_hsotg_ep_alloc_request(&ep->ep, GFP_ATOMIC); | ||
884 | hsotg->ep0_reply = req; | ||
885 | if (!req) { | ||
886 | dev_warn(hsotg->dev, "%s: cannot alloc req\n", __func__); | ||
887 | return -ENOMEM; | ||
888 | } | ||
889 | |||
890 | req->buf = hsotg->ep0_buff; | ||
891 | req->length = length; | ||
892 | req->zero = 1; /* always do zero-length final transfer */ | ||
893 | req->complete = s3c_hsotg_complete_oursetup; | ||
894 | |||
895 | if (length) | ||
896 | memcpy(req->buf, buff, length); | ||
897 | else | ||
898 | ep->sent_zlp = 1; | ||
899 | |||
900 | ret = s3c_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC); | ||
901 | if (ret) { | ||
902 | dev_warn(hsotg->dev, "%s: cannot queue req\n", __func__); | ||
903 | return ret; | ||
904 | } | ||
905 | |||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | /** | ||
910 | * s3c_hsotg_process_req_status - process request GET_STATUS | ||
911 | * @hsotg: The device state | ||
912 | * @ctrl: USB control request | ||
913 | */ | ||
914 | static int s3c_hsotg_process_req_status(struct s3c_hsotg *hsotg, | ||
915 | struct usb_ctrlrequest *ctrl) | ||
916 | { | ||
917 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | ||
918 | struct s3c_hsotg_ep *ep; | ||
919 | __le16 reply; | ||
920 | int ret; | ||
921 | |||
922 | dev_dbg(hsotg->dev, "%s: USB_REQ_GET_STATUS\n", __func__); | ||
923 | |||
924 | if (!ep0->dir_in) { | ||
925 | dev_warn(hsotg->dev, "%s: direction out?\n", __func__); | ||
926 | return -EINVAL; | ||
927 | } | ||
928 | |||
929 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
930 | case USB_RECIP_DEVICE: | ||
931 | reply = cpu_to_le16(0); /* bit 0 => self powered, | ||
932 | * bit 1 => remote wakeup */ | ||
933 | break; | ||
934 | |||
935 | case USB_RECIP_INTERFACE: | ||
936 | /* currently, the data result should be zero */ | ||
937 | reply = cpu_to_le16(0); | ||
938 | break; | ||
939 | |||
940 | case USB_RECIP_ENDPOINT: | ||
941 | ep = ep_from_windex(hsotg, le16_to_cpu(ctrl->wIndex)); | ||
942 | if (!ep) | ||
943 | return -ENOENT; | ||
944 | |||
945 | reply = cpu_to_le16(ep->halted ? 1 : 0); | ||
946 | break; | ||
947 | |||
948 | default: | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | if (le16_to_cpu(ctrl->wLength) != 2) | ||
953 | return -EINVAL; | ||
954 | |||
955 | ret = s3c_hsotg_send_reply(hsotg, ep0, &reply, 2); | ||
956 | if (ret) { | ||
957 | dev_err(hsotg->dev, "%s: failed to send reply\n", __func__); | ||
958 | return ret; | ||
959 | } | ||
960 | |||
961 | return 1; | ||
962 | } | ||
963 | |||
964 | static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value); | ||
965 | |||
966 | /** | ||
967 | * s3c_hsotg_process_req_featire - process request {SET,CLEAR}_FEATURE | ||
968 | * @hsotg: The device state | ||
969 | * @ctrl: USB control request | ||
970 | */ | ||
971 | static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg, | ||
972 | struct usb_ctrlrequest *ctrl) | ||
973 | { | ||
974 | bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); | ||
975 | struct s3c_hsotg_ep *ep; | ||
976 | |||
977 | dev_dbg(hsotg->dev, "%s: %s_FEATURE\n", | ||
978 | __func__, set ? "SET" : "CLEAR"); | ||
979 | |||
980 | if (ctrl->bRequestType == USB_RECIP_ENDPOINT) { | ||
981 | ep = ep_from_windex(hsotg, le16_to_cpu(ctrl->wIndex)); | ||
982 | if (!ep) { | ||
983 | dev_dbg(hsotg->dev, "%s: no endpoint for 0x%04x\n", | ||
984 | __func__, le16_to_cpu(ctrl->wIndex)); | ||
985 | return -ENOENT; | ||
986 | } | ||
987 | |||
988 | switch (le16_to_cpu(ctrl->wValue)) { | ||
989 | case USB_ENDPOINT_HALT: | ||
990 | s3c_hsotg_ep_sethalt(&ep->ep, set); | ||
991 | break; | ||
992 | |||
993 | default: | ||
994 | return -ENOENT; | ||
995 | } | ||
996 | } else | ||
997 | return -ENOENT; /* currently only deal with endpoint */ | ||
998 | |||
999 | return 1; | ||
1000 | } | ||
1001 | |||
1002 | /** | ||
1003 | * s3c_hsotg_process_control - process a control request | ||
1004 | * @hsotg: The device state | ||
1005 | * @ctrl: The control request received | ||
1006 | * | ||
1007 | * The controller has received the SETUP phase of a control request, and | ||
1008 | * needs to work out what to do next (and whether to pass it on to the | ||
1009 | * gadget driver). | ||
1010 | */ | ||
1011 | static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg, | ||
1012 | struct usb_ctrlrequest *ctrl) | ||
1013 | { | ||
1014 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | ||
1015 | int ret = 0; | ||
1016 | u32 dcfg; | ||
1017 | |||
1018 | ep0->sent_zlp = 0; | ||
1019 | |||
1020 | dev_dbg(hsotg->dev, "ctrl Req=%02x, Type=%02x, V=%04x, L=%04x\n", | ||
1021 | ctrl->bRequest, ctrl->bRequestType, | ||
1022 | ctrl->wValue, ctrl->wLength); | ||
1023 | |||
1024 | /* record the direction of the request, for later use when enquing | ||
1025 | * packets onto EP0. */ | ||
1026 | |||
1027 | ep0->dir_in = (ctrl->bRequestType & USB_DIR_IN) ? 1 : 0; | ||
1028 | dev_dbg(hsotg->dev, "ctrl: dir_in=%d\n", ep0->dir_in); | ||
1029 | |||
1030 | /* if we've no data with this request, then the last part of the | ||
1031 | * transaction is going to implicitly be IN. */ | ||
1032 | if (ctrl->wLength == 0) | ||
1033 | ep0->dir_in = 1; | ||
1034 | |||
1035 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | ||
1036 | switch (ctrl->bRequest) { | ||
1037 | case USB_REQ_SET_ADDRESS: | ||
1038 | dcfg = readl(hsotg->regs + S3C_DCFG); | ||
1039 | dcfg &= ~S3C_DCFG_DevAddr_MASK; | ||
1040 | dcfg |= ctrl->wValue << S3C_DCFG_DevAddr_SHIFT; | ||
1041 | writel(dcfg, hsotg->regs + S3C_DCFG); | ||
1042 | |||
1043 | dev_info(hsotg->dev, "new address %d\n", ctrl->wValue); | ||
1044 | |||
1045 | ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); | ||
1046 | return; | ||
1047 | |||
1048 | case USB_REQ_GET_STATUS: | ||
1049 | ret = s3c_hsotg_process_req_status(hsotg, ctrl); | ||
1050 | break; | ||
1051 | |||
1052 | case USB_REQ_CLEAR_FEATURE: | ||
1053 | case USB_REQ_SET_FEATURE: | ||
1054 | ret = s3c_hsotg_process_req_feature(hsotg, ctrl); | ||
1055 | break; | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | /* as a fallback, try delivering it to the driver to deal with */ | ||
1060 | |||
1061 | if (ret == 0 && hsotg->driver) { | ||
1062 | ret = hsotg->driver->setup(&hsotg->gadget, ctrl); | ||
1063 | if (ret < 0) | ||
1064 | dev_dbg(hsotg->dev, "driver->setup() ret %d\n", ret); | ||
1065 | } | ||
1066 | |||
1067 | if (ret > 0) { | ||
1068 | if (!ep0->dir_in) { | ||
1069 | /* need to generate zlp in reply or take data */ | ||
1070 | /* todo - deal with any data we might be sent? */ | ||
1071 | ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1075 | /* the request is either unhandlable, or is not formatted correctly | ||
1076 | * so respond with a STALL for the status stage to indicate failure. | ||
1077 | */ | ||
1078 | |||
1079 | if (ret < 0) { | ||
1080 | u32 reg; | ||
1081 | u32 ctrl; | ||
1082 | |||
1083 | dev_dbg(hsotg->dev, "ep0 stall (dir=%d)\n", ep0->dir_in); | ||
1084 | reg = (ep0->dir_in) ? S3C_DIEPCTL0 : S3C_DOEPCTL0; | ||
1085 | |||
1086 | /* S3C_DxEPCTL_Stall will be cleared by EP once it has | ||
1087 | * taken effect, so no need to clear later. */ | ||
1088 | |||
1089 | ctrl = readl(hsotg->regs + reg); | ||
1090 | ctrl |= S3C_DxEPCTL_Stall; | ||
1091 | ctrl |= S3C_DxEPCTL_CNAK; | ||
1092 | writel(ctrl, hsotg->regs + reg); | ||
1093 | |||
1094 | dev_dbg(hsotg->dev, | ||
1095 | "writen DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n", | ||
1096 | ctrl, reg, readl(hsotg->regs + reg)); | ||
1097 | |||
1098 | /* don't belive we need to anything more to get the EP | ||
1099 | * to reply with a STALL packet */ | ||
1100 | } | ||
1101 | } | ||
1102 | |||
1103 | static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg); | ||
1104 | |||
1105 | /** | ||
1106 | * s3c_hsotg_complete_setup - completion of a setup transfer | ||
1107 | * @ep: The endpoint the request was on. | ||
1108 | * @req: The request completed. | ||
1109 | * | ||
1110 | * Called on completion of any requests the driver itself submitted for | ||
1111 | * EP0 setup packets | ||
1112 | */ | ||
1113 | static void s3c_hsotg_complete_setup(struct usb_ep *ep, | ||
1114 | struct usb_request *req) | ||
1115 | { | ||
1116 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
1117 | struct s3c_hsotg *hsotg = hs_ep->parent; | ||
1118 | |||
1119 | if (req->status < 0) { | ||
1120 | dev_dbg(hsotg->dev, "%s: failed %d\n", __func__, req->status); | ||
1121 | return; | ||
1122 | } | ||
1123 | |||
1124 | if (req->actual == 0) | ||
1125 | s3c_hsotg_enqueue_setup(hsotg); | ||
1126 | else | ||
1127 | s3c_hsotg_process_control(hsotg, req->buf); | ||
1128 | } | ||
1129 | |||
1130 | /** | ||
1131 | * s3c_hsotg_enqueue_setup - start a request for EP0 packets | ||
1132 | * @hsotg: The device state. | ||
1133 | * | ||
1134 | * Enqueue a request on EP0 if necessary to received any SETUP packets | ||
1135 | * received from the host. | ||
1136 | */ | ||
1137 | static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg) | ||
1138 | { | ||
1139 | struct usb_request *req = hsotg->ctrl_req; | ||
1140 | struct s3c_hsotg_req *hs_req = our_req(req); | ||
1141 | int ret; | ||
1142 | |||
1143 | dev_dbg(hsotg->dev, "%s: queueing setup request\n", __func__); | ||
1144 | |||
1145 | req->zero = 0; | ||
1146 | req->length = 8; | ||
1147 | req->buf = hsotg->ctrl_buff; | ||
1148 | req->complete = s3c_hsotg_complete_setup; | ||
1149 | |||
1150 | if (!list_empty(&hs_req->queue)) { | ||
1151 | dev_dbg(hsotg->dev, "%s already queued???\n", __func__); | ||
1152 | return; | ||
1153 | } | ||
1154 | |||
1155 | hsotg->eps[0].dir_in = 0; | ||
1156 | |||
1157 | ret = s3c_hsotg_ep_queue(&hsotg->eps[0].ep, req, GFP_ATOMIC); | ||
1158 | if (ret < 0) { | ||
1159 | dev_err(hsotg->dev, "%s: failed queue (%d)\n", __func__, ret); | ||
1160 | /* Don't think there's much we can do other than watch the | ||
1161 | * driver fail. */ | ||
1162 | } | ||
1163 | } | ||
1164 | |||
1165 | /** | ||
1166 | * get_ep_head - return the first request on the endpoint | ||
1167 | * @hs_ep: The controller endpoint to get | ||
1168 | * | ||
1169 | * Get the first request on the endpoint. | ||
1170 | */ | ||
1171 | static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep) | ||
1172 | { | ||
1173 | if (list_empty(&hs_ep->queue)) | ||
1174 | return NULL; | ||
1175 | |||
1176 | return list_first_entry(&hs_ep->queue, struct s3c_hsotg_req, queue); | ||
1177 | } | ||
1178 | |||
1179 | /** | ||
1180 | * s3c_hsotg_complete_request - complete a request given to us | ||
1181 | * @hsotg: The device state. | ||
1182 | * @hs_ep: The endpoint the request was on. | ||
1183 | * @hs_req: The request to complete. | ||
1184 | * @result: The result code (0 => Ok, otherwise errno) | ||
1185 | * | ||
1186 | * The given request has finished, so call the necessary completion | ||
1187 | * if it has one and then look to see if we can start a new request | ||
1188 | * on the endpoint. | ||
1189 | * | ||
1190 | * Note, expects the ep to already be locked as appropriate. | ||
1191 | */ | ||
1192 | static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, | ||
1193 | struct s3c_hsotg_ep *hs_ep, | ||
1194 | struct s3c_hsotg_req *hs_req, | ||
1195 | int result) | ||
1196 | { | ||
1197 | bool restart; | ||
1198 | |||
1199 | if (!hs_req) { | ||
1200 | dev_dbg(hsotg->dev, "%s: nothing to complete?\n", __func__); | ||
1201 | return; | ||
1202 | } | ||
1203 | |||
1204 | dev_dbg(hsotg->dev, "complete: ep %p %s, req %p, %d => %p\n", | ||
1205 | hs_ep, hs_ep->ep.name, hs_req, result, hs_req->req.complete); | ||
1206 | |||
1207 | /* only replace the status if we've not already set an error | ||
1208 | * from a previous transaction */ | ||
1209 | |||
1210 | if (hs_req->req.status == -EINPROGRESS) | ||
1211 | hs_req->req.status = result; | ||
1212 | |||
1213 | hs_ep->req = NULL; | ||
1214 | list_del_init(&hs_req->queue); | ||
1215 | |||
1216 | if (using_dma(hsotg)) | ||
1217 | s3c_hsotg_unmap_dma(hsotg, hs_ep, hs_req); | ||
1218 | |||
1219 | /* call the complete request with the locks off, just in case the | ||
1220 | * request tries to queue more work for this endpoint. */ | ||
1221 | |||
1222 | if (hs_req->req.complete) { | ||
1223 | spin_unlock(&hs_ep->lock); | ||
1224 | hs_req->req.complete(&hs_ep->ep, &hs_req->req); | ||
1225 | spin_lock(&hs_ep->lock); | ||
1226 | } | ||
1227 | |||
1228 | /* Look to see if there is anything else to do. Note, the completion | ||
1229 | * of the previous request may have caused a new request to be started | ||
1230 | * so be careful when doing this. */ | ||
1231 | |||
1232 | if (!hs_ep->req && result >= 0) { | ||
1233 | restart = !list_empty(&hs_ep->queue); | ||
1234 | if (restart) { | ||
1235 | hs_req = get_ep_head(hs_ep); | ||
1236 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, false); | ||
1237 | } | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1241 | /** | ||
1242 | * s3c_hsotg_complete_request_lock - complete a request given to us (locked) | ||
1243 | * @hsotg: The device state. | ||
1244 | * @hs_ep: The endpoint the request was on. | ||
1245 | * @hs_req: The request to complete. | ||
1246 | * @result: The result code (0 => Ok, otherwise errno) | ||
1247 | * | ||
1248 | * See s3c_hsotg_complete_request(), but called with the endpoint's | ||
1249 | * lock held. | ||
1250 | */ | ||
1251 | static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg, | ||
1252 | struct s3c_hsotg_ep *hs_ep, | ||
1253 | struct s3c_hsotg_req *hs_req, | ||
1254 | int result) | ||
1255 | { | ||
1256 | unsigned long flags; | ||
1257 | |||
1258 | spin_lock_irqsave(&hs_ep->lock, flags); | ||
1259 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); | ||
1260 | spin_unlock_irqrestore(&hs_ep->lock, flags); | ||
1261 | } | ||
1262 | |||
1263 | /** | ||
1264 | * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint | ||
1265 | * @hsotg: The device state. | ||
1266 | * @ep_idx: The endpoint index for the data | ||
1267 | * @size: The size of data in the fifo, in bytes | ||
1268 | * | ||
1269 | * The FIFO status shows there is data to read from the FIFO for a given | ||
1270 | * endpoint, so sort out whether we need to read the data into a request | ||
1271 | * that has been made for that endpoint. | ||
1272 | */ | ||
1273 | static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | ||
1274 | { | ||
1275 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep_idx]; | ||
1276 | struct s3c_hsotg_req *hs_req = hs_ep->req; | ||
1277 | void __iomem *fifo = hsotg->regs + S3C_EPFIFO(ep_idx); | ||
1278 | int to_read; | ||
1279 | int max_req; | ||
1280 | int read_ptr; | ||
1281 | |||
1282 | if (!hs_req) { | ||
1283 | u32 epctl = readl(hsotg->regs + S3C_DOEPCTL(ep_idx)); | ||
1284 | int ptr; | ||
1285 | |||
1286 | dev_warn(hsotg->dev, | ||
1287 | "%s: FIFO %d bytes on ep%d but no req (DxEPCTl=0x%08x)\n", | ||
1288 | __func__, size, ep_idx, epctl); | ||
1289 | |||
1290 | /* dump the data from the FIFO, we've nothing we can do */ | ||
1291 | for (ptr = 0; ptr < size; ptr += 4) | ||
1292 | (void)readl(fifo); | ||
1293 | |||
1294 | return; | ||
1295 | } | ||
1296 | |||
1297 | spin_lock(&hs_ep->lock); | ||
1298 | |||
1299 | to_read = size; | ||
1300 | read_ptr = hs_req->req.actual; | ||
1301 | max_req = hs_req->req.length - read_ptr; | ||
1302 | |||
1303 | if (to_read > max_req) { | ||
1304 | /* more data appeared than we where willing | ||
1305 | * to deal with in this request. | ||
1306 | */ | ||
1307 | |||
1308 | /* currently we don't deal this */ | ||
1309 | WARN_ON_ONCE(1); | ||
1310 | } | ||
1311 | |||
1312 | dev_dbg(hsotg->dev, "%s: read %d/%d, done %d/%d\n", | ||
1313 | __func__, to_read, max_req, read_ptr, hs_req->req.length); | ||
1314 | |||
1315 | hs_ep->total_data += to_read; | ||
1316 | hs_req->req.actual += to_read; | ||
1317 | to_read = DIV_ROUND_UP(to_read, 4); | ||
1318 | |||
1319 | /* note, we might over-write the buffer end by 3 bytes depending on | ||
1320 | * alignment of the data. */ | ||
1321 | readsl(fifo, hs_req->req.buf + read_ptr, to_read); | ||
1322 | |||
1323 | spin_unlock(&hs_ep->lock); | ||
1324 | } | ||
1325 | |||
1326 | /** | ||
1327 | * s3c_hsotg_send_zlp - send zero-length packet on control endpoint | ||
1328 | * @hsotg: The device instance | ||
1329 | * @req: The request currently on this endpoint | ||
1330 | * | ||
1331 | * Generate a zero-length IN packet request for terminating a SETUP | ||
1332 | * transaction. | ||
1333 | * | ||
1334 | * Note, since we don't write any data to the TxFIFO, then it is | ||
1335 | * currently belived that we do not need to wait for any space in | ||
1336 | * the TxFIFO. | ||
1337 | */ | ||
1338 | static void s3c_hsotg_send_zlp(struct s3c_hsotg *hsotg, | ||
1339 | struct s3c_hsotg_req *req) | ||
1340 | { | ||
1341 | u32 ctrl; | ||
1342 | |||
1343 | if (!req) { | ||
1344 | dev_warn(hsotg->dev, "%s: no request?\n", __func__); | ||
1345 | return; | ||
1346 | } | ||
1347 | |||
1348 | if (req->req.length == 0) { | ||
1349 | hsotg->eps[0].sent_zlp = 1; | ||
1350 | s3c_hsotg_enqueue_setup(hsotg); | ||
1351 | return; | ||
1352 | } | ||
1353 | |||
1354 | hsotg->eps[0].dir_in = 1; | ||
1355 | hsotg->eps[0].sent_zlp = 1; | ||
1356 | |||
1357 | dev_dbg(hsotg->dev, "sending zero-length packet\n"); | ||
1358 | |||
1359 | /* issue a zero-sized packet to terminate this */ | ||
1360 | writel(S3C_DxEPTSIZ_MC(1) | S3C_DxEPTSIZ_PktCnt(1) | | ||
1361 | S3C_DxEPTSIZ_XferSize(0), hsotg->regs + S3C_DIEPTSIZ(0)); | ||
1362 | |||
1363 | ctrl = readl(hsotg->regs + S3C_DIEPCTL0); | ||
1364 | ctrl |= S3C_DxEPCTL_CNAK; /* clear NAK set by core */ | ||
1365 | ctrl |= S3C_DxEPCTL_EPEna; /* ensure ep enabled */ | ||
1366 | ctrl |= S3C_DxEPCTL_USBActEp; | ||
1367 | writel(ctrl, hsotg->regs + S3C_DIEPCTL0); | ||
1368 | } | ||
1369 | |||
1370 | /** | ||
1371 | * s3c_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO | ||
1372 | * @hsotg: The device instance | ||
1373 | * @epnum: The endpoint received from | ||
1374 | * @was_setup: Set if processing a SetupDone event. | ||
1375 | * | ||
1376 | * The RXFIFO has delivered an OutDone event, which means that the data | ||
1377 | * transfer for an OUT endpoint has been completed, either by a short | ||
1378 | * packet or by the finish of a transfer. | ||
1379 | */ | ||
1380 | static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg, | ||
1381 | int epnum, bool was_setup) | ||
1382 | { | ||
1383 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[epnum]; | ||
1384 | struct s3c_hsotg_req *hs_req = hs_ep->req; | ||
1385 | struct usb_request *req = &hs_req->req; | ||
1386 | int result = 0; | ||
1387 | |||
1388 | if (!hs_req) { | ||
1389 | dev_dbg(hsotg->dev, "%s: no request active\n", __func__); | ||
1390 | return; | ||
1391 | } | ||
1392 | |||
1393 | if (using_dma(hsotg)) { | ||
1394 | u32 epsize = readl(hsotg->regs + S3C_DOEPTSIZ(epnum)); | ||
1395 | unsigned size_done; | ||
1396 | unsigned size_left; | ||
1397 | |||
1398 | /* Calculate the size of the transfer by checking how much | ||
1399 | * is left in the endpoint size register and then working it | ||
1400 | * out from the amount we loaded for the transfer. | ||
1401 | * | ||
1402 | * We need to do this as DMA pointers are always 32bit aligned | ||
1403 | * so may overshoot/undershoot the transfer. | ||
1404 | */ | ||
1405 | |||
1406 | size_left = S3C_DxEPTSIZ_XferSize_GET(epsize); | ||
1407 | |||
1408 | size_done = hs_ep->size_loaded - size_left; | ||
1409 | size_done += hs_ep->last_load; | ||
1410 | |||
1411 | req->actual = size_done; | ||
1412 | } | ||
1413 | |||
1414 | if (req->actual < req->length && req->short_not_ok) { | ||
1415 | dev_dbg(hsotg->dev, "%s: got %d/%d (short not ok) => error\n", | ||
1416 | __func__, req->actual, req->length); | ||
1417 | |||
1418 | /* todo - what should we return here? there's no one else | ||
1419 | * even bothering to check the status. */ | ||
1420 | } | ||
1421 | |||
1422 | if (epnum == 0) { | ||
1423 | if (!was_setup && req->complete != s3c_hsotg_complete_setup) | ||
1424 | s3c_hsotg_send_zlp(hsotg, hs_req); | ||
1425 | } | ||
1426 | |||
1427 | s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, result); | ||
1428 | } | ||
1429 | |||
1430 | /** | ||
1431 | * s3c_hsotg_read_frameno - read current frame number | ||
1432 | * @hsotg: The device instance | ||
1433 | * | ||
1434 | * Return the current frame number | ||
1435 | */ | ||
1436 | static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg) | ||
1437 | { | ||
1438 | u32 dsts; | ||
1439 | |||
1440 | dsts = readl(hsotg->regs + S3C_DSTS); | ||
1441 | dsts &= S3C_DSTS_SOFFN_MASK; | ||
1442 | dsts >>= S3C_DSTS_SOFFN_SHIFT; | ||
1443 | |||
1444 | return dsts; | ||
1445 | } | ||
1446 | |||
1447 | /** | ||
1448 | * s3c_hsotg_handle_rx - RX FIFO has data | ||
1449 | * @hsotg: The device instance | ||
1450 | * | ||
1451 | * The IRQ handler has detected that the RX FIFO has some data in it | ||
1452 | * that requires processing, so find out what is in there and do the | ||
1453 | * appropriate read. | ||
1454 | * | ||
1455 | * The RXFIFO is a true FIFO, the packets comming out are still in packet | ||
1456 | * chunks, so if you have x packets received on an endpoint you'll get x | ||
1457 | * FIFO events delivered, each with a packet's worth of data in it. | ||
1458 | * | ||
1459 | * When using DMA, we should not be processing events from the RXFIFO | ||
1460 | * as the actual data should be sent to the memory directly and we turn | ||
1461 | * on the completion interrupts to get notifications of transfer completion. | ||
1462 | */ | ||
1463 | void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg) | ||
1464 | { | ||
1465 | u32 grxstsr = readl(hsotg->regs + S3C_GRXSTSP); | ||
1466 | u32 epnum, status, size; | ||
1467 | |||
1468 | WARN_ON(using_dma(hsotg)); | ||
1469 | |||
1470 | epnum = grxstsr & S3C_GRXSTS_EPNum_MASK; | ||
1471 | status = grxstsr & S3C_GRXSTS_PktSts_MASK; | ||
1472 | |||
1473 | size = grxstsr & S3C_GRXSTS_ByteCnt_MASK; | ||
1474 | size >>= S3C_GRXSTS_ByteCnt_SHIFT; | ||
1475 | |||
1476 | if (1) | ||
1477 | dev_dbg(hsotg->dev, "%s: GRXSTSP=0x%08x (%d@%d)\n", | ||
1478 | __func__, grxstsr, size, epnum); | ||
1479 | |||
1480 | #define __status(x) ((x) >> S3C_GRXSTS_PktSts_SHIFT) | ||
1481 | |||
1482 | switch (status >> S3C_GRXSTS_PktSts_SHIFT) { | ||
1483 | case __status(S3C_GRXSTS_PktSts_GlobalOutNAK): | ||
1484 | dev_dbg(hsotg->dev, "GlobalOutNAK\n"); | ||
1485 | break; | ||
1486 | |||
1487 | case __status(S3C_GRXSTS_PktSts_OutDone): | ||
1488 | dev_dbg(hsotg->dev, "OutDone (Frame=0x%08x)\n", | ||
1489 | s3c_hsotg_read_frameno(hsotg)); | ||
1490 | |||
1491 | if (!using_dma(hsotg)) | ||
1492 | s3c_hsotg_handle_outdone(hsotg, epnum, false); | ||
1493 | break; | ||
1494 | |||
1495 | case __status(S3C_GRXSTS_PktSts_SetupDone): | ||
1496 | dev_dbg(hsotg->dev, | ||
1497 | "SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n", | ||
1498 | s3c_hsotg_read_frameno(hsotg), | ||
1499 | readl(hsotg->regs + S3C_DOEPCTL(0))); | ||
1500 | |||
1501 | s3c_hsotg_handle_outdone(hsotg, epnum, true); | ||
1502 | break; | ||
1503 | |||
1504 | case __status(S3C_GRXSTS_PktSts_OutRX): | ||
1505 | s3c_hsotg_rx_data(hsotg, epnum, size); | ||
1506 | break; | ||
1507 | |||
1508 | case __status(S3C_GRXSTS_PktSts_SetupRX): | ||
1509 | dev_dbg(hsotg->dev, | ||
1510 | "SetupRX (Frame=0x%08x, DOPEPCTL=0x%08x)\n", | ||
1511 | s3c_hsotg_read_frameno(hsotg), | ||
1512 | readl(hsotg->regs + S3C_DOEPCTL(0))); | ||
1513 | |||
1514 | s3c_hsotg_rx_data(hsotg, epnum, size); | ||
1515 | break; | ||
1516 | |||
1517 | default: | ||
1518 | dev_warn(hsotg->dev, "%s: unknown status %08x\n", | ||
1519 | __func__, grxstsr); | ||
1520 | |||
1521 | s3c_hsotg_dump(hsotg); | ||
1522 | break; | ||
1523 | } | ||
1524 | } | ||
1525 | |||
1526 | /** | ||
1527 | * s3c_hsotg_ep0_mps - turn max packet size into register setting | ||
1528 | * @mps: The maximum packet size in bytes. | ||
1529 | */ | ||
1530 | static u32 s3c_hsotg_ep0_mps(unsigned int mps) | ||
1531 | { | ||
1532 | switch (mps) { | ||
1533 | case 64: | ||
1534 | return S3C_D0EPCTL_MPS_64; | ||
1535 | case 32: | ||
1536 | return S3C_D0EPCTL_MPS_32; | ||
1537 | case 16: | ||
1538 | return S3C_D0EPCTL_MPS_16; | ||
1539 | case 8: | ||
1540 | return S3C_D0EPCTL_MPS_8; | ||
1541 | } | ||
1542 | |||
1543 | /* bad max packet size, warn and return invalid result */ | ||
1544 | WARN_ON(1); | ||
1545 | return (u32)-1; | ||
1546 | } | ||
1547 | |||
1548 | /** | ||
1549 | * s3c_hsotg_set_ep_maxpacket - set endpoint's max-packet field | ||
1550 | * @hsotg: The driver state. | ||
1551 | * @ep: The index number of the endpoint | ||
1552 | * @mps: The maximum packet size in bytes | ||
1553 | * | ||
1554 | * Configure the maximum packet size for the given endpoint, updating | ||
1555 | * the hardware control registers to reflect this. | ||
1556 | */ | ||
1557 | static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, | ||
1558 | unsigned int ep, unsigned int mps) | ||
1559 | { | ||
1560 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep]; | ||
1561 | void __iomem *regs = hsotg->regs; | ||
1562 | u32 mpsval; | ||
1563 | u32 reg; | ||
1564 | |||
1565 | if (ep == 0) { | ||
1566 | /* EP0 is a special case */ | ||
1567 | mpsval = s3c_hsotg_ep0_mps(mps); | ||
1568 | if (mpsval > 3) | ||
1569 | goto bad_mps; | ||
1570 | } else { | ||
1571 | if (mps >= S3C_DxEPCTL_MPS_LIMIT+1) | ||
1572 | goto bad_mps; | ||
1573 | |||
1574 | mpsval = mps; | ||
1575 | } | ||
1576 | |||
1577 | hs_ep->ep.maxpacket = mps; | ||
1578 | |||
1579 | /* update both the in and out endpoint controldir_ registers, even | ||
1580 | * if one of the directions may not be in use. */ | ||
1581 | |||
1582 | reg = readl(regs + S3C_DIEPCTL(ep)); | ||
1583 | reg &= ~S3C_DxEPCTL_MPS_MASK; | ||
1584 | reg |= mpsval; | ||
1585 | writel(reg, regs + S3C_DIEPCTL(ep)); | ||
1586 | |||
1587 | reg = readl(regs + S3C_DOEPCTL(ep)); | ||
1588 | reg &= ~S3C_DxEPCTL_MPS_MASK; | ||
1589 | reg |= mpsval; | ||
1590 | writel(reg, regs + S3C_DOEPCTL(ep)); | ||
1591 | |||
1592 | return; | ||
1593 | |||
1594 | bad_mps: | ||
1595 | dev_err(hsotg->dev, "ep%d: bad mps of %d\n", ep, mps); | ||
1596 | } | ||
1597 | |||
1598 | |||
1599 | /** | ||
1600 | * s3c_hsotg_trytx - check to see if anything needs transmitting | ||
1601 | * @hsotg: The driver state | ||
1602 | * @hs_ep: The driver endpoint to check. | ||
1603 | * | ||
1604 | * Check to see if there is a request that has data to send, and if so | ||
1605 | * make an attempt to write data into the FIFO. | ||
1606 | */ | ||
1607 | static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg, | ||
1608 | struct s3c_hsotg_ep *hs_ep) | ||
1609 | { | ||
1610 | struct s3c_hsotg_req *hs_req = hs_ep->req; | ||
1611 | |||
1612 | if (!hs_ep->dir_in || !hs_req) | ||
1613 | return 0; | ||
1614 | |||
1615 | if (hs_req->req.actual < hs_req->req.length) { | ||
1616 | dev_dbg(hsotg->dev, "trying to write more for ep%d\n", | ||
1617 | hs_ep->index); | ||
1618 | return s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req); | ||
1619 | } | ||
1620 | |||
1621 | return 0; | ||
1622 | } | ||
1623 | |||
1624 | /** | ||
1625 | * s3c_hsotg_complete_in - complete IN transfer | ||
1626 | * @hsotg: The device state. | ||
1627 | * @hs_ep: The endpoint that has just completed. | ||
1628 | * | ||
1629 | * An IN transfer has been completed, update the transfer's state and then | ||
1630 | * call the relevant completion routines. | ||
1631 | */ | ||
1632 | static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, | ||
1633 | struct s3c_hsotg_ep *hs_ep) | ||
1634 | { | ||
1635 | struct s3c_hsotg_req *hs_req = hs_ep->req; | ||
1636 | u32 epsize = readl(hsotg->regs + S3C_DIEPTSIZ(hs_ep->index)); | ||
1637 | int size_left, size_done; | ||
1638 | |||
1639 | if (!hs_req) { | ||
1640 | dev_dbg(hsotg->dev, "XferCompl but no req\n"); | ||
1641 | return; | ||
1642 | } | ||
1643 | |||
1644 | /* Calculate the size of the transfer by checking how much is left | ||
1645 | * in the endpoint size register and then working it out from | ||
1646 | * the amount we loaded for the transfer. | ||
1647 | * | ||
1648 | * We do this even for DMA, as the transfer may have incremented | ||
1649 | * past the end of the buffer (DMA transfers are always 32bit | ||
1650 | * aligned). | ||
1651 | */ | ||
1652 | |||
1653 | size_left = S3C_DxEPTSIZ_XferSize_GET(epsize); | ||
1654 | |||
1655 | size_done = hs_ep->size_loaded - size_left; | ||
1656 | size_done += hs_ep->last_load; | ||
1657 | |||
1658 | if (hs_req->req.actual != size_done) | ||
1659 | dev_dbg(hsotg->dev, "%s: adjusting size done %d => %d\n", | ||
1660 | __func__, hs_req->req.actual, size_done); | ||
1661 | |||
1662 | hs_req->req.actual = size_done; | ||
1663 | |||
1664 | /* if we did all of the transfer, and there is more data left | ||
1665 | * around, then try restarting the rest of the request */ | ||
1666 | |||
1667 | if (!size_left && hs_req->req.actual < hs_req->req.length) { | ||
1668 | dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); | ||
1669 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); | ||
1670 | } else | ||
1671 | s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0); | ||
1672 | } | ||
1673 | |||
1674 | /** | ||
1675 | * s3c_hsotg_epint - handle an in/out endpoint interrupt | ||
1676 | * @hsotg: The driver state | ||
1677 | * @idx: The index for the endpoint (0..15) | ||
1678 | * @dir_in: Set if this is an IN endpoint | ||
1679 | * | ||
1680 | * Process and clear any interrupt pending for an individual endpoint | ||
1681 | */ | ||
1682 | static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | ||
1683 | int dir_in) | ||
1684 | { | ||
1685 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx]; | ||
1686 | u32 epint_reg = dir_in ? S3C_DIEPINT(idx) : S3C_DOEPINT(idx); | ||
1687 | u32 epctl_reg = dir_in ? S3C_DIEPCTL(idx) : S3C_DOEPCTL(idx); | ||
1688 | u32 epsiz_reg = dir_in ? S3C_DIEPTSIZ(idx) : S3C_DOEPTSIZ(idx); | ||
1689 | u32 ints; | ||
1690 | u32 clear = 0; | ||
1691 | |||
1692 | ints = readl(hsotg->regs + epint_reg); | ||
1693 | |||
1694 | dev_dbg(hsotg->dev, "%s: ep%d(%s) DxEPINT=0x%08x\n", | ||
1695 | __func__, idx, dir_in ? "in" : "out", ints); | ||
1696 | |||
1697 | if (ints & S3C_DxEPINT_XferCompl) { | ||
1698 | dev_dbg(hsotg->dev, | ||
1699 | "%s: XferCompl: DxEPCTL=0x%08x, DxEPTSIZ=%08x\n", | ||
1700 | __func__, readl(hsotg->regs + epctl_reg), | ||
1701 | readl(hsotg->regs + epsiz_reg)); | ||
1702 | |||
1703 | /* we get OutDone from the FIFO, so we only need to look | ||
1704 | * at completing IN requests here */ | ||
1705 | if (dir_in) { | ||
1706 | s3c_hsotg_complete_in(hsotg, hs_ep); | ||
1707 | |||
1708 | if (idx == 0) | ||
1709 | s3c_hsotg_enqueue_setup(hsotg); | ||
1710 | } else if (using_dma(hsotg)) { | ||
1711 | /* We're using DMA, we need to fire an OutDone here | ||
1712 | * as we ignore the RXFIFO. */ | ||
1713 | |||
1714 | s3c_hsotg_handle_outdone(hsotg, idx, false); | ||
1715 | } | ||
1716 | |||
1717 | clear |= S3C_DxEPINT_XferCompl; | ||
1718 | } | ||
1719 | |||
1720 | if (ints & S3C_DxEPINT_EPDisbld) { | ||
1721 | dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__); | ||
1722 | clear |= S3C_DxEPINT_EPDisbld; | ||
1723 | } | ||
1724 | |||
1725 | if (ints & S3C_DxEPINT_AHBErr) { | ||
1726 | dev_dbg(hsotg->dev, "%s: AHBErr\n", __func__); | ||
1727 | clear |= S3C_DxEPINT_AHBErr; | ||
1728 | } | ||
1729 | |||
1730 | if (ints & S3C_DxEPINT_Setup) { /* Setup or Timeout */ | ||
1731 | dev_dbg(hsotg->dev, "%s: Setup/Timeout\n", __func__); | ||
1732 | |||
1733 | if (using_dma(hsotg) && idx == 0) { | ||
1734 | /* this is the notification we've received a | ||
1735 | * setup packet. In non-DMA mode we'd get this | ||
1736 | * from the RXFIFO, instead we need to process | ||
1737 | * the setup here. */ | ||
1738 | |||
1739 | if (dir_in) | ||
1740 | WARN_ON_ONCE(1); | ||
1741 | else | ||
1742 | s3c_hsotg_handle_outdone(hsotg, 0, true); | ||
1743 | } | ||
1744 | |||
1745 | clear |= S3C_DxEPINT_Setup; | ||
1746 | } | ||
1747 | |||
1748 | if (ints & S3C_DxEPINT_Back2BackSetup) { | ||
1749 | dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__); | ||
1750 | clear |= S3C_DxEPINT_Back2BackSetup; | ||
1751 | } | ||
1752 | |||
1753 | if (dir_in) { | ||
1754 | /* not sure if this is important, but we'll clear it anyway | ||
1755 | */ | ||
1756 | if (ints & S3C_DIEPMSK_INTknTXFEmpMsk) { | ||
1757 | dev_dbg(hsotg->dev, "%s: ep%d: INTknTXFEmpMsk\n", | ||
1758 | __func__, idx); | ||
1759 | clear |= S3C_DIEPMSK_INTknTXFEmpMsk; | ||
1760 | } | ||
1761 | |||
1762 | /* this probably means something bad is happening */ | ||
1763 | if (ints & S3C_DIEPMSK_INTknEPMisMsk) { | ||
1764 | dev_warn(hsotg->dev, "%s: ep%d: INTknEP\n", | ||
1765 | __func__, idx); | ||
1766 | clear |= S3C_DIEPMSK_INTknEPMisMsk; | ||
1767 | } | ||
1768 | } | ||
1769 | |||
1770 | writel(clear, hsotg->regs + epint_reg); | ||
1771 | } | ||
1772 | |||
1773 | /** | ||
1774 | * s3c_hsotg_irq_enumdone - Handle EnumDone interrupt (enumeration done) | ||
1775 | * @hsotg: The device state. | ||
1776 | * | ||
1777 | * Handle updating the device settings after the enumeration phase has | ||
1778 | * been completed. | ||
1779 | */ | ||
1780 | static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) | ||
1781 | { | ||
1782 | u32 dsts = readl(hsotg->regs + S3C_DSTS); | ||
1783 | int ep0_mps = 0, ep_mps; | ||
1784 | |||
1785 | /* This should signal the finish of the enumeration phase | ||
1786 | * of the USB handshaking, so we should now know what rate | ||
1787 | * we connected at. */ | ||
1788 | |||
1789 | dev_dbg(hsotg->dev, "EnumDone (DSTS=0x%08x)\n", dsts); | ||
1790 | |||
1791 | /* note, since we're limited by the size of transfer on EP0, and | ||
1792 | * it seems IN transfers must be a even number of packets we do | ||
1793 | * not advertise a 64byte MPS on EP0. */ | ||
1794 | |||
1795 | /* catch both EnumSpd_FS and EnumSpd_FS48 */ | ||
1796 | switch (dsts & S3C_DSTS_EnumSpd_MASK) { | ||
1797 | case S3C_DSTS_EnumSpd_FS: | ||
1798 | case S3C_DSTS_EnumSpd_FS48: | ||
1799 | hsotg->gadget.speed = USB_SPEED_FULL; | ||
1800 | dev_info(hsotg->dev, "new device is full-speed\n"); | ||
1801 | |||
1802 | ep0_mps = EP0_MPS_LIMIT; | ||
1803 | ep_mps = 64; | ||
1804 | break; | ||
1805 | |||
1806 | case S3C_DSTS_EnumSpd_HS: | ||
1807 | dev_info(hsotg->dev, "new device is high-speed\n"); | ||
1808 | hsotg->gadget.speed = USB_SPEED_HIGH; | ||
1809 | |||
1810 | ep0_mps = EP0_MPS_LIMIT; | ||
1811 | ep_mps = 512; | ||
1812 | break; | ||
1813 | |||
1814 | case S3C_DSTS_EnumSpd_LS: | ||
1815 | hsotg->gadget.speed = USB_SPEED_LOW; | ||
1816 | dev_info(hsotg->dev, "new device is low-speed\n"); | ||
1817 | |||
1818 | /* note, we don't actually support LS in this driver at the | ||
1819 | * moment, and the documentation seems to imply that it isn't | ||
1820 | * supported by the PHYs on some of the devices. | ||
1821 | */ | ||
1822 | break; | ||
1823 | } | ||
1824 | |||
1825 | /* we should now know the maximum packet size for an | ||
1826 | * endpoint, so set the endpoints to a default value. */ | ||
1827 | |||
1828 | if (ep0_mps) { | ||
1829 | int i; | ||
1830 | s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps); | ||
1831 | for (i = 1; i < S3C_HSOTG_EPS; i++) | ||
1832 | s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps); | ||
1833 | } | ||
1834 | |||
1835 | /* ensure after enumeration our EP0 is active */ | ||
1836 | |||
1837 | s3c_hsotg_enqueue_setup(hsotg); | ||
1838 | |||
1839 | dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", | ||
1840 | readl(hsotg->regs + S3C_DIEPCTL0), | ||
1841 | readl(hsotg->regs + S3C_DOEPCTL0)); | ||
1842 | } | ||
1843 | |||
1844 | /** | ||
1845 | * kill_all_requests - remove all requests from the endpoint's queue | ||
1846 | * @hsotg: The device state. | ||
1847 | * @ep: The endpoint the requests may be on. | ||
1848 | * @result: The result code to use. | ||
1849 | * @force: Force removal of any current requests | ||
1850 | * | ||
1851 | * Go through the requests on the given endpoint and mark them | ||
1852 | * completed with the given result code. | ||
1853 | */ | ||
1854 | static void kill_all_requests(struct s3c_hsotg *hsotg, | ||
1855 | struct s3c_hsotg_ep *ep, | ||
1856 | int result, bool force) | ||
1857 | { | ||
1858 | struct s3c_hsotg_req *req, *treq; | ||
1859 | unsigned long flags; | ||
1860 | |||
1861 | spin_lock_irqsave(&ep->lock, flags); | ||
1862 | |||
1863 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { | ||
1864 | /* currently, we can't do much about an already | ||
1865 | * running request on an in endpoint */ | ||
1866 | |||
1867 | if (ep->req == req && ep->dir_in && !force) | ||
1868 | continue; | ||
1869 | |||
1870 | s3c_hsotg_complete_request(hsotg, ep, req, | ||
1871 | result); | ||
1872 | } | ||
1873 | |||
1874 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1875 | } | ||
1876 | |||
1877 | #define call_gadget(_hs, _entry) \ | ||
1878 | if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ | ||
1879 | (_hs)->driver && (_hs)->driver->_entry) \ | ||
1880 | (_hs)->driver->_entry(&(_hs)->gadget); | ||
1881 | |||
1882 | /** | ||
1883 | * s3c_hsotg_disconnect_irq - disconnect irq service | ||
1884 | * @hsotg: The device state. | ||
1885 | * | ||
1886 | * A disconnect IRQ has been received, meaning that the host has | ||
1887 | * lost contact with the bus. Remove all current transactions | ||
1888 | * and signal the gadget driver that this has happened. | ||
1889 | */ | ||
1890 | static void s3c_hsotg_disconnect_irq(struct s3c_hsotg *hsotg) | ||
1891 | { | ||
1892 | unsigned ep; | ||
1893 | |||
1894 | for (ep = 0; ep < S3C_HSOTG_EPS; ep++) | ||
1895 | kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true); | ||
1896 | |||
1897 | call_gadget(hsotg, disconnect); | ||
1898 | } | ||
1899 | |||
1900 | /** | ||
1901 | * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler | ||
1902 | * @hsotg: The device state: | ||
1903 | * @periodic: True if this is a periodic FIFO interrupt | ||
1904 | */ | ||
1905 | static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic) | ||
1906 | { | ||
1907 | struct s3c_hsotg_ep *ep; | ||
1908 | int epno, ret; | ||
1909 | |||
1910 | /* look through for any more data to transmit */ | ||
1911 | |||
1912 | for (epno = 0; epno < S3C_HSOTG_EPS; epno++) { | ||
1913 | ep = &hsotg->eps[epno]; | ||
1914 | |||
1915 | if (!ep->dir_in) | ||
1916 | continue; | ||
1917 | |||
1918 | if ((periodic && !ep->periodic) || | ||
1919 | (!periodic && ep->periodic)) | ||
1920 | continue; | ||
1921 | |||
1922 | ret = s3c_hsotg_trytx(hsotg, ep); | ||
1923 | if (ret < 0) | ||
1924 | break; | ||
1925 | } | ||
1926 | } | ||
1927 | |||
1928 | static struct s3c_hsotg *our_hsotg; | ||
1929 | |||
1930 | /* IRQ flags which will trigger a retry around the IRQ loop */ | ||
1931 | #define IRQ_RETRY_MASK (S3C_GINTSTS_NPTxFEmp | \ | ||
1932 | S3C_GINTSTS_PTxFEmp | \ | ||
1933 | S3C_GINTSTS_RxFLvl) | ||
1934 | |||
1935 | /** | ||
1936 | * s3c_hsotg_irq - handle device interrupt | ||
1937 | * @irq: The IRQ number triggered | ||
1938 | * @pw: The pw value when registered the handler. | ||
1939 | */ | ||
1940 | static irqreturn_t s3c_hsotg_irq(int irq, void *pw) | ||
1941 | { | ||
1942 | struct s3c_hsotg *hsotg = pw; | ||
1943 | int retry_count = 8; | ||
1944 | u32 gintsts; | ||
1945 | u32 gintmsk; | ||
1946 | |||
1947 | irq_retry: | ||
1948 | gintsts = readl(hsotg->regs + S3C_GINTSTS); | ||
1949 | gintmsk = readl(hsotg->regs + S3C_GINTMSK); | ||
1950 | |||
1951 | dev_dbg(hsotg->dev, "%s: %08x %08x (%08x) retry %d\n", | ||
1952 | __func__, gintsts, gintsts & gintmsk, gintmsk, retry_count); | ||
1953 | |||
1954 | gintsts &= gintmsk; | ||
1955 | |||
1956 | if (gintsts & S3C_GINTSTS_OTGInt) { | ||
1957 | u32 otgint = readl(hsotg->regs + S3C_GOTGINT); | ||
1958 | |||
1959 | dev_info(hsotg->dev, "OTGInt: %08x\n", otgint); | ||
1960 | |||
1961 | writel(otgint, hsotg->regs + S3C_GOTGINT); | ||
1962 | writel(S3C_GINTSTS_OTGInt, hsotg->regs + S3C_GINTSTS); | ||
1963 | } | ||
1964 | |||
1965 | if (gintsts & S3C_GINTSTS_DisconnInt) { | ||
1966 | dev_dbg(hsotg->dev, "%s: DisconnInt\n", __func__); | ||
1967 | writel(S3C_GINTSTS_DisconnInt, hsotg->regs + S3C_GINTSTS); | ||
1968 | |||
1969 | s3c_hsotg_disconnect_irq(hsotg); | ||
1970 | } | ||
1971 | |||
1972 | if (gintsts & S3C_GINTSTS_SessReqInt) { | ||
1973 | dev_dbg(hsotg->dev, "%s: SessReqInt\n", __func__); | ||
1974 | writel(S3C_GINTSTS_SessReqInt, hsotg->regs + S3C_GINTSTS); | ||
1975 | } | ||
1976 | |||
1977 | if (gintsts & S3C_GINTSTS_EnumDone) { | ||
1978 | s3c_hsotg_irq_enumdone(hsotg); | ||
1979 | writel(S3C_GINTSTS_EnumDone, hsotg->regs + S3C_GINTSTS); | ||
1980 | } | ||
1981 | |||
1982 | if (gintsts & S3C_GINTSTS_ConIDStsChng) { | ||
1983 | dev_dbg(hsotg->dev, "ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n", | ||
1984 | readl(hsotg->regs + S3C_DSTS), | ||
1985 | readl(hsotg->regs + S3C_GOTGCTL)); | ||
1986 | |||
1987 | writel(S3C_GINTSTS_ConIDStsChng, hsotg->regs + S3C_GINTSTS); | ||
1988 | } | ||
1989 | |||
1990 | if (gintsts & (S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt)) { | ||
1991 | u32 daint = readl(hsotg->regs + S3C_DAINT); | ||
1992 | u32 daint_out = daint >> S3C_DAINT_OutEP_SHIFT; | ||
1993 | u32 daint_in = daint & ~(daint_out << S3C_DAINT_OutEP_SHIFT); | ||
1994 | int ep; | ||
1995 | |||
1996 | dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint); | ||
1997 | |||
1998 | for (ep = 0; ep < 15 && daint_out; ep++, daint_out >>= 1) { | ||
1999 | if (daint_out & 1) | ||
2000 | s3c_hsotg_epint(hsotg, ep, 0); | ||
2001 | } | ||
2002 | |||
2003 | for (ep = 0; ep < 15 && daint_in; ep++, daint_in >>= 1) { | ||
2004 | if (daint_in & 1) | ||
2005 | s3c_hsotg_epint(hsotg, ep, 1); | ||
2006 | } | ||
2007 | |||
2008 | writel(daint, hsotg->regs + S3C_DAINT); | ||
2009 | writel(gintsts & (S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt), | ||
2010 | hsotg->regs + S3C_GINTSTS); | ||
2011 | } | ||
2012 | |||
2013 | if (gintsts & S3C_GINTSTS_USBRst) { | ||
2014 | dev_info(hsotg->dev, "%s: USBRst\n", __func__); | ||
2015 | dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", | ||
2016 | readl(hsotg->regs + S3C_GNPTXSTS)); | ||
2017 | |||
2018 | kill_all_requests(hsotg, &hsotg->eps[0], -ECONNRESET, true); | ||
2019 | |||
2020 | /* it seems after a reset we can end up with a situation | ||
2021 | * where the TXFIFO still has data in it... try flushing | ||
2022 | * it to remove anything that may still be in it. | ||
2023 | */ | ||
2024 | |||
2025 | if (1) { | ||
2026 | writel(S3C_GRSTCTL_TxFNum(0) | S3C_GRSTCTL_TxFFlsh, | ||
2027 | hsotg->regs + S3C_GRSTCTL); | ||
2028 | |||
2029 | dev_info(hsotg->dev, "GNPTXSTS=%08x\n", | ||
2030 | readl(hsotg->regs + S3C_GNPTXSTS)); | ||
2031 | } | ||
2032 | |||
2033 | s3c_hsotg_enqueue_setup(hsotg); | ||
2034 | |||
2035 | writel(S3C_GINTSTS_USBRst, hsotg->regs + S3C_GINTSTS); | ||
2036 | } | ||
2037 | |||
2038 | /* check both FIFOs */ | ||
2039 | |||
2040 | if (gintsts & S3C_GINTSTS_NPTxFEmp) { | ||
2041 | dev_dbg(hsotg->dev, "NPTxFEmp\n"); | ||
2042 | |||
2043 | /* Disable the interrupt to stop it happening again | ||
2044 | * unless one of these endpoint routines decides that | ||
2045 | * it needs re-enabling */ | ||
2046 | |||
2047 | s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_NPTxFEmp); | ||
2048 | s3c_hsotg_irq_fifoempty(hsotg, false); | ||
2049 | |||
2050 | writel(S3C_GINTSTS_NPTxFEmp, hsotg->regs + S3C_GINTSTS); | ||
2051 | } | ||
2052 | |||
2053 | if (gintsts & S3C_GINTSTS_PTxFEmp) { | ||
2054 | dev_dbg(hsotg->dev, "PTxFEmp\n"); | ||
2055 | |||
2056 | /* See note in S3C_GINTSTS_NPTxFEmp */ | ||
2057 | |||
2058 | s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_PTxFEmp); | ||
2059 | s3c_hsotg_irq_fifoempty(hsotg, true); | ||
2060 | |||
2061 | writel(S3C_GINTSTS_PTxFEmp, hsotg->regs + S3C_GINTSTS); | ||
2062 | } | ||
2063 | |||
2064 | if (gintsts & S3C_GINTSTS_RxFLvl) { | ||
2065 | /* note, since GINTSTS_RxFLvl doubles as FIFO-not-empty, | ||
2066 | * we need to retry s3c_hsotg_handle_rx if this is still | ||
2067 | * set. */ | ||
2068 | |||
2069 | s3c_hsotg_handle_rx(hsotg); | ||
2070 | writel(S3C_GINTSTS_RxFLvl, hsotg->regs + S3C_GINTSTS); | ||
2071 | } | ||
2072 | |||
2073 | if (gintsts & S3C_GINTSTS_ModeMis) { | ||
2074 | dev_warn(hsotg->dev, "warning, mode mismatch triggered\n"); | ||
2075 | writel(S3C_GINTSTS_ModeMis, hsotg->regs + S3C_GINTSTS); | ||
2076 | } | ||
2077 | |||
2078 | if (gintsts & S3C_GINTSTS_USBSusp) { | ||
2079 | dev_info(hsotg->dev, "S3C_GINTSTS_USBSusp\n"); | ||
2080 | writel(S3C_GINTSTS_USBSusp, hsotg->regs + S3C_GINTSTS); | ||
2081 | |||
2082 | call_gadget(hsotg, suspend); | ||
2083 | } | ||
2084 | |||
2085 | if (gintsts & S3C_GINTSTS_WkUpInt) { | ||
2086 | dev_info(hsotg->dev, "S3C_GINTSTS_WkUpIn\n"); | ||
2087 | writel(S3C_GINTSTS_WkUpInt, hsotg->regs + S3C_GINTSTS); | ||
2088 | |||
2089 | call_gadget(hsotg, resume); | ||
2090 | } | ||
2091 | |||
2092 | if (gintsts & S3C_GINTSTS_ErlySusp) { | ||
2093 | dev_dbg(hsotg->dev, "S3C_GINTSTS_ErlySusp\n"); | ||
2094 | writel(S3C_GINTSTS_ErlySusp, hsotg->regs + S3C_GINTSTS); | ||
2095 | } | ||
2096 | |||
2097 | /* these next two seem to crop-up occasionally causing the core | ||
2098 | * to shutdown the USB transfer, so try clearing them and logging | ||
2099 | * the occurence. */ | ||
2100 | |||
2101 | if (gintsts & S3C_GINTSTS_GOUTNakEff) { | ||
2102 | dev_info(hsotg->dev, "GOUTNakEff triggered\n"); | ||
2103 | |||
2104 | s3c_hsotg_dump(hsotg); | ||
2105 | |||
2106 | writel(S3C_DCTL_CGOUTNak, hsotg->regs + S3C_DCTL); | ||
2107 | writel(S3C_GINTSTS_GOUTNakEff, hsotg->regs + S3C_GINTSTS); | ||
2108 | } | ||
2109 | |||
2110 | if (gintsts & S3C_GINTSTS_GINNakEff) { | ||
2111 | dev_info(hsotg->dev, "GINNakEff triggered\n"); | ||
2112 | |||
2113 | s3c_hsotg_dump(hsotg); | ||
2114 | |||
2115 | writel(S3C_DCTL_CGNPInNAK, hsotg->regs + S3C_DCTL); | ||
2116 | writel(S3C_GINTSTS_GINNakEff, hsotg->regs + S3C_GINTSTS); | ||
2117 | } | ||
2118 | |||
2119 | /* if we've had fifo events, we should try and go around the | ||
2120 | * loop again to see if there's any point in returning yet. */ | ||
2121 | |||
2122 | if (gintsts & IRQ_RETRY_MASK && --retry_count > 0) | ||
2123 | goto irq_retry; | ||
2124 | |||
2125 | return IRQ_HANDLED; | ||
2126 | } | ||
2127 | |||
2128 | /** | ||
2129 | * s3c_hsotg_ep_enable - enable the given endpoint | ||
2130 | * @ep: The USB endpint to configure | ||
2131 | * @desc: The USB endpoint descriptor to configure with. | ||
2132 | * | ||
2133 | * This is called from the USB gadget code's usb_ep_enable(). | ||
2134 | */ | ||
2135 | static int s3c_hsotg_ep_enable(struct usb_ep *ep, | ||
2136 | const struct usb_endpoint_descriptor *desc) | ||
2137 | { | ||
2138 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
2139 | struct s3c_hsotg *hsotg = hs_ep->parent; | ||
2140 | unsigned long flags; | ||
2141 | int index = hs_ep->index; | ||
2142 | u32 epctrl_reg; | ||
2143 | u32 epctrl; | ||
2144 | u32 mps; | ||
2145 | int dir_in; | ||
2146 | |||
2147 | dev_dbg(hsotg->dev, | ||
2148 | "%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n", | ||
2149 | __func__, ep->name, desc->bEndpointAddress, desc->bmAttributes, | ||
2150 | desc->wMaxPacketSize, desc->bInterval); | ||
2151 | |||
2152 | /* not to be called for EP0 */ | ||
2153 | WARN_ON(index == 0); | ||
2154 | |||
2155 | dir_in = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? 1 : 0; | ||
2156 | if (dir_in != hs_ep->dir_in) { | ||
2157 | dev_err(hsotg->dev, "%s: direction mismatch!\n", __func__); | ||
2158 | return -EINVAL; | ||
2159 | } | ||
2160 | |||
2161 | mps = le16_to_cpu(desc->wMaxPacketSize); | ||
2162 | |||
2163 | /* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */ | ||
2164 | |||
2165 | epctrl_reg = dir_in ? S3C_DIEPCTL(index) : S3C_DOEPCTL(index); | ||
2166 | epctrl = readl(hsotg->regs + epctrl_reg); | ||
2167 | |||
2168 | dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", | ||
2169 | __func__, epctrl, epctrl_reg); | ||
2170 | |||
2171 | spin_lock_irqsave(&hs_ep->lock, flags); | ||
2172 | |||
2173 | epctrl &= ~(S3C_DxEPCTL_EPType_MASK | S3C_DxEPCTL_MPS_MASK); | ||
2174 | epctrl |= S3C_DxEPCTL_MPS(mps); | ||
2175 | |||
2176 | /* mark the endpoint as active, otherwise the core may ignore | ||
2177 | * transactions entirely for this endpoint */ | ||
2178 | epctrl |= S3C_DxEPCTL_USBActEp; | ||
2179 | |||
2180 | /* set the NAK status on the endpoint, otherwise we might try and | ||
2181 | * do something with data that we've yet got a request to process | ||
2182 | * since the RXFIFO will take data for an endpoint even if the | ||
2183 | * size register hasn't been set. | ||
2184 | */ | ||
2185 | |||
2186 | epctrl |= S3C_DxEPCTL_SNAK; | ||
2187 | |||
2188 | /* update the endpoint state */ | ||
2189 | hs_ep->ep.maxpacket = mps; | ||
2190 | |||
2191 | /* default, set to non-periodic */ | ||
2192 | hs_ep->periodic = 0; | ||
2193 | |||
2194 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
2195 | case USB_ENDPOINT_XFER_ISOC: | ||
2196 | dev_err(hsotg->dev, "no current ISOC support\n"); | ||
2197 | return -EINVAL; | ||
2198 | |||
2199 | case USB_ENDPOINT_XFER_BULK: | ||
2200 | epctrl |= S3C_DxEPCTL_EPType_Bulk; | ||
2201 | break; | ||
2202 | |||
2203 | case USB_ENDPOINT_XFER_INT: | ||
2204 | if (dir_in) { | ||
2205 | /* Allocate our TxFNum by simply using the index | ||
2206 | * of the endpoint for the moment. We could do | ||
2207 | * something better if the host indicates how | ||
2208 | * many FIFOs we are expecting to use. */ | ||
2209 | |||
2210 | hs_ep->periodic = 1; | ||
2211 | epctrl |= S3C_DxEPCTL_TxFNum(index); | ||
2212 | } | ||
2213 | |||
2214 | epctrl |= S3C_DxEPCTL_EPType_Intterupt; | ||
2215 | break; | ||
2216 | |||
2217 | case USB_ENDPOINT_XFER_CONTROL: | ||
2218 | epctrl |= S3C_DxEPCTL_EPType_Control; | ||
2219 | break; | ||
2220 | } | ||
2221 | |||
2222 | /* for non control endpoints, set PID to D0 */ | ||
2223 | if (index) | ||
2224 | epctrl |= S3C_DxEPCTL_SetD0PID; | ||
2225 | |||
2226 | dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n", | ||
2227 | __func__, epctrl); | ||
2228 | |||
2229 | writel(epctrl, hsotg->regs + epctrl_reg); | ||
2230 | dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x\n", | ||
2231 | __func__, readl(hsotg->regs + epctrl_reg)); | ||
2232 | |||
2233 | /* enable the endpoint interrupt */ | ||
2234 | s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); | ||
2235 | |||
2236 | spin_unlock_irqrestore(&hs_ep->lock, flags); | ||
2237 | return 0; | ||
2238 | } | ||
2239 | |||
2240 | static int s3c_hsotg_ep_disable(struct usb_ep *ep) | ||
2241 | { | ||
2242 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
2243 | struct s3c_hsotg *hsotg = hs_ep->parent; | ||
2244 | int dir_in = hs_ep->dir_in; | ||
2245 | int index = hs_ep->index; | ||
2246 | unsigned long flags; | ||
2247 | u32 epctrl_reg; | ||
2248 | u32 ctrl; | ||
2249 | |||
2250 | dev_info(hsotg->dev, "%s(ep %p)\n", __func__, ep); | ||
2251 | |||
2252 | if (ep == &hsotg->eps[0].ep) { | ||
2253 | dev_err(hsotg->dev, "%s: called for ep0\n", __func__); | ||
2254 | return -EINVAL; | ||
2255 | } | ||
2256 | |||
2257 | epctrl_reg = dir_in ? S3C_DIEPCTL(index) : S3C_DOEPCTL(index); | ||
2258 | |||
2259 | /* terminate all requests with shutdown */ | ||
2260 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); | ||
2261 | |||
2262 | spin_lock_irqsave(&hs_ep->lock, flags); | ||
2263 | |||
2264 | ctrl = readl(hsotg->regs + epctrl_reg); | ||
2265 | ctrl &= ~S3C_DxEPCTL_EPEna; | ||
2266 | ctrl &= ~S3C_DxEPCTL_USBActEp; | ||
2267 | ctrl |= S3C_DxEPCTL_SNAK; | ||
2268 | |||
2269 | dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl); | ||
2270 | writel(ctrl, hsotg->regs + epctrl_reg); | ||
2271 | |||
2272 | /* disable endpoint interrupts */ | ||
2273 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); | ||
2274 | |||
2275 | spin_unlock_irqrestore(&hs_ep->lock, flags); | ||
2276 | return 0; | ||
2277 | } | ||
2278 | |||
2279 | /** | ||
2280 | * on_list - check request is on the given endpoint | ||
2281 | * @ep: The endpoint to check. | ||
2282 | * @test: The request to test if it is on the endpoint. | ||
2283 | */ | ||
2284 | static bool on_list(struct s3c_hsotg_ep *ep, struct s3c_hsotg_req *test) | ||
2285 | { | ||
2286 | struct s3c_hsotg_req *req, *treq; | ||
2287 | |||
2288 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { | ||
2289 | if (req == test) | ||
2290 | return true; | ||
2291 | } | ||
2292 | |||
2293 | return false; | ||
2294 | } | ||
2295 | |||
2296 | static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | ||
2297 | { | ||
2298 | struct s3c_hsotg_req *hs_req = our_req(req); | ||
2299 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
2300 | struct s3c_hsotg *hs = hs_ep->parent; | ||
2301 | unsigned long flags; | ||
2302 | |||
2303 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); | ||
2304 | |||
2305 | if (hs_req == hs_ep->req) { | ||
2306 | dev_dbg(hs->dev, "%s: already in progress\n", __func__); | ||
2307 | return -EINPROGRESS; | ||
2308 | } | ||
2309 | |||
2310 | spin_lock_irqsave(&hs_ep->lock, flags); | ||
2311 | |||
2312 | if (!on_list(hs_ep, hs_req)) { | ||
2313 | spin_unlock_irqrestore(&hs_ep->lock, flags); | ||
2314 | return -EINVAL; | ||
2315 | } | ||
2316 | |||
2317 | s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); | ||
2318 | spin_unlock_irqrestore(&hs_ep->lock, flags); | ||
2319 | |||
2320 | return 0; | ||
2321 | } | ||
2322 | |||
2323 | static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | ||
2324 | { | ||
2325 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
2326 | struct s3c_hsotg *hs = hs_ep->parent; | ||
2327 | int index = hs_ep->index; | ||
2328 | unsigned long irqflags; | ||
2329 | u32 epreg; | ||
2330 | u32 epctl; | ||
2331 | |||
2332 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); | ||
2333 | |||
2334 | spin_lock_irqsave(&hs_ep->lock, irqflags); | ||
2335 | |||
2336 | /* write both IN and OUT control registers */ | ||
2337 | |||
2338 | epreg = S3C_DIEPCTL(index); | ||
2339 | epctl = readl(hs->regs + epreg); | ||
2340 | |||
2341 | if (value) | ||
2342 | epctl |= S3C_DxEPCTL_Stall; | ||
2343 | else | ||
2344 | epctl &= ~S3C_DxEPCTL_Stall; | ||
2345 | |||
2346 | writel(epctl, hs->regs + epreg); | ||
2347 | |||
2348 | epreg = S3C_DOEPCTL(index); | ||
2349 | epctl = readl(hs->regs + epreg); | ||
2350 | |||
2351 | if (value) | ||
2352 | epctl |= S3C_DxEPCTL_Stall; | ||
2353 | else | ||
2354 | epctl &= ~S3C_DxEPCTL_Stall; | ||
2355 | |||
2356 | writel(epctl, hs->regs + epreg); | ||
2357 | |||
2358 | spin_unlock_irqrestore(&hs_ep->lock, irqflags); | ||
2359 | |||
2360 | return 0; | ||
2361 | } | ||
2362 | |||
2363 | static struct usb_ep_ops s3c_hsotg_ep_ops = { | ||
2364 | .enable = s3c_hsotg_ep_enable, | ||
2365 | .disable = s3c_hsotg_ep_disable, | ||
2366 | .alloc_request = s3c_hsotg_ep_alloc_request, | ||
2367 | .free_request = s3c_hsotg_ep_free_request, | ||
2368 | .queue = s3c_hsotg_ep_queue, | ||
2369 | .dequeue = s3c_hsotg_ep_dequeue, | ||
2370 | .set_halt = s3c_hsotg_ep_sethalt, | ||
2371 | /* note, don't belive we have any call for the fifo routines */ | ||
2372 | }; | ||
2373 | |||
2374 | /** | ||
2375 | * s3c_hsotg_corereset - issue softreset to the core | ||
2376 | * @hsotg: The device state | ||
2377 | * | ||
2378 | * Issue a soft reset to the core, and await the core finishing it. | ||
2379 | */ | ||
2380 | static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) | ||
2381 | { | ||
2382 | int timeout; | ||
2383 | u32 grstctl; | ||
2384 | |||
2385 | dev_dbg(hsotg->dev, "resetting core\n"); | ||
2386 | |||
2387 | /* issue soft reset */ | ||
2388 | writel(S3C_GRSTCTL_CSftRst, hsotg->regs + S3C_GRSTCTL); | ||
2389 | |||
2390 | timeout = 1000; | ||
2391 | do { | ||
2392 | grstctl = readl(hsotg->regs + S3C_GRSTCTL); | ||
2393 | } while (!(grstctl & S3C_GRSTCTL_CSftRst) && timeout-- > 0); | ||
2394 | |||
2395 | if (!grstctl & S3C_GRSTCTL_CSftRst) { | ||
2396 | dev_err(hsotg->dev, "Failed to get CSftRst asserted\n"); | ||
2397 | return -EINVAL; | ||
2398 | } | ||
2399 | |||
2400 | timeout = 1000; | ||
2401 | |||
2402 | while (1) { | ||
2403 | u32 grstctl = readl(hsotg->regs + S3C_GRSTCTL); | ||
2404 | |||
2405 | if (timeout-- < 0) { | ||
2406 | dev_info(hsotg->dev, | ||
2407 | "%s: reset failed, GRSTCTL=%08x\n", | ||
2408 | __func__, grstctl); | ||
2409 | return -ETIMEDOUT; | ||
2410 | } | ||
2411 | |||
2412 | if (grstctl & S3C_GRSTCTL_CSftRst) | ||
2413 | continue; | ||
2414 | |||
2415 | if (!(grstctl & S3C_GRSTCTL_AHBIdle)) | ||
2416 | continue; | ||
2417 | |||
2418 | break; /* reset done */ | ||
2419 | } | ||
2420 | |||
2421 | dev_dbg(hsotg->dev, "reset successful\n"); | ||
2422 | return 0; | ||
2423 | } | ||
2424 | |||
2425 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
2426 | { | ||
2427 | struct s3c_hsotg *hsotg = our_hsotg; | ||
2428 | int ret; | ||
2429 | |||
2430 | if (!hsotg) { | ||
2431 | printk(KERN_ERR "%s: called with no device\n", __func__); | ||
2432 | return -ENODEV; | ||
2433 | } | ||
2434 | |||
2435 | if (!driver) { | ||
2436 | dev_err(hsotg->dev, "%s: no driver\n", __func__); | ||
2437 | return -EINVAL; | ||
2438 | } | ||
2439 | |||
2440 | if (driver->speed != USB_SPEED_HIGH && | ||
2441 | driver->speed != USB_SPEED_FULL) { | ||
2442 | dev_err(hsotg->dev, "%s: bad speed\n", __func__); | ||
2443 | } | ||
2444 | |||
2445 | if (!driver->bind || !driver->setup) { | ||
2446 | dev_err(hsotg->dev, "%s: missing entry points\n", __func__); | ||
2447 | return -EINVAL; | ||
2448 | } | ||
2449 | |||
2450 | WARN_ON(hsotg->driver); | ||
2451 | |||
2452 | driver->driver.bus = NULL; | ||
2453 | hsotg->driver = driver; | ||
2454 | hsotg->gadget.dev.driver = &driver->driver; | ||
2455 | hsotg->gadget.dev.dma_mask = hsotg->dev->dma_mask; | ||
2456 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | ||
2457 | |||
2458 | ret = device_add(&hsotg->gadget.dev); | ||
2459 | if (ret) { | ||
2460 | dev_err(hsotg->dev, "failed to register gadget device\n"); | ||
2461 | goto err; | ||
2462 | } | ||
2463 | |||
2464 | ret = driver->bind(&hsotg->gadget); | ||
2465 | if (ret) { | ||
2466 | dev_err(hsotg->dev, "failed bind %s\n", driver->driver.name); | ||
2467 | |||
2468 | hsotg->gadget.dev.driver = NULL; | ||
2469 | hsotg->driver = NULL; | ||
2470 | goto err; | ||
2471 | } | ||
2472 | |||
2473 | /* we must now enable ep0 ready for host detection and then | ||
2474 | * set configuration. */ | ||
2475 | |||
2476 | s3c_hsotg_corereset(hsotg); | ||
2477 | |||
2478 | /* set the PLL on, remove the HNP/SRP and set the PHY */ | ||
2479 | writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) | | ||
2480 | (0x5 << 10), hsotg->regs + S3C_GUSBCFG); | ||
2481 | |||
2482 | /* looks like soft-reset changes state of FIFOs */ | ||
2483 | s3c_hsotg_init_fifo(hsotg); | ||
2484 | |||
2485 | __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); | ||
2486 | |||
2487 | writel(1 << 18 | S3C_DCFG_DevSpd_HS, hsotg->regs + S3C_DCFG); | ||
2488 | |||
2489 | writel(S3C_GINTSTS_DisconnInt | S3C_GINTSTS_SessReqInt | | ||
2490 | S3C_GINTSTS_ConIDStsChng | S3C_GINTSTS_USBRst | | ||
2491 | S3C_GINTSTS_EnumDone | S3C_GINTSTS_OTGInt | | ||
2492 | S3C_GINTSTS_USBSusp | S3C_GINTSTS_WkUpInt | | ||
2493 | S3C_GINTSTS_GOUTNakEff | S3C_GINTSTS_GINNakEff | | ||
2494 | S3C_GINTSTS_ErlySusp, | ||
2495 | hsotg->regs + S3C_GINTMSK); | ||
2496 | |||
2497 | if (using_dma(hsotg)) | ||
2498 | writel(S3C_GAHBCFG_GlblIntrEn | S3C_GAHBCFG_DMAEn | | ||
2499 | S3C_GAHBCFG_HBstLen_Incr4, | ||
2500 | hsotg->regs + S3C_GAHBCFG); | ||
2501 | else | ||
2502 | writel(S3C_GAHBCFG_GlblIntrEn, hsotg->regs + S3C_GAHBCFG); | ||
2503 | |||
2504 | /* Enabling INTknTXFEmpMsk here seems to be a big mistake, we end | ||
2505 | * up being flooded with interrupts if the host is polling the | ||
2506 | * endpoint to try and read data. */ | ||
2507 | |||
2508 | writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk | | ||
2509 | S3C_DIEPMSK_INTknEPMisMsk | | ||
2510 | S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk, | ||
2511 | hsotg->regs + S3C_DIEPMSK); | ||
2512 | |||
2513 | /* don't need XferCompl, we get that from RXFIFO in slave mode. In | ||
2514 | * DMA mode we may need this. */ | ||
2515 | writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk | | ||
2516 | S3C_DOEPMSK_EPDisbldMsk | | ||
2517 | using_dma(hsotg) ? (S3C_DIEPMSK_XferComplMsk | | ||
2518 | S3C_DIEPMSK_TimeOUTMsk) : 0, | ||
2519 | hsotg->regs + S3C_DOEPMSK); | ||
2520 | |||
2521 | writel(0, hsotg->regs + S3C_DAINTMSK); | ||
2522 | |||
2523 | dev_info(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", | ||
2524 | readl(hsotg->regs + S3C_DIEPCTL0), | ||
2525 | readl(hsotg->regs + S3C_DOEPCTL0)); | ||
2526 | |||
2527 | /* enable in and out endpoint interrupts */ | ||
2528 | s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt); | ||
2529 | |||
2530 | /* Enable the RXFIFO when in slave mode, as this is how we collect | ||
2531 | * the data. In DMA mode, we get events from the FIFO but also | ||
2532 | * things we cannot process, so do not use it. */ | ||
2533 | if (!using_dma(hsotg)) | ||
2534 | s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_RxFLvl); | ||
2535 | |||
2536 | /* Enable interrupts for EP0 in and out */ | ||
2537 | s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1); | ||
2538 | s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1); | ||
2539 | |||
2540 | __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone); | ||
2541 | udelay(10); /* see openiboot */ | ||
2542 | __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone); | ||
2543 | |||
2544 | dev_info(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + S3C_DCTL)); | ||
2545 | |||
2546 | /* S3C_DxEPCTL_USBActEp says RO in manual, but seems to be set by | ||
2547 | writing to the EPCTL register.. */ | ||
2548 | |||
2549 | /* set to read 1 8byte packet */ | ||
2550 | writel(S3C_DxEPTSIZ_MC(1) | S3C_DxEPTSIZ_PktCnt(1) | | ||
2551 | S3C_DxEPTSIZ_XferSize(8), hsotg->regs + DOEPTSIZ0); | ||
2552 | |||
2553 | writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) | | ||
2554 | S3C_DxEPCTL_CNAK | S3C_DxEPCTL_EPEna | | ||
2555 | S3C_DxEPCTL_USBActEp, | ||
2556 | hsotg->regs + S3C_DOEPCTL0); | ||
2557 | |||
2558 | /* enable, but don't activate EP0in */ | ||
2559 | writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) | | ||
2560 | S3C_DxEPCTL_USBActEp, hsotg->regs + S3C_DIEPCTL0); | ||
2561 | |||
2562 | s3c_hsotg_enqueue_setup(hsotg); | ||
2563 | |||
2564 | dev_info(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", | ||
2565 | readl(hsotg->regs + S3C_DIEPCTL0), | ||
2566 | readl(hsotg->regs + S3C_DOEPCTL0)); | ||
2567 | |||
2568 | /* clear global NAKs */ | ||
2569 | writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK, | ||
2570 | hsotg->regs + S3C_DCTL); | ||
2571 | |||
2572 | /* remove the soft-disconnect and let's go */ | ||
2573 | __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); | ||
2574 | |||
2575 | /* report to the user, and return */ | ||
2576 | |||
2577 | dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); | ||
2578 | return 0; | ||
2579 | |||
2580 | err: | ||
2581 | hsotg->driver = NULL; | ||
2582 | hsotg->gadget.dev.driver = NULL; | ||
2583 | return ret; | ||
2584 | } | ||
2585 | |||
2586 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
2587 | { | ||
2588 | struct s3c_hsotg *hsotg = our_hsotg; | ||
2589 | int ep; | ||
2590 | |||
2591 | if (!hsotg) | ||
2592 | return -ENODEV; | ||
2593 | |||
2594 | if (!driver || driver != hsotg->driver || !driver->unbind) | ||
2595 | return -EINVAL; | ||
2596 | |||
2597 | /* all endpoints should be shutdown */ | ||
2598 | for (ep = 0; ep < S3C_HSOTG_EPS; ep++) | ||
2599 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | ||
2600 | |||
2601 | call_gadget(hsotg, disconnect); | ||
2602 | |||
2603 | driver->unbind(&hsotg->gadget); | ||
2604 | hsotg->driver = NULL; | ||
2605 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | ||
2606 | |||
2607 | device_del(&hsotg->gadget.dev); | ||
2608 | |||
2609 | dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", | ||
2610 | driver->driver.name); | ||
2611 | |||
2612 | return 0; | ||
2613 | } | ||
2614 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
2615 | |||
2616 | static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget) | ||
2617 | { | ||
2618 | return s3c_hsotg_read_frameno(to_hsotg(gadget)); | ||
2619 | } | ||
2620 | |||
2621 | static struct usb_gadget_ops s3c_hsotg_gadget_ops = { | ||
2622 | .get_frame = s3c_hsotg_gadget_getframe, | ||
2623 | }; | ||
2624 | |||
2625 | /** | ||
2626 | * s3c_hsotg_initep - initialise a single endpoint | ||
2627 | * @hsotg: The device state. | ||
2628 | * @hs_ep: The endpoint to be initialised. | ||
2629 | * @epnum: The endpoint number | ||
2630 | * | ||
2631 | * Initialise the given endpoint (as part of the probe and device state | ||
2632 | * creation) to give to the gadget driver. Setup the endpoint name, any | ||
2633 | * direction information and other state that may be required. | ||
2634 | */ | ||
2635 | static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg, | ||
2636 | struct s3c_hsotg_ep *hs_ep, | ||
2637 | int epnum) | ||
2638 | { | ||
2639 | u32 ptxfifo; | ||
2640 | char *dir; | ||
2641 | |||
2642 | if (epnum == 0) | ||
2643 | dir = ""; | ||
2644 | else if ((epnum % 2) == 0) { | ||
2645 | dir = "out"; | ||
2646 | } else { | ||
2647 | dir = "in"; | ||
2648 | hs_ep->dir_in = 1; | ||
2649 | } | ||
2650 | |||
2651 | hs_ep->index = epnum; | ||
2652 | |||
2653 | snprintf(hs_ep->name, sizeof(hs_ep->name), "ep%d%s", epnum, dir); | ||
2654 | |||
2655 | INIT_LIST_HEAD(&hs_ep->queue); | ||
2656 | INIT_LIST_HEAD(&hs_ep->ep.ep_list); | ||
2657 | |||
2658 | spin_lock_init(&hs_ep->lock); | ||
2659 | |||
2660 | /* add to the list of endpoints known by the gadget driver */ | ||
2661 | if (epnum) | ||
2662 | list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); | ||
2663 | |||
2664 | hs_ep->parent = hsotg; | ||
2665 | hs_ep->ep.name = hs_ep->name; | ||
2666 | hs_ep->ep.maxpacket = epnum ? 512 : EP0_MPS_LIMIT; | ||
2667 | hs_ep->ep.ops = &s3c_hsotg_ep_ops; | ||
2668 | |||
2669 | /* Read the FIFO size for the Periodic TX FIFO, even if we're | ||
2670 | * an OUT endpoint, we may as well do this if in future the | ||
2671 | * code is changed to make each endpoint's direction changeable. | ||
2672 | */ | ||
2673 | |||
2674 | ptxfifo = readl(hsotg->regs + S3C_DPTXFSIZn(epnum)); | ||
2675 | hs_ep->fifo_size = S3C_DPTXFSIZn_DPTxFSize_GET(ptxfifo); | ||
2676 | |||
2677 | /* if we're using dma, we need to set the next-endpoint pointer | ||
2678 | * to be something valid. | ||
2679 | */ | ||
2680 | |||
2681 | if (using_dma(hsotg)) { | ||
2682 | u32 next = S3C_DxEPCTL_NextEp((epnum + 1) % 15); | ||
2683 | writel(next, hsotg->regs + S3C_DIEPCTL(epnum)); | ||
2684 | writel(next, hsotg->regs + S3C_DOEPCTL(epnum)); | ||
2685 | } | ||
2686 | } | ||
2687 | |||
2688 | /** | ||
2689 | * s3c_hsotg_otgreset - reset the OtG phy block | ||
2690 | * @hsotg: The host state. | ||
2691 | * | ||
2692 | * Power up the phy, set the basic configuration and start the PHY. | ||
2693 | */ | ||
2694 | static void s3c_hsotg_otgreset(struct s3c_hsotg *hsotg) | ||
2695 | { | ||
2696 | u32 osc; | ||
2697 | |||
2698 | writel(0, S3C_PHYPWR); | ||
2699 | mdelay(1); | ||
2700 | |||
2701 | osc = hsotg->plat->is_osc ? S3C_PHYCLK_EXT_OSC : 0; | ||
2702 | |||
2703 | writel(osc | 0x10, S3C_PHYCLK); | ||
2704 | |||
2705 | /* issue a full set of resets to the otg and core */ | ||
2706 | |||
2707 | writel(S3C_RSTCON_PHY, S3C_RSTCON); | ||
2708 | udelay(20); /* at-least 10uS */ | ||
2709 | writel(0, S3C_RSTCON); | ||
2710 | } | ||
2711 | |||
2712 | |||
2713 | static void s3c_hsotg_init(struct s3c_hsotg *hsotg) | ||
2714 | { | ||
2715 | /* unmask subset of endpoint interrupts */ | ||
2716 | |||
2717 | writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk | | ||
2718 | S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk, | ||
2719 | hsotg->regs + S3C_DIEPMSK); | ||
2720 | |||
2721 | writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk | | ||
2722 | S3C_DOEPMSK_EPDisbldMsk | S3C_DOEPMSK_XferComplMsk, | ||
2723 | hsotg->regs + S3C_DOEPMSK); | ||
2724 | |||
2725 | writel(0, hsotg->regs + S3C_DAINTMSK); | ||
2726 | |||
2727 | if (0) { | ||
2728 | /* post global nak until we're ready */ | ||
2729 | writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak, | ||
2730 | hsotg->regs + S3C_DCTL); | ||
2731 | } | ||
2732 | |||
2733 | /* setup fifos */ | ||
2734 | |||
2735 | dev_info(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", | ||
2736 | readl(hsotg->regs + S3C_GRXFSIZ), | ||
2737 | readl(hsotg->regs + S3C_GNPTXFSIZ)); | ||
2738 | |||
2739 | s3c_hsotg_init_fifo(hsotg); | ||
2740 | |||
2741 | /* set the PLL on, remove the HNP/SRP and set the PHY */ | ||
2742 | writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) | (0x5 << 10), | ||
2743 | hsotg->regs + S3C_GUSBCFG); | ||
2744 | |||
2745 | writel(using_dma(hsotg) ? S3C_GAHBCFG_DMAEn : 0x0, | ||
2746 | hsotg->regs + S3C_GAHBCFG); | ||
2747 | } | ||
2748 | |||
2749 | static void s3c_hsotg_dump(struct s3c_hsotg *hsotg) | ||
2750 | { | ||
2751 | struct device *dev = hsotg->dev; | ||
2752 | void __iomem *regs = hsotg->regs; | ||
2753 | u32 val; | ||
2754 | int idx; | ||
2755 | |||
2756 | dev_info(dev, "DCFG=0x%08x, DCTL=0x%08x, DIEPMSK=%08x\n", | ||
2757 | readl(regs + S3C_DCFG), readl(regs + S3C_DCTL), | ||
2758 | readl(regs + S3C_DIEPMSK)); | ||
2759 | |||
2760 | dev_info(dev, "GAHBCFG=0x%08x, 0x44=0x%08x\n", | ||
2761 | readl(regs + S3C_GAHBCFG), readl(regs + 0x44)); | ||
2762 | |||
2763 | dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", | ||
2764 | readl(regs + S3C_GRXFSIZ), readl(regs + S3C_GNPTXFSIZ)); | ||
2765 | |||
2766 | /* show periodic fifo settings */ | ||
2767 | |||
2768 | for (idx = 1; idx <= 15; idx++) { | ||
2769 | val = readl(regs + S3C_DPTXFSIZn(idx)); | ||
2770 | dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx, | ||
2771 | val >> S3C_DPTXFSIZn_DPTxFSize_SHIFT, | ||
2772 | val & S3C_DPTXFSIZn_DPTxFStAddr_MASK); | ||
2773 | } | ||
2774 | |||
2775 | for (idx = 0; idx < 15; idx++) { | ||
2776 | dev_info(dev, | ||
2777 | "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx, | ||
2778 | readl(regs + S3C_DIEPCTL(idx)), | ||
2779 | readl(regs + S3C_DIEPTSIZ(idx)), | ||
2780 | readl(regs + S3C_DIEPDMA(idx))); | ||
2781 | |||
2782 | val = readl(regs + S3C_DOEPCTL(idx)); | ||
2783 | dev_info(dev, | ||
2784 | "ep%d-out: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", | ||
2785 | idx, readl(regs + S3C_DOEPCTL(idx)), | ||
2786 | readl(regs + S3C_DOEPTSIZ(idx)), | ||
2787 | readl(regs + S3C_DOEPDMA(idx))); | ||
2788 | |||
2789 | } | ||
2790 | |||
2791 | dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n", | ||
2792 | readl(regs + S3C_DVBUSDIS), readl(regs + S3C_DVBUSPULSE)); | ||
2793 | } | ||
2794 | |||
2795 | |||
2796 | /** | ||
2797 | * state_show - debugfs: show overall driver and device state. | ||
2798 | * @seq: The seq file to write to. | ||
2799 | * @v: Unused parameter. | ||
2800 | * | ||
2801 | * This debugfs entry shows the overall state of the hardware and | ||
2802 | * some general information about each of the endpoints available | ||
2803 | * to the system. | ||
2804 | */ | ||
2805 | static int state_show(struct seq_file *seq, void *v) | ||
2806 | { | ||
2807 | struct s3c_hsotg *hsotg = seq->private; | ||
2808 | void __iomem *regs = hsotg->regs; | ||
2809 | int idx; | ||
2810 | |||
2811 | seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n", | ||
2812 | readl(regs + S3C_DCFG), | ||
2813 | readl(regs + S3C_DCTL), | ||
2814 | readl(regs + S3C_DSTS)); | ||
2815 | |||
2816 | seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n", | ||
2817 | readl(regs + S3C_DIEPMSK), readl(regs + S3C_DOEPMSK)); | ||
2818 | |||
2819 | seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n", | ||
2820 | readl(regs + S3C_GINTMSK), | ||
2821 | readl(regs + S3C_GINTSTS)); | ||
2822 | |||
2823 | seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n", | ||
2824 | readl(regs + S3C_DAINTMSK), | ||
2825 | readl(regs + S3C_DAINT)); | ||
2826 | |||
2827 | seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n", | ||
2828 | readl(regs + S3C_GNPTXSTS), | ||
2829 | readl(regs + S3C_GRXSTSR)); | ||
2830 | |||
2831 | seq_printf(seq, "\nEndpoint status:\n"); | ||
2832 | |||
2833 | for (idx = 0; idx < 15; idx++) { | ||
2834 | u32 in, out; | ||
2835 | |||
2836 | in = readl(regs + S3C_DIEPCTL(idx)); | ||
2837 | out = readl(regs + S3C_DOEPCTL(idx)); | ||
2838 | |||
2839 | seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x", | ||
2840 | idx, in, out); | ||
2841 | |||
2842 | in = readl(regs + S3C_DIEPTSIZ(idx)); | ||
2843 | out = readl(regs + S3C_DOEPTSIZ(idx)); | ||
2844 | |||
2845 | seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x", | ||
2846 | in, out); | ||
2847 | |||
2848 | seq_printf(seq, "\n"); | ||
2849 | } | ||
2850 | |||
2851 | return 0; | ||
2852 | } | ||
2853 | |||
2854 | static int state_open(struct inode *inode, struct file *file) | ||
2855 | { | ||
2856 | return single_open(file, state_show, inode->i_private); | ||
2857 | } | ||
2858 | |||
2859 | static const struct file_operations state_fops = { | ||
2860 | .owner = THIS_MODULE, | ||
2861 | .open = state_open, | ||
2862 | .read = seq_read, | ||
2863 | .llseek = seq_lseek, | ||
2864 | .release = single_release, | ||
2865 | }; | ||
2866 | |||
2867 | /** | ||
2868 | * fifo_show - debugfs: show the fifo information | ||
2869 | * @seq: The seq_file to write data to. | ||
2870 | * @v: Unused parameter. | ||
2871 | * | ||
2872 | * Show the FIFO information for the overall fifo and all the | ||
2873 | * periodic transmission FIFOs. | ||
2874 | */ | ||
2875 | static int fifo_show(struct seq_file *seq, void *v) | ||
2876 | { | ||
2877 | struct s3c_hsotg *hsotg = seq->private; | ||
2878 | void __iomem *regs = hsotg->regs; | ||
2879 | u32 val; | ||
2880 | int idx; | ||
2881 | |||
2882 | seq_printf(seq, "Non-periodic FIFOs:\n"); | ||
2883 | seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + S3C_GRXFSIZ)); | ||
2884 | |||
2885 | val = readl(regs + S3C_GNPTXFSIZ); | ||
2886 | seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n", | ||
2887 | val >> S3C_GNPTXFSIZ_NPTxFDep_SHIFT, | ||
2888 | val & S3C_GNPTXFSIZ_NPTxFStAddr_MASK); | ||
2889 | |||
2890 | seq_printf(seq, "\nPeriodic TXFIFOs:\n"); | ||
2891 | |||
2892 | for (idx = 1; idx <= 15; idx++) { | ||
2893 | val = readl(regs + S3C_DPTXFSIZn(idx)); | ||
2894 | |||
2895 | seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx, | ||
2896 | val >> S3C_DPTXFSIZn_DPTxFSize_SHIFT, | ||
2897 | val & S3C_DPTXFSIZn_DPTxFStAddr_MASK); | ||
2898 | } | ||
2899 | |||
2900 | return 0; | ||
2901 | } | ||
2902 | |||
2903 | static int fifo_open(struct inode *inode, struct file *file) | ||
2904 | { | ||
2905 | return single_open(file, fifo_show, inode->i_private); | ||
2906 | } | ||
2907 | |||
2908 | static const struct file_operations fifo_fops = { | ||
2909 | .owner = THIS_MODULE, | ||
2910 | .open = fifo_open, | ||
2911 | .read = seq_read, | ||
2912 | .llseek = seq_lseek, | ||
2913 | .release = single_release, | ||
2914 | }; | ||
2915 | |||
2916 | |||
2917 | static const char *decode_direction(int is_in) | ||
2918 | { | ||
2919 | return is_in ? "in" : "out"; | ||
2920 | } | ||
2921 | |||
2922 | /** | ||
2923 | * ep_show - debugfs: show the state of an endpoint. | ||
2924 | * @seq: The seq_file to write data to. | ||
2925 | * @v: Unused parameter. | ||
2926 | * | ||
2927 | * This debugfs entry shows the state of the given endpoint (one is | ||
2928 | * registered for each available). | ||
2929 | */ | ||
2930 | static int ep_show(struct seq_file *seq, void *v) | ||
2931 | { | ||
2932 | struct s3c_hsotg_ep *ep = seq->private; | ||
2933 | struct s3c_hsotg *hsotg = ep->parent; | ||
2934 | struct s3c_hsotg_req *req; | ||
2935 | void __iomem *regs = hsotg->regs; | ||
2936 | int index = ep->index; | ||
2937 | int show_limit = 15; | ||
2938 | unsigned long flags; | ||
2939 | |||
2940 | seq_printf(seq, "Endpoint index %d, named %s, dir %s:\n", | ||
2941 | ep->index, ep->ep.name, decode_direction(ep->dir_in)); | ||
2942 | |||
2943 | /* first show the register state */ | ||
2944 | |||
2945 | seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n", | ||
2946 | readl(regs + S3C_DIEPCTL(index)), | ||
2947 | readl(regs + S3C_DOEPCTL(index))); | ||
2948 | |||
2949 | seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n", | ||
2950 | readl(regs + S3C_DIEPDMA(index)), | ||
2951 | readl(regs + S3C_DOEPDMA(index))); | ||
2952 | |||
2953 | seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n", | ||
2954 | readl(regs + S3C_DIEPINT(index)), | ||
2955 | readl(regs + S3C_DOEPINT(index))); | ||
2956 | |||
2957 | seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n", | ||
2958 | readl(regs + S3C_DIEPTSIZ(index)), | ||
2959 | readl(regs + S3C_DOEPTSIZ(index))); | ||
2960 | |||
2961 | seq_printf(seq, "\n"); | ||
2962 | seq_printf(seq, "mps %d\n", ep->ep.maxpacket); | ||
2963 | seq_printf(seq, "total_data=%ld\n", ep->total_data); | ||
2964 | |||
2965 | seq_printf(seq, "request list (%p,%p):\n", | ||
2966 | ep->queue.next, ep->queue.prev); | ||
2967 | |||
2968 | spin_lock_irqsave(&ep->lock, flags); | ||
2969 | |||
2970 | list_for_each_entry(req, &ep->queue, queue) { | ||
2971 | if (--show_limit < 0) { | ||
2972 | seq_printf(seq, "not showing more requests...\n"); | ||
2973 | break; | ||
2974 | } | ||
2975 | |||
2976 | seq_printf(seq, "%c req %p: %d bytes @%p, ", | ||
2977 | req == ep->req ? '*' : ' ', | ||
2978 | req, req->req.length, req->req.buf); | ||
2979 | seq_printf(seq, "%d done, res %d\n", | ||
2980 | req->req.actual, req->req.status); | ||
2981 | } | ||
2982 | |||
2983 | spin_unlock_irqrestore(&ep->lock, flags); | ||
2984 | |||
2985 | return 0; | ||
2986 | } | ||
2987 | |||
2988 | static int ep_open(struct inode *inode, struct file *file) | ||
2989 | { | ||
2990 | return single_open(file, ep_show, inode->i_private); | ||
2991 | } | ||
2992 | |||
2993 | static const struct file_operations ep_fops = { | ||
2994 | .owner = THIS_MODULE, | ||
2995 | .open = ep_open, | ||
2996 | .read = seq_read, | ||
2997 | .llseek = seq_lseek, | ||
2998 | .release = single_release, | ||
2999 | }; | ||
3000 | |||
3001 | /** | ||
3002 | * s3c_hsotg_create_debug - create debugfs directory and files | ||
3003 | * @hsotg: The driver state | ||
3004 | * | ||
3005 | * Create the debugfs files to allow the user to get information | ||
3006 | * about the state of the system. The directory name is created | ||
3007 | * with the same name as the device itself, in case we end up | ||
3008 | * with multiple blocks in future systems. | ||
3009 | */ | ||
3010 | static void __devinit s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) | ||
3011 | { | ||
3012 | struct dentry *root; | ||
3013 | unsigned epidx; | ||
3014 | |||
3015 | root = debugfs_create_dir(dev_name(hsotg->dev), NULL); | ||
3016 | hsotg->debug_root = root; | ||
3017 | if (IS_ERR(root)) { | ||
3018 | dev_err(hsotg->dev, "cannot create debug root\n"); | ||
3019 | return; | ||
3020 | } | ||
3021 | |||
3022 | /* create general state file */ | ||
3023 | |||
3024 | hsotg->debug_file = debugfs_create_file("state", 0444, root, | ||
3025 | hsotg, &state_fops); | ||
3026 | |||
3027 | if (IS_ERR(hsotg->debug_file)) | ||
3028 | dev_err(hsotg->dev, "%s: failed to create state\n", __func__); | ||
3029 | |||
3030 | hsotg->debug_fifo = debugfs_create_file("fifo", 0444, root, | ||
3031 | hsotg, &fifo_fops); | ||
3032 | |||
3033 | if (IS_ERR(hsotg->debug_fifo)) | ||
3034 | dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__); | ||
3035 | |||
3036 | /* create one file for each endpoint */ | ||
3037 | |||
3038 | for (epidx = 0; epidx < S3C_HSOTG_EPS; epidx++) { | ||
3039 | struct s3c_hsotg_ep *ep = &hsotg->eps[epidx]; | ||
3040 | |||
3041 | ep->debugfs = debugfs_create_file(ep->name, 0444, | ||
3042 | root, ep, &ep_fops); | ||
3043 | |||
3044 | if (IS_ERR(ep->debugfs)) | ||
3045 | dev_err(hsotg->dev, "failed to create %s debug file\n", | ||
3046 | ep->name); | ||
3047 | } | ||
3048 | } | ||
3049 | |||
3050 | /** | ||
3051 | * s3c_hsotg_delete_debug - cleanup debugfs entries | ||
3052 | * @hsotg: The driver state | ||
3053 | * | ||
3054 | * Cleanup (remove) the debugfs files for use on module exit. | ||
3055 | */ | ||
3056 | static void __devexit s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) | ||
3057 | { | ||
3058 | unsigned epidx; | ||
3059 | |||
3060 | for (epidx = 0; epidx < S3C_HSOTG_EPS; epidx++) { | ||
3061 | struct s3c_hsotg_ep *ep = &hsotg->eps[epidx]; | ||
3062 | debugfs_remove(ep->debugfs); | ||
3063 | } | ||
3064 | |||
3065 | debugfs_remove(hsotg->debug_file); | ||
3066 | debugfs_remove(hsotg->debug_fifo); | ||
3067 | debugfs_remove(hsotg->debug_root); | ||
3068 | } | ||
3069 | |||
3070 | /** | ||
3071 | * s3c_hsotg_gate - set the hardware gate for the block | ||
3072 | * @pdev: The device we bound to | ||
3073 | * @on: On or off. | ||
3074 | * | ||
3075 | * Set the hardware gate setting into the block. If we end up on | ||
3076 | * something other than an S3C64XX, then we might need to change this | ||
3077 | * to using a platform data callback, or some other mechanism. | ||
3078 | */ | ||
3079 | static void s3c_hsotg_gate(struct platform_device *pdev, bool on) | ||
3080 | { | ||
3081 | unsigned long flags; | ||
3082 | u32 others; | ||
3083 | |||
3084 | local_irq_save(flags); | ||
3085 | |||
3086 | others = __raw_readl(S3C64XX_OTHERS); | ||
3087 | if (on) | ||
3088 | others |= S3C64XX_OTHERS_USBMASK; | ||
3089 | else | ||
3090 | others &= ~S3C64XX_OTHERS_USBMASK; | ||
3091 | __raw_writel(others, S3C64XX_OTHERS); | ||
3092 | |||
3093 | local_irq_restore(flags); | ||
3094 | } | ||
3095 | |||
3096 | struct s3c_hsotg_plat s3c_hsotg_default_pdata; | ||
3097 | |||
3098 | static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | ||
3099 | { | ||
3100 | struct s3c_hsotg_plat *plat = pdev->dev.platform_data; | ||
3101 | struct device *dev = &pdev->dev; | ||
3102 | struct s3c_hsotg *hsotg; | ||
3103 | struct resource *res; | ||
3104 | int epnum; | ||
3105 | int ret; | ||
3106 | |||
3107 | if (!plat) | ||
3108 | plat = &s3c_hsotg_default_pdata; | ||
3109 | |||
3110 | hsotg = kzalloc(sizeof(struct s3c_hsotg) + | ||
3111 | sizeof(struct s3c_hsotg_ep) * S3C_HSOTG_EPS, | ||
3112 | GFP_KERNEL); | ||
3113 | if (!hsotg) { | ||
3114 | dev_err(dev, "cannot get memory\n"); | ||
3115 | return -ENOMEM; | ||
3116 | } | ||
3117 | |||
3118 | hsotg->dev = dev; | ||
3119 | hsotg->plat = plat; | ||
3120 | |||
3121 | platform_set_drvdata(pdev, hsotg); | ||
3122 | |||
3123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
3124 | if (!res) { | ||
3125 | dev_err(dev, "cannot find register resource 0\n"); | ||
3126 | ret = -EINVAL; | ||
3127 | goto err_mem; | ||
3128 | } | ||
3129 | |||
3130 | hsotg->regs_res = request_mem_region(res->start, resource_size(res), | ||
3131 | dev_name(dev)); | ||
3132 | if (!hsotg->regs_res) { | ||
3133 | dev_err(dev, "cannot reserve registers\n"); | ||
3134 | ret = -ENOENT; | ||
3135 | goto err_mem; | ||
3136 | } | ||
3137 | |||
3138 | hsotg->regs = ioremap(res->start, resource_size(res)); | ||
3139 | if (!hsotg->regs) { | ||
3140 | dev_err(dev, "cannot map registers\n"); | ||
3141 | ret = -ENXIO; | ||
3142 | goto err_regs_res; | ||
3143 | } | ||
3144 | |||
3145 | ret = platform_get_irq(pdev, 0); | ||
3146 | if (ret < 0) { | ||
3147 | dev_err(dev, "cannot find IRQ\n"); | ||
3148 | goto err_regs; | ||
3149 | } | ||
3150 | |||
3151 | hsotg->irq = ret; | ||
3152 | |||
3153 | ret = request_irq(ret, s3c_hsotg_irq, 0, dev_name(dev), hsotg); | ||
3154 | if (ret < 0) { | ||
3155 | dev_err(dev, "cannot claim IRQ\n"); | ||
3156 | goto err_regs; | ||
3157 | } | ||
3158 | |||
3159 | dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); | ||
3160 | |||
3161 | device_initialize(&hsotg->gadget.dev); | ||
3162 | |||
3163 | dev_set_name(&hsotg->gadget.dev, "gadget"); | ||
3164 | |||
3165 | hsotg->gadget.is_dualspeed = 1; | ||
3166 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; | ||
3167 | hsotg->gadget.name = dev_name(dev); | ||
3168 | |||
3169 | hsotg->gadget.dev.parent = dev; | ||
3170 | hsotg->gadget.dev.dma_mask = dev->dma_mask; | ||
3171 | |||
3172 | /* setup endpoint information */ | ||
3173 | |||
3174 | INIT_LIST_HEAD(&hsotg->gadget.ep_list); | ||
3175 | hsotg->gadget.ep0 = &hsotg->eps[0].ep; | ||
3176 | |||
3177 | /* allocate EP0 request */ | ||
3178 | |||
3179 | hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps[0].ep, | ||
3180 | GFP_KERNEL); | ||
3181 | if (!hsotg->ctrl_req) { | ||
3182 | dev_err(dev, "failed to allocate ctrl req\n"); | ||
3183 | goto err_regs; | ||
3184 | } | ||
3185 | |||
3186 | /* reset the system */ | ||
3187 | |||
3188 | s3c_hsotg_gate(pdev, true); | ||
3189 | |||
3190 | s3c_hsotg_otgreset(hsotg); | ||
3191 | s3c_hsotg_corereset(hsotg); | ||
3192 | s3c_hsotg_init(hsotg); | ||
3193 | |||
3194 | /* initialise the endpoints now the core has been initialised */ | ||
3195 | for (epnum = 0; epnum < S3C_HSOTG_EPS; epnum++) | ||
3196 | s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum); | ||
3197 | |||
3198 | s3c_hsotg_create_debug(hsotg); | ||
3199 | |||
3200 | s3c_hsotg_dump(hsotg); | ||
3201 | |||
3202 | our_hsotg = hsotg; | ||
3203 | return 0; | ||
3204 | |||
3205 | err_regs: | ||
3206 | iounmap(hsotg->regs); | ||
3207 | |||
3208 | err_regs_res: | ||
3209 | release_resource(hsotg->regs_res); | ||
3210 | kfree(hsotg->regs_res); | ||
3211 | |||
3212 | err_mem: | ||
3213 | kfree(hsotg); | ||
3214 | return ret; | ||
3215 | } | ||
3216 | |||
3217 | static int __devexit s3c_hsotg_remove(struct platform_device *pdev) | ||
3218 | { | ||
3219 | struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); | ||
3220 | |||
3221 | s3c_hsotg_delete_debug(hsotg); | ||
3222 | |||
3223 | usb_gadget_unregister_driver(hsotg->driver); | ||
3224 | |||
3225 | free_irq(hsotg->irq, hsotg); | ||
3226 | iounmap(hsotg->regs); | ||
3227 | |||
3228 | release_resource(hsotg->regs_res); | ||
3229 | kfree(hsotg->regs_res); | ||
3230 | |||
3231 | s3c_hsotg_gate(pdev, false); | ||
3232 | |||
3233 | kfree(hsotg); | ||
3234 | return 0; | ||
3235 | } | ||
3236 | |||
3237 | #if 1 | ||
3238 | #define s3c_hsotg_suspend NULL | ||
3239 | #define s3c_hsotg_resume NULL | ||
3240 | #endif | ||
3241 | |||
3242 | static struct platform_driver s3c_hsotg_driver = { | ||
3243 | .driver = { | ||
3244 | .name = "s3c-hsotg", | ||
3245 | .owner = THIS_MODULE, | ||
3246 | }, | ||
3247 | .probe = s3c_hsotg_probe, | ||
3248 | .remove = __devexit_p(s3c_hsotg_remove), | ||
3249 | .suspend = s3c_hsotg_suspend, | ||
3250 | .resume = s3c_hsotg_resume, | ||
3251 | }; | ||
3252 | |||
3253 | static int __init s3c_hsotg_modinit(void) | ||
3254 | { | ||
3255 | return platform_driver_register(&s3c_hsotg_driver); | ||
3256 | } | ||
3257 | |||
3258 | static void __exit s3c_hsotg_modexit(void) | ||
3259 | { | ||
3260 | platform_driver_unregister(&s3c_hsotg_driver); | ||
3261 | } | ||
3262 | |||
3263 | module_init(s3c_hsotg_modinit); | ||
3264 | module_exit(s3c_hsotg_modexit); | ||
3265 | |||
3266 | MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device"); | ||
3267 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
3268 | MODULE_LICENSE("GPL"); | ||
3269 | MODULE_ALIAS("platform:s3c-hsotg"); | ||