提交 bc46e23c 编写于 作者: G Greg Kroah-Hartman

Merge tag 'usb-for-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next

Felipe writes:

USB: changes for v4.11

Here's the big pull request for the Gadget
API. Again the majority of changes sit in dwc2
driver. Most important changes contain a workaround
for GOTGCTL being wrong, a sleep-inside-spinlock fix
and the big series of cleanups on dwc2.

One important thing on dwc3 is that we don't anymore
need gadget drivers to cope with unaligned OUT
transfers for us. We have support for appending one
extra chained TRB to align transfer ourselves.

Apart from these, the usual set of typos,
non-critical fixes, etc.
...@@ -20,10 +20,10 @@ See: Documentation/devicetree/bindings/reset/reset.txt ...@@ -20,10 +20,10 @@ See: Documentation/devicetree/bindings/reset/reset.txt
with 'reg' property with 'reg' property
- pinctl-names : A pinctrl state named "default" must be defined - pinctl-names : A pinctrl state named "default" must be defined
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
- pinctrl-0 : Pin control group - pinctrl-0 : Pin control group
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
- ranges : allows valid 1:1 translation between child's address space and - ranges : allows valid 1:1 translation between child's address space and
parent's address space parent's address space
......
...@@ -56,6 +56,10 @@ Optional properties: ...@@ -56,6 +56,10 @@ Optional properties:
- <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated. - <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated.
- in addition all properties from usb-xhci.txt from the current directory are
supported as well
This is usually a subnode to DWC3 glue to which it is connected. This is usually a subnode to DWC3 glue to which it is connected.
dwc3@4a030000 { dwc3@4a030000 {
......
...@@ -7,7 +7,7 @@ Required properties: ...@@ -7,7 +7,7 @@ Required properties:
- interrupts : one EHCI interrupt should be described here - interrupts : one EHCI interrupt should be described here
- pinctrl-names : a pinctrl state named "default" must be defined - pinctrl-names : a pinctrl state named "default" must be defined
- pinctrl-0 : phandle referencing pin configuration of the USB controller - pinctrl-0 : phandle referencing pin configuration of the USB controller
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
- clocks : phandle list of usb clocks - clocks : phandle list of usb clocks
- clock-names : should be "ic" for interconnect clock and "clk48" - clock-names : should be "ic" for interconnect clock and "clk48"
See: Documentation/devicetree/bindings/clock/clock-bindings.txt See: Documentation/devicetree/bindings/clock/clock-bindings.txt
......
...@@ -30,7 +30,7 @@ Optional properties: ...@@ -30,7 +30,7 @@ Optional properties:
"id_float" and "id_ground" are optinal which depends on "id_float" and "id_ground" are optinal which depends on
"mediatek,enable-manual-drd" "mediatek,enable-manual-drd"
- pinctrl-0 : pin control group - pinctrl-0 : pin control group
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
- maximum-speed : valid arguments are "super-speed", "high-speed" and - maximum-speed : valid arguments are "super-speed", "high-speed" and
"full-speed"; refer to usb/generic.txt "full-speed"; refer to usb/generic.txt
......
...@@ -38,7 +38,7 @@ Optional properties: ...@@ -38,7 +38,7 @@ Optional properties:
- usb3-lpm-capable : supports USB3.0 LPM - usb3-lpm-capable : supports USB3.0 LPM
- pinctrl-names : a pinctrl state named "default" must be defined - pinctrl-names : a pinctrl state named "default" must be defined
- pinctrl-0 : pin control group - pinctrl-0 : pin control group
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
Example: Example:
usb30: usb@11270000 { usb30: usb@11270000 {
...@@ -68,7 +68,7 @@ usb30: usb@11270000 { ...@@ -68,7 +68,7 @@ usb30: usb@11270000 {
In the case, xhci is added as subnode to mtu3. An example and the DT binding In the case, xhci is added as subnode to mtu3. An example and the DT binding
details of mtu3 can be found in: details of mtu3 can be found in:
Documentation/devicetree/bindings/usb/mtu3.txt Documentation/devicetree/bindings/usb/mt8173-mtu3.txt
Required properties: Required properties:
- compatible : should contain "mediatek,mt8173-xhci" - compatible : should contain "mediatek,mt8173-xhci"
......
...@@ -18,7 +18,7 @@ A child node must exist to represent the core DWC3 IP block. The name of ...@@ -18,7 +18,7 @@ A child node must exist to represent the core DWC3 IP block. The name of
the node is not important. The content of the node is defined in dwc3.txt. the node is not important. The content of the node is defined in dwc3.txt.
Phy documentation is provided in the following places: Phy documentation is provided in the following places:
Documentation/devicetree/bindings/phy/qcom,dwc3-usb-phy.txt Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
Example device nodes: Example device nodes:
......
...@@ -632,6 +632,8 @@ The uac2 function provides these attributes in its function directory: ...@@ -632,6 +632,8 @@ The uac2 function provides these attributes in its function directory:
p_chmask - playback channel mask p_chmask - playback channel mask
p_srate - playback sampling rate p_srate - playback sampling rate
p_ssize - playback sample size (bytes) p_ssize - playback sample size (bytes)
req_number - the number of pre-allocated request for both capture
and playback
The attributes have sane default values. The attributes have sane default values.
......
...@@ -313,7 +313,7 @@ static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg) ...@@ -313,7 +313,7 @@ static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg)
* Do core a soft reset of the core. Be careful with this because it * Do core a soft reset of the core. Be careful with this because it
* resets all the internal state machines of the core. * resets all the internal state machines of the core.
*/ */
int dwc2_core_reset(struct dwc2_hsotg *hsotg) int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait)
{ {
u32 greset; u32 greset;
int count = 0; int count = 0;
...@@ -369,7 +369,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) ...@@ -369,7 +369,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg)
} }
} while (!(greset & GRSTCTL_AHBIDLE)); } while (!(greset & GRSTCTL_AHBIDLE));
if (wait_for_host_mode) if (wait_for_host_mode && !skip_wait)
dwc2_wait_for_mode(hsotg, true); dwc2_wait_for_mode(hsotg, true);
return 0; return 0;
...@@ -455,7 +455,7 @@ void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) ...@@ -455,7 +455,7 @@ void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
if (dwc2_iddig_filter_enabled(hsotg)) if (dwc2_iddig_filter_enabled(hsotg))
usleep_range(100000, 110000); msleep(100);
} }
/* /*
...@@ -500,7 +500,7 @@ int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg) ...@@ -500,7 +500,7 @@ int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg)
{ {
int retval; int retval;
retval = dwc2_core_reset(hsotg); retval = dwc2_core_reset(hsotg, false);
if (retval) if (retval)
return retval; return retval;
...@@ -541,7 +541,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg) ...@@ -541,7 +541,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
addr = hsotg->regs + HAINTMSK; addr = hsotg->regs + HAINTMSK;
dev_dbg(hsotg->dev, "HAINTMSK @0x%08lX : 0x%08X\n", dev_dbg(hsotg->dev, "HAINTMSK @0x%08lX : 0x%08X\n",
(unsigned long)addr, dwc2_readl(addr)); (unsigned long)addr, dwc2_readl(addr));
if (hsotg->params.dma_desc_enable > 0) { if (hsotg->params.dma_desc_enable) {
addr = hsotg->regs + HFLBADDR; addr = hsotg->regs + HFLBADDR;
dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n", dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n",
(unsigned long)addr, dwc2_readl(addr)); (unsigned long)addr, dwc2_readl(addr));
...@@ -571,7 +571,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg) ...@@ -571,7 +571,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
addr = hsotg->regs + HCDMA(i); addr = hsotg->regs + HCDMA(i);
dev_dbg(hsotg->dev, "HCDMA @0x%08lX : 0x%08X\n", dev_dbg(hsotg->dev, "HCDMA @0x%08lX : 0x%08X\n",
(unsigned long)addr, dwc2_readl(addr)); (unsigned long)addr, dwc2_readl(addr));
if (hsotg->params.dma_desc_enable > 0) { if (hsotg->params.dma_desc_enable) {
addr = hsotg->regs + HCDMAB(i); addr = hsotg->regs + HCDMAB(i);
dev_dbg(hsotg->dev, "HCDMAB @0x%08lX : 0x%08X\n", dev_dbg(hsotg->dev, "HCDMAB @0x%08lX : 0x%08X\n",
(unsigned long)addr, dwc2_readl(addr)); (unsigned long)addr, dwc2_readl(addr));
...@@ -751,11 +751,6 @@ bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host) ...@@ -751,11 +751,6 @@ bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host)
return dwc2_force_mode(hsotg, host); return dwc2_force_mode(hsotg, host);
} }
u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg)
{
return hsotg->params.otg_ver == 1 ? 0x0200 : 0x0103;
}
bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg) bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
{ {
if (dwc2_readl(hsotg->regs + GSNPSID) == 0xffffffff) if (dwc2_readl(hsotg->regs + GSNPSID) == 0xffffffff)
...@@ -793,7 +788,7 @@ void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg) ...@@ -793,7 +788,7 @@ void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg)
} }
/* Returns the controller's GHWCFG2.OTG_MODE. */ /* Returns the controller's GHWCFG2.OTG_MODE. */
unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg) unsigned int dwc2_op_mode(struct dwc2_hsotg *hsotg)
{ {
u32 ghwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2); u32 ghwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2);
...@@ -804,7 +799,7 @@ unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg) ...@@ -804,7 +799,7 @@ unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg)
/* Returns true if the controller is capable of DRD. */ /* Returns true if the controller is capable of DRD. */
bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg) bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg)
{ {
unsigned op_mode = dwc2_op_mode(hsotg); unsigned int op_mode = dwc2_op_mode(hsotg);
return (op_mode == GHWCFG2_OP_MODE_HNP_SRP_CAPABLE) || return (op_mode == GHWCFG2_OP_MODE_HNP_SRP_CAPABLE) ||
(op_mode == GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE) || (op_mode == GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE) ||
...@@ -814,7 +809,7 @@ bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg) ...@@ -814,7 +809,7 @@ bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg)
/* Returns true if the controller is host-only. */ /* Returns true if the controller is host-only. */
bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg) bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg)
{ {
unsigned op_mode = dwc2_op_mode(hsotg); unsigned int op_mode = dwc2_op_mode(hsotg);
return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_HOST) || return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_HOST) ||
(op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST); (op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST);
...@@ -823,7 +818,7 @@ bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg) ...@@ -823,7 +818,7 @@ bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg)
/* Returns true if the controller is device-only. */ /* Returns true if the controller is device-only. */
bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg) bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg)
{ {
unsigned op_mode = dwc2_op_mode(hsotg); unsigned int op_mode = dwc2_op_mode(hsotg);
return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) || return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
(op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE); (op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE);
......
...@@ -127,6 +127,8 @@ static const char * const dwc2_hsotg_supply_names[] = { ...@@ -127,6 +127,8 @@ static const char * const dwc2_hsotg_supply_names[] = {
"vusb_a", /* analog USB supply, 1.1V */ "vusb_a", /* analog USB supply, 1.1V */
}; };
#define DWC2_NUM_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names)
/* /*
* EP0_MPS_LIMIT * EP0_MPS_LIMIT
* *
...@@ -246,7 +248,8 @@ struct dwc2_hsotg_req { ...@@ -246,7 +248,8 @@ struct dwc2_hsotg_req {
void *saved_req_buf; void *saved_req_buf;
}; };
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
#define call_gadget(_hs, _entry) \ #define call_gadget(_hs, _entry) \
do { \ do { \
if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \
...@@ -271,13 +274,6 @@ enum dwc2_lx_state { ...@@ -271,13 +274,6 @@ enum dwc2_lx_state {
DWC2_L3, /* Off state */ DWC2_L3, /* Off state */
}; };
/*
* Gadget periodic tx fifo sizes as used by legacy driver
* EP0 is not included
*/
#define DWC2_G_P_LEGACY_TX_FIFO_SIZE {256, 256, 256, 256, 768, 768, 768, \
768, 0, 0, 0, 0, 0, 0, 0}
/* Gadget ep0 states */ /* Gadget ep0 states */
enum dwc2_ep0_state { enum dwc2_ep0_state {
DWC2_EP0_SETUP, DWC2_EP0_SETUP,
...@@ -295,9 +291,6 @@ enum dwc2_ep0_state { ...@@ -295,9 +291,6 @@ enum dwc2_ep0_state {
* 1 - SRP Only capable * 1 - SRP Only capable
* 2 - No HNP/SRP capable (always available) * 2 - No HNP/SRP capable (always available)
* Defaults to best available option (0, 1, then 2) * Defaults to best available option (0, 1, then 2)
* @otg_ver: OTG version supported
* 0 - 1.3 (default)
* 1 - 2.0
* @host_dma: Specifies whether to use slave or DMA mode for accessing * @host_dma: Specifies whether to use slave or DMA mode for accessing
* the data FIFOs. The driver will automatically detect the * the data FIFOs. The driver will automatically detect the
* value for this parameter if none is specified. * value for this parameter if none is specified.
...@@ -444,6 +437,11 @@ enum dwc2_ep0_state { ...@@ -444,6 +437,11 @@ enum dwc2_ep0_state {
* in DWORDS with possible values from from * in DWORDS with possible values from from
* 16-32768 (default: 256, 256, 256, 256, 768, * 16-32768 (default: 256, 256, 256, 256, 768,
* 768, 768, 768, 0, 0, 0, 0, 0, 0, 0). * 768, 768, 768, 0, 0, 0, 0, 0, 0, 0).
* @change_speed_quirk: Change speed configuration to DWC2_SPEED_PARAM_FULL
* while full&low speed device connect. And change speed
* back to DWC2_SPEED_PARAM_HIGH while device is gone.
* 0 - No (default)
* 1 - Yes
* *
* The following parameters may be specified when starting the module. These * The following parameters may be specified when starting the module. These
* parameters define how the DWC_otg controller should be configured. A * parameters define how the DWC_otg controller should be configured. A
...@@ -452,63 +450,48 @@ enum dwc2_ep0_state { ...@@ -452,63 +450,48 @@ enum dwc2_ep0_state {
* default described above. * default described above.
*/ */
struct dwc2_core_params { struct dwc2_core_params {
/* u8 otg_cap;
* Don't add any non-int members here, this will break
* dwc2_set_all_params!
*/
int otg_cap;
#define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0 #define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0
#define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1 #define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1
#define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2 #define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
int otg_ver; u8 phy_type;
int dma_desc_enable;
int dma_desc_fs_enable;
int speed;
#define DWC2_SPEED_PARAM_HIGH 0
#define DWC2_SPEED_PARAM_FULL 1
#define DWC2_SPEED_PARAM_LOW 2
int enable_dynamic_fifo;
int en_multiple_tx_fifo;
int host_rx_fifo_size;
int host_nperio_tx_fifo_size;
int host_perio_tx_fifo_size;
int max_transfer_size;
int max_packet_count;
int host_channels;
int phy_type;
#define DWC2_PHY_TYPE_PARAM_FS 0 #define DWC2_PHY_TYPE_PARAM_FS 0
#define DWC2_PHY_TYPE_PARAM_UTMI 1 #define DWC2_PHY_TYPE_PARAM_UTMI 1
#define DWC2_PHY_TYPE_PARAM_ULPI 2 #define DWC2_PHY_TYPE_PARAM_ULPI 2
int phy_utmi_width; u8 speed;
int phy_ulpi_ddr; #define DWC2_SPEED_PARAM_HIGH 0
int phy_ulpi_ext_vbus; #define DWC2_SPEED_PARAM_FULL 1
#define DWC2_PHY_ULPI_INTERNAL_VBUS 0 #define DWC2_SPEED_PARAM_LOW 2
#define DWC2_PHY_ULPI_EXTERNAL_VBUS 1
int i2c_enable;
int ulpi_fs_ls;
int host_support_fs_ls_low_power;
int host_ls_low_power_phy_clk;
#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
int ts_dline;
int reload_ctl;
int ahbcfg;
int uframe_sched;
int external_id_pin_ctl;
int hibernation;
/* u8 phy_utmi_width;
* The following parameters are *only* set via device bool phy_ulpi_ddr;
* properties and cannot be set directly in this structure. bool phy_ulpi_ext_vbus;
*/ bool enable_dynamic_fifo;
bool en_multiple_tx_fifo;
bool i2c_enable;
bool ulpi_fs_ls;
bool ts_dline;
bool reload_ctl;
bool uframe_sched;
bool external_id_pin_ctl;
bool hibernation;
u16 max_packet_count;
u32 max_transfer_size;
u32 ahbcfg;
/* Host parameters */ /* Host parameters */
bool host_dma; bool host_dma;
bool dma_desc_enable;
bool dma_desc_fs_enable;
bool host_support_fs_ls_low_power;
bool host_ls_low_power_phy_clk;
u8 host_channels;
u16 host_rx_fifo_size;
u16 host_nperio_tx_fifo_size;
u16 host_perio_tx_fifo_size;
/* Gadget parameters */ /* Gadget parameters */
bool g_dma; bool g_dma;
...@@ -516,6 +499,8 @@ struct dwc2_core_params { ...@@ -516,6 +499,8 @@ struct dwc2_core_params {
u32 g_rx_fifo_size; u32 g_rx_fifo_size;
u32 g_np_tx_fifo_size; u32 g_np_tx_fifo_size;
u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; u32 g_tx_fifo_size[MAX_EPS_CHANNELS];
bool change_speed_quirk;
}; };
/** /**
...@@ -603,8 +588,8 @@ struct dwc2_hw_params { ...@@ -603,8 +588,8 @@ struct dwc2_hw_params {
#define DWC2_CTRL_BUFF_SIZE 8 #define DWC2_CTRL_BUFF_SIZE 8
/** /**
* struct dwc2_gregs_backup - Holds global registers state before entering partial * struct dwc2_gregs_backup - Holds global registers state before
* power down * entering partial power down
* @gotgctl: Backup of GOTGCTL register * @gotgctl: Backup of GOTGCTL register
* @gintmsk: Backup of GINTMSK register * @gintmsk: Backup of GINTMSK register
* @gahbcfg: Backup of GAHBCFG register * @gahbcfg: Backup of GAHBCFG register
...@@ -634,8 +619,8 @@ struct dwc2_gregs_backup { ...@@ -634,8 +619,8 @@ struct dwc2_gregs_backup {
}; };
/** /**
* struct dwc2_dregs_backup - Holds device registers state before entering partial * struct dwc2_dregs_backup - Holds device registers state before
* power down * entering partial power down
* @dcfg: Backup of DCFG register * @dcfg: Backup of DCFG register
* @dctl: Backup of DCTL register * @dctl: Backup of DCTL register
* @daintmsk: Backup of DAINTMSK register * @daintmsk: Backup of DAINTMSK register
...@@ -664,8 +649,8 @@ struct dwc2_dregs_backup { ...@@ -664,8 +649,8 @@ struct dwc2_dregs_backup {
}; };
/** /**
* struct dwc2_hregs_backup - Holds host registers state before entering partial * struct dwc2_hregs_backup - Holds host registers state before
* power down * entering partial power down
* @hcfg: Backup of HCFG register * @hcfg: Backup of HCFG register
* @haintmsk: Backup of HAINTMSK register * @haintmsk: Backup of HAINTMSK register
* @hcintmsk: Backup of HCINTMSK register * @hcintmsk: Backup of HCINTMSK register
...@@ -782,9 +767,10 @@ struct dwc2_hregs_backup { ...@@ -782,9 +767,10 @@ struct dwc2_hregs_backup {
* @gadget_enabled Peripheral mode sub-driver initialization indicator. * @gadget_enabled Peripheral mode sub-driver initialization indicator.
* @ll_hw_enabled Status of low-level hardware resources. * @ll_hw_enabled Status of low-level hardware resources.
* @phy: The otg phy transceiver structure for phy control. * @phy: The otg phy transceiver structure for phy control.
* @uphy: The otg phy transceiver structure for old USB phy control. * @uphy: The otg phy transceiver structure for old USB phy
* @plat: The platform specific configuration data. This can be removed once * control.
* all SoCs support usb transceiver. * @plat: The platform specific configuration data. This can be
* removed once all SoCs support usb transceiver.
* @supplies: Definition of USB power supplies * @supplies: Definition of USB power supplies
* @phyif: PHY interface width * @phyif: PHY interface width
* @lock: Spinlock that protects all the driver data structures * @lock: Spinlock that protects all the driver data structures
...@@ -921,7 +907,7 @@ struct dwc2_hsotg { ...@@ -921,7 +907,7 @@ struct dwc2_hsotg {
struct phy *phy; struct phy *phy;
struct usb_phy *uphy; struct usb_phy *uphy;
struct dwc2_hsotg_plat *plat; struct dwc2_hsotg_plat *plat;
struct regulator_bulk_data supplies[ARRAY_SIZE(dwc2_hsotg_supply_names)]; struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES];
u32 phyif; u32 phyif;
spinlock_t lock; spinlock_t lock;
...@@ -947,6 +933,7 @@ struct dwc2_hsotg { ...@@ -947,6 +933,7 @@ struct dwc2_hsotg {
/* DWC OTG HW Release versions */ /* DWC OTG HW Release versions */
#define DWC2_CORE_REV_2_71a 0x4f54271a #define DWC2_CORE_REV_2_71a 0x4f54271a
#define DWC2_CORE_REV_2_90a 0x4f54290a #define DWC2_CORE_REV_2_90a 0x4f54290a
#define DWC2_CORE_REV_2_91a 0x4f54291a
#define DWC2_CORE_REV_2_92a 0x4f54292a #define DWC2_CORE_REV_2_92a 0x4f54292a
#define DWC2_CORE_REV_2_94a 0x4f54294a #define DWC2_CORE_REV_2_94a 0x4f54294a
#define DWC2_CORE_REV_3_00a 0x4f54300a #define DWC2_CORE_REV_3_00a 0x4f54300a
...@@ -1033,7 +1020,8 @@ struct dwc2_hsotg { ...@@ -1033,7 +1020,8 @@ struct dwc2_hsotg {
#endif #endif
#endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */ #endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
/* Gadget structures */ /* Gadget structures */
struct usb_gadget_driver *driver; struct usb_gadget_driver *driver;
int fifo_mem; int fifo_mem;
...@@ -1101,37 +1089,37 @@ static inline bool dwc2_is_hs_iot(struct dwc2_hsotg *hsotg) ...@@ -1101,37 +1089,37 @@ static inline bool dwc2_is_hs_iot(struct dwc2_hsotg *hsotg)
* The following functions support initialization of the core driver component * The following functions support initialization of the core driver component
* and the DWC_otg controller * and the DWC_otg controller
*/ */
extern int dwc2_core_reset(struct dwc2_hsotg *hsotg); int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait);
extern int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg); int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg);
extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg); int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg);
extern int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore); int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore);
bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host); bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host);
void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg); void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg);
void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg); void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg);
extern bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg); bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg);
/* /*
* Common core Functions. * Common core Functions.
* The following functions support managing the DWC_otg controller in either * The following functions support managing the DWC_otg controller in either
* device or host mode. * device or host mode.
*/ */
extern void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes); void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes);
extern void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num); void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num);
extern void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg); void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg);
extern void dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd); void dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd);
extern void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd); void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd);
/* This function should be called on every hardware interrupt. */ /* This function should be called on every hardware interrupt. */
extern irqreturn_t dwc2_handle_common_intr(int irq, void *dev); irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
/* The device ID match table */ /* The device ID match table */
extern const struct of_device_id dwc2_of_match_table[]; extern const struct of_device_id dwc2_of_match_table[];
extern int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg); int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg);
extern int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg); int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg);
/* Parameters */ /* Parameters */
int dwc2_get_hwparams(struct dwc2_hsotg *hsotg); int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
...@@ -1145,7 +1133,7 @@ int dwc2_init_params(struct dwc2_hsotg *hsotg); ...@@ -1145,7 +1133,7 @@ int dwc2_init_params(struct dwc2_hsotg *hsotg);
* are read in and cached so they always read directly from the * are read in and cached so they always read directly from the
* GHWCFG2 register. * GHWCFG2 register.
*/ */
unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg); unsigned int dwc2_op_mode(struct dwc2_hsotg *hsotg);
bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg); bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg);
bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg); bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg);
bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg); bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg);
...@@ -1157,6 +1145,7 @@ static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg) ...@@ -1157,6 +1145,7 @@ static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg)
{ {
return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0; return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0;
} }
static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg) static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
{ {
return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0; return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
...@@ -1165,29 +1154,28 @@ static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg) ...@@ -1165,29 +1154,28 @@ static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
/* /*
* Dump core registers and SPRAM * Dump core registers and SPRAM
*/ */
extern void dwc2_dump_dev_registers(struct dwc2_hsotg *hsotg); void dwc2_dump_dev_registers(struct dwc2_hsotg *hsotg);
extern void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg); void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg);
extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg);
/*
* Return OTG version - either 1.3 or 2.0
*/
extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg);
/* Gadget defines */ /* Gadget defines */
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
extern int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg); IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
extern int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2); int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg);
extern int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2); int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2);
extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2);
extern void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq);
void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
bool reset); bool reset);
extern void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg); void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg);
extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2); void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2);
extern int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode); int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
#define dwc2_is_device_connected(hsotg) (hsotg->connected) #define dwc2_is_device_connected(hsotg) (hsotg->connected)
int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg); int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg); int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg);
int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg);
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
#else #else
static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2) static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
{ return 0; } { return 0; }
...@@ -1209,14 +1197,20 @@ static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) ...@@ -1209,14 +1197,20 @@ static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
{ return 0; } { return 0; }
static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
{ return 0; } { return 0; }
static inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
{ return 0; }
static inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
{ return 0; }
static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
{ return 0; }
#endif #endif
#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg);
extern int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us); int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us);
extern void dwc2_hcd_connect(struct dwc2_hsotg *hsotg); void dwc2_hcd_connect(struct dwc2_hsotg *hsotg);
extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force);
extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg); int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg);
int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg); int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg);
#else #else
...@@ -1229,7 +1223,7 @@ static inline void dwc2_hcd_connect(struct dwc2_hsotg *hsotg) {} ...@@ -1229,7 +1223,7 @@ static inline void dwc2_hcd_connect(struct dwc2_hsotg *hsotg) {}
static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) {} static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) {}
static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {}
static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {}
static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
{ return 0; } { return 0; }
static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
{ return 0; } { return 0; }
......
...@@ -159,9 +159,8 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) ...@@ -159,9 +159,8 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
" ++OTG Interrupt: Session Request Success Status Change++\n"); " ++OTG Interrupt: Session Request Success Status Change++\n");
gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
if (gotgctl & GOTGCTL_SESREQSCS) { if (gotgctl & GOTGCTL_SESREQSCS) {
if (hsotg->params.phy_type == if (hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS &&
DWC2_PHY_TYPE_PARAM_FS hsotg->params.i2c_enable) {
&& hsotg->params.i2c_enable > 0) {
hsotg->srp_success = 1; hsotg->srp_success = 1;
} else { } else {
/* Clear Session Request */ /* Clear Session Request */
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#include "core.h" #include "core.h"
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
extern int dwc2_debugfs_init(struct dwc2_hsotg *); int dwc2_debugfs_init(struct dwc2_hsotg *hsotg);
extern void dwc2_debugfs_exit(struct dwc2_hsotg *); void dwc2_debugfs_exit(struct dwc2_hsotg *hsotg);
#else #else
static inline int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) static inline int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
{ return 0; } { return 0; }
......
...@@ -338,23 +338,23 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg) ...@@ -338,23 +338,23 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg)
{ {
struct dentry *root; struct dentry *root;
struct dentry *file; struct dentry *file;
unsigned epidx; unsigned int epidx;
root = hsotg->debug_root; root = hsotg->debug_root;
/* create general state file */ /* create general state file */
file = debugfs_create_file("state", S_IRUGO, root, hsotg, &state_fops); file = debugfs_create_file("state", 0444, root, hsotg, &state_fops);
if (IS_ERR(file)) if (IS_ERR(file))
dev_err(hsotg->dev, "%s: failed to create state\n", __func__); dev_err(hsotg->dev, "%s: failed to create state\n", __func__);
file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, hsotg, file = debugfs_create_file("testmode", 0644, root, hsotg,
&testmode_fops); &testmode_fops);
if (IS_ERR(file)) if (IS_ERR(file))
dev_err(hsotg->dev, "%s: failed to create testmode\n", dev_err(hsotg->dev, "%s: failed to create testmode\n",
__func__); __func__);
file = debugfs_create_file("fifo", S_IRUGO, root, hsotg, &fifo_fops); file = debugfs_create_file("fifo", 0444, root, hsotg, &fifo_fops);
if (IS_ERR(file)) if (IS_ERR(file))
dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__); dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__);
...@@ -364,7 +364,7 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg) ...@@ -364,7 +364,7 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg)
ep = hsotg->eps_out[epidx]; ep = hsotg->eps_out[epidx];
if (ep) { if (ep) {
file = debugfs_create_file(ep->name, S_IRUGO, file = debugfs_create_file(ep->name, 0444,
root, ep, &ep_fops); root, ep, &ep_fops);
if (IS_ERR(file)) if (IS_ERR(file))
dev_err(hsotg->dev, "failed to create %s debug file\n", dev_err(hsotg->dev, "failed to create %s debug file\n",
...@@ -377,7 +377,7 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg) ...@@ -377,7 +377,7 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg)
ep = hsotg->eps_in[epidx]; ep = hsotg->eps_in[epidx];
if (ep) { if (ep) {
file = debugfs_create_file(ep->name, S_IRUGO, file = debugfs_create_file(ep->name, 0444,
root, ep, &ep_fops); root, ep, &ep_fops);
if (IS_ERR(file)) if (IS_ERR(file))
dev_err(hsotg->dev, "failed to create %s debug file\n", dev_err(hsotg->dev, "failed to create %s debug file\n",
...@@ -725,6 +725,143 @@ static const struct debugfs_reg32 dwc2_regs[] = { ...@@ -725,6 +725,143 @@ static const struct debugfs_reg32 dwc2_regs[] = {
dump_register(HCDMAB(15)), dump_register(HCDMAB(15)),
}; };
#define print_param(_seq, _ptr, _param) \
seq_printf((_seq), "%-30s: %d\n", #_param, (_ptr)->_param)
#define print_param_hex(_seq, _ptr, _param) \
seq_printf((_seq), "%-30s: 0x%x\n", #_param, (_ptr)->_param)
static int params_show(struct seq_file *seq, void *v)
{
struct dwc2_hsotg *hsotg = seq->private;
struct dwc2_core_params *p = &hsotg->params;
int i;
print_param(seq, p, otg_cap);
print_param(seq, p, dma_desc_enable);
print_param(seq, p, dma_desc_fs_enable);
print_param(seq, p, speed);
print_param(seq, p, enable_dynamic_fifo);
print_param(seq, p, en_multiple_tx_fifo);
print_param(seq, p, host_rx_fifo_size);
print_param(seq, p, host_nperio_tx_fifo_size);
print_param(seq, p, host_perio_tx_fifo_size);
print_param(seq, p, max_transfer_size);
print_param(seq, p, max_packet_count);
print_param(seq, p, host_channels);
print_param(seq, p, phy_type);
print_param(seq, p, phy_utmi_width);
print_param(seq, p, phy_ulpi_ddr);
print_param(seq, p, phy_ulpi_ext_vbus);
print_param(seq, p, i2c_enable);
print_param(seq, p, ulpi_fs_ls);
print_param(seq, p, host_support_fs_ls_low_power);
print_param(seq, p, host_ls_low_power_phy_clk);
print_param(seq, p, ts_dline);
print_param(seq, p, reload_ctl);
print_param_hex(seq, p, ahbcfg);
print_param(seq, p, uframe_sched);
print_param(seq, p, external_id_pin_ctl);
print_param(seq, p, hibernation);
print_param(seq, p, host_dma);
print_param(seq, p, g_dma);
print_param(seq, p, g_dma_desc);
print_param(seq, p, g_rx_fifo_size);
print_param(seq, p, g_np_tx_fifo_size);
for (i = 0; i < MAX_EPS_CHANNELS; i++) {
char str[32];
snprintf(str, 32, "g_tx_fifo_size[%d]", i);
seq_printf(seq, "%-30s: %d\n", str, p->g_tx_fifo_size[i]);
}
return 0;
}
static int params_open(struct inode *inode, struct file *file)
{
return single_open(file, params_show, inode->i_private);
}
static const struct file_operations params_fops = {
.owner = THIS_MODULE,
.open = params_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int hw_params_show(struct seq_file *seq, void *v)
{
struct dwc2_hsotg *hsotg = seq->private;
struct dwc2_hw_params *hw = &hsotg->hw_params;
print_param(seq, hw, op_mode);
print_param(seq, hw, arch);
print_param(seq, hw, dma_desc_enable);
print_param(seq, hw, enable_dynamic_fifo);
print_param(seq, hw, en_multiple_tx_fifo);
print_param(seq, hw, rx_fifo_size);
print_param(seq, hw, host_nperio_tx_fifo_size);
print_param(seq, hw, dev_nperio_tx_fifo_size);
print_param(seq, hw, host_perio_tx_fifo_size);
print_param(seq, hw, nperio_tx_q_depth);
print_param(seq, hw, host_perio_tx_q_depth);
print_param(seq, hw, dev_token_q_depth);
print_param(seq, hw, max_transfer_size);
print_param(seq, hw, max_packet_count);
print_param(seq, hw, host_channels);
print_param(seq, hw, hs_phy_type);
print_param(seq, hw, fs_phy_type);
print_param(seq, hw, i2c_enable);
print_param(seq, hw, num_dev_ep);
print_param(seq, hw, num_dev_perio_in_ep);
print_param(seq, hw, total_fifo_size);
print_param(seq, hw, power_optimized);
print_param(seq, hw, utmi_phy_data_width);
print_param_hex(seq, hw, snpsid);
print_param_hex(seq, hw, dev_ep_dirs);
return 0;
}
static int hw_params_open(struct inode *inode, struct file *file)
{
return single_open(file, hw_params_show, inode->i_private);
}
static const struct file_operations hw_params_fops = {
.owner = THIS_MODULE,
.open = hw_params_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int dr_mode_show(struct seq_file *seq, void *v)
{
struct dwc2_hsotg *hsotg = seq->private;
const char *dr_mode = "";
device_property_read_string(hsotg->dev, "dr_mode", &dr_mode);
seq_printf(seq, "%s\n", dr_mode);
return 0;
}
static int dr_mode_open(struct inode *inode, struct file *file)
{
return single_open(file, dr_mode_show, inode->i_private);
}
static const struct file_operations dr_mode_fops = {
.owner = THIS_MODULE,
.open = dr_mode_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
{ {
int ret; int ret;
...@@ -736,6 +873,25 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) ...@@ -736,6 +873,25 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
goto err0; goto err0;
} }
file = debugfs_create_file("params", 0444,
hsotg->debug_root,
hsotg, &params_fops);
if (IS_ERR(file))
dev_err(hsotg->dev, "%s: failed to create params\n", __func__);
file = debugfs_create_file("hw_params", 0444,
hsotg->debug_root,
hsotg, &hw_params_fops);
if (IS_ERR(file))
dev_err(hsotg->dev, "%s: failed to create hw_params\n",
__func__);
file = debugfs_create_file("dr_mode", 0444,
hsotg->debug_root,
hsotg, &dr_mode_fops);
if (IS_ERR(file))
dev_err(hsotg->dev, "%s: failed to create dr_mode\n", __func__);
/* Add gadget debugfs nodes */ /* Add gadget debugfs nodes */
dwc2_hsotg_create_debug(hsotg); dwc2_hsotg_create_debug(hsotg);
...@@ -750,7 +906,7 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) ...@@ -750,7 +906,7 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
hsotg->regset->nregs = ARRAY_SIZE(dwc2_regs); hsotg->regset->nregs = ARRAY_SIZE(dwc2_regs);
hsotg->regset->base = hsotg->regs; hsotg->regset->base = hsotg->regs;
file = debugfs_create_regset32("regdump", S_IRUGO, hsotg->debug_root, file = debugfs_create_regset32("regdump", 0444, hsotg->debug_root,
hsotg->regset); hsotg->regset);
if (!file) { if (!file) {
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -191,6 +191,99 @@ static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, ...@@ -191,6 +191,99 @@ static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
local_irq_restore(flags); local_irq_restore(flags);
} }
/**
* dwc2_hsotg_tx_fifo_count - return count of TX FIFOs in device mode
*/
int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
{
if (hsotg->hw_params.en_multiple_tx_fifo)
/* In dedicated FIFO mode we need count of IN EPs */
return (dwc2_readl(hsotg->regs + GHWCFG4) &
GHWCFG4_NUM_IN_EPS_MASK) >> GHWCFG4_NUM_IN_EPS_SHIFT;
else
/* In shared FIFO mode we need count of Periodic IN EPs */
return hsotg->hw_params.num_dev_perio_in_ep;
}
/**
* dwc2_hsotg_ep_info_size - return Endpoint Info Control block size in DWORDs
*/
static int dwc2_hsotg_ep_info_size(struct dwc2_hsotg *hsotg)
{
int val = 0;
int i;
u32 ep_dirs;
/*
* Don't need additional space for ep info control registers in
* slave mode.
*/
if (!using_dma(hsotg)) {
dev_dbg(hsotg->dev, "Buffer DMA ep info size 0\n");
return 0;
}
/*
* Buffer DMA mode - 1 location per endpoit
* Descriptor DMA mode - 4 locations per endpoint
*/
ep_dirs = hsotg->hw_params.dev_ep_dirs;
for (i = 0; i <= hsotg->hw_params.num_dev_ep; i++) {
val += ep_dirs & 3 ? 1 : 2;
ep_dirs >>= 2;
}
if (using_desc_dma(hsotg))
val = val * 4;
return val;
}
/**
* dwc2_hsotg_tx_fifo_total_depth - return total FIFO depth available for
* device mode TX FIFOs
*/
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
{
int ep_info_size;
int addr;
int tx_addr_max;
u32 np_tx_fifo_size;
np_tx_fifo_size = min_t(u32, hsotg->hw_params.dev_nperio_tx_fifo_size,
hsotg->params.g_np_tx_fifo_size);
/* Get Endpoint Info Control block size in DWORDs. */
ep_info_size = dwc2_hsotg_ep_info_size(hsotg);
tx_addr_max = hsotg->hw_params.total_fifo_size - ep_info_size;
addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size;
if (tx_addr_max <= addr)
return 0;
return tx_addr_max - addr;
}
/**
* dwc2_hsotg_tx_fifo_average_depth - returns average depth of device mode
* TX FIFOs
*/
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
{
int tx_fifo_count;
int tx_fifo_depth;
tx_fifo_depth = dwc2_hsotg_tx_fifo_total_depth(hsotg);
tx_fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
if (!tx_fifo_count)
return tx_fifo_depth;
else
return tx_fifo_depth / tx_fifo_count;
}
/** /**
* dwc2_hsotg_init_fifo - initialise non-periodic FIFOs * dwc2_hsotg_init_fifo - initialise non-periodic FIFOs
* @hsotg: The device instance. * @hsotg: The device instance.
...@@ -241,6 +334,9 @@ static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) ...@@ -241,6 +334,9 @@ static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
val = dwc2_readl(hsotg->regs + DPTXFSIZN(ep)); val = dwc2_readl(hsotg->regs + DPTXFSIZN(ep));
} }
dwc2_writel(hsotg->hw_params.total_fifo_size |
addr << GDFIFOCFG_EPINFOBASE_SHIFT,
hsotg->regs + GDFIFOCFG);
/* /*
* according to p428 of the design guide, we need to ensure that * according to p428 of the design guide, we need to ensure that
* all fifos are flushed before continuing * all fifos are flushed before continuing
...@@ -281,7 +377,7 @@ static struct usb_request *dwc2_hsotg_ep_alloc_request(struct usb_ep *ep, ...@@ -281,7 +377,7 @@ static struct usb_request *dwc2_hsotg_ep_alloc_request(struct usb_ep *ep,
{ {
struct dwc2_hsotg_req *req; struct dwc2_hsotg_req *req;
req = kzalloc(sizeof(struct dwc2_hsotg_req), flags); req = kzalloc(sizeof(*req), flags);
if (!req) if (!req)
return NULL; return NULL;
...@@ -316,6 +412,7 @@ static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg, ...@@ -316,6 +412,7 @@ static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
struct dwc2_hsotg_req *hs_req) struct dwc2_hsotg_req *hs_req)
{ {
struct usb_request *req = &hs_req->req; struct usb_request *req = &hs_req->req;
usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in); usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in);
} }
...@@ -547,17 +644,17 @@ static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg, ...@@ -547,17 +644,17 @@ static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
* Return the maximum data that can be queued in one go on a given endpoint * Return the maximum data that can be queued in one go on a given endpoint
* so that transfers that are too long can be split. * so that transfers that are too long can be split.
*/ */
static unsigned get_ep_limit(struct dwc2_hsotg_ep *hs_ep) static unsigned int get_ep_limit(struct dwc2_hsotg_ep *hs_ep)
{ {
int index = hs_ep->index; int index = hs_ep->index;
unsigned maxsize; unsigned int maxsize;
unsigned maxpkt; unsigned int maxpkt;
if (index != 0) { if (index != 0) {
maxsize = DXEPTSIZ_XFERSIZE_LIMIT + 1; maxsize = DXEPTSIZ_XFERSIZE_LIMIT + 1;
maxpkt = DXEPTSIZ_PKTCNT_LIMIT + 1; maxpkt = DXEPTSIZ_PKTCNT_LIMIT + 1;
} else { } else {
maxsize = 64+64; maxsize = 64 + 64;
if (hs_ep->dir_in) if (hs_ep->dir_in)
maxpkt = DIEPTSIZ0_PKTCNT_LIMIT + 1; maxpkt = DIEPTSIZ0_PKTCNT_LIMIT + 1;
else else
...@@ -580,11 +677,11 @@ static unsigned get_ep_limit(struct dwc2_hsotg_ep *hs_ep) ...@@ -580,11 +677,11 @@ static unsigned get_ep_limit(struct dwc2_hsotg_ep *hs_ep)
} }
/** /**
* dwc2_hsotg_read_frameno - read current frame number * dwc2_hsotg_read_frameno - read current frame number
* @hsotg: The device instance * @hsotg: The device instance
* *
* Return the current frame number * Return the current frame number
*/ */
static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg) static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
{ {
u32 dsts; u32 dsts;
...@@ -885,9 +982,9 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, ...@@ -885,9 +982,9 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
u32 epsize_reg; u32 epsize_reg;
u32 epsize; u32 epsize;
u32 ctrl; u32 ctrl;
unsigned length; unsigned int length;
unsigned packets; unsigned int packets;
unsigned maxreq; unsigned int maxreq;
unsigned int dma_reg; unsigned int dma_reg;
if (index != 0) { if (index != 0) {
...@@ -1112,7 +1209,8 @@ static int dwc2_hsotg_map_dma(struct dwc2_hsotg *hsotg, ...@@ -1112,7 +1209,8 @@ static int dwc2_hsotg_map_dma(struct dwc2_hsotg *hsotg,
} }
static int dwc2_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg, static int dwc2_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg,
struct dwc2_hsotg_ep *hs_ep, struct dwc2_hsotg_req *hs_req) struct dwc2_hsotg_ep *hs_ep,
struct dwc2_hsotg_req *hs_req)
{ {
void *req_buf = hs_req->req.buf; void *req_buf = hs_req->req.buf;
...@@ -1142,8 +1240,10 @@ static int dwc2_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg, ...@@ -1142,8 +1240,10 @@ static int dwc2_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg,
return 0; return 0;
} }
static void dwc2_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg, static void
struct dwc2_hsotg_ep *hs_ep, struct dwc2_hsotg_req *hs_req) dwc2_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg,
struct dwc2_hsotg_ep *hs_ep,
struct dwc2_hsotg_req *hs_req)
{ {
/* If dma is not being used or buffer was aligned */ /* If dma is not being used or buffer was aligned */
if (!using_dma(hsotg) || !hs_req->saved_req_buf) if (!using_dma(hsotg) || !hs_req->saved_req_buf)
...@@ -1466,8 +1566,11 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg, ...@@ -1466,8 +1566,11 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
switch (ctrl->bRequestType & USB_RECIP_MASK) { switch (ctrl->bRequestType & USB_RECIP_MASK) {
case USB_RECIP_DEVICE: case USB_RECIP_DEVICE:
reply = cpu_to_le16(0); /* bit 0 => self powered, /*
* bit 1 => remote wakeup */ * bit 0 => self powered
* bit 1 => remote wakeup
*/
reply = cpu_to_le16(0);
break; break;
case USB_RECIP_INTERFACE: case USB_RECIP_INTERFACE:
...@@ -1640,10 +1743,9 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, ...@@ -1640,10 +1743,9 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
} }
/* If we have pending request, then start it */ /* If we have pending request, then start it */
if (!ep->req) { if (!ep->req)
dwc2_gadget_start_next_request(ep); dwc2_gadget_start_next_request(ep);
} }
}
break; break;
...@@ -1889,7 +1991,6 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg, ...@@ -1889,7 +1991,6 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg,
struct dwc2_hsotg_req *hs_req, struct dwc2_hsotg_req *hs_req,
int result) int result)
{ {
if (!hs_req) { if (!hs_req) {
dev_dbg(hsotg->dev, "%s: nothing to complete?\n", __func__); dev_dbg(hsotg->dev, "%s: nothing to complete?\n", __func__);
return; return;
...@@ -1935,9 +2036,8 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg, ...@@ -1935,9 +2036,8 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg,
* so be careful when doing this. * so be careful when doing this.
*/ */
if (!hs_ep->req && result >= 0) { if (!hs_ep->req && result >= 0)
dwc2_gadget_start_next_request(hs_ep); dwc2_gadget_start_next_request(hs_ep);
}
} }
/* /*
...@@ -2068,7 +2168,6 @@ static void dwc2_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) ...@@ -2068,7 +2168,6 @@ static void dwc2_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
int max_req; int max_req;
int read_ptr; int read_ptr;
if (!hs_req) { if (!hs_req) {
u32 epctl = dwc2_readl(hsotg->regs + DOEPCTL(ep_idx)); u32 epctl = dwc2_readl(hsotg->regs + DOEPCTL(ep_idx));
int ptr; int ptr;
...@@ -2191,7 +2290,7 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) ...@@ -2191,7 +2290,7 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[epnum]; struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[epnum];
struct dwc2_hsotg_req *hs_req = hs_ep->req; struct dwc2_hsotg_req *hs_req = hs_ep->req;
struct usb_request *req = &hs_req->req; struct usb_request *req = &hs_req->req;
unsigned size_left = DXEPTSIZ_XFERSIZE_GET(epsize); unsigned int size_left = DXEPTSIZ_XFERSIZE_GET(epsize);
int result = 0; int result = 0;
if (!hs_req) { if (!hs_req) {
...@@ -2210,7 +2309,7 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) ...@@ -2210,7 +2309,7 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
size_left = dwc2_gadget_get_xfersize_ddma(hs_ep); size_left = dwc2_gadget_get_xfersize_ddma(hs_ep);
if (using_dma(hsotg)) { if (using_dma(hsotg)) {
unsigned size_done; unsigned int size_done;
/* /*
* Calculate the size of the transfer by checking how much * Calculate the size of the transfer by checking how much
...@@ -2751,19 +2850,19 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep) ...@@ -2751,19 +2850,19 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep)
} }
/** /**
* dwc2_gadget_handle_nak - handle NAK interrupt * dwc2_gadget_handle_nak - handle NAK interrupt
* @hs_ep: The endpoint on which interrupt is asserted. * @hs_ep: The endpoint on which interrupt is asserted.
* *
* This is starting point for ISOC-IN transfer, synchronization done with * This is starting point for ISOC-IN transfer, synchronization done with
* first IN token received from host while corresponding EP is disabled. * first IN token received from host while corresponding EP is disabled.
* *
* Device does not know when first one token will arrive from host. On first * Device does not know when first one token will arrive from host. On first
* token arrival HW generates 2 interrupts: 'in token received while FIFO empty' * token arrival HW generates 2 interrupts: 'in token received while FIFO empty'
* and 'NAK'. NAK interrupt for ISOC-IN means that token has arrived and ZLP was * and 'NAK'. NAK interrupt for ISOC-IN means that token has arrived and ZLP was
* sent in response to that as there was no data in FIFO. SW is basing on this * sent in response to that as there was no data in FIFO. SW is basing on this
* interrupt to obtain frame in which token has come and then based on the * interrupt to obtain frame in which token has come and then based on the
* interval calculates next frame for transfer. * interval calculates next frame for transfer.
*/ */
static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep)
{ {
struct dwc2_hsotg *hsotg = hs_ep->parent; struct dwc2_hsotg *hsotg = hs_ep->parent;
...@@ -3059,7 +3158,7 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg, ...@@ -3059,7 +3158,7 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg,
int result) int result)
{ {
struct dwc2_hsotg_req *req, *treq; struct dwc2_hsotg_req *req, *treq;
unsigned size; unsigned int size;
ep->req = NULL; ep->req = NULL;
...@@ -3084,7 +3183,7 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg, ...@@ -3084,7 +3183,7 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg,
*/ */
void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg) void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg)
{ {
unsigned ep; unsigned int ep;
if (!hsotg->connected) if (!hsotg->connected)
return; return;
...@@ -3158,7 +3257,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, ...@@ -3158,7 +3257,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
if (!is_usb_reset) if (!is_usb_reset)
if (dwc2_core_reset(hsotg)) if (dwc2_core_reset(hsotg, true))
return; return;
/* /*
...@@ -3221,7 +3320,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, ...@@ -3221,7 +3320,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
if (!using_desc_dma(hsotg)) if (!using_desc_dma(hsotg))
intmsk |= GINTSTS_INCOMPL_SOIN | GINTSTS_INCOMPL_SOOUT; intmsk |= GINTSTS_INCOMPL_SOIN | GINTSTS_INCOMPL_SOOUT;
if (hsotg->params.external_id_pin_ctl <= 0) if (!hsotg->params.external_id_pin_ctl)
intmsk |= GINTSTS_CONIDSTSCHNG; intmsk |= GINTSTS_CONIDSTSCHNG;
dwc2_writel(intmsk, hsotg->regs + GINTMSK); dwc2_writel(intmsk, hsotg->regs + GINTMSK);
...@@ -3462,7 +3561,6 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw) ...@@ -3462,7 +3561,6 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw)
} }
if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) { if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) {
u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL); u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL);
u32 connected = hsotg->connected; u32 connected = hsotg->connected;
...@@ -3827,12 +3925,13 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, ...@@ -3827,12 +3925,13 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
if (dir_in && hsotg->dedicated_fifos) { if (dir_in && hsotg->dedicated_fifos) {
u32 fifo_index = 0; u32 fifo_index = 0;
u32 fifo_size = UINT_MAX; u32 fifo_size = UINT_MAX;
size = hs_ep->ep.maxpacket*hs_ep->mc;
size = hs_ep->ep.maxpacket * hs_ep->mc;
for (i = 1; i < hsotg->num_of_eps; ++i) { for (i = 1; i < hsotg->num_of_eps; ++i) {
if (hsotg->fifo_map & (1<<i)) if (hsotg->fifo_map & (1 << i))
continue; continue;
val = dwc2_readl(hsotg->regs + DPTXFSIZN(i)); val = dwc2_readl(hsotg->regs + DPTXFSIZN(i));
val = (val >> FIFOSIZE_DEPTH_SHIFT)*4; val = (val >> FIFOSIZE_DEPTH_SHIFT) * 4;
if (val < size) if (val < size)
continue; continue;
/* Search for smallest acceptable fifo */ /* Search for smallest acceptable fifo */
...@@ -4038,13 +4137,12 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value, bool now) ...@@ -4038,13 +4137,12 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value, bool now)
} }
dwc2_writel(epctl, hs->regs + epreg); dwc2_writel(epctl, hs->regs + epreg);
} else { } else {
epreg = DOEPCTL(index); epreg = DOEPCTL(index);
epctl = dwc2_readl(hs->regs + epreg); epctl = dwc2_readl(hs->regs + epreg);
if (value) if (value) {
epctl |= DXEPCTL_STALL; epctl |= DXEPCTL_STALL;
else { } else {
epctl &= ~DXEPCTL_STALL; epctl &= ~DXEPCTL_STALL;
xfertype = epctl & DXEPCTL_EPTYPE_MASK; xfertype = epctl & DXEPCTL_EPTYPE_MASK;
if (xfertype == DXEPCTL_EPTYPE_BULK || if (xfertype == DXEPCTL_EPTYPE_BULK ||
...@@ -4090,7 +4188,7 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = { ...@@ -4090,7 +4188,7 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = {
}; };
/** /**
* dwc2_hsotg_init - initalize the usb core * dwc2_hsotg_init - initialize the usb core
* @hsotg: The driver state * @hsotg: The driver state
*/ */
static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg)
...@@ -4329,7 +4427,7 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) ...@@ -4329,7 +4427,7 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
* *
* Report how much power the device may consume to the phy. * Report how much power the device may consume to the phy.
*/ */
static int dwc2_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA) static int dwc2_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned int mA)
{ {
struct dwc2_hsotg *hsotg = to_hsotg(gadget); struct dwc2_hsotg *hsotg = to_hsotg(gadget);
...@@ -4415,6 +4513,7 @@ static void dwc2_hsotg_initep(struct dwc2_hsotg *hsotg, ...@@ -4415,6 +4513,7 @@ static void dwc2_hsotg_initep(struct dwc2_hsotg *hsotg,
if (using_dma(hsotg)) { if (using_dma(hsotg)) {
u32 next = DXEPCTL_NEXTEP((epnum + 1) % 15); u32 next = DXEPCTL_NEXTEP((epnum + 1) % 15);
if (dir_in) if (dir_in)
dwc2_writel(next, hsotg->regs + DIEPCTL(epnum)); dwc2_writel(next, hsotg->regs + DIEPCTL(epnum));
else else
...@@ -4441,7 +4540,8 @@ static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) ...@@ -4441,7 +4540,8 @@ static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
/* Add ep0 */ /* Add ep0 */
hsotg->num_of_eps++; hsotg->num_of_eps++;
hsotg->eps_in[0] = devm_kzalloc(hsotg->dev, sizeof(struct dwc2_hsotg_ep), hsotg->eps_in[0] = devm_kzalloc(hsotg->dev,
sizeof(struct dwc2_hsotg_ep),
GFP_KERNEL); GFP_KERNEL);
if (!hsotg->eps_in[0]) if (!hsotg->eps_in[0])
return -ENOMEM; return -ENOMEM;
...@@ -4521,7 +4621,6 @@ static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg) ...@@ -4521,7 +4621,6 @@ static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg)
idx, dwc2_readl(regs + DOEPCTL(idx)), idx, dwc2_readl(regs + DOEPCTL(idx)),
dwc2_readl(regs + DOEPTSIZ(idx)), dwc2_readl(regs + DOEPTSIZ(idx)),
dwc2_readl(regs + DOEPDMA(idx))); dwc2_readl(regs + DOEPDMA(idx)));
} }
dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n", dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n",
......
此差异已折叠。
...@@ -521,28 +521,28 @@ static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe) ...@@ -521,28 +521,28 @@ static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe)
return !dwc2_hcd_is_pipe_in(pipe); return !dwc2_hcd_is_pipe_in(pipe);
} }
extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq); int dwc2_hcd_init(struct dwc2_hsotg *hsotg);
extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg); void dwc2_hcd_remove(struct dwc2_hsotg *hsotg);
/* Transaction Execution Functions */ /* Transaction Execution Functions */
extern enum dwc2_transaction_type dwc2_hcd_select_transactions( enum dwc2_transaction_type dwc2_hcd_select_transactions(
struct dwc2_hsotg *hsotg); struct dwc2_hsotg *hsotg);
extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg, void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
enum dwc2_transaction_type tr_type); enum dwc2_transaction_type tr_type);
/* Schedule Queue Functions */ /* Schedule Queue Functions */
/* Implemented in hcd_queue.c */ /* Implemented in hcd_queue.c */
extern struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
struct dwc2_hcd_urb *urb, struct dwc2_hcd_urb *urb,
gfp_t mem_flags); gfp_t mem_flags);
extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
int sched_csplit); int sched_csplit);
extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb); void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb);
extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
struct dwc2_qh *qh); struct dwc2_qh *qh);
/* Unlinks and frees a QTD */ /* Unlinks and frees a QTD */
...@@ -556,15 +556,15 @@ static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg, ...@@ -556,15 +556,15 @@ static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
} }
/* Descriptor DMA support functions */ /* Descriptor DMA support functions */
extern void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg, void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg,
struct dwc2_qh *qh); struct dwc2_qh *qh);
extern void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
struct dwc2_host_chan *chan, int chnum, struct dwc2_host_chan *chan, int chnum,
enum dwc2_halt_status halt_status); enum dwc2_halt_status halt_status);
extern int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
gfp_t mem_flags); gfp_t mem_flags);
extern void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
/* Check if QH is non-periodic */ /* Check if QH is non-periodic */
#define dwc2_qh_is_non_per(_qh_ptr_) \ #define dwc2_qh_is_non_per(_qh_ptr_) \
...@@ -732,7 +732,7 @@ static inline u16 dwc2_hcd_get_ep_bandwidth(struct dwc2_hsotg *hsotg, ...@@ -732,7 +732,7 @@ static inline u16 dwc2_hcd_get_ep_bandwidth(struct dwc2_hsotg *hsotg,
return qh->host_us; return qh->host_us;
} }
extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg, void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
struct dwc2_host_chan *chan, int chnum, struct dwc2_host_chan *chan, int chnum,
struct dwc2_qtd *qtd); struct dwc2_qtd *qtd);
...@@ -746,14 +746,14 @@ extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg, ...@@ -746,14 +746,14 @@ extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
* Returns IRQ_HANDLED if interrupt is handled * Returns IRQ_HANDLED if interrupt is handled
* Return IRQ_NONE if interrupt is not handled * Return IRQ_NONE if interrupt is not handled
*/ */
extern irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg); irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg);
/** /**
* dwc2_hcd_stop() - Halts the DWC_otg host mode operation * dwc2_hcd_stop() - Halts the DWC_otg host mode operation
* *
* @hsotg: The DWC2 HCD * @hsotg: The DWC2 HCD
*/ */
extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg); void dwc2_hcd_stop(struct dwc2_hsotg *hsotg);
/** /**
* dwc2_hcd_is_b_host() - Returns 1 if core currently is acting as B host, * dwc2_hcd_is_b_host() - Returns 1 if core currently is acting as B host,
...@@ -761,7 +761,7 @@ extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg); ...@@ -761,7 +761,7 @@ extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg);
* *
* @hsotg: The DWC2 HCD * @hsotg: The DWC2 HCD
*/ */
extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg); int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg);
/** /**
* dwc2_hcd_dump_state() - Dumps hsotg state * dwc2_hcd_dump_state() - Dumps hsotg state
...@@ -771,7 +771,7 @@ extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg); ...@@ -771,7 +771,7 @@ extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg);
* NOTE: This function will be removed once the peripheral controller code * NOTE: This function will be removed once the peripheral controller code
* is integrated and the driver is stable * is integrated and the driver is stable
*/ */
extern void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg); void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg);
/** /**
* dwc2_hcd_dump_frrem() - Dumps the average frame remaining at SOF * dwc2_hcd_dump_frrem() - Dumps the average frame remaining at SOF
...@@ -784,7 +784,7 @@ extern void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg); ...@@ -784,7 +784,7 @@ extern void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg);
* NOTE: This function will be removed once the peripheral controller code * NOTE: This function will be removed once the peripheral controller code
* is integrated and the driver is stable * is integrated and the driver is stable
*/ */
extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg); void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg);
/* URB interface */ /* URB interface */
...@@ -793,14 +793,14 @@ extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg); ...@@ -793,14 +793,14 @@ extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg);
#define URB_SEND_ZERO_PACKET 0x2 #define URB_SEND_ZERO_PACKET 0x2
/* Host driver callbacks */ /* Host driver callbacks */
extern struct dwc2_tt *dwc2_host_get_tt_info(struct dwc2_hsotg *hsotg, struct dwc2_tt *dwc2_host_get_tt_info(struct dwc2_hsotg *hsotg,
void *context, gfp_t mem_flags, void *context, gfp_t mem_flags,
int *ttport); int *ttport);
extern void dwc2_host_put_tt_info(struct dwc2_hsotg *hsotg, void dwc2_host_put_tt_info(struct dwc2_hsotg *hsotg,
struct dwc2_tt *dwc_tt); struct dwc2_tt *dwc_tt);
extern int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context); int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context);
extern void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
int status); int status);
#ifdef DEBUG #ifdef DEBUG
......
...@@ -89,8 +89,8 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, ...@@ -89,8 +89,8 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
{ {
struct kmem_cache *desc_cache; struct kmem_cache *desc_cache;
if (qh->ep_type == USB_ENDPOINT_XFER_ISOC if (qh->ep_type == USB_ENDPOINT_XFER_ISOC &&
&& qh->dev_speed == USB_SPEED_HIGH) qh->dev_speed == USB_SPEED_HIGH)
desc_cache = hsotg->desc_hsisoc_cache; desc_cache = hsotg->desc_hsisoc_cache;
else else
desc_cache = hsotg->desc_gen_cache; desc_cache = hsotg->desc_gen_cache;
...@@ -106,7 +106,7 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, ...@@ -106,7 +106,7 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
qh->desc_list_sz, qh->desc_list_sz,
DMA_TO_DEVICE); DMA_TO_DEVICE);
qh->n_bytes = kzalloc(sizeof(u32) * dwc2_max_desc_num(qh), flags); qh->n_bytes = kcalloc(dwc2_max_desc_num(qh), sizeof(u32), flags);
if (!qh->n_bytes) { if (!qh->n_bytes) {
dma_unmap_single(hsotg->dev, qh->desc_list_dma, dma_unmap_single(hsotg->dev, qh->desc_list_dma,
qh->desc_list_sz, qh->desc_list_sz,
...@@ -123,8 +123,8 @@ static void dwc2_desc_list_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) ...@@ -123,8 +123,8 @@ static void dwc2_desc_list_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
{ {
struct kmem_cache *desc_cache; struct kmem_cache *desc_cache;
if (qh->ep_type == USB_ENDPOINT_XFER_ISOC if (qh->ep_type == USB_ENDPOINT_XFER_ISOC &&
&& qh->dev_speed == USB_SPEED_HIGH) qh->dev_speed == USB_SPEED_HIGH)
desc_cache = hsotg->desc_hsisoc_cache; desc_cache = hsotg->desc_hsisoc_cache;
else else
desc_cache = hsotg->desc_gen_cache; desc_cache = hsotg->desc_gen_cache;
...@@ -175,7 +175,6 @@ static void dwc2_frame_list_free(struct dwc2_hsotg *hsotg) ...@@ -175,7 +175,6 @@ static void dwc2_frame_list_free(struct dwc2_hsotg *hsotg)
hsotg->frame_list = NULL; hsotg->frame_list = NULL;
spin_unlock_irqrestore(&hsotg->lock, flags); spin_unlock_irqrestore(&hsotg->lock, flags);
} }
static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en) static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en)
...@@ -297,7 +296,7 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg, ...@@ -297,7 +296,7 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg,
struct dwc2_host_chan *chan = qh->channel; struct dwc2_host_chan *chan = qh->channel;
if (dwc2_qh_is_non_per(qh)) { if (dwc2_qh_is_non_per(qh)) {
if (hsotg->params.uframe_sched > 0) if (hsotg->params.uframe_sched)
hsotg->available_host_channels++; hsotg->available_host_channels++;
else else
hsotg->non_periodic_channels--; hsotg->non_periodic_channels--;
...@@ -404,7 +403,7 @@ void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) ...@@ -404,7 +403,7 @@ void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC || if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC ||
qh->ep_type == USB_ENDPOINT_XFER_INT) && qh->ep_type == USB_ENDPOINT_XFER_INT) &&
(hsotg->params.uframe_sched > 0 || (hsotg->params.uframe_sched ||
!hsotg->periodic_channels) && hsotg->frame_list) { !hsotg->periodic_channels) && hsotg->frame_list) {
dwc2_per_sched_disable(hsotg); dwc2_per_sched_disable(hsotg);
dwc2_frame_list_free(hsotg); dwc2_frame_list_free(hsotg);
......
...@@ -297,8 +297,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, ...@@ -297,8 +297,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
HCFG_FSLSPCLKSEL_SHIFT; HCFG_FSLSPCLKSEL_SHIFT;
if (prtspd == HPRT0_SPD_LOW_SPEED && if (prtspd == HPRT0_SPD_LOW_SPEED &&
params->host_ls_low_power_phy_clk == params->host_ls_low_power_phy_clk) {
DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ) {
/* 6 MHZ */ /* 6 MHZ */
dev_vdbg(hsotg->dev, dev_vdbg(hsotg->dev,
"FS_PHY programming HCFG to 6 MHz\n"); "FS_PHY programming HCFG to 6 MHz\n");
...@@ -398,7 +397,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) ...@@ -398,7 +397,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg)
if (hsotg->params.dma_desc_fs_enable) { if (hsotg->params.dma_desc_fs_enable) {
u32 hcfg; u32 hcfg;
hsotg->params.dma_desc_enable = 0; hsotg->params.dma_desc_enable = false;
hsotg->new_connection = false; hsotg->new_connection = false;
hcfg = dwc2_readl(hsotg->regs + HCFG); hcfg = dwc2_readl(hsotg->regs + HCFG);
hcfg &= ~HCFG_DESCDMA; hcfg &= ~HCFG_DESCDMA;
...@@ -442,7 +441,7 @@ static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg, ...@@ -442,7 +441,7 @@ static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg,
count = (hctsiz & TSIZ_XFERSIZE_MASK) >> count = (hctsiz & TSIZ_XFERSIZE_MASK) >>
TSIZ_XFERSIZE_SHIFT; TSIZ_XFERSIZE_SHIFT;
length = chan->xfer_len - count; length = chan->xfer_len - count;
if (short_read != NULL) if (short_read)
*short_read = (count != 0); *short_read = (count != 0);
} else if (chan->qh->do_split) { } else if (chan->qh->do_split) {
length = qtd->ssplit_out_xfer_count; length = qtd->ssplit_out_xfer_count;
...@@ -604,7 +603,7 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state( ...@@ -604,7 +603,7 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
/* Skip whole frame */ /* Skip whole frame */
if (chan->qh->do_split && if (chan->qh->do_split &&
chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in && chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in &&
hsotg->params.host_dma > 0) { hsotg->params.host_dma) {
qtd->complete_split = 0; qtd->complete_split = 0;
qtd->isoc_split_offset = 0; qtd->isoc_split_offset = 0;
} }
...@@ -743,7 +742,7 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg, ...@@ -743,7 +742,7 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
dwc2_hc_cleanup(hsotg, chan); dwc2_hc_cleanup(hsotg, chan);
list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list); list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list);
if (hsotg->params.uframe_sched > 0) { if (hsotg->params.uframe_sched) {
hsotg->available_host_channels++; hsotg->available_host_channels++;
} else { } else {
switch (chan->ep_type) { switch (chan->ep_type) {
...@@ -789,7 +788,7 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg, ...@@ -789,7 +788,7 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
if (dbg_hc(chan)) if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "%s()\n", __func__); dev_vdbg(hsotg->dev, "%s()\n", __func__);
if (hsotg->params.host_dma > 0) { if (hsotg->params.host_dma) {
if (dbg_hc(chan)) if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "DMA enabled\n"); dev_vdbg(hsotg->dev, "DMA enabled\n");
dwc2_release_channel(hsotg, chan, qtd, halt_status); dwc2_release_channel(hsotg, chan, qtd, halt_status);
...@@ -979,7 +978,7 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, ...@@ -979,7 +978,7 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg,
pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info);
if (hsotg->params.dma_desc_enable > 0) { if (hsotg->params.dma_desc_enable) {
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status); dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status);
if (pipe_type == USB_ENDPOINT_XFER_ISOC) if (pipe_type == USB_ENDPOINT_XFER_ISOC)
/* Do not disable the interrupt, just clear it */ /* Do not disable the interrupt, just clear it */
...@@ -990,7 +989,7 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, ...@@ -990,7 +989,7 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg,
/* Handle xfer complete on CSPLIT */ /* Handle xfer complete on CSPLIT */
if (chan->qh->do_split) { if (chan->qh->do_split) {
if (chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in && if (chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in &&
hsotg->params.host_dma > 0) { hsotg->params.host_dma) {
if (qtd->complete_split && if (qtd->complete_split &&
dwc2_xfercomp_isoc_split_in(hsotg, chan, chnum, dwc2_xfercomp_isoc_split_in(hsotg, chan, chnum,
qtd)) qtd))
...@@ -1078,7 +1077,8 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, ...@@ -1078,7 +1077,8 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg,
dev_vdbg(hsotg->dev, " Isochronous transfer complete\n"); dev_vdbg(hsotg->dev, " Isochronous transfer complete\n");
if (qtd->isoc_split_pos == DWC2_HCSPLT_XACTPOS_ALL) if (qtd->isoc_split_pos == DWC2_HCSPLT_XACTPOS_ALL)
halt_status = dwc2_update_isoc_urb_state(hsotg, chan, halt_status = dwc2_update_isoc_urb_state(hsotg, chan,
chnum, qtd, DWC2_HC_XFER_COMPLETE); chnum, qtd,
DWC2_HC_XFER_COMPLETE);
dwc2_complete_periodic_xfer(hsotg, chan, chnum, qtd, dwc2_complete_periodic_xfer(hsotg, chan, chnum, qtd,
halt_status); halt_status);
break; break;
...@@ -1102,7 +1102,7 @@ static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg, ...@@ -1102,7 +1102,7 @@ static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg,
dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n", dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n",
chnum); chnum);
if (hsotg->params.dma_desc_enable > 0) { if (hsotg->params.dma_desc_enable) {
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
DWC2_HC_XFER_STALL); DWC2_HC_XFER_STALL);
goto handle_stall_done; goto handle_stall_done;
...@@ -1212,7 +1212,7 @@ static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg, ...@@ -1212,7 +1212,7 @@ static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg,
switch (dwc2_hcd_get_pipe_type(&qtd->urb->pipe_info)) { switch (dwc2_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
case USB_ENDPOINT_XFER_CONTROL: case USB_ENDPOINT_XFER_CONTROL:
case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_BULK:
if (hsotg->params.host_dma > 0 && chan->ep_is_in) { if (hsotg->params.host_dma && chan->ep_is_in) {
/* /*
* NAK interrupts are enabled on bulk/control IN * NAK interrupts are enabled on bulk/control IN
* transfers in DMA mode for the sole purpose of * transfers in DMA mode for the sole purpose of
...@@ -1358,7 +1358,7 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg, ...@@ -1358,7 +1358,7 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
*/ */
if (chan->do_split && chan->complete_split) { if (chan->do_split && chan->complete_split) {
if (chan->ep_is_in && chan->ep_type == USB_ENDPOINT_XFER_ISOC && if (chan->ep_is_in && chan->ep_type == USB_ENDPOINT_XFER_ISOC &&
hsotg->params.host_dma > 0) { hsotg->params.host_dma) {
qtd->complete_split = 0; qtd->complete_split = 0;
qtd->isoc_split_offset = 0; qtd->isoc_split_offset = 0;
qtd->isoc_frame_index++; qtd->isoc_frame_index++;
...@@ -1379,7 +1379,7 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg, ...@@ -1379,7 +1379,7 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
struct dwc2_qh *qh = chan->qh; struct dwc2_qh *qh = chan->qh;
bool past_end; bool past_end;
if (hsotg->params.uframe_sched <= 0) { if (!hsotg->params.uframe_sched) {
int frnum = dwc2_hcd_get_frame_number(hsotg); int frnum = dwc2_hcd_get_frame_number(hsotg);
/* Don't have num_hs_transfers; simple logic */ /* Don't have num_hs_transfers; simple logic */
...@@ -1389,21 +1389,26 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg, ...@@ -1389,21 +1389,26 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
int end_frnum; int end_frnum;
/* /*
* Figure out the end frame based on schedule. * Figure out the end frame based on
* schedule.
* *
* We don't want to go on trying again and again * We don't want to go on trying again
* forever. Let's stop when we've done all the * and again forever. Let's stop when
* transfers that were scheduled. * we've done all the transfers that
* were scheduled.
* *
* We're going to be comparing start_active_frame * We're going to be comparing
* and next_active_frame, both of which are 1 * start_active_frame and
* before the time the packet goes on the wire, * next_active_frame, both of which
* so that cancels out. Basically if had 1 * are 1 before the time the packet
* transfer and we saw 1 NYET then we're done. * goes on the wire, so that cancels
* We're getting a NYET here so if next >= * out. Basically if had 1 transfer
* (start + num_transfers) we're done. The * and we saw 1 NYET then we're done.
* complexity is that for all but ISOC_OUT we * We're getting a NYET here so if
* skip one slot. * next >= (start + num_transfers)
* we're done. The complexity is that
* for all but ISOC_OUT we skip one
* slot.
*/ */
end_frnum = dwc2_frame_num_inc( end_frnum = dwc2_frame_num_inc(
qh->start_active_frame, qh->start_active_frame,
...@@ -1472,7 +1477,7 @@ static void dwc2_hc_babble_intr(struct dwc2_hsotg *hsotg, ...@@ -1472,7 +1477,7 @@ static void dwc2_hc_babble_intr(struct dwc2_hsotg *hsotg,
dwc2_hc_handle_tt_clear(hsotg, chan, qtd); dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
if (hsotg->params.dma_desc_enable > 0) { if (hsotg->params.dma_desc_enable) {
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
DWC2_HC_XFER_BABBLE_ERR); DWC2_HC_XFER_BABBLE_ERR);
goto disable_int; goto disable_int;
...@@ -1577,7 +1582,7 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg, ...@@ -1577,7 +1582,7 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg,
dev_err(hsotg->dev, " Interval: %d\n", urb->interval); dev_err(hsotg->dev, " Interval: %d\n", urb->interval);
/* Core halts the channel for Descriptor DMA mode */ /* Core halts the channel for Descriptor DMA mode */
if (hsotg->params.dma_desc_enable > 0) { if (hsotg->params.dma_desc_enable) {
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
DWC2_HC_XFER_AHB_ERR); DWC2_HC_XFER_AHB_ERR);
goto handle_ahberr_done; goto handle_ahberr_done;
...@@ -1609,7 +1614,7 @@ static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg, ...@@ -1609,7 +1614,7 @@ static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg,
dwc2_hc_handle_tt_clear(hsotg, chan, qtd); dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
if (hsotg->params.dma_desc_enable > 0) { if (hsotg->params.dma_desc_enable) {
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
DWC2_HC_XFER_XACT_ERR); DWC2_HC_XFER_XACT_ERR);
goto handle_xacterr_done; goto handle_xacterr_done;
...@@ -1620,7 +1625,6 @@ static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg, ...@@ -1620,7 +1625,6 @@ static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg,
case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_BULK:
qtd->error_count++; qtd->error_count++;
if (!chan->qh->ping_state) { if (!chan->qh->ping_state) {
dwc2_update_urb_state_abn(hsotg, chan, chnum, qtd->urb, dwc2_update_urb_state_abn(hsotg, chan, chnum, qtd->urb,
qtd, DWC2_HC_XFER_XACT_ERR); qtd, DWC2_HC_XFER_XACT_ERR);
dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd); dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd);
...@@ -1803,8 +1807,8 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg, ...@@ -1803,8 +1807,8 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE || if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE ||
(chan->halt_status == DWC2_HC_XFER_AHB_ERR && (chan->halt_status == DWC2_HC_XFER_AHB_ERR &&
hsotg->params.dma_desc_enable <= 0)) { !hsotg->params.dma_desc_enable)) {
if (hsotg->params.dma_desc_enable > 0) if (hsotg->params.dma_desc_enable)
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
chan->halt_status); chan->halt_status);
else else
...@@ -1835,7 +1839,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg, ...@@ -1835,7 +1839,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
} else if (chan->hcint & HCINTMSK_STALL) { } else if (chan->hcint & HCINTMSK_STALL) {
dwc2_hc_stall_intr(hsotg, chan, chnum, qtd); dwc2_hc_stall_intr(hsotg, chan, chnum, qtd);
} else if ((chan->hcint & HCINTMSK_XACTERR) && } else if ((chan->hcint & HCINTMSK_XACTERR) &&
hsotg->params.dma_desc_enable <= 0) { !hsotg->params.dma_desc_enable) {
if (out_nak_enh) { if (out_nak_enh) {
if (chan->hcint & if (chan->hcint &
(HCINTMSK_NYET | HCINTMSK_NAK | HCINTMSK_ACK)) { (HCINTMSK_NYET | HCINTMSK_NAK | HCINTMSK_ACK)) {
...@@ -1855,10 +1859,10 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg, ...@@ -1855,10 +1859,10 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
*/ */
dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd); dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
} else if ((chan->hcint & HCINTMSK_XCS_XACT) && } else if ((chan->hcint & HCINTMSK_XCS_XACT) &&
hsotg->params.dma_desc_enable > 0) { hsotg->params.dma_desc_enable) {
dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd); dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
} else if ((chan->hcint & HCINTMSK_AHBERR) && } else if ((chan->hcint & HCINTMSK_AHBERR) &&
hsotg->params.dma_desc_enable > 0) { hsotg->params.dma_desc_enable) {
dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd); dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd);
} else if (chan->hcint & HCINTMSK_BBLERR) { } else if (chan->hcint & HCINTMSK_BBLERR) {
dwc2_hc_babble_intr(hsotg, chan, chnum, qtd); dwc2_hc_babble_intr(hsotg, chan, chnum, qtd);
...@@ -1951,7 +1955,7 @@ static void dwc2_hc_chhltd_intr(struct dwc2_hsotg *hsotg, ...@@ -1951,7 +1955,7 @@ static void dwc2_hc_chhltd_intr(struct dwc2_hsotg *hsotg,
dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: Channel Halted--\n", dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: Channel Halted--\n",
chnum); chnum);
if (hsotg->params.host_dma > 0) { if (hsotg->params.host_dma) {
dwc2_hc_chhltd_intr_dma(hsotg, chan, chnum, qtd); dwc2_hc_chhltd_intr_dma(hsotg, chan, chnum, qtd);
} else { } else {
if (!dwc2_halt_status_ok(hsotg, chan, chnum, qtd)) if (!dwc2_halt_status_ok(hsotg, chan, chnum, qtd))
...@@ -1970,7 +1974,7 @@ static bool dwc2_check_qtd_still_ok(struct dwc2_qtd *qtd, struct dwc2_qh *qh) ...@@ -1970,7 +1974,7 @@ static bool dwc2_check_qtd_still_ok(struct dwc2_qtd *qtd, struct dwc2_qh *qh)
{ {
struct dwc2_qtd *cur_head; struct dwc2_qtd *cur_head;
if (qh == NULL) if (!qh)
return false; return false;
cur_head = list_first_entry(&qh->qtd_list, struct dwc2_qtd, cur_head = list_first_entry(&qh->qtd_list, struct dwc2_qtd,
...@@ -2028,7 +2032,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) ...@@ -2028,7 +2032,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
* interrupt unmasked * interrupt unmasked
*/ */
WARN_ON(hcint != HCINTMSK_CHHLTD); WARN_ON(hcint != HCINTMSK_CHHLTD);
if (hsotg->params.dma_desc_enable > 0) if (hsotg->params.dma_desc_enable)
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
chan->halt_status); chan->halt_status);
else else
...@@ -2056,7 +2060,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) ...@@ -2056,7 +2060,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
qtd = list_first_entry(&chan->qh->qtd_list, struct dwc2_qtd, qtd = list_first_entry(&chan->qh->qtd_list, struct dwc2_qtd,
qtd_list_entry); qtd_list_entry);
if (hsotg->params.host_dma <= 0) { if (!hsotg->params.host_dma) {
if ((hcint & HCINTMSK_CHHLTD) && hcint != HCINTMSK_CHHLTD) if ((hcint & HCINTMSK_CHHLTD) && hcint != HCINTMSK_CHHLTD)
hcint &= ~HCINTMSK_CHHLTD; hcint &= ~HCINTMSK_CHHLTD;
} }
......
...@@ -76,14 +76,13 @@ static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg) ...@@ -76,14 +76,13 @@ static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg)
int num_channels; int num_channels;
num_channels = hsotg->params.host_channels; num_channels = hsotg->params.host_channels;
if (hsotg->periodic_channels + hsotg->non_periodic_channels < if ((hsotg->periodic_channels + hsotg->non_periodic_channels <
num_channels num_channels) && (hsotg->periodic_channels < num_channels - 1)) {
&& hsotg->periodic_channels < num_channels - 1) {
status = 0; status = 0;
} else { } else {
dev_dbg(hsotg->dev, dev_dbg(hsotg->dev,
"%s: Total channels: %d, Periodic: %d, " "%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n",
"Non-periodic: %d\n", __func__, num_channels, __func__, num_channels,
hsotg->periodic_channels, hsotg->non_periodic_channels); hsotg->periodic_channels, hsotg->non_periodic_channels);
status = -ENOSPC; status = -ENOSPC;
} }
...@@ -485,7 +484,6 @@ static void pmap_print(unsigned long *map, int bits_per_period, ...@@ -485,7 +484,6 @@ static void pmap_print(unsigned long *map, int bits_per_period,
} }
} }
struct dwc2_qh_print_data { struct dwc2_qh_print_data {
struct dwc2_hsotg *hsotg; struct dwc2_hsotg *hsotg;
struct dwc2_qh *qh; struct dwc2_qh *qh;
...@@ -558,7 +556,6 @@ static void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg, ...@@ -558,7 +556,6 @@ static void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg,
DWC2_HS_SCHEDULE_UFRAMES, "uFrame", "us", DWC2_HS_SCHEDULE_UFRAMES, "uFrame", "us",
dwc2_qh_print, &print_data); dwc2_qh_print, &print_data);
} }
return;
} }
#else #else
static inline void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg, static inline void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg,
...@@ -587,7 +584,7 @@ static int dwc2_ls_pmap_schedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, ...@@ -587,7 +584,7 @@ static int dwc2_ls_pmap_schedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
unsigned long *map = dwc2_get_ls_map(hsotg, qh); unsigned long *map = dwc2_get_ls_map(hsotg, qh);
int slice; int slice;
if (map == NULL) if (!map)
return -EINVAL; return -EINVAL;
/* /*
...@@ -626,7 +623,7 @@ static void dwc2_ls_pmap_unschedule(struct dwc2_hsotg *hsotg, ...@@ -626,7 +623,7 @@ static void dwc2_ls_pmap_unschedule(struct dwc2_hsotg *hsotg,
unsigned long *map = dwc2_get_ls_map(hsotg, qh); unsigned long *map = dwc2_get_ls_map(hsotg, qh);
/* Schedule should have failed, so no worries about no error code */ /* Schedule should have failed, so no worries about no error code */
if (map == NULL) if (!map)
return; return;
pmap_unschedule(map, DWC2_LS_PERIODIC_SLICES_PER_FRAME, pmap_unschedule(map, DWC2_LS_PERIODIC_SLICES_PER_FRAME,
...@@ -1107,7 +1104,7 @@ static void dwc2_pick_first_frame(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) ...@@ -1107,7 +1104,7 @@ static void dwc2_pick_first_frame(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
next_active_frame = earliest_frame; next_active_frame = earliest_frame;
/* Get the "no microframe schduler" out of the way... */ /* Get the "no microframe schduler" out of the way... */
if (hsotg->params.uframe_sched <= 0) { if (!hsotg->params.uframe_sched) {
if (qh->do_split) if (qh->do_split)
/* Splits are active at microframe 0 minus 1 */ /* Splits are active at microframe 0 minus 1 */
next_active_frame |= 0x7; next_active_frame |= 0x7;
...@@ -1200,7 +1197,7 @@ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) ...@@ -1200,7 +1197,7 @@ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
{ {
int status; int status;
if (hsotg->params.uframe_sched > 0) { if (hsotg->params.uframe_sched) {
status = dwc2_uframe_schedule(hsotg, qh); status = dwc2_uframe_schedule(hsotg, qh);
} else { } else {
status = dwc2_periodic_channel_available(hsotg); status = dwc2_periodic_channel_available(hsotg);
...@@ -1221,7 +1218,7 @@ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) ...@@ -1221,7 +1218,7 @@ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
return status; return status;
} }
if (hsotg->params.uframe_sched <= 0) if (!hsotg->params.uframe_sched)
/* Reserve periodic channel */ /* Reserve periodic channel */
hsotg->periodic_channels++; hsotg->periodic_channels++;
...@@ -1257,7 +1254,7 @@ static void dwc2_do_unreserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) ...@@ -1257,7 +1254,7 @@ static void dwc2_do_unreserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
/* Update claimed usecs per (micro)frame */ /* Update claimed usecs per (micro)frame */
hsotg->periodic_usecs -= qh->host_us; hsotg->periodic_usecs -= qh->host_us;
if (hsotg->params.uframe_sched > 0) { if (hsotg->params.uframe_sched) {
dwc2_uframe_unschedule(hsotg, qh); dwc2_uframe_unschedule(hsotg, qh);
} else { } else {
/* Release periodic channel reservation */ /* Release periodic channel reservation */
...@@ -1394,7 +1391,7 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) ...@@ -1394,7 +1391,7 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
qh->unreserve_pending = 0; qh->unreserve_pending = 0;
if (hsotg->params.dma_desc_enable > 0) if (hsotg->params.dma_desc_enable)
/* Don't rely on SOF and start in ready schedule */ /* Don't rely on SOF and start in ready schedule */
list_add_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); list_add_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready);
else else
...@@ -1501,7 +1498,6 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, ...@@ -1501,7 +1498,6 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
device_ns += dwc_tt->usb_tt->think_time; device_ns += dwc_tt->usb_tt->think_time;
qh->device_us = NS_TO_US(device_ns); qh->device_us = NS_TO_US(device_ns);
qh->device_interval = urb->interval; qh->device_interval = urb->interval;
qh->host_interval = urb->interval * (do_split ? 8 : 1); qh->host_interval = urb->interval * (do_split ? 8 : 1);
...@@ -1602,7 +1598,7 @@ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, ...@@ -1602,7 +1598,7 @@ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
dwc2_qh_init(hsotg, qh, urb, mem_flags); dwc2_qh_init(hsotg, qh, urb, mem_flags);
if (hsotg->params.dma_desc_enable > 0 && if (hsotg->params.dma_desc_enable &&
dwc2_hcd_qh_init_ddma(hsotg, qh, mem_flags) < 0) { dwc2_hcd_qh_init_ddma(hsotg, qh, mem_flags) < 0) {
dwc2_hcd_qh_free(hsotg, qh); dwc2_hcd_qh_free(hsotg, qh);
return NULL; return NULL;
...@@ -1714,7 +1710,7 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) ...@@ -1714,7 +1710,7 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
dwc2_deschedule_periodic(hsotg, qh); dwc2_deschedule_periodic(hsotg, qh);
hsotg->periodic_qh_count--; hsotg->periodic_qh_count--;
if (!hsotg->periodic_qh_count && if (!hsotg->periodic_qh_count &&
hsotg->params.dma_desc_enable <= 0) { !hsotg->params.dma_desc_enable) {
intr_mask = dwc2_readl(hsotg->regs + GINTMSK); intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
intr_mask &= ~GINTSTS_SOF; intr_mask &= ~GINTSTS_SOF;
dwc2_writel(intr_mask, hsotg->regs + GINTMSK); dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
......
此差异已折叠。
此差异已折叠。
...@@ -136,11 +136,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) ...@@ -136,11 +136,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
return ret; return ret;
} }
if (hsotg->uphy) if (hsotg->uphy) {
ret = usb_phy_init(hsotg->uphy); ret = usb_phy_init(hsotg->uphy);
else if (hsotg->plat && hsotg->plat->phy_init) } else if (hsotg->plat && hsotg->plat->phy_init) {
ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
else { } else {
ret = phy_power_on(hsotg->phy); ret = phy_power_on(hsotg->phy);
if (ret == 0) if (ret == 0)
ret = phy_init(hsotg->phy); ret = phy_init(hsotg->phy);
...@@ -170,11 +170,11 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) ...@@ -170,11 +170,11 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
struct platform_device *pdev = to_platform_device(hsotg->dev); struct platform_device *pdev = to_platform_device(hsotg->dev);
int ret = 0; int ret = 0;
if (hsotg->uphy) if (hsotg->uphy) {
usb_phy_shutdown(hsotg->uphy); usb_phy_shutdown(hsotg->uphy);
else if (hsotg->plat && hsotg->plat->phy_exit) } else if (hsotg->plat && hsotg->plat->phy_exit) {
ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
else { } else {
ret = phy_exit(hsotg->phy); ret = phy_exit(hsotg->phy);
if (ret == 0) if (ret == 0)
ret = phy_power_off(hsotg->phy); ret = phy_power_off(hsotg->phy);
...@@ -445,7 +445,7 @@ static int dwc2_driver_probe(struct platform_device *dev) ...@@ -445,7 +445,7 @@ static int dwc2_driver_probe(struct platform_device *dev)
} }
if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) { if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
retval = dwc2_hcd_init(hsotg, hsotg->irq); retval = dwc2_hcd_init(hsotg);
if (retval) { if (retval) {
if (hsotg->gadget_enabled) if (hsotg->gadget_enabled)
dwc2_hsotg_remove(hsotg); dwc2_hsotg_remove(hsotg);
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
/* Global constants */ /* Global constants */
#define DWC3_PULL_UP_TIMEOUT 500 /* ms */ #define DWC3_PULL_UP_TIMEOUT 500 /* ms */
#define DWC3_ZLP_BUF_SIZE 1024 /* size of a superspeed bulk */ #define DWC3_ZLP_BUF_SIZE 1024 /* size of a superspeed bulk */
#define DWC3_BOUNCE_SIZE 1024 /* size of a superspeed bulk */
#define DWC3_EP0_BOUNCE_SIZE 512 #define DWC3_EP0_BOUNCE_SIZE 512
#define DWC3_ENDPOINTS_NUM 32 #define DWC3_ENDPOINTS_NUM 32
#define DWC3_XHCI_RESOURCES_NUM 2 #define DWC3_XHCI_RESOURCES_NUM 2
...@@ -724,6 +725,7 @@ struct dwc3_hwparams { ...@@ -724,6 +725,7 @@ struct dwc3_hwparams {
* @epnum: endpoint number to which this request refers * @epnum: endpoint number to which this request refers
* @trb: pointer to struct dwc3_trb * @trb: pointer to struct dwc3_trb
* @trb_dma: DMA address of @trb * @trb_dma: DMA address of @trb
* @unaligned: true for OUT endpoints with length not divisible by maxp
* @direction: IN or OUT direction flag * @direction: IN or OUT direction flag
* @mapped: true when request has been dma-mapped * @mapped: true when request has been dma-mapped
* @queued: true when request has been queued to HW * @queued: true when request has been queued to HW
...@@ -740,6 +742,7 @@ struct dwc3_request { ...@@ -740,6 +742,7 @@ struct dwc3_request {
struct dwc3_trb *trb; struct dwc3_trb *trb;
dma_addr_t trb_dma; dma_addr_t trb_dma;
unsigned unaligned:1;
unsigned direction:1; unsigned direction:1;
unsigned mapped:1; unsigned mapped:1;
unsigned started:1; unsigned started:1;
...@@ -857,12 +860,14 @@ struct dwc3_scratchpad_array { ...@@ -857,12 +860,14 @@ struct dwc3_scratchpad_array {
struct dwc3 { struct dwc3 {
struct usb_ctrlrequest *ctrl_req; struct usb_ctrlrequest *ctrl_req;
struct dwc3_trb *ep0_trb; struct dwc3_trb *ep0_trb;
void *bounce;
void *ep0_bounce; void *ep0_bounce;
void *zlp_buf; void *zlp_buf;
void *scratchbuf; void *scratchbuf;
u8 *setup_buf; u8 *setup_buf;
dma_addr_t ctrl_req_addr; dma_addr_t ctrl_req_addr;
dma_addr_t ep0_trb_addr; dma_addr_t ep0_trb_addr;
dma_addr_t bounce_addr;
dma_addr_t ep0_bounce_addr; dma_addr_t ep0_bounce_addr;
dma_addr_t scratch_addr; dma_addr_t scratch_addr;
struct dwc3_request ep0_usb_req; struct dwc3_request ep0_usb_req;
......
...@@ -128,10 +128,8 @@ static int dwc3_exynos_probe(struct platform_device *pdev) ...@@ -128,10 +128,8 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
clk_prepare_enable(exynos->clk); clk_prepare_enable(exynos->clk);
exynos->susp_clk = devm_clk_get(dev, "usbdrd30_susp_clk"); exynos->susp_clk = devm_clk_get(dev, "usbdrd30_susp_clk");
if (IS_ERR(exynos->susp_clk)) { if (IS_ERR(exynos->susp_clk))
dev_info(dev, "no suspend clk specified\n");
exynos->susp_clk = NULL; exynos->susp_clk = NULL;
}
clk_prepare_enable(exynos->susp_clk); clk_prepare_enable(exynos->susp_clk);
if (of_device_is_compatible(node, "samsung,exynos7-dwusb3")) { if (of_device_is_compatible(node, "samsung,exynos7-dwusb3")) {
...@@ -290,7 +288,6 @@ static struct platform_driver dwc3_exynos_driver = { ...@@ -290,7 +288,6 @@ static struct platform_driver dwc3_exynos_driver = {
module_platform_driver(dwc3_exynos_driver); module_platform_driver(dwc3_exynos_driver);
MODULE_ALIAS("platform:exynos-dwc3");
MODULE_AUTHOR("Anton Tikhomirov <av.tikhomirov@samsung.com>"); MODULE_AUTHOR("Anton Tikhomirov <av.tikhomirov@samsung.com>");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("DesignWare USB3 EXYNOS Glue Layer"); MODULE_DESCRIPTION("DesignWare USB3 EXYNOS Glue Layer");
此差异已折叠。
...@@ -1123,7 +1123,21 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, ...@@ -1123,7 +1123,21 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
dwc->ep0state = EP0_STATUS_PHASE; dwc->ep0state = EP0_STATUS_PHASE;
if (dwc->delayed_status) { if (dwc->delayed_status) {
struct dwc3_ep *dep = dwc->eps[0];
WARN_ON_ONCE(event->endpoint_number != 1); WARN_ON_ONCE(event->endpoint_number != 1);
/*
* We should handle the delay STATUS phase here if the
* request for handling delay STATUS has been queued
* into the list.
*/
if (!list_empty(&dep->pending_list)) {
dwc->delayed_status = false;
usb_gadget_set_state(&dwc->gadget,
USB_STATE_CONFIGURED);
dwc3_ep0_do_control_status(dwc, event);
}
return; return;
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
mutex_lock(&opts->lock); \ mutex_lock(&opts->lock); \
qmult = gether_get_qmult(opts->net); \ qmult = gether_get_qmult(opts->net); \
mutex_unlock(&opts->lock); \ mutex_unlock(&opts->lock); \
return sprintf(page, "%d", qmult); \ return sprintf(page, "%d\n", qmult); \
} \ } \
\ \
static ssize_t _f_##_opts_qmult_store(struct config_item *item, \ static ssize_t _f_##_opts_qmult_store(struct config_item *item, \
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册