12f98382dSKuninori Morimoto /* 22f98382dSKuninori Morimoto * Renesas USB driver 32f98382dSKuninori Morimoto * 42f98382dSKuninori Morimoto * Copyright (C) 2011 Renesas Solutions Corp. 52f98382dSKuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 62f98382dSKuninori Morimoto * 72f98382dSKuninori Morimoto * This program is distributed in the hope that it will be useful, 82f98382dSKuninori Morimoto * but WITHOUT ANY WARRANTY; without even the implied warranty of 92f98382dSKuninori Morimoto * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 102f98382dSKuninori Morimoto * GNU General Public License for more details. 112f98382dSKuninori Morimoto * 122f98382dSKuninori Morimoto * You should have received a copy of the GNU General Public License 132f98382dSKuninori Morimoto * along with this program; if not, write to the Free Software 142f98382dSKuninori Morimoto * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 152f98382dSKuninori Morimoto * 162f98382dSKuninori Morimoto */ 17d128a259SKuninori Morimoto #include <linux/dma-mapping.h> 182f98382dSKuninori Morimoto #include <linux/io.h> 192f98382dSKuninori Morimoto #include <linux/module.h> 202f98382dSKuninori Morimoto #include <linux/platform_device.h> 212f98382dSKuninori Morimoto #include <linux/usb/ch9.h> 222f98382dSKuninori Morimoto #include <linux/usb/gadget.h> 232f98382dSKuninori Morimoto #include "common.h" 242f98382dSKuninori Morimoto 252f98382dSKuninori Morimoto /* 262f98382dSKuninori Morimoto * struct 272f98382dSKuninori Morimoto */ 282f98382dSKuninori Morimoto struct usbhsg_request { 292f98382dSKuninori Morimoto struct usb_request req; 304bd04811SKuninori Morimoto struct usbhs_pkt pkt; 312f98382dSKuninori Morimoto }; 322f98382dSKuninori Morimoto 332f98382dSKuninori Morimoto #define EP_NAME_SIZE 8 342f98382dSKuninori Morimoto struct usbhsg_gpriv; 352f98382dSKuninori Morimoto struct usbhsg_uep { 362f98382dSKuninori Morimoto struct usb_ep ep; 372f98382dSKuninori Morimoto struct usbhs_pipe *pipe; 382f98382dSKuninori Morimoto 392f98382dSKuninori Morimoto char ep_name[EP_NAME_SIZE]; 402f98382dSKuninori Morimoto 412f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv; 42dad67397SKuninori Morimoto struct usbhs_pkt_handle *handler; 432f98382dSKuninori Morimoto }; 442f98382dSKuninori Morimoto 452f98382dSKuninori Morimoto struct usbhsg_gpriv { 462f98382dSKuninori Morimoto struct usb_gadget gadget; 472f98382dSKuninori Morimoto struct usbhs_mod mod; 483b872188SKuninori Morimoto struct list_head link; 492f98382dSKuninori Morimoto 502f98382dSKuninori Morimoto struct usbhsg_uep *uep; 512f98382dSKuninori Morimoto int uep_size; 522f98382dSKuninori Morimoto 532f98382dSKuninori Morimoto struct usb_gadget_driver *driver; 542f98382dSKuninori Morimoto 552f98382dSKuninori Morimoto u32 status; 562f98382dSKuninori Morimoto #define USBHSG_STATUS_STARTED (1 << 0) 572f98382dSKuninori Morimoto #define USBHSG_STATUS_REGISTERD (1 << 1) 582f98382dSKuninori Morimoto #define USBHSG_STATUS_WEDGE (1 << 2) 592f98382dSKuninori Morimoto }; 602f98382dSKuninori Morimoto 612f98382dSKuninori Morimoto struct usbhsg_recip_handle { 622f98382dSKuninori Morimoto char *name; 632f98382dSKuninori Morimoto int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 642f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 652f98382dSKuninori Morimoto int (*interface)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 662f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 672f98382dSKuninori Morimoto int (*endpoint)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 682f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 692f98382dSKuninori Morimoto }; 702f98382dSKuninori Morimoto 712f98382dSKuninori Morimoto /* 722f98382dSKuninori Morimoto * macro 732f98382dSKuninori Morimoto */ 742f98382dSKuninori Morimoto #define usbhsg_priv_to_gpriv(priv) \ 752f98382dSKuninori Morimoto container_of( \ 762f98382dSKuninori Morimoto usbhs_mod_get(priv, USBHS_GADGET), \ 772f98382dSKuninori Morimoto struct usbhsg_gpriv, mod) 782f98382dSKuninori Morimoto 792f98382dSKuninori Morimoto #define __usbhsg_for_each_uep(start, pos, g, i) \ 80e94c587eSKuninori Morimoto for (i = start, pos = (g)->uep + i; \ 812f98382dSKuninori Morimoto i < (g)->uep_size; \ 822f98382dSKuninori Morimoto i++, pos = (g)->uep + i) 832f98382dSKuninori Morimoto 842f98382dSKuninori Morimoto #define usbhsg_for_each_uep(pos, gpriv, i) \ 852f98382dSKuninori Morimoto __usbhsg_for_each_uep(1, pos, gpriv, i) 862f98382dSKuninori Morimoto 872f98382dSKuninori Morimoto #define usbhsg_for_each_uep_with_dcp(pos, gpriv, i) \ 882f98382dSKuninori Morimoto __usbhsg_for_each_uep(0, pos, gpriv, i) 892f98382dSKuninori Morimoto 902f98382dSKuninori Morimoto #define usbhsg_gadget_to_gpriv(g)\ 912f98382dSKuninori Morimoto container_of(g, struct usbhsg_gpriv, gadget) 922f98382dSKuninori Morimoto 932f98382dSKuninori Morimoto #define usbhsg_req_to_ureq(r)\ 942f98382dSKuninori Morimoto container_of(r, struct usbhsg_request, req) 952f98382dSKuninori Morimoto 962f98382dSKuninori Morimoto #define usbhsg_ep_to_uep(e) container_of(e, struct usbhsg_uep, ep) 972f98382dSKuninori Morimoto #define usbhsg_gpriv_to_dev(gp) usbhs_priv_to_dev((gp)->mod.priv) 982f98382dSKuninori Morimoto #define usbhsg_gpriv_to_priv(gp) ((gp)->mod.priv) 992f98382dSKuninori Morimoto #define usbhsg_gpriv_to_dcp(gp) ((gp)->uep) 1002f98382dSKuninori Morimoto #define usbhsg_gpriv_to_nth_uep(gp, i) ((gp)->uep + i) 1012f98382dSKuninori Morimoto #define usbhsg_uep_to_gpriv(u) ((u)->gpriv) 1022f98382dSKuninori Morimoto #define usbhsg_uep_to_pipe(u) ((u)->pipe) 1032f98382dSKuninori Morimoto #define usbhsg_pipe_to_uep(p) ((p)->mod_private) 1042f98382dSKuninori Morimoto #define usbhsg_is_dcp(u) ((u) == usbhsg_gpriv_to_dcp((u)->gpriv)) 1052f98382dSKuninori Morimoto 1064bd04811SKuninori Morimoto #define usbhsg_ureq_to_pkt(u) (&(u)->pkt) 1074bd04811SKuninori Morimoto #define usbhsg_pkt_to_ureq(i) \ 1084bd04811SKuninori Morimoto container_of(i, struct usbhsg_request, pkt) 1094bd04811SKuninori Morimoto 1102f98382dSKuninori Morimoto #define usbhsg_is_not_connected(gp) ((gp)->gadget.speed == USB_SPEED_UNKNOWN) 1112f98382dSKuninori Morimoto 1122f98382dSKuninori Morimoto /* status */ 1132f98382dSKuninori Morimoto #define usbhsg_status_init(gp) do {(gp)->status = 0; } while (0) 1142f98382dSKuninori Morimoto #define usbhsg_status_set(gp, b) (gp->status |= b) 1152f98382dSKuninori Morimoto #define usbhsg_status_clr(gp, b) (gp->status &= ~b) 1162f98382dSKuninori Morimoto #define usbhsg_status_has(gp, b) (gp->status & b) 1172f98382dSKuninori Morimoto 1183b872188SKuninori Morimoto /* controller */ 1193b872188SKuninori Morimoto LIST_HEAD(the_controller_link); 1203b872188SKuninori Morimoto 1213b872188SKuninori Morimoto #define usbhsg_for_each_controller(gpriv)\ 1223b872188SKuninori Morimoto list_for_each_entry(gpriv, &the_controller_link, link) 1233b872188SKuninori Morimoto #define usbhsg_controller_register(gpriv)\ 1243b872188SKuninori Morimoto list_add_tail(&(gpriv)->link, &the_controller_link) 1253b872188SKuninori Morimoto #define usbhsg_controller_unregister(gpriv)\ 1263b872188SKuninori Morimoto list_del_init(&(gpriv)->link) 1273b872188SKuninori Morimoto 1282f98382dSKuninori Morimoto /* 129233f519dSKuninori Morimoto * queue push/pop 1302f98382dSKuninori Morimoto */ 1312f98382dSKuninori Morimoto static void usbhsg_queue_push(struct usbhsg_uep *uep, 1322f98382dSKuninori Morimoto struct usbhsg_request *ureq) 1332f98382dSKuninori Morimoto { 1342f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 1352f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 1362f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 1376acb95d4SKuninori Morimoto struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); 138659d4954SKuninori Morimoto struct usb_request *req = &ureq->req; 1392f98382dSKuninori Morimoto 140659d4954SKuninori Morimoto req->actual = 0; 141659d4954SKuninori Morimoto req->status = -EINPROGRESS; 1420432eed0SKuninori Morimoto usbhs_pkt_push(pipe, pkt, uep->handler, 1430432eed0SKuninori Morimoto req->buf, req->length, req->zero); 1442f98382dSKuninori Morimoto 1452f98382dSKuninori Morimoto dev_dbg(dev, "pipe %d : queue push (%d)\n", 1462f98382dSKuninori Morimoto usbhs_pipe_number(pipe), 147659d4954SKuninori Morimoto req->length); 1482f98382dSKuninori Morimoto } 1492f98382dSKuninori Morimoto 1502f98382dSKuninori Morimoto static void usbhsg_queue_pop(struct usbhsg_uep *uep, 1512f98382dSKuninori Morimoto struct usbhsg_request *ureq, 1522f98382dSKuninori Morimoto int status) 1532f98382dSKuninori Morimoto { 1542f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 1552f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 1562f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 1572f98382dSKuninori Morimoto 1582f98382dSKuninori Morimoto dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); 1592f98382dSKuninori Morimoto 1602f98382dSKuninori Morimoto ureq->req.status = status; 1612f98382dSKuninori Morimoto ureq->req.complete(&uep->ep, &ureq->req); 1622f98382dSKuninori Morimoto } 1632f98382dSKuninori Morimoto 164dad67397SKuninori Morimoto static void usbhsg_queue_done(struct usbhs_pkt *pkt) 1652f98382dSKuninori Morimoto { 1664bd04811SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 1674bd04811SKuninori Morimoto struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); 1684bd04811SKuninori Morimoto struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); 1694bd04811SKuninori Morimoto 170659d4954SKuninori Morimoto ureq->req.actual = pkt->actual; 1712f98382dSKuninori Morimoto 1722f98382dSKuninori Morimoto usbhsg_queue_pop(uep, ureq, 0); 1732f98382dSKuninori Morimoto } 1744bd04811SKuninori Morimoto 175233f519dSKuninori Morimoto /* 176233f519dSKuninori Morimoto * dma map/unmap 177233f519dSKuninori Morimoto */ 178e73a9891SKuninori Morimoto static int usbhsg_dma_map(struct device *dev, 179e73a9891SKuninori Morimoto struct usbhs_pkt *pkt, 180e73a9891SKuninori Morimoto enum dma_data_direction dir) 181e73a9891SKuninori Morimoto { 182e73a9891SKuninori Morimoto struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); 183e73a9891SKuninori Morimoto struct usb_request *req = &ureq->req; 184e73a9891SKuninori Morimoto 185e73a9891SKuninori Morimoto if (pkt->dma != DMA_ADDR_INVALID) { 186e73a9891SKuninori Morimoto dev_err(dev, "dma is already mapped\n"); 187e73a9891SKuninori Morimoto return -EIO; 188e73a9891SKuninori Morimoto } 189e73a9891SKuninori Morimoto 190e73a9891SKuninori Morimoto if (req->dma == DMA_ADDR_INVALID) { 191e73a9891SKuninori Morimoto pkt->dma = dma_map_single(dev, pkt->buf, pkt->length, dir); 192e73a9891SKuninori Morimoto } else { 193e73a9891SKuninori Morimoto dma_sync_single_for_device(dev, req->dma, req->length, dir); 194e73a9891SKuninori Morimoto pkt->dma = req->dma; 195e73a9891SKuninori Morimoto } 196e73a9891SKuninori Morimoto 197e73a9891SKuninori Morimoto if (dma_mapping_error(dev, pkt->dma)) { 198e73a9891SKuninori Morimoto dev_err(dev, "dma mapping error %x\n", pkt->dma); 199e73a9891SKuninori Morimoto return -EIO; 200e73a9891SKuninori Morimoto } 201e73a9891SKuninori Morimoto 202e73a9891SKuninori Morimoto return 0; 203e73a9891SKuninori Morimoto } 204e73a9891SKuninori Morimoto 205e73a9891SKuninori Morimoto static int usbhsg_dma_unmap(struct device *dev, 206e73a9891SKuninori Morimoto struct usbhs_pkt *pkt, 207e73a9891SKuninori Morimoto enum dma_data_direction dir) 208e73a9891SKuninori Morimoto { 209e73a9891SKuninori Morimoto struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); 210e73a9891SKuninori Morimoto struct usb_request *req = &ureq->req; 211e73a9891SKuninori Morimoto 212e73a9891SKuninori Morimoto if (pkt->dma == DMA_ADDR_INVALID) { 213e73a9891SKuninori Morimoto dev_err(dev, "dma is not mapped\n"); 214e73a9891SKuninori Morimoto return -EIO; 215e73a9891SKuninori Morimoto } 216e73a9891SKuninori Morimoto 217e73a9891SKuninori Morimoto if (req->dma == DMA_ADDR_INVALID) 218e73a9891SKuninori Morimoto dma_unmap_single(dev, pkt->dma, pkt->length, dir); 219e73a9891SKuninori Morimoto else 220e73a9891SKuninori Morimoto dma_sync_single_for_cpu(dev, req->dma, req->length, dir); 221e73a9891SKuninori Morimoto 222e73a9891SKuninori Morimoto pkt->dma = DMA_ADDR_INVALID; 223e73a9891SKuninori Morimoto 224e73a9891SKuninori Morimoto return 0; 225e73a9891SKuninori Morimoto } 226e73a9891SKuninori Morimoto 227e73a9891SKuninori Morimoto static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map) 228e73a9891SKuninori Morimoto { 229e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 230e73a9891SKuninori Morimoto struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); 231e73a9891SKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 232e73a9891SKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 233e73a9891SKuninori Morimoto enum dma_data_direction dir; 234e73a9891SKuninori Morimoto 235e73a9891SKuninori Morimoto dir = usbhs_pipe_is_dir_in(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 236e73a9891SKuninori Morimoto 237e73a9891SKuninori Morimoto if (map) 238e73a9891SKuninori Morimoto return usbhsg_dma_map(dev, pkt, dir); 239e73a9891SKuninori Morimoto else 240e73a9891SKuninori Morimoto return usbhsg_dma_unmap(dev, pkt, dir); 241e73a9891SKuninori Morimoto } 242e73a9891SKuninori Morimoto 2432f98382dSKuninori Morimoto /* 2442f98382dSKuninori Morimoto * USB_TYPE_STANDARD / clear feature functions 2452f98382dSKuninori Morimoto */ 2462f98382dSKuninori Morimoto static int usbhsg_recip_handler_std_control_done(struct usbhs_priv *priv, 2472f98382dSKuninori Morimoto struct usbhsg_uep *uep, 2482f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 2492f98382dSKuninori Morimoto { 2502f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 2512f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 2522f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); 2532f98382dSKuninori Morimoto 2542f98382dSKuninori Morimoto usbhs_dcp_control_transfer_done(pipe); 2552f98382dSKuninori Morimoto 2562f98382dSKuninori Morimoto return 0; 2572f98382dSKuninori Morimoto } 2582f98382dSKuninori Morimoto 2592f98382dSKuninori Morimoto static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, 2602f98382dSKuninori Morimoto struct usbhsg_uep *uep, 2612f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 2622f98382dSKuninori Morimoto { 2632f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 2642f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 2652f98382dSKuninori Morimoto 2662f98382dSKuninori Morimoto if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { 267e8d548d5SKuninori Morimoto usbhs_pipe_disable(pipe); 2682f98382dSKuninori Morimoto usbhs_pipe_clear_sequence(pipe); 269e8d548d5SKuninori Morimoto usbhs_pipe_enable(pipe); 2702f98382dSKuninori Morimoto } 2712f98382dSKuninori Morimoto 2722f98382dSKuninori Morimoto usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 2732f98382dSKuninori Morimoto 2742f98382dSKuninori Morimoto return 0; 2752f98382dSKuninori Morimoto } 2762f98382dSKuninori Morimoto 2772f98382dSKuninori Morimoto struct usbhsg_recip_handle req_clear_feature = { 2782f98382dSKuninori Morimoto .name = "clear feature", 2792f98382dSKuninori Morimoto .device = usbhsg_recip_handler_std_control_done, 2802f98382dSKuninori Morimoto .interface = usbhsg_recip_handler_std_control_done, 2812f98382dSKuninori Morimoto .endpoint = usbhsg_recip_handler_std_clear_endpoint, 2822f98382dSKuninori Morimoto }; 2832f98382dSKuninori Morimoto 2842f98382dSKuninori Morimoto /* 2852f98382dSKuninori Morimoto * USB_TYPE handler 2862f98382dSKuninori Morimoto */ 2872f98382dSKuninori Morimoto static int usbhsg_recip_run_handle(struct usbhs_priv *priv, 2882f98382dSKuninori Morimoto struct usbhsg_recip_handle *handler, 2892f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 2902f98382dSKuninori Morimoto { 2912f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 2922f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 2932f98382dSKuninori Morimoto struct usbhsg_uep *uep; 2940432eed0SKuninori Morimoto struct usbhs_pipe *pipe; 2952f98382dSKuninori Morimoto int recip = ctrl->bRequestType & USB_RECIP_MASK; 2962f98382dSKuninori Morimoto int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; 2972f98382dSKuninori Morimoto int ret; 2982f98382dSKuninori Morimoto int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 2992f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 3002f98382dSKuninori Morimoto char *msg; 3012f98382dSKuninori Morimoto 3022f98382dSKuninori Morimoto uep = usbhsg_gpriv_to_nth_uep(gpriv, nth); 3030432eed0SKuninori Morimoto pipe = usbhsg_uep_to_pipe(uep); 3040432eed0SKuninori Morimoto if (!pipe) { 3059a28b7bdSKuninori Morimoto dev_err(dev, "wrong recip request\n"); 30697664a20SKuninori Morimoto ret = -EINVAL; 30797664a20SKuninori Morimoto goto usbhsg_recip_run_handle_end; 3089a28b7bdSKuninori Morimoto } 3092f98382dSKuninori Morimoto 3102f98382dSKuninori Morimoto switch (recip) { 3112f98382dSKuninori Morimoto case USB_RECIP_DEVICE: 3122f98382dSKuninori Morimoto msg = "DEVICE"; 3132f98382dSKuninori Morimoto func = handler->device; 3142f98382dSKuninori Morimoto break; 3152f98382dSKuninori Morimoto case USB_RECIP_INTERFACE: 3162f98382dSKuninori Morimoto msg = "INTERFACE"; 3172f98382dSKuninori Morimoto func = handler->interface; 3182f98382dSKuninori Morimoto break; 3192f98382dSKuninori Morimoto case USB_RECIP_ENDPOINT: 3202f98382dSKuninori Morimoto msg = "ENDPOINT"; 3212f98382dSKuninori Morimoto func = handler->endpoint; 3222f98382dSKuninori Morimoto break; 3232f98382dSKuninori Morimoto default: 3242f98382dSKuninori Morimoto dev_warn(dev, "unsupported RECIP(%d)\n", recip); 3252f98382dSKuninori Morimoto func = NULL; 3262f98382dSKuninori Morimoto ret = -EINVAL; 3272f98382dSKuninori Morimoto } 3282f98382dSKuninori Morimoto 3292f98382dSKuninori Morimoto if (func) { 33097664a20SKuninori Morimoto unsigned long flags; 33197664a20SKuninori Morimoto 3322f98382dSKuninori Morimoto dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); 33397664a20SKuninori Morimoto 33497664a20SKuninori Morimoto /******************** spin lock ********************/ 33597664a20SKuninori Morimoto usbhs_lock(priv, flags); 3362f98382dSKuninori Morimoto ret = func(priv, uep, ctrl); 33797664a20SKuninori Morimoto usbhs_unlock(priv, flags); 33897664a20SKuninori Morimoto /******************** spin unlock ******************/ 3392f98382dSKuninori Morimoto } 3402f98382dSKuninori Morimoto 34197664a20SKuninori Morimoto usbhsg_recip_run_handle_end: 3420432eed0SKuninori Morimoto usbhs_pkt_start(pipe); 34397664a20SKuninori Morimoto 3442f98382dSKuninori Morimoto return ret; 3452f98382dSKuninori Morimoto } 3462f98382dSKuninori Morimoto 3472f98382dSKuninori Morimoto /* 3482f98382dSKuninori Morimoto * irq functions 3492f98382dSKuninori Morimoto * 3502f98382dSKuninori Morimoto * it will be called from usbhs_interrupt 3512f98382dSKuninori Morimoto */ 3522f98382dSKuninori Morimoto static int usbhsg_irq_dev_state(struct usbhs_priv *priv, 3532f98382dSKuninori Morimoto struct usbhs_irq_state *irq_state) 3542f98382dSKuninori Morimoto { 3552f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 3562f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 3572f98382dSKuninori Morimoto 3582f98382dSKuninori Morimoto gpriv->gadget.speed = usbhs_status_get_usb_speed(irq_state); 3592f98382dSKuninori Morimoto 3602f98382dSKuninori Morimoto dev_dbg(dev, "state = %x : speed : %d\n", 3612f98382dSKuninori Morimoto usbhs_status_get_device_state(irq_state), 3622f98382dSKuninori Morimoto gpriv->gadget.speed); 3632f98382dSKuninori Morimoto 3642f98382dSKuninori Morimoto return 0; 3652f98382dSKuninori Morimoto } 3662f98382dSKuninori Morimoto 3672f98382dSKuninori Morimoto static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, 3682f98382dSKuninori Morimoto struct usbhs_irq_state *irq_state) 3692f98382dSKuninori Morimoto { 3702f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 3712f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 3722f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); 3732f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 3742f98382dSKuninori Morimoto struct usb_ctrlrequest ctrl; 3752f98382dSKuninori Morimoto struct usbhsg_recip_handle *recip_handler = NULL; 3762f98382dSKuninori Morimoto int stage = usbhs_status_get_ctrl_stage(irq_state); 3772f98382dSKuninori Morimoto int ret = 0; 3782f98382dSKuninori Morimoto 3792f98382dSKuninori Morimoto dev_dbg(dev, "stage = %d\n", stage); 3802f98382dSKuninori Morimoto 3812f98382dSKuninori Morimoto /* 3822f98382dSKuninori Morimoto * see Manual 3832f98382dSKuninori Morimoto * 3842f98382dSKuninori Morimoto * "Operation" 3852f98382dSKuninori Morimoto * - "Interrupt Function" 3862f98382dSKuninori Morimoto * - "Control Transfer Stage Transition Interrupt" 3872f98382dSKuninori Morimoto * - Fig. "Control Transfer Stage Transitions" 3882f98382dSKuninori Morimoto */ 3892f98382dSKuninori Morimoto 3902f98382dSKuninori Morimoto switch (stage) { 3912f98382dSKuninori Morimoto case READ_DATA_STAGE: 3920cb7e61dSKuninori Morimoto dcp->handler = &usbhs_fifo_pio_push_handler; 3932f98382dSKuninori Morimoto break; 3942f98382dSKuninori Morimoto case WRITE_DATA_STAGE: 3950cb7e61dSKuninori Morimoto dcp->handler = &usbhs_fifo_pio_pop_handler; 3962f98382dSKuninori Morimoto break; 3972f98382dSKuninori Morimoto case NODATA_STATUS_STAGE: 398dad67397SKuninori Morimoto dcp->handler = &usbhs_ctrl_stage_end_handler; 3992f98382dSKuninori Morimoto break; 4002f98382dSKuninori Morimoto default: 4012f98382dSKuninori Morimoto return ret; 4022f98382dSKuninori Morimoto } 4032f98382dSKuninori Morimoto 4042f98382dSKuninori Morimoto /* 4052f98382dSKuninori Morimoto * get usb request 4062f98382dSKuninori Morimoto */ 4072f98382dSKuninori Morimoto usbhs_usbreq_get_val(priv, &ctrl); 4082f98382dSKuninori Morimoto 4092f98382dSKuninori Morimoto switch (ctrl.bRequestType & USB_TYPE_MASK) { 4102f98382dSKuninori Morimoto case USB_TYPE_STANDARD: 4112f98382dSKuninori Morimoto switch (ctrl.bRequest) { 4122f98382dSKuninori Morimoto case USB_REQ_CLEAR_FEATURE: 4132f98382dSKuninori Morimoto recip_handler = &req_clear_feature; 4142f98382dSKuninori Morimoto break; 4152f98382dSKuninori Morimoto } 4162f98382dSKuninori Morimoto } 4172f98382dSKuninori Morimoto 4182f98382dSKuninori Morimoto /* 4192f98382dSKuninori Morimoto * setup stage / run recip 4202f98382dSKuninori Morimoto */ 4212f98382dSKuninori Morimoto if (recip_handler) 4222f98382dSKuninori Morimoto ret = usbhsg_recip_run_handle(priv, recip_handler, &ctrl); 4232f98382dSKuninori Morimoto else 4242f98382dSKuninori Morimoto ret = gpriv->driver->setup(&gpriv->gadget, &ctrl); 4252f98382dSKuninori Morimoto 4262f98382dSKuninori Morimoto if (ret < 0) 427e8d548d5SKuninori Morimoto usbhs_pipe_stall(pipe); 4282f98382dSKuninori Morimoto 4292f98382dSKuninori Morimoto return ret; 4302f98382dSKuninori Morimoto } 4312f98382dSKuninori Morimoto 4322f98382dSKuninori Morimoto /* 4332f98382dSKuninori Morimoto * 4342f98382dSKuninori Morimoto * usb_dcp_ops 4352f98382dSKuninori Morimoto * 4362f98382dSKuninori Morimoto */ 4372f98382dSKuninori Morimoto static int usbhsg_pipe_disable(struct usbhsg_uep *uep) 4382f98382dSKuninori Morimoto { 4392f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 4408a2c225dSKuninori Morimoto struct usbhs_pkt *pkt; 4412f98382dSKuninori Morimoto 442e8d548d5SKuninori Morimoto usbhs_pipe_disable(pipe); 4432f98382dSKuninori Morimoto 4442f98382dSKuninori Morimoto while (1) { 44597664a20SKuninori Morimoto pkt = usbhs_pkt_pop(pipe, NULL); 4468a2c225dSKuninori Morimoto if (!pkt) 4472f98382dSKuninori Morimoto break; 4482f98382dSKuninori Morimoto } 4492f98382dSKuninori Morimoto 4502f98382dSKuninori Morimoto return 0; 4512f98382dSKuninori Morimoto } 4522f98382dSKuninori Morimoto 453409ba9e7SKuninori Morimoto static void usbhsg_uep_init(struct usbhsg_gpriv *gpriv) 454409ba9e7SKuninori Morimoto { 455409ba9e7SKuninori Morimoto int i; 456409ba9e7SKuninori Morimoto struct usbhsg_uep *uep; 457409ba9e7SKuninori Morimoto 458409ba9e7SKuninori Morimoto usbhsg_for_each_uep_with_dcp(uep, gpriv, i) 459409ba9e7SKuninori Morimoto uep->pipe = NULL; 460409ba9e7SKuninori Morimoto } 461409ba9e7SKuninori Morimoto 4622f98382dSKuninori Morimoto /* 4632f98382dSKuninori Morimoto * 4642f98382dSKuninori Morimoto * usb_ep_ops 4652f98382dSKuninori Morimoto * 4662f98382dSKuninori Morimoto */ 4672f98382dSKuninori Morimoto static int usbhsg_ep_enable(struct usb_ep *ep, 4682f98382dSKuninori Morimoto const struct usb_endpoint_descriptor *desc) 4692f98382dSKuninori Morimoto { 4702f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 4712f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 4722f98382dSKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 4732f98382dSKuninori Morimoto struct usbhs_pipe *pipe; 4742f98382dSKuninori Morimoto int ret = -EIO; 4752f98382dSKuninori Morimoto 476409ba9e7SKuninori Morimoto /* 477409ba9e7SKuninori Morimoto * if it already have pipe, 478409ba9e7SKuninori Morimoto * nothing to do 479409ba9e7SKuninori Morimoto */ 48008e6c611SKuninori Morimoto if (uep->pipe) { 48108e6c611SKuninori Morimoto usbhs_pipe_clear(uep->pipe); 48208e6c611SKuninori Morimoto usbhs_pipe_clear_sequence(uep->pipe); 483409ba9e7SKuninori Morimoto return 0; 48408e6c611SKuninori Morimoto } 485409ba9e7SKuninori Morimoto 486*f5aa889fSKuninori Morimoto pipe = usbhs_pipe_malloc(priv, 487*f5aa889fSKuninori Morimoto usb_endpoint_type(desc), 488*f5aa889fSKuninori Morimoto usb_endpoint_dir_in(desc)); 4892f98382dSKuninori Morimoto if (pipe) { 4902f98382dSKuninori Morimoto uep->pipe = pipe; 4912f98382dSKuninori Morimoto pipe->mod_private = uep; 4922f98382dSKuninori Morimoto 493*f5aa889fSKuninori Morimoto /* set epnum / maxp */ 494*f5aa889fSKuninori Morimoto usbhs_pipe_config_update(pipe, 495*f5aa889fSKuninori Morimoto usb_endpoint_num(desc), 496*f5aa889fSKuninori Morimoto usb_endpoint_maxp(desc)); 497*f5aa889fSKuninori Morimoto 498233f519dSKuninori Morimoto /* 499233f519dSKuninori Morimoto * usbhs_fifo_dma_push/pop_handler try to 500233f519dSKuninori Morimoto * use dmaengine if possible. 501233f519dSKuninori Morimoto * It will use pio handler if impossible. 502233f519dSKuninori Morimoto */ 5032f98382dSKuninori Morimoto if (usb_endpoint_dir_in(desc)) 5046d721b29SKuninori Morimoto uep->handler = &usbhs_fifo_dma_push_handler; 5052f98382dSKuninori Morimoto else 5066d721b29SKuninori Morimoto uep->handler = &usbhs_fifo_dma_pop_handler; 5072f98382dSKuninori Morimoto 5082f98382dSKuninori Morimoto ret = 0; 5092f98382dSKuninori Morimoto } 510cb96632cSKuninori Morimoto 5112f98382dSKuninori Morimoto return ret; 5122f98382dSKuninori Morimoto } 5132f98382dSKuninori Morimoto 5142f98382dSKuninori Morimoto static int usbhsg_ep_disable(struct usb_ep *ep) 5152f98382dSKuninori Morimoto { 5162f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5172f98382dSKuninori Morimoto 51897664a20SKuninori Morimoto return usbhsg_pipe_disable(uep); 5192f98382dSKuninori Morimoto } 5202f98382dSKuninori Morimoto 5212f98382dSKuninori Morimoto static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, 5222f98382dSKuninori Morimoto gfp_t gfp_flags) 5232f98382dSKuninori Morimoto { 5242f98382dSKuninori Morimoto struct usbhsg_request *ureq; 5252f98382dSKuninori Morimoto 5262f98382dSKuninori Morimoto ureq = kzalloc(sizeof *ureq, gfp_flags); 5272f98382dSKuninori Morimoto if (!ureq) 5282f98382dSKuninori Morimoto return NULL; 5292f98382dSKuninori Morimoto 5306acb95d4SKuninori Morimoto usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); 5316acb95d4SKuninori Morimoto 532e73a9891SKuninori Morimoto ureq->req.dma = DMA_ADDR_INVALID; 533e73a9891SKuninori Morimoto 5342f98382dSKuninori Morimoto return &ureq->req; 5352f98382dSKuninori Morimoto } 5362f98382dSKuninori Morimoto 5372f98382dSKuninori Morimoto static void usbhsg_ep_free_request(struct usb_ep *ep, 5382f98382dSKuninori Morimoto struct usb_request *req) 5392f98382dSKuninori Morimoto { 5402f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 5412f98382dSKuninori Morimoto 5426acb95d4SKuninori Morimoto WARN_ON(!list_empty(&ureq->pkt.node)); 5432f98382dSKuninori Morimoto kfree(ureq); 5442f98382dSKuninori Morimoto } 5452f98382dSKuninori Morimoto 5462f98382dSKuninori Morimoto static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, 5472f98382dSKuninori Morimoto gfp_t gfp_flags) 5482f98382dSKuninori Morimoto { 5492f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5502f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 5512f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 5522f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 5532f98382dSKuninori Morimoto 5542f98382dSKuninori Morimoto /* param check */ 5552f98382dSKuninori Morimoto if (usbhsg_is_not_connected(gpriv) || 5562f98382dSKuninori Morimoto unlikely(!gpriv->driver) || 5572f98382dSKuninori Morimoto unlikely(!pipe)) 55897664a20SKuninori Morimoto return -ESHUTDOWN; 55997664a20SKuninori Morimoto 5602f98382dSKuninori Morimoto usbhsg_queue_push(uep, ureq); 5612f98382dSKuninori Morimoto 56297664a20SKuninori Morimoto return 0; 5632f98382dSKuninori Morimoto } 5642f98382dSKuninori Morimoto 5652f98382dSKuninori Morimoto static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) 5662f98382dSKuninori Morimoto { 5672f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5682f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 56997664a20SKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 5702f98382dSKuninori Morimoto 57197664a20SKuninori Morimoto usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); 5722f98382dSKuninori Morimoto usbhsg_queue_pop(uep, ureq, -ECONNRESET); 5732f98382dSKuninori Morimoto 5742f98382dSKuninori Morimoto return 0; 5752f98382dSKuninori Morimoto } 5762f98382dSKuninori Morimoto 5772f98382dSKuninori Morimoto static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) 5782f98382dSKuninori Morimoto { 5792f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5802f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 5812f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 58297664a20SKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 5832f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 5842f98382dSKuninori Morimoto unsigned long flags; 5852f98382dSKuninori Morimoto 58697664a20SKuninori Morimoto usbhsg_pipe_disable(uep); 5872f98382dSKuninori Morimoto 5882f98382dSKuninori Morimoto dev_dbg(dev, "set halt %d (pipe %d)\n", 5892f98382dSKuninori Morimoto halt, usbhs_pipe_number(pipe)); 5902f98382dSKuninori Morimoto 59197664a20SKuninori Morimoto /******************** spin lock ********************/ 59297664a20SKuninori Morimoto usbhs_lock(priv, flags); 59397664a20SKuninori Morimoto 5942f98382dSKuninori Morimoto if (halt) 595e8d548d5SKuninori Morimoto usbhs_pipe_stall(pipe); 5962f98382dSKuninori Morimoto else 597e8d548d5SKuninori Morimoto usbhs_pipe_disable(pipe); 5982f98382dSKuninori Morimoto 5992f98382dSKuninori Morimoto if (halt && wedge) 6002f98382dSKuninori Morimoto usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); 6012f98382dSKuninori Morimoto else 6022f98382dSKuninori Morimoto usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); 6032f98382dSKuninori Morimoto 60497664a20SKuninori Morimoto usbhs_unlock(priv, flags); 6052f98382dSKuninori Morimoto /******************** spin unlock ******************/ 6062f98382dSKuninori Morimoto 60797664a20SKuninori Morimoto return 0; 6082f98382dSKuninori Morimoto } 6092f98382dSKuninori Morimoto 6102f98382dSKuninori Morimoto static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) 6112f98382dSKuninori Morimoto { 6122f98382dSKuninori Morimoto return __usbhsg_ep_set_halt_wedge(ep, value, 0); 6132f98382dSKuninori Morimoto } 6142f98382dSKuninori Morimoto 6152f98382dSKuninori Morimoto static int usbhsg_ep_set_wedge(struct usb_ep *ep) 6162f98382dSKuninori Morimoto { 6172f98382dSKuninori Morimoto return __usbhsg_ep_set_halt_wedge(ep, 1, 1); 6182f98382dSKuninori Morimoto } 6192f98382dSKuninori Morimoto 6202f98382dSKuninori Morimoto static struct usb_ep_ops usbhsg_ep_ops = { 6212f98382dSKuninori Morimoto .enable = usbhsg_ep_enable, 6222f98382dSKuninori Morimoto .disable = usbhsg_ep_disable, 6232f98382dSKuninori Morimoto 6242f98382dSKuninori Morimoto .alloc_request = usbhsg_ep_alloc_request, 6252f98382dSKuninori Morimoto .free_request = usbhsg_ep_free_request, 6262f98382dSKuninori Morimoto 6272f98382dSKuninori Morimoto .queue = usbhsg_ep_queue, 6282f98382dSKuninori Morimoto .dequeue = usbhsg_ep_dequeue, 6292f98382dSKuninori Morimoto 6302f98382dSKuninori Morimoto .set_halt = usbhsg_ep_set_halt, 6312f98382dSKuninori Morimoto .set_wedge = usbhsg_ep_set_wedge, 6322f98382dSKuninori Morimoto }; 6332f98382dSKuninori Morimoto 6342f98382dSKuninori Morimoto /* 6352f98382dSKuninori Morimoto * usb module start/end 6362f98382dSKuninori Morimoto */ 6372f98382dSKuninori Morimoto static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) 6382f98382dSKuninori Morimoto { 6392f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 6402f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 6412f98382dSKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 6422f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 6432f98382dSKuninori Morimoto unsigned long flags; 64497664a20SKuninori Morimoto int ret = 0; 6452f98382dSKuninori Morimoto 6462f98382dSKuninori Morimoto /******************** spin lock ********************/ 64797664a20SKuninori Morimoto usbhs_lock(priv, flags); 64897664a20SKuninori Morimoto 64997664a20SKuninori Morimoto usbhsg_status_set(gpriv, status); 65097664a20SKuninori Morimoto if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && 65197664a20SKuninori Morimoto usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) 65297664a20SKuninori Morimoto ret = -1; /* not ready */ 65397664a20SKuninori Morimoto 65497664a20SKuninori Morimoto usbhs_unlock(priv, flags); 65597664a20SKuninori Morimoto /******************** spin unlock ********************/ 65697664a20SKuninori Morimoto 65797664a20SKuninori Morimoto if (ret < 0) 65897664a20SKuninori Morimoto return 0; /* not ready is not error */ 6592f98382dSKuninori Morimoto 6602f98382dSKuninori Morimoto /* 6612f98382dSKuninori Morimoto * enable interrupt and systems if ready 6622f98382dSKuninori Morimoto */ 6632f98382dSKuninori Morimoto dev_dbg(dev, "start gadget\n"); 6642f98382dSKuninori Morimoto 6652f98382dSKuninori Morimoto /* 6662f98382dSKuninori Morimoto * pipe initialize and enable DCP 6672f98382dSKuninori Morimoto */ 6684bd04811SKuninori Morimoto usbhs_pipe_init(priv, 669e73a9891SKuninori Morimoto usbhsg_queue_done, 670e73a9891SKuninori Morimoto usbhsg_dma_map_ctrl); 671dad67397SKuninori Morimoto usbhs_fifo_init(priv); 672409ba9e7SKuninori Morimoto usbhsg_uep_init(gpriv); 67397664a20SKuninori Morimoto 67497664a20SKuninori Morimoto /* dcp init */ 67597664a20SKuninori Morimoto dcp->pipe = usbhs_dcp_malloc(priv); 67697664a20SKuninori Morimoto dcp->pipe->mod_private = dcp; 677*f5aa889fSKuninori Morimoto usbhs_pipe_config_update(dcp->pipe, 0, 64); 6782f98382dSKuninori Morimoto 6792f98382dSKuninori Morimoto /* 6802f98382dSKuninori Morimoto * system config enble 6812f98382dSKuninori Morimoto * - HI speed 6822f98382dSKuninori Morimoto * - function 6832f98382dSKuninori Morimoto * - usb module 6842f98382dSKuninori Morimoto */ 6852f98382dSKuninori Morimoto usbhs_sys_hispeed_ctrl(priv, 1); 6862f98382dSKuninori Morimoto usbhs_sys_function_ctrl(priv, 1); 6872f98382dSKuninori Morimoto usbhs_sys_usb_ctrl(priv, 1); 6882f98382dSKuninori Morimoto 6892f98382dSKuninori Morimoto /* 6902f98382dSKuninori Morimoto * enable irq callback 6912f98382dSKuninori Morimoto */ 6922f98382dSKuninori Morimoto mod->irq_dev_state = usbhsg_irq_dev_state; 6932f98382dSKuninori Morimoto mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; 6942f98382dSKuninori Morimoto usbhs_irq_callback_update(priv, mod); 6952f98382dSKuninori Morimoto 6962f98382dSKuninori Morimoto return 0; 6972f98382dSKuninori Morimoto } 6982f98382dSKuninori Morimoto 6992f98382dSKuninori Morimoto static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) 7002f98382dSKuninori Morimoto { 7012f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 7022f98382dSKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 7032f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 7042f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 7052f98382dSKuninori Morimoto unsigned long flags; 70697664a20SKuninori Morimoto int ret = 0; 7072f98382dSKuninori Morimoto 7082f98382dSKuninori Morimoto /******************** spin lock ********************/ 70997664a20SKuninori Morimoto usbhs_lock(priv, flags); 71097664a20SKuninori Morimoto 71197664a20SKuninori Morimoto usbhsg_status_clr(gpriv, status); 71297664a20SKuninori Morimoto if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && 71397664a20SKuninori Morimoto !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) 71497664a20SKuninori Morimoto ret = -1; /* already done */ 71597664a20SKuninori Morimoto 71697664a20SKuninori Morimoto usbhs_unlock(priv, flags); 71797664a20SKuninori Morimoto /******************** spin unlock ********************/ 71897664a20SKuninori Morimoto 71997664a20SKuninori Morimoto if (ret < 0) 72097664a20SKuninori Morimoto return 0; /* already done is not error */ 7212f98382dSKuninori Morimoto 7222f98382dSKuninori Morimoto /* 7232f98382dSKuninori Morimoto * disable interrupt and systems if 1st try 7242f98382dSKuninori Morimoto */ 725dad67397SKuninori Morimoto usbhs_fifo_quit(priv); 726dad67397SKuninori Morimoto 7272f98382dSKuninori Morimoto /* disable all irq */ 7282f98382dSKuninori Morimoto mod->irq_dev_state = NULL; 7292f98382dSKuninori Morimoto mod->irq_ctrl_stage = NULL; 7302f98382dSKuninori Morimoto usbhs_irq_callback_update(priv, mod); 7312f98382dSKuninori Morimoto 7322f98382dSKuninori Morimoto gpriv->gadget.speed = USB_SPEED_UNKNOWN; 7332f98382dSKuninori Morimoto 7342f98382dSKuninori Morimoto /* disable sys */ 7352f98382dSKuninori Morimoto usbhs_sys_hispeed_ctrl(priv, 0); 7362f98382dSKuninori Morimoto usbhs_sys_function_ctrl(priv, 0); 7372f98382dSKuninori Morimoto usbhs_sys_usb_ctrl(priv, 0); 7382f98382dSKuninori Morimoto 73997664a20SKuninori Morimoto usbhsg_pipe_disable(dcp); 7402f98382dSKuninori Morimoto 7412f98382dSKuninori Morimoto dev_dbg(dev, "stop gadget\n"); 7422f98382dSKuninori Morimoto 7432f98382dSKuninori Morimoto return 0; 7442f98382dSKuninori Morimoto } 7452f98382dSKuninori Morimoto 7462f98382dSKuninori Morimoto /* 7472f98382dSKuninori Morimoto * 7482f98382dSKuninori Morimoto * linux usb function 7492f98382dSKuninori Morimoto * 7502f98382dSKuninori Morimoto */ 751af1d7056SFelipe Balbi static int usbhsg_gadget_start(struct usb_gadget *gadget, 752af1d7056SFelipe Balbi struct usb_gadget_driver *driver) 7532f98382dSKuninori Morimoto { 754af1d7056SFelipe Balbi struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 7552f98382dSKuninori Morimoto struct usbhs_priv *priv; 7562f98382dSKuninori Morimoto struct device *dev; 7572f98382dSKuninori Morimoto int ret; 7582f98382dSKuninori Morimoto 759af1d7056SFelipe Balbi if (!driver || 7602f98382dSKuninori Morimoto !driver->setup || 7612f98382dSKuninori Morimoto driver->speed != USB_SPEED_HIGH) 7622f98382dSKuninori Morimoto return -EINVAL; 7633b872188SKuninori Morimoto 7642f98382dSKuninori Morimoto dev = usbhsg_gpriv_to_dev(gpriv); 7652f98382dSKuninori Morimoto priv = usbhsg_gpriv_to_priv(gpriv); 7662f98382dSKuninori Morimoto 7672f98382dSKuninori Morimoto /* first hook up the driver ... */ 7682f98382dSKuninori Morimoto gpriv->driver = driver; 7692f98382dSKuninori Morimoto gpriv->gadget.dev.driver = &driver->driver; 7702f98382dSKuninori Morimoto 7712f98382dSKuninori Morimoto ret = device_add(&gpriv->gadget.dev); 7722f98382dSKuninori Morimoto if (ret) { 7732f98382dSKuninori Morimoto dev_err(dev, "device_add error %d\n", ret); 7742f98382dSKuninori Morimoto goto add_fail; 7752f98382dSKuninori Morimoto } 7762f98382dSKuninori Morimoto 7772f98382dSKuninori Morimoto return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); 7782f98382dSKuninori Morimoto 7792f98382dSKuninori Morimoto add_fail: 7802f98382dSKuninori Morimoto gpriv->driver = NULL; 7812f98382dSKuninori Morimoto gpriv->gadget.dev.driver = NULL; 7822f98382dSKuninori Morimoto 7832f98382dSKuninori Morimoto return ret; 7842f98382dSKuninori Morimoto } 7852f98382dSKuninori Morimoto 786af1d7056SFelipe Balbi static int usbhsg_gadget_stop(struct usb_gadget *gadget, 787af1d7056SFelipe Balbi struct usb_gadget_driver *driver) 7882f98382dSKuninori Morimoto { 789af1d7056SFelipe Balbi struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 7902f98382dSKuninori Morimoto struct usbhs_priv *priv; 7913b872188SKuninori Morimoto struct device *dev; 7922f98382dSKuninori Morimoto 7932f98382dSKuninori Morimoto if (!driver || 7943b872188SKuninori Morimoto !driver->unbind) 7952f98382dSKuninori Morimoto return -EINVAL; 7962f98382dSKuninori Morimoto 7972f98382dSKuninori Morimoto dev = usbhsg_gpriv_to_dev(gpriv); 7982f98382dSKuninori Morimoto priv = usbhsg_gpriv_to_priv(gpriv); 7992f98382dSKuninori Morimoto 8002f98382dSKuninori Morimoto usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); 8012f98382dSKuninori Morimoto device_del(&gpriv->gadget.dev); 8022f98382dSKuninori Morimoto gpriv->driver = NULL; 8032f98382dSKuninori Morimoto 8042f98382dSKuninori Morimoto return 0; 8052f98382dSKuninori Morimoto } 8062f98382dSKuninori Morimoto 8072f98382dSKuninori Morimoto /* 8082f98382dSKuninori Morimoto * usb gadget ops 8092f98382dSKuninori Morimoto */ 8102f98382dSKuninori Morimoto static int usbhsg_get_frame(struct usb_gadget *gadget) 8112f98382dSKuninori Morimoto { 8122f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 8132f98382dSKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 8142f98382dSKuninori Morimoto 8152f98382dSKuninori Morimoto return usbhs_frame_get_num(priv); 8162f98382dSKuninori Morimoto } 8172f98382dSKuninori Morimoto 8182f98382dSKuninori Morimoto static struct usb_gadget_ops usbhsg_gadget_ops = { 8192f98382dSKuninori Morimoto .get_frame = usbhsg_get_frame, 820af1d7056SFelipe Balbi .udc_start = usbhsg_gadget_start, 821af1d7056SFelipe Balbi .udc_stop = usbhsg_gadget_stop, 8222f98382dSKuninori Morimoto }; 8232f98382dSKuninori Morimoto 8242f98382dSKuninori Morimoto static int usbhsg_start(struct usbhs_priv *priv) 8252f98382dSKuninori Morimoto { 8262f98382dSKuninori Morimoto return usbhsg_try_start(priv, USBHSG_STATUS_STARTED); 8272f98382dSKuninori Morimoto } 8282f98382dSKuninori Morimoto 8292f98382dSKuninori Morimoto static int usbhsg_stop(struct usbhs_priv *priv) 8302f98382dSKuninori Morimoto { 8312f98382dSKuninori Morimoto return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); 8322f98382dSKuninori Morimoto } 8332f98382dSKuninori Morimoto 8342f98382dSKuninori Morimoto int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv) 8352f98382dSKuninori Morimoto { 8362f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv; 8372f98382dSKuninori Morimoto struct usbhsg_uep *uep; 8382f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 8392f98382dSKuninori Morimoto int pipe_size = usbhs_get_dparam(priv, pipe_size); 8402f98382dSKuninori Morimoto int i; 8410f91349bSSebastian Andrzej Siewior int ret; 8422f98382dSKuninori Morimoto 8432f98382dSKuninori Morimoto gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL); 8442f98382dSKuninori Morimoto if (!gpriv) { 8452f98382dSKuninori Morimoto dev_err(dev, "Could not allocate gadget priv\n"); 8462f98382dSKuninori Morimoto return -ENOMEM; 8472f98382dSKuninori Morimoto } 8482f98382dSKuninori Morimoto 8492f98382dSKuninori Morimoto uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL); 8502f98382dSKuninori Morimoto if (!uep) { 8512f98382dSKuninori Morimoto dev_err(dev, "Could not allocate ep\n"); 8520f91349bSSebastian Andrzej Siewior ret = -ENOMEM; 8532f98382dSKuninori Morimoto goto usbhs_mod_gadget_probe_err_gpriv; 8542f98382dSKuninori Morimoto } 8552f98382dSKuninori Morimoto 8562f98382dSKuninori Morimoto /* 8572f98382dSKuninori Morimoto * CAUTION 8582f98382dSKuninori Morimoto * 8592f98382dSKuninori Morimoto * There is no guarantee that it is possible to access usb module here. 8602f98382dSKuninori Morimoto * Don't accesses to it. 8612f98382dSKuninori Morimoto * The accesse will be enable after "usbhsg_start" 8622f98382dSKuninori Morimoto */ 8632f98382dSKuninori Morimoto 8642f98382dSKuninori Morimoto /* 8652f98382dSKuninori Morimoto * register itself 8662f98382dSKuninori Morimoto */ 8672f98382dSKuninori Morimoto usbhs_mod_register(priv, &gpriv->mod, USBHS_GADGET); 8682f98382dSKuninori Morimoto 8692f98382dSKuninori Morimoto /* init gpriv */ 8702f98382dSKuninori Morimoto gpriv->mod.name = "gadget"; 8712f98382dSKuninori Morimoto gpriv->mod.start = usbhsg_start; 8722f98382dSKuninori Morimoto gpriv->mod.stop = usbhsg_stop; 8732f98382dSKuninori Morimoto gpriv->uep = uep; 8742f98382dSKuninori Morimoto gpriv->uep_size = pipe_size; 8752f98382dSKuninori Morimoto usbhsg_status_init(gpriv); 8762f98382dSKuninori Morimoto 8772f98382dSKuninori Morimoto /* 8782f98382dSKuninori Morimoto * init gadget 8792f98382dSKuninori Morimoto */ 8802f98382dSKuninori Morimoto device_initialize(&gpriv->gadget.dev); 8812f98382dSKuninori Morimoto dev_set_name(&gpriv->gadget.dev, "gadget"); 8822f98382dSKuninori Morimoto gpriv->gadget.dev.parent = dev; 8832f98382dSKuninori Morimoto gpriv->gadget.name = "renesas_usbhs_udc"; 8842f98382dSKuninori Morimoto gpriv->gadget.ops = &usbhsg_gadget_ops; 8852f98382dSKuninori Morimoto gpriv->gadget.is_dualspeed = 1; 8862f98382dSKuninori Morimoto 8872f98382dSKuninori Morimoto INIT_LIST_HEAD(&gpriv->gadget.ep_list); 8882f98382dSKuninori Morimoto 8892f98382dSKuninori Morimoto /* 8902f98382dSKuninori Morimoto * init usb_ep 8912f98382dSKuninori Morimoto */ 8922f98382dSKuninori Morimoto usbhsg_for_each_uep_with_dcp(uep, gpriv, i) { 8932f98382dSKuninori Morimoto uep->gpriv = gpriv; 8942f98382dSKuninori Morimoto snprintf(uep->ep_name, EP_NAME_SIZE, "ep%d", i); 8952f98382dSKuninori Morimoto 8962f98382dSKuninori Morimoto uep->ep.name = uep->ep_name; 8972f98382dSKuninori Morimoto uep->ep.ops = &usbhsg_ep_ops; 8982f98382dSKuninori Morimoto INIT_LIST_HEAD(&uep->ep.ep_list); 8992f98382dSKuninori Morimoto 9002f98382dSKuninori Morimoto /* init DCP */ 9012f98382dSKuninori Morimoto if (usbhsg_is_dcp(uep)) { 9022f98382dSKuninori Morimoto gpriv->gadget.ep0 = &uep->ep; 9032f98382dSKuninori Morimoto uep->ep.maxpacket = 64; 9042f98382dSKuninori Morimoto } 9052f98382dSKuninori Morimoto /* init normal pipe */ 9062f98382dSKuninori Morimoto else { 9072f98382dSKuninori Morimoto uep->ep.maxpacket = 512; 9082f98382dSKuninori Morimoto list_add_tail(&uep->ep.ep_list, &gpriv->gadget.ep_list); 9092f98382dSKuninori Morimoto } 9102f98382dSKuninori Morimoto } 9112f98382dSKuninori Morimoto 9123b872188SKuninori Morimoto usbhsg_controller_register(gpriv); 9132f98382dSKuninori Morimoto 9140f91349bSSebastian Andrzej Siewior ret = usb_add_gadget_udc(dev, &gpriv->gadget); 9150f91349bSSebastian Andrzej Siewior if (ret) 9160f91349bSSebastian Andrzej Siewior goto err_add_udc; 9170f91349bSSebastian Andrzej Siewior 9180f91349bSSebastian Andrzej Siewior 9192f98382dSKuninori Morimoto dev_info(dev, "gadget probed\n"); 9202f98382dSKuninori Morimoto 9212f98382dSKuninori Morimoto return 0; 9220f91349bSSebastian Andrzej Siewior err_add_udc: 9230f91349bSSebastian Andrzej Siewior kfree(gpriv->uep); 9242f98382dSKuninori Morimoto 9252f98382dSKuninori Morimoto usbhs_mod_gadget_probe_err_gpriv: 9262f98382dSKuninori Morimoto kfree(gpriv); 9272f98382dSKuninori Morimoto 9280f91349bSSebastian Andrzej Siewior return ret; 9292f98382dSKuninori Morimoto } 9302f98382dSKuninori Morimoto 9312f98382dSKuninori Morimoto void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv) 9322f98382dSKuninori Morimoto { 9332f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 9342f98382dSKuninori Morimoto 9350f91349bSSebastian Andrzej Siewior usb_del_gadget_udc(&gpriv->gadget); 9363b872188SKuninori Morimoto 9373b872188SKuninori Morimoto usbhsg_controller_unregister(gpriv); 9383b872188SKuninori Morimoto 9393af51ac9SSebastian Andrzej Siewior kfree(gpriv->uep); 9402f98382dSKuninori Morimoto kfree(gpriv); 9412f98382dSKuninori Morimoto } 942