aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/s3c-hsotg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/s3c-hsotg.c')
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c78
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);
1186static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); 1186static 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 */
1194static 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);