From 961b3d0a990f8b1214f5425c4acbebbd0b777e36 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 8 May 2014 19:25:57 +0300 Subject: usb: xhci: Use IS_ENABLED() macro Using the IS_ENABLED() macro can make the code shorter and easier to read. Signed-off-by: Fabio Estevam Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/usb/host/xhci.h') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 4746816aed3e..cc67c7686706 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1738,8 +1738,7 @@ static inline int xhci_register_pci(void) { return 0; } static inline void xhci_unregister_pci(void) {} #endif -#if defined(CONFIG_USB_XHCI_PLATFORM) \ - || defined(CONFIG_USB_XHCI_PLATFORM_MODULE) +#if IS_ENABLED(CONFIG_USB_XHCI_PLATFORM) int xhci_register_plat(void); void xhci_unregister_plat(void); #else -- cgit v1.2.2 From ddba5cd0aeff5bbed92ebdf4b1223300b0541e78 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 8 May 2014 19:26:00 +0300 Subject: xhci: Use command structures when queuing commands on the command ring To create a global command queue we require that each command put on the command ring is submitted with a command structure. Functions that queue commands and wait for completion need to allocate a command before submitting it, and free it once completed. The following command queuing functions need to be modified. xhci_configure_endpoint() xhci_address_device() xhci_queue_slot_control() xhci_queue_stop_endpoint() xhci_queue_new_dequeue_state() xhci_queue_reset_ep() xhci_configure_endpoint() xhci_configure_endpoint() could already be called with a command structure, and only xhci_check_maxpacket and xhci_check_bandwidth did not do so. These are changed and a command structure is now required. This change also simplifies the configure endpoint command completion handling and the "goto bandwidth_change" handling code can be removed. In some cases the command queuing function is called in interrupt context. These commands needs to be allocated atomically, and they can't wait for completion. These commands will in this patch be freed directly after queuing, but freeing will be moved to the command completion event handler in a later patch once we get the global command queue up.(Just so that we won't leak memory in the middle of the patch set) Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers/usb/host/xhci.h') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index cc67c7686706..c0fdb4984b0d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1807,13 +1807,14 @@ struct xhci_segment *trb_in_td(struct xhci_segment *start_seg, dma_addr_t suspect_dma); int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code); void xhci_ring_cmd_db(struct xhci_hcd *xhci); -int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); -int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, - u32 slot_id, enum xhci_setup_dev); -int xhci_queue_vendor_command(struct xhci_hcd *xhci, +int xhci_queue_slot_control(struct xhci_hcd *xhci, struct xhci_command *cmd, + u32 trb_type, u32 slot_id); +int xhci_queue_address_device(struct xhci_hcd *xhci, struct xhci_command *cmd, + dma_addr_t in_ctx_ptr, u32 slot_id, enum xhci_setup_dev); +int xhci_queue_vendor_command(struct xhci_hcd *xhci, struct xhci_command *cmd, u32 field1, u32 field2, u32 field3, u32 field4); -int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, - unsigned int ep_index, int suspend); +int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, struct xhci_command *cmd, + int slot_id, unsigned int ep_index, int suspend); int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int slot_id, unsigned int ep_index); int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, @@ -1822,18 +1823,21 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int slot_id, unsigned int ep_index); int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int slot_id, unsigned int ep_index); -int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, - u32 slot_id, bool command_must_succeed); -int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, - u32 slot_id, bool command_must_succeed); -int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, - unsigned int ep_index); -int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id); +int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, + struct xhci_command *cmd, dma_addr_t in_ctx_ptr, u32 slot_id, + bool command_must_succeed); +int xhci_queue_evaluate_context(struct xhci_hcd *xhci, struct xhci_command *cmd, + dma_addr_t in_ctx_ptr, u32 slot_id, bool command_must_succeed); +int xhci_queue_reset_ep(struct xhci_hcd *xhci, struct xhci_command *cmd, + int slot_id, unsigned int ep_index); +int xhci_queue_reset_device(struct xhci_hcd *xhci, struct xhci_command *cmd, + u32 slot_id); void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id, struct xhci_td *cur_td, struct xhci_dequeue_state *state); void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, + struct xhci_command *cmd, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id, struct xhci_dequeue_state *deq_state); @@ -1847,7 +1851,6 @@ int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, union xhci_trb *cmd_trb); void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id); -union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring); /* xHCI roothub code */ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, -- cgit v1.2.2 From c9aa1a2de4cbf7d0db6012fbf86b6ee0c3719470 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 8 May 2014 19:26:01 +0300 Subject: xhci: Add a global command queue Create a list to store command structures, add a structure to it every time a command is submitted, and remove it from the list once we get a command completion event matching the command. Callers that wait for completion will free their command structures themselves. The other command structures are freed in the command completion event handler. Also add a check that prevents queuing commands if host is dying Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb/host/xhci.h') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c0fdb4984b0d..d33cd3750a15 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1484,6 +1484,7 @@ struct xhci_hcd { #define CMD_RING_STATE_ABORTED (1 << 1) #define CMD_RING_STATE_STOPPED (1 << 2) struct list_head cancel_cmd_list; + struct list_head cmd_list; unsigned int cmd_ring_reserved_trbs; struct xhci_ring *event_ring; struct xhci_erst erst; @@ -1851,6 +1852,7 @@ int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, union xhci_trb *cmd_trb); void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id); +void xhci_cleanup_command_queue(struct xhci_hcd *xhci); /* xHCI roothub code */ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, -- cgit v1.2.2 From 9ea1833e4c210ac5580f63495be15502f275c578 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 8 May 2014 19:26:02 +0300 Subject: xhci: Use completion and status in global command queue Remove the per-device command list and handle_cmd_in_cmd_wait_list() and use the completion and status variables found in the command structure in the global command list. Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/usb/host/xhci.h') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d33cd3750a15..fde57b09a9bd 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -937,9 +937,6 @@ struct xhci_virt_device { #define XHCI_MAX_RINGS_CACHED 31 struct xhci_virt_ep eps[31]; struct completion cmd_completion; - /* Status of the last command issued for this device */ - u32 cmd_status; - struct list_head cmd_list; u8 fake_port; u8 real_port; struct xhci_interval_bw_table *bw_table; -- cgit v1.2.2 From c311e391a7efd101250c0e123286709b7e736249 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 8 May 2014 19:26:03 +0300 Subject: xhci: rework command timeout and cancellation, Use one timer to control command timeout. start/kick the timer every time a command is completed and a new command is waiting, or a new command is added to a empty list. If the timer runs out, then tag the current command as "aborted", and start the xhci command abortion process. Previously each function that submitted a command had its own timer. If that command timed out, a new command structure for the command was created and it was put on a cancel_cmd_list list, then a pci write to abort the command ring was issued. when the ring was aborted, it checked if the current command was the one to be canceled, later when the ring was stopped the driver got ownership of the TRBs in the command ring, compared then to the TRBs in the cancel_cmd_list, and turned them into No-ops. Now, instead, at timeout we tag the status of the command in the command queue to be aborted, and start the ring abortion. Ring abortion stops the command ring and gives control of the commands to us. All the aborted commands are now turned into No-ops. If the ring is already stopped when the command times outs its not possible to start the ring abortion, in this case the command is turnd to No-op right away. All these changes allows us to remove the entire cancel_cmd_list code. The functions waiting for a command to finish no longer have their own timeouts. They will wait either until the command completes normally, or until the whole command abortion is done. Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb/host/xhci.h') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index fde57b09a9bd..2774526449a6 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1295,7 +1295,6 @@ struct xhci_td { /* command descriptor */ struct xhci_cd { - struct list_head cancel_cmd_list; struct xhci_command *command; union xhci_trb *cmd_trb; }; @@ -1480,9 +1479,10 @@ struct xhci_hcd { #define CMD_RING_STATE_RUNNING (1 << 0) #define CMD_RING_STATE_ABORTED (1 << 1) #define CMD_RING_STATE_STOPPED (1 << 2) - struct list_head cancel_cmd_list; struct list_head cmd_list; unsigned int cmd_ring_reserved_trbs; + struct timer_list cmd_timer; + struct xhci_command *current_cmd; struct xhci_ring *event_ring; struct xhci_erst erst; /* Scratchpad */ @@ -1845,8 +1845,8 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct xhci_dequeue_state *deq_state); void xhci_stop_endpoint_command_watchdog(unsigned long arg); -int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, - union xhci_trb *cmd_trb); +void xhci_handle_command_timeout(unsigned long data); + void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id); void xhci_cleanup_command_queue(struct xhci_hcd *xhci); -- cgit v1.2.2 From 4718c177405112386a977fd9f1cba5fd6aa82315 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 15 May 2014 12:17:32 +0200 Subject: usb: host: xhci-plat: add clock support Some platforms (such as the Armada 38x ones) can gate the clock of their USB controller. This patch adds the support for one clock in xhci-plat, by enabling it during probe and disabling it on remove. To achieve this, it adds a 'struct clk *' member in xhci_hcd. While only used for now in xhci-plat, it might be used by other drivers in the future. Moreover, the xhci_hcd structure already holds other members such as msix_count and msix_entries, which are MSI-X specific, and therefore only used by xhci-pci. Signed-off-by: Gregory CLEMENT Signed-off-by: Thomas Petazzoni Acked-by: Felipe Balbi Acked-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb/host/xhci.h') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2774526449a6..9ffecd56600d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1472,6 +1472,8 @@ struct xhci_hcd { /* msi-x vectors */ int msix_count; struct msix_entry *msix_entries; + /* optional clock */ + struct clk *clk; /* data structures */ struct xhci_device_context_array *dcbaa; struct xhci_ring *cmd_ring; -- cgit v1.2.2