|
@@ -21,6 +21,7 @@
|
|
#include <linux/platform_device.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/debugfs.h>
|
|
|
|
+#include <linux/mutex.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/io.h>
|
|
#include <linux/io.h>
|
|
@@ -36,6 +37,7 @@
|
|
#include <linux/platform_data/s3c-hsotg.h>
|
|
#include <linux/platform_data/s3c-hsotg.h>
|
|
|
|
|
|
#include "core.h"
|
|
#include "core.h"
|
|
|
|
+#include "hw.h"
|
|
|
|
|
|
/* conversion functions */
|
|
/* conversion functions */
|
|
static inline struct s3c_hsotg_req *our_req(struct usb_request *req)
|
|
static inline struct s3c_hsotg_req *our_req(struct usb_request *req)
|
|
@@ -48,9 +50,9 @@ static inline struct s3c_hsotg_ep *our_ep(struct usb_ep *ep)
|
|
return container_of(ep, struct s3c_hsotg_ep, ep);
|
|
return container_of(ep, struct s3c_hsotg_ep, ep);
|
|
}
|
|
}
|
|
|
|
|
|
-static inline struct s3c_hsotg *to_hsotg(struct usb_gadget *gadget)
|
|
|
|
|
|
+static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget)
|
|
{
|
|
{
|
|
- return container_of(gadget, struct s3c_hsotg, gadget);
|
|
|
|
|
|
+ return container_of(gadget, struct dwc2_hsotg, gadget);
|
|
}
|
|
}
|
|
|
|
|
|
static inline void __orr32(void __iomem *ptr, u32 val)
|
|
static inline void __orr32(void __iomem *ptr, u32 val)
|
|
@@ -64,7 +66,7 @@ static inline void __bic32(void __iomem *ptr, u32 val)
|
|
}
|
|
}
|
|
|
|
|
|
/* forward decleration of functions */
|
|
/* forward decleration of functions */
|
|
-static void s3c_hsotg_dump(struct s3c_hsotg *hsotg);
|
|
|
|
|
|
+static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg);
|
|
|
|
|
|
/**
|
|
/**
|
|
* using_dma - return the DMA status of the driver.
|
|
* using_dma - return the DMA status of the driver.
|
|
@@ -85,7 +87,7 @@ static void s3c_hsotg_dump(struct s3c_hsotg *hsotg);
|
|
*
|
|
*
|
|
* Until this issue is sorted out, we always return 'false'.
|
|
* Until this issue is sorted out, we always return 'false'.
|
|
*/
|
|
*/
|
|
-static inline bool using_dma(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static inline bool using_dma(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
return false; /* support is not complete */
|
|
return false; /* support is not complete */
|
|
}
|
|
}
|
|
@@ -95,7 +97,7 @@ static inline bool using_dma(struct s3c_hsotg *hsotg)
|
|
* @hsotg: The device state
|
|
* @hsotg: The device state
|
|
* @ints: A bitmask of the interrupts to enable
|
|
* @ints: A bitmask of the interrupts to enable
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints)
|
|
|
|
|
|
+static void s3c_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints)
|
|
{
|
|
{
|
|
u32 gsintmsk = readl(hsotg->regs + GINTMSK);
|
|
u32 gsintmsk = readl(hsotg->regs + GINTMSK);
|
|
u32 new_gsintmsk;
|
|
u32 new_gsintmsk;
|
|
@@ -113,7 +115,7 @@ static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints)
|
|
* @hsotg: The device state
|
|
* @hsotg: The device state
|
|
* @ints: A bitmask of the interrupts to enable
|
|
* @ints: A bitmask of the interrupts to enable
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints)
|
|
|
|
|
|
+static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints)
|
|
{
|
|
{
|
|
u32 gsintmsk = readl(hsotg->regs + GINTMSK);
|
|
u32 gsintmsk = readl(hsotg->regs + GINTMSK);
|
|
u32 new_gsintmsk;
|
|
u32 new_gsintmsk;
|
|
@@ -134,7 +136,7 @@ static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints)
|
|
* Set or clear the mask for an individual endpoint's interrupt
|
|
* Set or clear the mask for an individual endpoint's interrupt
|
|
* request.
|
|
* request.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
|
|
unsigned int ep, unsigned int dir_in,
|
|
unsigned int ep, unsigned int dir_in,
|
|
unsigned int en)
|
|
unsigned int en)
|
|
{
|
|
{
|
|
@@ -159,7 +161,7 @@ static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg,
|
|
* s3c_hsotg_init_fifo - initialise non-periodic FIFOs
|
|
* s3c_hsotg_init_fifo - initialise non-periodic FIFOs
|
|
* @hsotg: The device instance.
|
|
* @hsotg: The device instance.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
unsigned int ep;
|
|
unsigned int ep;
|
|
unsigned int addr;
|
|
unsigned int addr;
|
|
@@ -283,7 +285,7 @@ static inline int is_ep_periodic(struct s3c_hsotg_ep *hs_ep)
|
|
* This is the reverse of s3c_hsotg_map_dma(), called for the completion
|
|
* This is the reverse of s3c_hsotg_map_dma(), called for the completion
|
|
* of a request to ensure the buffer is ready for access by the caller.
|
|
* of a request to ensure the buffer is ready for access by the caller.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_req *hs_req)
|
|
struct s3c_hsotg_req *hs_req)
|
|
{
|
|
{
|
|
@@ -312,7 +314,7 @@ static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg,
|
|
*
|
|
*
|
|
* This routine is only needed for PIO
|
|
* This routine is only needed for PIO
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_req *hs_req)
|
|
struct s3c_hsotg_req *hs_req)
|
|
{
|
|
{
|
|
@@ -517,7 +519,7 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep)
|
|
* Start the given request running by setting the endpoint registers
|
|
* Start the given request running by setting the endpoint registers
|
|
* appropriately, and writing any data to the FIFOs.
|
|
* appropriately, and writing any data to the FIFOs.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_req *hs_req,
|
|
struct s3c_hsotg_req *hs_req,
|
|
bool continuing)
|
|
bool continuing)
|
|
@@ -707,7 +709,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
|
|
* DMA memory, then we map the memory and mark our request to allow us to
|
|
* DMA memory, then we map the memory and mark our request to allow us to
|
|
* cleanup on completion.
|
|
* cleanup on completion.
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_map_dma(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static int s3c_hsotg_map_dma(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct usb_request *req)
|
|
struct usb_request *req)
|
|
{
|
|
{
|
|
@@ -736,7 +738,7 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
|
|
{
|
|
{
|
|
struct s3c_hsotg_req *hs_req = our_req(req);
|
|
struct s3c_hsotg_req *hs_req = our_req(req);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hs = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hs = hs_ep->parent;
|
|
bool first;
|
|
bool first;
|
|
|
|
|
|
dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n",
|
|
dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n",
|
|
@@ -768,7 +770,7 @@ static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req,
|
|
gfp_t gfp_flags)
|
|
gfp_t gfp_flags)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hs = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hs = hs_ep->parent;
|
|
unsigned long flags = 0;
|
|
unsigned long flags = 0;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
@@ -799,7 +801,7 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep,
|
|
struct usb_request *req)
|
|
struct usb_request *req)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hsotg = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = hs_ep->parent;
|
|
|
|
|
|
dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req);
|
|
dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req);
|
|
|
|
|
|
@@ -814,7 +816,7 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep,
|
|
* Convert the given wIndex into a pointer to an driver endpoint
|
|
* Convert the given wIndex into a pointer to an driver endpoint
|
|
* structure, or return NULL if it is not a valid endpoint.
|
|
* structure, or return NULL if it is not a valid endpoint.
|
|
*/
|
|
*/
|
|
-static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
|
|
u32 windex)
|
|
u32 windex)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *ep = &hsotg->eps[windex & 0x7F];
|
|
struct s3c_hsotg_ep *ep = &hsotg->eps[windex & 0x7F];
|
|
@@ -843,7 +845,7 @@ static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg,
|
|
* Create a request and queue it on the given endpoint. This is useful as
|
|
* Create a request and queue it on the given endpoint. This is useful as
|
|
* an internal method of sending replies to certain control requests, etc.
|
|
* an internal method of sending replies to certain control requests, etc.
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_send_reply(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *ep,
|
|
struct s3c_hsotg_ep *ep,
|
|
void *buff,
|
|
void *buff,
|
|
int length)
|
|
int length)
|
|
@@ -884,7 +886,7 @@ static int s3c_hsotg_send_reply(struct s3c_hsotg *hsotg,
|
|
* @hsotg: The device state
|
|
* @hsotg: The device state
|
|
* @ctrl: USB control request
|
|
* @ctrl: USB control request
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_process_req_status(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
|
|
struct usb_ctrlrequest *ctrl)
|
|
struct usb_ctrlrequest *ctrl)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
|
|
struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
|
|
@@ -955,7 +957,7 @@ static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep)
|
|
* @hsotg: The device state
|
|
* @hsotg: The device state
|
|
* @ctrl: USB control request
|
|
* @ctrl: USB control request
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
|
|
struct usb_ctrlrequest *ctrl)
|
|
struct usb_ctrlrequest *ctrl)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
|
|
struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
|
|
@@ -1028,8 +1030,7 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg);
|
|
|
|
-static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg);
|
|
|
|
|
|
+static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg);
|
|
|
|
|
|
/**
|
|
/**
|
|
* s3c_hsotg_stall_ep0 - stall ep0
|
|
* s3c_hsotg_stall_ep0 - stall ep0
|
|
@@ -1037,7 +1038,7 @@ static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg);
|
|
*
|
|
*
|
|
* Set stall for ep0 as response for setup request.
|
|
* Set stall for ep0 as response for setup request.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
|
|
struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
|
|
u32 reg;
|
|
u32 reg;
|
|
@@ -1076,7 +1077,7 @@ static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg)
|
|
* needs to work out what to do next (and whether to pass it on to the
|
|
* needs to work out what to do next (and whether to pass it on to the
|
|
* gadget driver).
|
|
* gadget driver).
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg,
|
|
struct usb_ctrlrequest *ctrl)
|
|
struct usb_ctrlrequest *ctrl)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
|
|
struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
|
|
@@ -1107,7 +1108,6 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg,
|
|
if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
|
|
if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
|
|
switch (ctrl->bRequest) {
|
|
switch (ctrl->bRequest) {
|
|
case USB_REQ_SET_ADDRESS:
|
|
case USB_REQ_SET_ADDRESS:
|
|
- s3c_hsotg_disconnect(hsotg);
|
|
|
|
dcfg = readl(hsotg->regs + DCFG);
|
|
dcfg = readl(hsotg->regs + DCFG);
|
|
dcfg &= ~DCFG_DEVADDR_MASK;
|
|
dcfg &= ~DCFG_DEVADDR_MASK;
|
|
dcfg |= (le16_to_cpu(ctrl->wValue) <<
|
|
dcfg |= (le16_to_cpu(ctrl->wValue) <<
|
|
@@ -1161,7 +1161,7 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep,
|
|
struct usb_request *req)
|
|
struct usb_request *req)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hsotg = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = hs_ep->parent;
|
|
|
|
|
|
if (req->status < 0) {
|
|
if (req->status < 0) {
|
|
dev_dbg(hsotg->dev, "%s: failed %d\n", __func__, req->status);
|
|
dev_dbg(hsotg->dev, "%s: failed %d\n", __func__, req->status);
|
|
@@ -1183,7 +1183,7 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep,
|
|
* Enqueue a request on EP0 if necessary to received any SETUP packets
|
|
* Enqueue a request on EP0 if necessary to received any SETUP packets
|
|
* received from the host.
|
|
* received from the host.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
struct usb_request *req = hsotg->ctrl_req;
|
|
struct usb_request *req = hsotg->ctrl_req;
|
|
struct s3c_hsotg_req *hs_req = our_req(req);
|
|
struct s3c_hsotg_req *hs_req = our_req(req);
|
|
@@ -1226,7 +1226,7 @@ static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg)
|
|
*
|
|
*
|
|
* Note, expects the ep to already be locked as appropriate.
|
|
* Note, expects the ep to already be locked as appropriate.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_req *hs_req,
|
|
struct s3c_hsotg_req *hs_req,
|
|
int result)
|
|
int result)
|
|
@@ -1291,7 +1291,7 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg,
|
|
* endpoint, so sort out whether we need to read the data into a request
|
|
* endpoint, so sort out whether we need to read the data into a request
|
|
* that has been made for that endpoint.
|
|
* that has been made for that endpoint.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size)
|
|
|
|
|
|
+static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep_idx];
|
|
struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep_idx];
|
|
struct s3c_hsotg_req *hs_req = hs_ep->req;
|
|
struct s3c_hsotg_req *hs_req = hs_ep->req;
|
|
@@ -1356,7 +1356,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size)
|
|
* currently believed that we do not need to wait for any space in
|
|
* currently believed that we do not need to wait for any space in
|
|
* the TxFIFO.
|
|
* the TxFIFO.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_send_zlp(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_send_zlp(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_req *req)
|
|
struct s3c_hsotg_req *req)
|
|
{
|
|
{
|
|
u32 ctrl;
|
|
u32 ctrl;
|
|
@@ -1398,7 +1398,7 @@ static void s3c_hsotg_send_zlp(struct s3c_hsotg *hsotg,
|
|
* transfer for an OUT endpoint has been completed, either by a short
|
|
* transfer for an OUT endpoint has been completed, either by a short
|
|
* packet or by the finish of a transfer.
|
|
* packet or by the finish of a transfer.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg,
|
|
int epnum, bool was_setup)
|
|
int epnum, bool was_setup)
|
|
{
|
|
{
|
|
u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum));
|
|
u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum));
|
|
@@ -1471,7 +1471,7 @@ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg,
|
|
*
|
|
*
|
|
* Return the current frame number
|
|
* Return the current frame number
|
|
*/
|
|
*/
|
|
-static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
u32 dsts;
|
|
u32 dsts;
|
|
|
|
|
|
@@ -1498,7 +1498,7 @@ static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg)
|
|
* as the actual data should be sent to the memory directly and we turn
|
|
* as the actual data should be sent to the memory directly and we turn
|
|
* on the completion interrupts to get notifications of transfer completion.
|
|
* on the completion interrupts to get notifications of transfer completion.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
u32 grxstsr = readl(hsotg->regs + GRXSTSP);
|
|
u32 grxstsr = readl(hsotg->regs + GRXSTSP);
|
|
u32 epnum, status, size;
|
|
u32 epnum, status, size;
|
|
@@ -1590,7 +1590,7 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps)
|
|
* Configure the maximum packet size for the given endpoint, updating
|
|
* Configure the maximum packet size for the given endpoint, updating
|
|
* the hardware control registers to reflect this.
|
|
* the hardware control registers to reflect this.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
|
|
unsigned int ep, unsigned int mps)
|
|
unsigned int ep, unsigned int mps)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep];
|
|
struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep];
|
|
@@ -1645,7 +1645,7 @@ bad_mps:
|
|
* @hsotg: The driver state
|
|
* @hsotg: The driver state
|
|
* @idx: The index for the endpoint (0..15)
|
|
* @idx: The index for the endpoint (0..15)
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx)
|
|
|
|
|
|
+static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx)
|
|
{
|
|
{
|
|
int timeout;
|
|
int timeout;
|
|
int val;
|
|
int val;
|
|
@@ -1681,7 +1681,7 @@ static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx)
|
|
* Check to see if there is a request that has data to send, and if so
|
|
* Check to see if there is a request that has data to send, and if so
|
|
* make an attempt to write data into the FIFO.
|
|
* make an attempt to write data into the FIFO.
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *hs_ep)
|
|
struct s3c_hsotg_ep *hs_ep)
|
|
{
|
|
{
|
|
struct s3c_hsotg_req *hs_req = hs_ep->req;
|
|
struct s3c_hsotg_req *hs_req = hs_ep->req;
|
|
@@ -1714,7 +1714,7 @@ static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg,
|
|
* An IN transfer has been completed, update the transfer's state and then
|
|
* An IN transfer has been completed, update the transfer's state and then
|
|
* call the relevant completion routines.
|
|
* call the relevant completion routines.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *hs_ep)
|
|
struct s3c_hsotg_ep *hs_ep)
|
|
{
|
|
{
|
|
struct s3c_hsotg_req *hs_req = hs_ep->req;
|
|
struct s3c_hsotg_req *hs_req = hs_ep->req;
|
|
@@ -1791,7 +1791,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg,
|
|
*
|
|
*
|
|
* Process and clear any interrupt pending for an individual endpoint
|
|
* Process and clear any interrupt pending for an individual endpoint
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
|
|
|
|
|
|
+static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
|
|
int dir_in)
|
|
int dir_in)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx];
|
|
struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx];
|
|
@@ -1916,7 +1916,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
|
|
* Handle updating the device settings after the enumeration phase has
|
|
* Handle updating the device settings after the enumeration phase has
|
|
* been completed.
|
|
* been completed.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
u32 dsts = readl(hsotg->regs + DSTS);
|
|
u32 dsts = readl(hsotg->regs + DSTS);
|
|
int ep0_mps = 0, ep_mps = 8;
|
|
int ep0_mps = 0, ep_mps = 8;
|
|
@@ -1993,7 +1993,7 @@ static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg)
|
|
* Go through the requests on the given endpoint and mark them
|
|
* Go through the requests on the given endpoint and mark them
|
|
* completed with the given result code.
|
|
* completed with the given result code.
|
|
*/
|
|
*/
|
|
-static void kill_all_requests(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void kill_all_requests(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *ep,
|
|
struct s3c_hsotg_ep *ep,
|
|
int result, bool force)
|
|
int result, bool force)
|
|
{
|
|
{
|
|
@@ -2027,22 +2027,27 @@ static void kill_all_requests(struct s3c_hsotg *hsotg,
|
|
* transactions and signal the gadget driver that this
|
|
* transactions and signal the gadget driver that this
|
|
* has happened.
|
|
* has happened.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
unsigned ep;
|
|
unsigned ep;
|
|
|
|
|
|
|
|
+ if (!hsotg->connected)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ hsotg->connected = 0;
|
|
for (ep = 0; ep < hsotg->num_of_eps; ep++)
|
|
for (ep = 0; ep < hsotg->num_of_eps; ep++)
|
|
kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true);
|
|
kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true);
|
|
|
|
|
|
call_gadget(hsotg, disconnect);
|
|
call_gadget(hsotg, disconnect);
|
|
}
|
|
}
|
|
|
|
+EXPORT_SYMBOL_GPL(s3c_hsotg_disconnect);
|
|
|
|
|
|
/**
|
|
/**
|
|
* s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler
|
|
* s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler
|
|
* @hsotg: The device state:
|
|
* @hsotg: The device state:
|
|
* @periodic: True if this is a periodic FIFO interrupt
|
|
* @periodic: True if this is a periodic FIFO interrupt
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic)
|
|
|
|
|
|
+static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *ep;
|
|
struct s3c_hsotg_ep *ep;
|
|
int epno, ret;
|
|
int epno, ret;
|
|
@@ -2076,7 +2081,7 @@ static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic)
|
|
*
|
|
*
|
|
* Issue a soft reset to the core, and await the core finishing it.
|
|
* Issue a soft reset to the core, and await the core finishing it.
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
int timeout;
|
|
int timeout;
|
|
u32 grstctl;
|
|
u32 grstctl;
|
|
@@ -2124,7 +2129,7 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg)
|
|
*
|
|
*
|
|
* Issue a soft reset to the core, and await the core finishing it.
|
|
* Issue a soft reset to the core, and await the core finishing it.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
s3c_hsotg_corereset(hsotg);
|
|
s3c_hsotg_corereset(hsotg);
|
|
|
|
|
|
@@ -2241,12 +2246,23 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg)
|
|
readl(hsotg->regs + DOEPCTL0));
|
|
readl(hsotg->regs + DOEPCTL0));
|
|
|
|
|
|
/* clear global NAKs */
|
|
/* clear global NAKs */
|
|
- writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK,
|
|
|
|
|
|
+ writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK | DCTL_SFTDISCON,
|
|
hsotg->regs + DCTL);
|
|
hsotg->regs + DCTL);
|
|
|
|
|
|
/* must be at-least 3ms to allow bus to see disconnect */
|
|
/* must be at-least 3ms to allow bus to see disconnect */
|
|
mdelay(3);
|
|
mdelay(3);
|
|
|
|
|
|
|
|
+ hsotg->last_rst = jiffies;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void s3c_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)
|
|
|
|
+{
|
|
|
|
+ /* set the soft-disconnect bit */
|
|
|
|
+ __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg)
|
|
|
|
+{
|
|
/* remove the soft-disconnect and let's go */
|
|
/* remove the soft-disconnect and let's go */
|
|
__bic32(hsotg->regs + DCTL, DCTL_SFTDISCON);
|
|
__bic32(hsotg->regs + DCTL, DCTL_SFTDISCON);
|
|
}
|
|
}
|
|
@@ -2258,7 +2274,7 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg)
|
|
*/
|
|
*/
|
|
static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
|
|
static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = pw;
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = pw;
|
|
int retry_count = 8;
|
|
int retry_count = 8;
|
|
u32 gintsts;
|
|
u32 gintsts;
|
|
u32 gintmsk;
|
|
u32 gintmsk;
|
|
@@ -2273,31 +2289,11 @@ irq_retry:
|
|
|
|
|
|
gintsts &= gintmsk;
|
|
gintsts &= gintmsk;
|
|
|
|
|
|
- if (gintsts & GINTSTS_OTGINT) {
|
|
|
|
- u32 otgint = readl(hsotg->regs + GOTGINT);
|
|
|
|
-
|
|
|
|
- dev_info(hsotg->dev, "OTGInt: %08x\n", otgint);
|
|
|
|
-
|
|
|
|
- writel(otgint, hsotg->regs + GOTGINT);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (gintsts & GINTSTS_SESSREQINT) {
|
|
|
|
- dev_dbg(hsotg->dev, "%s: SessReqInt\n", __func__);
|
|
|
|
- writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (gintsts & GINTSTS_ENUMDONE) {
|
|
if (gintsts & GINTSTS_ENUMDONE) {
|
|
writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
|
|
writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
|
|
|
|
|
|
s3c_hsotg_irq_enumdone(hsotg);
|
|
s3c_hsotg_irq_enumdone(hsotg);
|
|
- }
|
|
|
|
-
|
|
|
|
- if (gintsts & GINTSTS_CONIDSTSCHNG) {
|
|
|
|
- dev_dbg(hsotg->dev, "ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n",
|
|
|
|
- readl(hsotg->regs + DSTS),
|
|
|
|
- readl(hsotg->regs + GOTGCTL));
|
|
|
|
-
|
|
|
|
- writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS);
|
|
|
|
|
|
+ hsotg->connected = 1;
|
|
}
|
|
}
|
|
|
|
|
|
if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {
|
|
if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {
|
|
@@ -2340,8 +2336,8 @@ irq_retry:
|
|
kill_all_requests(hsotg, &hsotg->eps[0],
|
|
kill_all_requests(hsotg, &hsotg->eps[0],
|
|
-ECONNRESET, true);
|
|
-ECONNRESET, true);
|
|
|
|
|
|
- s3c_hsotg_core_init(hsotg);
|
|
|
|
- hsotg->last_rst = jiffies;
|
|
|
|
|
|
+ s3c_hsotg_core_init_disconnected(hsotg);
|
|
|
|
+ s3c_hsotg_core_connect(hsotg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2380,25 +2376,6 @@ irq_retry:
|
|
s3c_hsotg_handle_rx(hsotg);
|
|
s3c_hsotg_handle_rx(hsotg);
|
|
}
|
|
}
|
|
|
|
|
|
- if (gintsts & GINTSTS_MODEMIS) {
|
|
|
|
- dev_warn(hsotg->dev, "warning, mode mismatch triggered\n");
|
|
|
|
- writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (gintsts & GINTSTS_USBSUSP) {
|
|
|
|
- dev_info(hsotg->dev, "GINTSTS_USBSusp\n");
|
|
|
|
- writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS);
|
|
|
|
-
|
|
|
|
- call_gadget(hsotg, suspend);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (gintsts & GINTSTS_WKUPINT) {
|
|
|
|
- dev_info(hsotg->dev, "GINTSTS_WkUpIn\n");
|
|
|
|
- writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
|
|
|
|
-
|
|
|
|
- call_gadget(hsotg, resume);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (gintsts & GINTSTS_ERLYSUSP) {
|
|
if (gintsts & GINTSTS_ERLYSUSP) {
|
|
dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
|
|
dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
|
|
writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS);
|
|
writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS);
|
|
@@ -2450,7 +2427,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
|
|
const struct usb_endpoint_descriptor *desc)
|
|
const struct usb_endpoint_descriptor *desc)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hsotg = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = hs_ep->parent;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
int index = hs_ep->index;
|
|
int index = hs_ep->index;
|
|
u32 epctrl_reg;
|
|
u32 epctrl_reg;
|
|
@@ -2593,7 +2570,7 @@ error:
|
|
static int s3c_hsotg_ep_disable(struct usb_ep *ep)
|
|
static int s3c_hsotg_ep_disable(struct usb_ep *ep)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hsotg = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = hs_ep->parent;
|
|
int dir_in = hs_ep->dir_in;
|
|
int dir_in = hs_ep->dir_in;
|
|
int index = hs_ep->index;
|
|
int index = hs_ep->index;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
@@ -2658,7 +2635,7 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
|
|
{
|
|
{
|
|
struct s3c_hsotg_req *hs_req = our_req(req);
|
|
struct s3c_hsotg_req *hs_req = our_req(req);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hs = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hs = hs_ep->parent;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
dev_dbg(hs->dev, "ep_dequeue(%p,%p)\n", ep, req);
|
|
dev_dbg(hs->dev, "ep_dequeue(%p,%p)\n", ep, req);
|
|
@@ -2684,7 +2661,7 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
|
|
static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
|
|
static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hs = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hs = hs_ep->parent;
|
|
int index = hs_ep->index;
|
|
int index = hs_ep->index;
|
|
u32 epreg;
|
|
u32 epreg;
|
|
u32 epctl;
|
|
u32 epctl;
|
|
@@ -2748,7 +2725,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
|
|
static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
|
|
static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
struct s3c_hsotg_ep *hs_ep = our_ep(ep);
|
|
- struct s3c_hsotg *hs = hs_ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hs = hs_ep->parent;
|
|
unsigned long flags = 0;
|
|
unsigned long flags = 0;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
@@ -2777,7 +2754,7 @@ static struct usb_ep_ops s3c_hsotg_ep_ops = {
|
|
* A wrapper for platform code responsible for controlling
|
|
* A wrapper for platform code responsible for controlling
|
|
* low-level USB code
|
|
* low-level USB code
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_phy_enable(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
struct platform_device *pdev = to_platform_device(hsotg->dev);
|
|
struct platform_device *pdev = to_platform_device(hsotg->dev);
|
|
|
|
|
|
@@ -2800,7 +2777,7 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
|
|
* A wrapper for platform code responsible for controlling
|
|
* A wrapper for platform code responsible for controlling
|
|
* low-level USB code
|
|
* low-level USB code
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_phy_disable(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
struct platform_device *pdev = to_platform_device(hsotg->dev);
|
|
struct platform_device *pdev = to_platform_device(hsotg->dev);
|
|
|
|
|
|
@@ -2818,7 +2795,7 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
|
|
* s3c_hsotg_init - initalize the usb core
|
|
* s3c_hsotg_init - initalize the usb core
|
|
* @hsotg: The driver state
|
|
* @hsotg: The driver state
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_init(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
/* unmask subset of endpoint interrupts */
|
|
/* unmask subset of endpoint interrupts */
|
|
|
|
|
|
@@ -2868,7 +2845,8 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
|
|
static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
|
|
static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
|
|
struct usb_gadget_driver *driver)
|
|
struct usb_gadget_driver *driver)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = to_hsotg(gadget);
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = to_hsotg(gadget);
|
|
|
|
+ unsigned long flags;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
if (!hsotg) {
|
|
if (!hsotg) {
|
|
@@ -2889,6 +2867,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ mutex_lock(&hsotg->init_mutex);
|
|
WARN_ON(hsotg->driver);
|
|
WARN_ON(hsotg->driver);
|
|
|
|
|
|
driver->driver.bus = NULL;
|
|
driver->driver.bus = NULL;
|
|
@@ -2905,11 +2884,22 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
|
|
goto err;
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
|
|
- hsotg->last_rst = jiffies;
|
|
|
|
|
|
+ s3c_hsotg_phy_enable(hsotg);
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&hsotg->lock, flags);
|
|
|
|
+ s3c_hsotg_init(hsotg);
|
|
|
|
+ s3c_hsotg_core_init_disconnected(hsotg);
|
|
|
|
+ hsotg->enabled = 0;
|
|
|
|
+ spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
|
|
+
|
|
dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
|
|
dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
|
|
|
|
+
|
|
|
|
+ mutex_unlock(&hsotg->init_mutex);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
err:
|
|
err:
|
|
|
|
+ mutex_unlock(&hsotg->init_mutex);
|
|
hsotg->driver = NULL;
|
|
hsotg->driver = NULL;
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -2921,16 +2911,17 @@ err:
|
|
*
|
|
*
|
|
* Stop udc hw block and stay tunned for future transmissions
|
|
* Stop udc hw block and stay tunned for future transmissions
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
|
|
|
|
- struct usb_gadget_driver *driver)
|
|
|
|
|
|
+static int s3c_hsotg_udc_stop(struct usb_gadget *gadget)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = to_hsotg(gadget);
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = to_hsotg(gadget);
|
|
unsigned long flags = 0;
|
|
unsigned long flags = 0;
|
|
int ep;
|
|
int ep;
|
|
|
|
|
|
if (!hsotg)
|
|
if (!hsotg)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
+ mutex_lock(&hsotg->init_mutex);
|
|
|
|
+
|
|
/* all endpoints should be shutdown */
|
|
/* all endpoints should be shutdown */
|
|
for (ep = 1; ep < hsotg->num_of_eps; ep++)
|
|
for (ep = 1; ep < hsotg->num_of_eps; ep++)
|
|
s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
|
|
s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
|
|
@@ -2939,13 +2930,18 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
|
|
|
|
|
|
hsotg->driver = NULL;
|
|
hsotg->driver = NULL;
|
|
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
|
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
|
|
|
+ hsotg->enabled = 0;
|
|
|
|
|
|
spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
|
|
|
|
|
|
+ s3c_hsotg_phy_disable(hsotg);
|
|
|
|
+
|
|
regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
|
|
regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
|
|
|
|
|
|
clk_disable(hsotg->clk);
|
|
clk_disable(hsotg->clk);
|
|
|
|
|
|
|
|
+ mutex_unlock(&hsotg->init_mutex);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2969,23 +2965,26 @@ static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget)
|
|
*/
|
|
*/
|
|
static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on)
|
|
static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = to_hsotg(gadget);
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = to_hsotg(gadget);
|
|
unsigned long flags = 0;
|
|
unsigned long flags = 0;
|
|
|
|
|
|
dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on);
|
|
dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on);
|
|
|
|
|
|
|
|
+ mutex_lock(&hsotg->init_mutex);
|
|
spin_lock_irqsave(&hsotg->lock, flags);
|
|
spin_lock_irqsave(&hsotg->lock, flags);
|
|
if (is_on) {
|
|
if (is_on) {
|
|
- s3c_hsotg_phy_enable(hsotg);
|
|
|
|
clk_enable(hsotg->clk);
|
|
clk_enable(hsotg->clk);
|
|
- s3c_hsotg_core_init(hsotg);
|
|
|
|
|
|
+ hsotg->enabled = 1;
|
|
|
|
+ s3c_hsotg_core_connect(hsotg);
|
|
} else {
|
|
} else {
|
|
|
|
+ s3c_hsotg_core_disconnect(hsotg);
|
|
|
|
+ hsotg->enabled = 0;
|
|
clk_disable(hsotg->clk);
|
|
clk_disable(hsotg->clk);
|
|
- s3c_hsotg_phy_disable(hsotg);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
|
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
|
spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
|
|
+ mutex_unlock(&hsotg->init_mutex);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -3007,7 +3006,7 @@ static const struct usb_gadget_ops s3c_hsotg_gadget_ops = {
|
|
* creation) to give to the gadget driver. Setup the endpoint name, any
|
|
* creation) to give to the gadget driver. Setup the endpoint name, any
|
|
* direction information and other state that may be required.
|
|
* direction information and other state that may be required.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_initep(struct s3c_hsotg *hsotg,
|
|
|
|
|
|
+static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
struct s3c_hsotg_ep *hs_ep,
|
|
int epnum)
|
|
int epnum)
|
|
{
|
|
{
|
|
@@ -3056,7 +3055,7 @@ static void s3c_hsotg_initep(struct s3c_hsotg *hsotg,
|
|
*
|
|
*
|
|
* Read the USB core HW configuration registers
|
|
* Read the USB core HW configuration registers
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_hw_cfg(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
u32 cfg2, cfg3, cfg4;
|
|
u32 cfg2, cfg3, cfg4;
|
|
/* check hardware configuration */
|
|
/* check hardware configuration */
|
|
@@ -3080,7 +3079,7 @@ static void s3c_hsotg_hw_cfg(struct s3c_hsotg *hsotg)
|
|
* s3c_hsotg_dump - dump state of the udc
|
|
* s3c_hsotg_dump - dump state of the udc
|
|
* @param: The device state
|
|
* @param: The device state
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_dump(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
#ifdef DEBUG
|
|
#ifdef DEBUG
|
|
struct device *dev = hsotg->dev;
|
|
struct device *dev = hsotg->dev;
|
|
@@ -3139,7 +3138,7 @@ static void s3c_hsotg_dump(struct s3c_hsotg *hsotg)
|
|
*/
|
|
*/
|
|
static int state_show(struct seq_file *seq, void *v)
|
|
static int state_show(struct seq_file *seq, void *v)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = seq->private;
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = seq->private;
|
|
void __iomem *regs = hsotg->regs;
|
|
void __iomem *regs = hsotg->regs;
|
|
int idx;
|
|
int idx;
|
|
|
|
|
|
@@ -3209,7 +3208,7 @@ static const struct file_operations state_fops = {
|
|
*/
|
|
*/
|
|
static int fifo_show(struct seq_file *seq, void *v)
|
|
static int fifo_show(struct seq_file *seq, void *v)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = seq->private;
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = seq->private;
|
|
void __iomem *regs = hsotg->regs;
|
|
void __iomem *regs = hsotg->regs;
|
|
u32 val;
|
|
u32 val;
|
|
int idx;
|
|
int idx;
|
|
@@ -3265,7 +3264,7 @@ static const char *decode_direction(int is_in)
|
|
static int ep_show(struct seq_file *seq, void *v)
|
|
static int ep_show(struct seq_file *seq, void *v)
|
|
{
|
|
{
|
|
struct s3c_hsotg_ep *ep = seq->private;
|
|
struct s3c_hsotg_ep *ep = seq->private;
|
|
- struct s3c_hsotg *hsotg = ep->parent;
|
|
|
|
|
|
+ struct dwc2_hsotg *hsotg = ep->parent;
|
|
struct s3c_hsotg_req *req;
|
|
struct s3c_hsotg_req *req;
|
|
void __iomem *regs = hsotg->regs;
|
|
void __iomem *regs = hsotg->regs;
|
|
int index = ep->index;
|
|
int index = ep->index;
|
|
@@ -3342,7 +3341,7 @@ static const struct file_operations ep_fops = {
|
|
* with the same name as the device itself, in case we end up
|
|
* with the same name as the device itself, in case we end up
|
|
* with multiple blocks in future systems.
|
|
* with multiple blocks in future systems.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
struct dentry *root;
|
|
struct dentry *root;
|
|
unsigned epidx;
|
|
unsigned epidx;
|
|
@@ -3388,7 +3387,7 @@ static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg)
|
|
*
|
|
*
|
|
* Cleanup (remove) the debugfs files for use on module exit.
|
|
* Cleanup (remove) the debugfs files for use on module exit.
|
|
*/
|
|
*/
|
|
-static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
|
|
|
|
|
|
+static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
unsigned epidx;
|
|
unsigned epidx;
|
|
|
|
|
|
@@ -3403,27 +3402,21 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * s3c_hsotg_probe - probe function for hsotg driver
|
|
|
|
- * @pdev: The platform information for the driver
|
|
|
|
|
|
+ * dwc2_gadget_init - init function for gadget
|
|
|
|
+ * @dwc2: The data structure for the DWC2 driver.
|
|
|
|
+ * @irq: The IRQ number for the controller.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
-static int s3c_hsotg_probe(struct platform_device *pdev)
|
|
|
|
|
|
+int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
|
|
{
|
|
{
|
|
- struct s3c_hsotg_plat *plat = dev_get_platdata(&pdev->dev);
|
|
|
|
|
|
+ struct device *dev = hsotg->dev;
|
|
|
|
+ struct s3c_hsotg_plat *plat = dev->platform_data;
|
|
struct phy *phy;
|
|
struct phy *phy;
|
|
struct usb_phy *uphy;
|
|
struct usb_phy *uphy;
|
|
- struct device *dev = &pdev->dev;
|
|
|
|
struct s3c_hsotg_ep *eps;
|
|
struct s3c_hsotg_ep *eps;
|
|
- struct s3c_hsotg *hsotg;
|
|
|
|
- struct resource *res;
|
|
|
|
int epnum;
|
|
int epnum;
|
|
int ret;
|
|
int ret;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL);
|
|
|
|
- if (!hsotg)
|
|
|
|
- return -ENOMEM;
|
|
|
|
-
|
|
|
|
/* Set default UTMI width */
|
|
/* Set default UTMI width */
|
|
hsotg->phyif = GUSBCFG_PHYIF16;
|
|
hsotg->phyif = GUSBCFG_PHYIF16;
|
|
|
|
|
|
@@ -3431,14 +3424,14 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
|
|
* Attempt to find a generic PHY, then look for an old style
|
|
* Attempt to find a generic PHY, then look for an old style
|
|
* USB PHY, finally fall back to pdata
|
|
* USB PHY, finally fall back to pdata
|
|
*/
|
|
*/
|
|
- phy = devm_phy_get(&pdev->dev, "usb2-phy");
|
|
|
|
|
|
+ phy = devm_phy_get(dev, "usb2-phy");
|
|
if (IS_ERR(phy)) {
|
|
if (IS_ERR(phy)) {
|
|
uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
|
|
uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
|
|
if (IS_ERR(uphy)) {
|
|
if (IS_ERR(uphy)) {
|
|
/* Fallback for pdata */
|
|
/* Fallback for pdata */
|
|
- plat = dev_get_platdata(&pdev->dev);
|
|
|
|
|
|
+ plat = dev_get_platdata(dev);
|
|
if (!plat) {
|
|
if (!plat) {
|
|
- dev_err(&pdev->dev,
|
|
|
|
|
|
+ dev_err(dev,
|
|
"no platform data or transceiver defined\n");
|
|
"no platform data or transceiver defined\n");
|
|
return -EPROBE_DEFER;
|
|
return -EPROBE_DEFER;
|
|
}
|
|
}
|
|
@@ -3455,43 +3448,24 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
|
|
hsotg->phyif = GUSBCFG_PHYIF8;
|
|
hsotg->phyif = GUSBCFG_PHYIF8;
|
|
}
|
|
}
|
|
|
|
|
|
- hsotg->dev = dev;
|
|
|
|
-
|
|
|
|
- hsotg->clk = devm_clk_get(&pdev->dev, "otg");
|
|
|
|
|
|
+ hsotg->clk = devm_clk_get(dev, "otg");
|
|
if (IS_ERR(hsotg->clk)) {
|
|
if (IS_ERR(hsotg->clk)) {
|
|
- dev_err(dev, "cannot get otg clock\n");
|
|
|
|
- return PTR_ERR(hsotg->clk);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- platform_set_drvdata(pdev, hsotg);
|
|
|
|
-
|
|
|
|
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
|
-
|
|
|
|
- hsotg->regs = devm_ioremap_resource(&pdev->dev, res);
|
|
|
|
- if (IS_ERR(hsotg->regs)) {
|
|
|
|
- ret = PTR_ERR(hsotg->regs);
|
|
|
|
- goto err_clk;
|
|
|
|
|
|
+ hsotg->clk = NULL;
|
|
|
|
+ dev_dbg(dev, "cannot get otg clock\n");
|
|
}
|
|
}
|
|
|
|
|
|
- ret = platform_get_irq(pdev, 0);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- dev_err(dev, "cannot find IRQ\n");
|
|
|
|
- goto err_clk;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- spin_lock_init(&hsotg->lock);
|
|
|
|
-
|
|
|
|
- hsotg->irq = ret;
|
|
|
|
-
|
|
|
|
- dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq);
|
|
|
|
-
|
|
|
|
hsotg->gadget.max_speed = USB_SPEED_HIGH;
|
|
hsotg->gadget.max_speed = USB_SPEED_HIGH;
|
|
hsotg->gadget.ops = &s3c_hsotg_gadget_ops;
|
|
hsotg->gadget.ops = &s3c_hsotg_gadget_ops;
|
|
hsotg->gadget.name = dev_name(dev);
|
|
hsotg->gadget.name = dev_name(dev);
|
|
|
|
|
|
/* reset the system */
|
|
/* reset the system */
|
|
|
|
|
|
- clk_prepare_enable(hsotg->clk);
|
|
|
|
|
|
+ ret = clk_prepare_enable(hsotg->clk);
|
|
|
|
+ if (ret) {
|
|
|
|
+ dev_err(dev, "failed to enable otg clk\n");
|
|
|
|
+ goto err_clk;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
/* regulators */
|
|
/* regulators */
|
|
|
|
|
|
@@ -3509,7 +3483,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
|
|
hsotg->supplies);
|
|
hsotg->supplies);
|
|
|
|
|
|
if (ret) {
|
|
if (ret) {
|
|
- dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret);
|
|
|
|
|
|
+ dev_err(dev, "failed to enable supplies: %d\n", ret);
|
|
goto err_supplies;
|
|
goto err_supplies;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3520,14 +3494,14 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
|
|
s3c_hsotg_hw_cfg(hsotg);
|
|
s3c_hsotg_hw_cfg(hsotg);
|
|
s3c_hsotg_init(hsotg);
|
|
s3c_hsotg_init(hsotg);
|
|
|
|
|
|
- ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0,
|
|
|
|
- dev_name(dev), hsotg);
|
|
|
|
|
|
+ ret = devm_request_irq(hsotg->dev, irq, s3c_hsotg_irq, IRQF_SHARED,
|
|
|
|
+ dev_name(hsotg->dev), hsotg);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
s3c_hsotg_phy_disable(hsotg);
|
|
s3c_hsotg_phy_disable(hsotg);
|
|
clk_disable_unprepare(hsotg->clk);
|
|
clk_disable_unprepare(hsotg->clk);
|
|
regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
|
|
regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
|
|
hsotg->supplies);
|
|
hsotg->supplies);
|
|
- dev_err(dev, "cannot claim IRQ\n");
|
|
|
|
|
|
+ dev_err(dev, "cannot claim IRQ for gadget\n");
|
|
goto err_clk;
|
|
goto err_clk;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3573,11 +3547,11 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
|
|
ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
|
|
ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
|
|
hsotg->supplies);
|
|
hsotg->supplies);
|
|
if (ret) {
|
|
if (ret) {
|
|
- dev_err(hsotg->dev, "failed to disable supplies: %d\n", ret);
|
|
|
|
|
|
+ dev_err(dev, "failed to disable supplies: %d\n", ret);
|
|
goto err_ep_mem;
|
|
goto err_ep_mem;
|
|
}
|
|
}
|
|
|
|
|
|
- ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
|
|
|
|
|
|
+ ret = usb_add_gadget_udc(dev, &hsotg->gadget);
|
|
if (ret)
|
|
if (ret)
|
|
goto err_ep_mem;
|
|
goto err_ep_mem;
|
|
|
|
|
|
@@ -3596,47 +3570,44 @@ err_clk:
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
+EXPORT_SYMBOL_GPL(dwc2_gadget_init);
|
|
|
|
|
|
/**
|
|
/**
|
|
* s3c_hsotg_remove - remove function for hsotg driver
|
|
* s3c_hsotg_remove - remove function for hsotg driver
|
|
* @pdev: The platform information for the driver
|
|
* @pdev: The platform information for the driver
|
|
*/
|
|
*/
|
|
-static int s3c_hsotg_remove(struct platform_device *pdev)
|
|
|
|
|
|
+int s3c_hsotg_remove(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
|
|
|
|
-
|
|
|
|
usb_del_gadget_udc(&hsotg->gadget);
|
|
usb_del_gadget_udc(&hsotg->gadget);
|
|
-
|
|
|
|
s3c_hsotg_delete_debug(hsotg);
|
|
s3c_hsotg_delete_debug(hsotg);
|
|
-
|
|
|
|
- if (hsotg->driver) {
|
|
|
|
- /* should have been done already by driver model core */
|
|
|
|
- usb_gadget_unregister_driver(hsotg->driver);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
clk_disable_unprepare(hsotg->clk);
|
|
clk_disable_unprepare(hsotg->clk);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+EXPORT_SYMBOL_GPL(s3c_hsotg_remove);
|
|
|
|
|
|
-static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state)
|
|
|
|
|
|
+int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
- if (hsotg->driver)
|
|
|
|
|
|
+ mutex_lock(&hsotg->init_mutex);
|
|
|
|
+
|
|
|
|
+ if (hsotg->driver) {
|
|
|
|
+ int ep;
|
|
|
|
+
|
|
dev_info(hsotg->dev, "suspending usb gadget %s\n",
|
|
dev_info(hsotg->dev, "suspending usb gadget %s\n",
|
|
hsotg->driver->driver.name);
|
|
hsotg->driver->driver.name);
|
|
|
|
|
|
- spin_lock_irqsave(&hsotg->lock, flags);
|
|
|
|
- s3c_hsotg_disconnect(hsotg);
|
|
|
|
- s3c_hsotg_phy_disable(hsotg);
|
|
|
|
- hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
|
|
|
- spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
|
|
|
|
+ spin_lock_irqsave(&hsotg->lock, flags);
|
|
|
|
+ if (hsotg->enabled)
|
|
|
|
+ s3c_hsotg_core_disconnect(hsotg);
|
|
|
|
+ s3c_hsotg_disconnect(hsotg);
|
|
|
|
+ hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
|
|
|
+ spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
|
|
+
|
|
|
|
+ s3c_hsotg_phy_disable(hsotg);
|
|
|
|
|
|
- if (hsotg->driver) {
|
|
|
|
- int ep;
|
|
|
|
for (ep = 0; ep < hsotg->num_of_eps; ep++)
|
|
for (ep = 0; ep < hsotg->num_of_eps; ep++)
|
|
s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
|
|
s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
|
|
|
|
|
|
@@ -3645,57 +3616,37 @@ static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state)
|
|
clk_disable(hsotg->clk);
|
|
clk_disable(hsotg->clk);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ mutex_unlock(&hsotg->init_mutex);
|
|
|
|
+
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
+EXPORT_SYMBOL_GPL(s3c_hsotg_suspend);
|
|
|
|
|
|
-static int s3c_hsotg_resume(struct platform_device *pdev)
|
|
|
|
|
|
+int s3c_hsotg_resume(struct dwc2_hsotg *hsotg)
|
|
{
|
|
{
|
|
- struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
|
|
+ mutex_lock(&hsotg->init_mutex);
|
|
|
|
+
|
|
if (hsotg->driver) {
|
|
if (hsotg->driver) {
|
|
dev_info(hsotg->dev, "resuming usb gadget %s\n",
|
|
dev_info(hsotg->dev, "resuming usb gadget %s\n",
|
|
hsotg->driver->driver.name);
|
|
hsotg->driver->driver.name);
|
|
|
|
|
|
clk_enable(hsotg->clk);
|
|
clk_enable(hsotg->clk);
|
|
ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
|
|
ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
|
|
- hsotg->supplies);
|
|
|
|
- }
|
|
|
|
|
|
+ hsotg->supplies);
|
|
|
|
|
|
- spin_lock_irqsave(&hsotg->lock, flags);
|
|
|
|
- hsotg->last_rst = jiffies;
|
|
|
|
- s3c_hsotg_phy_enable(hsotg);
|
|
|
|
- s3c_hsotg_core_init(hsotg);
|
|
|
|
- spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
|
|
|
|
+ s3c_hsotg_phy_enable(hsotg);
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&hsotg->lock, flags);
|
|
|
|
+ s3c_hsotg_core_init_disconnected(hsotg);
|
|
|
|
+ if (hsotg->enabled)
|
|
|
|
+ s3c_hsotg_core_connect(hsotg);
|
|
|
|
+ spin_unlock_irqrestore(&hsotg->lock, flags);
|
|
|
|
+ }
|
|
|
|
+ mutex_unlock(&hsotg->init_mutex);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
-
|
|
|
|
-#ifdef CONFIG_OF
|
|
|
|
-static const struct of_device_id s3c_hsotg_of_ids[] = {
|
|
|
|
- { .compatible = "samsung,s3c6400-hsotg", },
|
|
|
|
- { .compatible = "snps,dwc2", },
|
|
|
|
- { /* sentinel */ }
|
|
|
|
-};
|
|
|
|
-MODULE_DEVICE_TABLE(of, s3c_hsotg_of_ids);
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-static struct platform_driver s3c_hsotg_driver = {
|
|
|
|
- .driver = {
|
|
|
|
- .name = "s3c-hsotg",
|
|
|
|
- .owner = THIS_MODULE,
|
|
|
|
- .of_match_table = of_match_ptr(s3c_hsotg_of_ids),
|
|
|
|
- },
|
|
|
|
- .probe = s3c_hsotg_probe,
|
|
|
|
- .remove = s3c_hsotg_remove,
|
|
|
|
- .suspend = s3c_hsotg_suspend,
|
|
|
|
- .resume = s3c_hsotg_resume,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-module_platform_driver(s3c_hsotg_driver);
|
|
|
|
-
|
|
|
|
-MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device");
|
|
|
|
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
|
|
|
|
-MODULE_LICENSE("GPL");
|
|
|
|
-MODULE_ALIAS("platform:s3c-hsotg");
|
|
|
|
|
|
+EXPORT_SYMBOL_GPL(s3c_hsotg_resume);
|