diff options
Diffstat (limited to 'drivers/usb/gadget/s3c-hsotg.c')
-rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 930c490dd83b..99c8e3ca6a3c 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -1186,6 +1186,41 @@ static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg); | |||
1186 | static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); | 1186 | static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); |
1187 | 1187 | ||
1188 | /** | 1188 | /** |
1189 | * s3c_hsotg_stall_ep0 - stall ep0 | ||
1190 | * @hsotg: The device state | ||
1191 | * | ||
1192 | * Set stall for ep0 as response for setup request. | ||
1193 | */ | ||
1194 | static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg) { | ||
1195 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | ||
1196 | u32 reg; | ||
1197 | u32 ctrl; | ||
1198 | |||
1199 | dev_dbg(hsotg->dev, "ep0 stall (dir=%d)\n", ep0->dir_in); | ||
1200 | reg = (ep0->dir_in) ? DIEPCTL0 : DOEPCTL0; | ||
1201 | |||
1202 | /* | ||
1203 | * DxEPCTL_Stall will be cleared by EP once it has | ||
1204 | * taken effect, so no need to clear later. | ||
1205 | */ | ||
1206 | |||
1207 | ctrl = readl(hsotg->regs + reg); | ||
1208 | ctrl |= DxEPCTL_Stall; | ||
1209 | ctrl |= DxEPCTL_CNAK; | ||
1210 | writel(ctrl, hsotg->regs + reg); | ||
1211 | |||
1212 | dev_dbg(hsotg->dev, | ||
1213 | "written DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n", | ||
1214 | ctrl, reg, readl(hsotg->regs + reg)); | ||
1215 | |||
1216 | /* | ||
1217 | * complete won't be called, so we enqueue | ||
1218 | * setup request here | ||
1219 | */ | ||
1220 | s3c_hsotg_enqueue_setup(hsotg); | ||
1221 | } | ||
1222 | |||
1223 | /** | ||
1189 | * s3c_hsotg_process_control - process a control request | 1224 | * s3c_hsotg_process_control - process a control request |
1190 | * @hsotg: The device state | 1225 | * @hsotg: The device state |
1191 | * @ctrl: The control request received | 1226 | * @ctrl: The control request received |
@@ -1262,38 +1297,8 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg, | |||
1262 | * so respond with a STALL for the status stage to indicate failure. | 1297 | * so respond with a STALL for the status stage to indicate failure. |
1263 | */ | 1298 | */ |
1264 | 1299 | ||
1265 | if (ret < 0) { | 1300 | if (ret < 0) |
1266 | u32 reg; | 1301 | s3c_hsotg_stall_ep0(hsotg); |
1267 | u32 ctrl; | ||
1268 | |||
1269 | dev_dbg(hsotg->dev, "ep0 stall (dir=%d)\n", ep0->dir_in); | ||
1270 | reg = (ep0->dir_in) ? DIEPCTL0 : DOEPCTL0; | ||
1271 | |||
1272 | /* | ||
1273 | * DxEPCTL_Stall will be cleared by EP once it has | ||
1274 | * taken effect, so no need to clear later. | ||
1275 | */ | ||
1276 | |||
1277 | ctrl = readl(hsotg->regs + reg); | ||
1278 | ctrl |= DxEPCTL_Stall; | ||
1279 | ctrl |= DxEPCTL_CNAK; | ||
1280 | writel(ctrl, hsotg->regs + reg); | ||
1281 | |||
1282 | dev_dbg(hsotg->dev, | ||
1283 | "written DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n", | ||
1284 | ctrl, reg, readl(hsotg->regs + reg)); | ||
1285 | |||
1286 | /* | ||
1287 | * don't believe we need to anything more to get the EP | ||
1288 | * to reply with a STALL packet | ||
1289 | */ | ||
1290 | |||
1291 | /* | ||
1292 | * complete won't be called, so we enqueue | ||
1293 | * setup request here | ||
1294 | */ | ||
1295 | s3c_hsotg_enqueue_setup(hsotg); | ||
1296 | } | ||
1297 | } | 1302 | } |
1298 | 1303 | ||
1299 | /** | 1304 | /** |
@@ -2832,6 +2837,15 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2832 | 2837 | ||
2833 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); | 2838 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); |
2834 | 2839 | ||
2840 | if (index == 0) { | ||
2841 | if (value) | ||
2842 | s3c_hsotg_stall_ep0(hs); | ||
2843 | else | ||
2844 | dev_warn(hs->dev, | ||
2845 | "%s: can't clear halt on ep0\n", __func__); | ||
2846 | return 0; | ||
2847 | } | ||
2848 | |||
2835 | /* write both IN and OUT control registers */ | 2849 | /* write both IN and OUT control registers */ |
2836 | 2850 | ||
2837 | epreg = DIEPCTL(index); | 2851 | epreg = DIEPCTL(index); |