linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pawel Laszczak <pawell@cadence.com>
To: unlisted-recipients:; (no To-header on input)
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	<linux-usb@vger.kernel.org>, Felipe Balbi <balbi@kernel.org>,
	<linux-kernel@vger.kernel.org>, <ltyrala@cadence.com>,
	<adouglas@cadence.com>, <pawell@cadence.com>
Subject: [PATCH 30/31] usb: usbssp: added support for TEST_MODE.
Date: Thu, 19 Jul 2018 18:58:03 +0100	[thread overview]
Message-ID: <1532023084-28083-31-git-send-email-pawell@cadence.com> (raw)
In-Reply-To: <1532023084-28083-1-git-send-email-pawell@cadence.com>

Patch implements TEST_MODE feature that puts the device port
into test mode. This feature is used only when device works
in HS mode

Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
 drivers/usb/usbssp/gadget-ep0.c  | 39 ++++++++++++++
 drivers/usb/usbssp/gadget-port.c | 93 ++++++++++++++++++++++++++++++++
 drivers/usb/usbssp/gadget.h      |  6 +++
 3 files changed, 138 insertions(+)

diff --git a/drivers/usb/usbssp/gadget-ep0.c b/drivers/usb/usbssp/gadget-ep0.c
index 3b7066875d46..e03a34d11dab 100644
--- a/drivers/usb/usbssp/gadget-ep0.c
+++ b/drivers/usb/usbssp/gadget-ep0.c
@@ -245,6 +245,41 @@ static int usbssp_ep0_handle_feature_u2(struct usbssp_udc *usbssp_data,
 	return 0;
 }
 
+static int usbssp_ep0_handle_feature_test(struct usbssp_udc *usbssp_data,
+					  enum usb_device_state state,
+					  u32 wIndex, int set)
+{
+	int test_mode;
+	__le32 __iomem *port_regs;
+	u32 temp;
+	unsigned long flags;
+	int retval;
+
+	if (usbssp_data->port_major_revision == 0x03)
+		return -EINVAL;
+
+	dev_info(usbssp_data->dev, "Test mode; %d\n", wIndex);
+
+	port_regs = usbssp_get_port_io_addr(usbssp_data);
+
+
+	test_mode = (wIndex & 0xff00) >> 8;
+
+	temp = readl(port_regs);
+	temp = usbssp_port_state_to_neutral(temp);
+
+	if (test_mode > TEST_FORCE_EN || test_mode < TEST_J) {
+		/* "stall" on error */
+		retval = -EPIPE;
+	}
+
+	usbssp_status_stage(usbssp_data);
+	retval = usbssp_enter_test_mode(usbssp_data, test_mode, &flags);
+	usbssp_exit_test_mode(usbssp_data);
+
+	return 0;
+}
+
 static int usbssp_ep0_handle_feature_device(struct usbssp_udc *usbssp_data,
 					    struct usb_ctrlrequest *ctrl,
 					    int set)
@@ -275,6 +310,10 @@ static int usbssp_ep0_handle_feature_device(struct usbssp_udc *usbssp_data,
 	case USB_DEVICE_LTM_ENABLE:
 		ret = -EINVAL;
 		break;
+	case USB_DEVICE_TEST_MODE:
+		ret = usbssp_ep0_handle_feature_test(usbssp_data, state,
+						wIndex, set);
+		break;
 	default:
 		dev_err(usbssp_data->dev, "%s Feature Request not supported\n",
 			(set) ? "Set" : "Clear");
diff --git a/drivers/usb/usbssp/gadget-port.c b/drivers/usb/usbssp/gadget-port.c
index 05a4eb2fd8bf..ebbff47e9455 100644
--- a/drivers/usb/usbssp/gadget-port.c
+++ b/drivers/usb/usbssp/gadget-port.c
@@ -192,3 +192,96 @@ void usbssp_test_and_clear_bit(struct usbssp_udc *usbssp_data,
 		writel(temp, port_regs);
 	}
 }
+
+static void usbssp_set_port_power(struct usbssp_udc *usbssp_data,
+				  bool on, unsigned long *flags)
+{
+	__le32 __iomem *addr;
+	u32 temp;
+
+	addr = usbssp_get_port_io_addr(usbssp_data);
+	temp = readl(addr);
+	temp = usbssp_port_state_to_neutral(temp);
+	if (on) {
+		/* Power on */
+		writel(temp | PORT_POWER, addr);
+		temp = readl(addr);
+		dev_dbg(usbssp_data->dev,
+			"set port power, actual port status = 0x%x\n",
+			temp);
+	} else {
+		/* Power off */
+		writel(temp & ~PORT_POWER, addr);
+		dev_dbg(usbssp_data->dev,
+			"clear port power, actual port status = 0x%x\n",
+			 temp);
+	}
+}
+
+static void usbssp_port_set_test_mode(struct usbssp_udc *usbssp_data,
+				      u16 test_mode)
+{
+	u32 temp;
+	__le32 __iomem *addr;
+
+	/* USBSSP only supports test mode for usb2 ports, */
+	addr = usbssp_get_port_io_addr(usbssp_data);
+	temp = readl(addr + PORTPMSC);
+	temp |= test_mode << PORT_TEST_MODE_SHIFT;
+	writel(temp, addr + PORTPMSC);
+	usbssp_data->test_mode = test_mode;
+	if (test_mode == TEST_FORCE_EN)
+		usbssp_start(usbssp_data);
+}
+
+int usbssp_enter_test_mode(struct usbssp_udc *usbssp_data,
+			   u16 test_mode, unsigned long *flags)
+{
+	int retval;
+
+	retval = usbssp_disable_slot(usbssp_data);
+	if (retval) {
+		dev_err(usbssp_data->dev,
+			"Failed to disable slot %d, %d. Enter test mode anyway\n",
+			usbssp_data->slot_id, retval);
+		return retval;
+	}
+
+	/* Put port to the Disable state by clear PP */
+	usbssp_set_port_power(usbssp_data, false, flags);
+
+	/* Stop the controller */
+	retval = usbssp_halt(usbssp_data);
+	if (retval)
+		return retval;
+
+	/* Disable runtime PM for test mode */
+	pm_runtime_forbid(usbssp_data->dev);
+
+	/* Set PORTPMSC.PTC field to enter selected test mode */
+	/* Port is selected by wIndex. port_id = wIndex + 1 */
+	dev_dbg(usbssp_data->dev, "Enter Test Mode: _id=%d\n",
+		test_mode);
+	usbssp_port_set_test_mode(usbssp_data, test_mode);
+
+	return retval;
+}
+
+int usbssp_exit_test_mode(struct usbssp_udc *usbssp_data)
+{
+	int retval;
+
+	if (!usbssp_data->test_mode) {
+		dev_err(usbssp_data->dev, "Not in test mode, do nothing.\n");
+		return 0;
+	}
+	if (usbssp_data->test_mode == TEST_FORCE_EN &&
+		!(usbssp_data->usbssp_state & USBSSP_STATE_HALTED)) {
+		retval = usbssp_halt(usbssp_data);
+		if (retval)
+			return retval;
+	}
+	pm_runtime_allow(usbssp_data->dev);
+	usbssp_data->test_mode = 0;
+	return usbssp_reset(usbssp_data);
+}
diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
index 59d7ef573d96..418bc5ad2a22 100644
--- a/drivers/usb/usbssp/gadget.h
+++ b/drivers/usb/usbssp/gadget.h
@@ -1744,6 +1744,7 @@ void usbssp_stop(struct usbssp_udc *usbssp_data);
 int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
 void usbssp_quiesce(struct usbssp_udc *usbssp_data);
 int usbssp_halt(struct usbssp_udc *usbssp_data);
+int usbssp_start(struct usbssp_udc *usbssp_data);
 extern int usbssp_reset(struct usbssp_udc *usbssp_data);
 int usbssp_disable_slot(struct usbssp_udc *usbssp_data);
 
@@ -1836,6 +1837,8 @@ void usbssp_test_and_clear_bit(struct usbssp_udc *usbssp_data,
 			__le32 __iomem *port_regs, u32 port_bit);
 
 void usbssp_udc_died(struct usbssp_udc *usbssp_data);
+u32 usbssp_port_state_to_neutral(u32 state);
+
 /* USBSSP DC contexts */
 struct usbssp_input_control_ctx *usbssp_get_input_control_ctx(
 					struct usbssp_container_ctx *ctx);
@@ -1867,6 +1870,9 @@ int usbssp_halt_endpoint(struct usbssp_udc *usbssp_data,
 			struct usbssp_ep *dep, int value);
 int usbssp_cmd_stop_ep(struct usbssp_udc *usbssp_data, struct usb_gadget *g,
 		struct usbssp_ep *ep_priv);
+int usbssp_enter_test_mode(struct usbssp_udc *usbssp_data,
+			u16 test_mode, unsigned long *flags);
+int usbssp_exit_test_mode(struct usbssp_udc *usbssp_data);
 int usbssp_setup_analyze(struct usbssp_udc *usbssp_data);
 int usbssp_status_stage(struct usbssp_udc *usbssp_data);
 
-- 
2.17.1


  parent reply	other threads:[~2018-07-19 17:59 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-19 17:57 [PATCH 00/31] Introduced new Cadence USBSSP DRD Driver Pawel Laszczak
2018-07-19 17:57 ` [PATCH 01/31] usb: usbssp: Defined register maps and other useful structures Pawel Laszczak
2018-07-19 17:57 ` [PATCH 02/31] usb: usbssp: Added some decoding functions Pawel Laszczak
2018-09-10 18:18   ` Greg Kroah-Hartman
2018-09-11  5:48     ` Felipe Balbi
2018-09-11  8:12       ` Greg Kroah-Hartman
2018-09-11  9:01         ` Pawel Laszczak
2018-07-19 17:57 ` [PATCH 03/31] usb: usbssp: Add trace events used in driver Pawel Laszczak
2018-07-19 17:57 ` [PATCH 04/31] usb: usbssp: Added USBSSP platform driver Pawel Laszczak
2018-08-01 12:24   ` Roger Quadros
2018-08-02  6:25     ` Pawel Laszczak
2018-08-02 13:28       ` Roger Quadros
2018-07-19 17:57 ` [PATCH 05/31] usb: usbssp: Added first part of initialization sequence Pawel Laszczak
2018-08-03 10:17   ` Roger Quadros
2018-08-06  8:57     ` Pawel Laszczak
2018-08-06 10:33       ` Roger Quadros
2018-08-06 12:03         ` Pawel Laszczak
2018-07-19 17:57 ` [PATCH 06/31] usb: usbssp: added template functions used by upper layer Pawel Laszczak
2018-08-03 10:42   ` Roger Quadros
2018-08-04  6:37     ` Pawel Laszczak
2018-08-06  8:57       ` Roger Quadros
2018-08-06 11:40         ` Pawel Laszczak
2018-07-19 17:57 ` [PATCH 07/31] usb: usbssp: Initialization - added usbssp_mem_init Pawel Laszczak
2018-07-19 17:57 ` [PATCH 08/31] usb: usbssp: Added ring and segment handling functions Pawel Laszczak
2018-07-19 17:57 ` [PATCH 09/31] usb: usbssp: add implementation of usbssp_mem_cleanup Pawel Laszczak
2018-07-19 17:57 ` [PATCH 10/31] usb: usbssp: added usbssp_trb_in_td function Pawel Laszczak
2018-07-19 17:57 ` [PATCH 11/31] usb: usbssp: added function for stopping driver Pawel Laszczak
2018-07-19 17:57 ` [PATCH 12/31] usb: usbssp: added functions for queuing commands Pawel Laszczak
2018-07-19 17:57 ` [PATCH 13/31] usb: usbssp: addec procedure for handlin Port Status Change events Pawel Laszczak
2018-07-19 17:57 ` [PATCH 14/31] usb: usbssp: added procedure handling command completion events Pawel Laszczak
2018-07-19 17:57 ` [PATCH 15/31] usb: usbssp: added device controller error, transfer and SETUP completion event Pawel Laszczak
2018-07-19 17:57 ` [PATCH 16/31] usb: usbssp: added connect/disconnect procedures Pawel Laszczak
2018-07-19 17:57 ` [PATCH 17/31] usb: usbssp: added implementation of usbssp_halt_endpoint function Pawel Laszczak
2018-07-19 17:57 ` [PATCH 18/31] usb: usbssp: added handling of Port Reset event Pawel Laszczak
2018-07-19 17:57 ` [PATCH 19/31] usb: usbssp: added support for USB enumeration process Pawel Laszczak
2018-07-19 17:57 ` [PATCH 20/31] usb: usbssp: added queuing procedure for control transfer Pawel Laszczak
2018-07-19 17:57 ` [PATCH 21/31] usb: usbssp: added queuing procedure for BULK and INT transfer Pawel Laszczak
2018-07-19 17:57 ` [PATCH 22/31] usb: usbssp: added procedure removing request from transfer ring Pawel Laszczak
2018-07-19 17:57 ` [PATCH 23/31] usb: usbssp: added implementation of transfer events Pawel Laszczak
2018-07-19 17:57 ` [PATCH 24/31] usb: usbssp: added detecting command timeout Pawel Laszczak
2018-07-19 17:57 ` [PATCH 25/31] usb: usbssp: added implementation of usbssp interface Pawel Laszczak
2018-07-19 17:57 ` [PATCH 26/31] usb: usbssp: added endpoint configuration functionality Pawel Laszczak
2018-07-19 17:58 ` [PATCH 27/31] usb: usbssp: implements usbssp_gadget_ep_enable function Pawel Laszczak
2018-07-19 17:58 ` [PATCH 28/31] usb: usbssp: implemented usbssp_gadget_ep_disable function Pawel Laszczak
2018-07-19 17:58 ` [PATCH 29/31] usb: usbssp: added support for LPM Pawel Laszczak
2018-07-19 17:58 ` Pawel Laszczak [this message]
2018-07-19 17:58 ` [PATCH 31/31] usb: usbssp: add pci to platform driver wrapper Pawel Laszczak
2018-08-01 11:27 ` [PATCH 00/31] Introduced new Cadence USBSSP DRD Driver Roger Quadros
2018-08-02  4:26   ` Pawel Laszczak
2018-08-02 13:24     ` Roger Quadros
2018-09-10 18:21     ` Greg Kroah-Hartman
2018-08-17 21:05 ` Bin Liu
2018-08-21 14:50   ` Pawel Laszczak
2018-09-10 18:20     ` Greg Kroah-Hartman
2018-09-10 18:16 ` Greg Kroah-Hartman
  -- strict thread matches above, loose matches on Subject: below --
2018-07-12  5:46 Pawel Laszczak
2018-07-12  5:47 ` [PATCH 30/31] usb: usbssp: added support for TEST_MODE Pawel Laszczak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1532023084-28083-31-git-send-email-pawell@cadence.com \
    --to=pawell@cadence.com \
    --cc=adouglas@cadence.com \
    --cc=balbi@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=ltyrala@cadence.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).