Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1010989imu; Tue, 11 Dec 2018 11:07:23 -0800 (PST) X-Google-Smtp-Source: AFSGD/WJCgD/E182LXiHgXz2EcsP8gTDGSuB7S7Kj5QS4Il9DR773Q30A41osLbHppcPGdguOtYv X-Received: by 2002:a17:902:aa82:: with SMTP id d2mr17132488plr.153.1544555243625; Tue, 11 Dec 2018 11:07:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544555243; cv=none; d=google.com; s=arc-20160816; b=r80WodgknOSzfFoDcFyglv5+gMzE00rQENLcdEonvGn2nGlWFPsNcbsi771zzJENme AR7lyg9sTEHOhbvLymA/p4uZtMEKBP9ggFtUNDuSeoU2M18UJpADlLCcex39nEp8hsim Q3VnGpFcjn5i2FDbU2xQ1O/LYuWn12ifWzn8XtBvZu0KsBud9rn65byYdLdPH04KYqsJ gJ8YqiHxoa+/8aN6l2tD0OZsxJn8MymqUhfYV/E/SSC0Tq1UdnTcC27PIw2qPsI05fwd ko3Du6OA28kNkvVeks1MbIEVAksS5CpkZ3sRtzLmbXtXdGoX5oN3Ou4Sv/f2Ks6xr0oa xG3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:content-transfer-encoding :spamdiagnosticmetadata:spamdiagnosticoutput:content-language :accept-language:in-reply-to:references:message-id:date:thread-index :thread-topic:subject:cc:to:from:dkim-signature:dkim-signature; bh=iU1GqBvi/bZwwUUe97QcmU2YIBKo58c2Y5kd6Ro6TQU=; b=lEESylKTnf2l2UluGaNxhDg5uq6BlPK3e+EEcF5pskCNvXJjxlSG5+5lupio50Joqw B9BkZLnDhw6Zif9SkCcFFPtL6rFVt2kdFAPNPIpcMBaWJP+rESzxZhfo1qj1N3om2aAK xPptk+UzPYy4nwOn1LMRUHDyb+zVNH/Xi12/+BU1box4ITwUiM+G2OzvlcC0OOqGFNAq /Os2tWtqoPfMhjTNhs4jb/MorpjS8kGKltKCJ18e3gRdKQtClH/DhDhfMMkpcCW2PIDI W3vMS91SvqDZfLjGgx1eVmzh6/m3BIYcMclOXHgrxK75A6aG5ILgQpv/nMsONw5SUKKK NlcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cadence.com header.s=proofpoint header.b=jU3BSCHO; dkim=pass header.i=@cadence.com header.s=selector1 header.b=H6pdcg9m; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cadence.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t19si13170007pgk.163.2018.12.11.11.06.45; Tue, 11 Dec 2018 11:07:23 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@cadence.com header.s=proofpoint header.b=jU3BSCHO; dkim=pass header.i=@cadence.com header.s=selector1 header.b=H6pdcg9m; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cadence.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726789AbeLKTEm (ORCPT + 99 others); Tue, 11 Dec 2018 14:04:42 -0500 Received: from mx0b-0014ca01.pphosted.com ([208.86.201.193]:52496 "EHLO mx0a-0014ca01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726331AbeLKTEl (ORCPT ); Tue, 11 Dec 2018 14:04:41 -0500 Received: from pps.filterd (m0042333.ppops.net [127.0.0.1]) by mx0b-0014ca01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id wBBJ3uSR010745; Tue, 11 Dec 2018 11:04:19 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cadence.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=proofpoint; bh=iU1GqBvi/bZwwUUe97QcmU2YIBKo58c2Y5kd6Ro6TQU=; b=jU3BSCHOGdc9xFBvgF2A/PU5C80KEMLKZWlAhq24LFuvsXxwzz2SkN54au2m9IfVS81a uCdokY8qBGQ5ps81QC9DTfQssuoOJ2IhohsFNIdVk6D6+318ONt/ZZSKfVxCdZGRc/+T CnkZVITL7Ge/xdZmBNzJALujHJsTz5qw2UkyeWXWwS8Dz7OIbx7k68dTveSaoHtpU6Rk bq421dwmP2kC8jiU4HPqHH1Ar5WpL2DgUBSUKtZRbeDxY27bb3G2uTfak7VBR2U0r++a GCt4wI8GzocnupV/MCdW9vEGb3PvxjXBbeGa2smAdPspv4gAEjNVAy26IsSlnsPusFHr Rg== Authentication-Results: cadence.com; spf=pass smtp.mailfrom=pawell@cadence.com Received: from nam05-dm3-obe.outbound.protection.outlook.com (mail-dm3nam05lp2055.outbound.protection.outlook.com [104.47.49.55]) by mx0b-0014ca01.pphosted.com with ESMTP id 2p9wg8e3d8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 11 Dec 2018 11:04:19 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cadence.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=iU1GqBvi/bZwwUUe97QcmU2YIBKo58c2Y5kd6Ro6TQU=; b=H6pdcg9mJqbuqfqdGZECP2vqhaJR87r3od8RFRqiBqzZFh8aJ3EFBbwJrMpfQPTXrSb6VYPpZs9Cvhjma7gBp7c4/jqLk0Oi9QXvLCsITzjvOkwHUVl/h89cQLmrQJPjlFPgh2Jx8SUgd+UtkKXCrWP6BfNthpviVICC8F+wAMI= Received: from BYAPR07MB4709.namprd07.prod.outlook.com (52.135.204.159) by BYAPR07MB5798.namprd07.prod.outlook.com (20.179.90.147) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1425.19; Tue, 11 Dec 2018 19:04:15 +0000 Received: from BYAPR07MB4709.namprd07.prod.outlook.com ([fe80::e0dc:ebd5:e248:d644]) by BYAPR07MB4709.namprd07.prod.outlook.com ([fe80::e0dc:ebd5:e248:d644%6]) with mapi id 15.20.1404.026; Tue, 11 Dec 2018 19:04:15 +0000 From: Pawel Laszczak To: Felipe Balbi , "devicetree@vger.kernel.org" CC: "gregkh@linuxfoundation.org" , "linux-usb@vger.kernel.org" , "rogerq@ti.com" , "linux-kernel@vger.kernel.org" , Alan Douglas , "jbergsagel@ti.com" , "nsekhar@ti.com" , "nm@ti.com" , Suresh Punnoose , "peter.chen@nxp.com" , Pawel Jez , Rahul Kumar Subject: RE: [PATCH v1 2/2] usb:cdns3 Add Cadence USB3 DRD Driver Thread-Topic: [PATCH v1 2/2] usb:cdns3 Add Cadence USB3 DRD Driver Thread-Index: AQHUkIWTYw8ZmuofoE+7Ba9cSOLyP6V5dPgAgAAFtpA= Date: Tue, 11 Dec 2018 19:04:15 +0000 Message-ID: References: <1544445555-17325-1-git-send-email-pawell@cadence.com> <1544445555-17325-3-git-send-email-pawell@cadence.com> <87h8fkmfar.fsf@linux.intel.com> In-Reply-To: <87h8fkmfar.fsf@linux.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-dg-tag-bcast: x-dg-ref: PG1ldGE+PGF0IG5tPSJib2R5LnR4dCIgcD0iYzpcdXNlcnNccGF3ZWxsXGFwcGRhdGFccm9hbWluZ1wwOWQ4NDliNi0zMmQzLTRhNDAtODVlZS02Yjg0YmEyOWUzNWJcbXNnc1xtc2ctOGJiODYzOTItZmQ3Ny0xMWU4LTg3MjctMWM0ZDcwMWRmYmE0XGFtZS10ZXN0XDhiYjg2MzkzLWZkNzctMTFlOC04NzI3LTFjNGQ3MDFkZmJhNGJvZHkudHh0IiBzej0iMjI1NTUiIHQ9IjEzMTg5MDI4NjUzMzY5ODI0MCIgaD0iOEpCdVVkMWM0bDZMMGhDNUsrNE1va3VvclZFPSIgaWQ9IiIgYmw9IjAiIGJvPSIxIi8+PC9tZXRhPg== x-dg-paste: x-dg-rorf: x-originating-ip: [185.217.253.59] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1;BYAPR07MB5798;20:0MkaQENzY1/XvO2ua+Bce0s2ckDsKI558UQOOQuN3I4n4NBtDGbrAs8SFQ7yQ7L9V6xR+KmpXelGmFGjjz5/Ct60PbcPECHPhBiHlKN1aRKP9N98jsjloTuIjg+6YVQgHv6WuC8y/q4ByWLe/rq4WwwrcUahzlaVE26uqJQsemBxGZg83cdUbG4BPu9ueuqyxsZtfPm2JpdkpuN+/FUc0N0h88uJcVAkWLZNN3i+9PWtx2XXcdLLx3dEjVVwTn+T x-ms-office365-filtering-correlation-id: 125fb89b-dee8-4199-5616-08d65f9b71c6 x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390098)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7153060)(7193020);SRVR:BYAPR07MB5798; x-ms-traffictypediagnostic: BYAPR07MB5798: x-microsoft-antispam-prvs: x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0;PCL:0;RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3002001)(3231455)(999002)(944501520)(52105112)(93006095)(93001095)(10201501046)(148016)(149066)(150057)(6041310)(20161123560045)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123558120)(201708071742011)(7699051)(76991095);SRVR:BYAPR07MB5798;BCL:0;PCL:0;RULEID:;SRVR:BYAPR07MB5798; x-forefront-prvs: 08831F51DC x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(346002)(39860400002)(376002)(136003)(366004)(396003)(36092001)(189003)(199004)(71190400001)(4744004)(186003)(55016002)(256004)(14444005)(6436002)(97736004)(11346002)(486006)(446003)(476003)(8676002)(74316002)(2501003)(8936002)(305945005)(7736002)(81156014)(7416002)(86362001)(81166006)(5660300001)(53936002)(14454004)(26005)(71200400001)(9686003)(53946003)(102836004)(3846002)(6506007)(6116002)(575784001)(107886003)(25786009)(7696005)(2906002)(110136005)(54906003)(99286004)(106356001)(68736007)(6246003)(478600001)(229853002)(4326008)(66066001)(316002)(105586002)(33656002)(76176011)(579004)(309714004);DIR:OUT;SFP:1101;SCL:1;SRVR:BYAPR07MB5798;H:BYAPR07MB4709.namprd07.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: cadence.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: eC7wJpmcnZQ/4oF2yUqN6xUTYLd8fsO6C2xnDcgU9qv7ZLWlopQTXto54RWlQTEXpAZAZFX1Of5OiCymagyOJEhkjArK6ZBoa5MMD0XjiCWwOussjgZlP8iScWAj9W4tkv93P4jekjkjkOq3czZGMOAe5f8X9LkJTheE6j9NPGeNJan7rWwknr6XaAUozJ0TMzacjy+ExjvDkcS8g6hfDOI8lHjSYgyiwK2MnUdJxxMOSg5AOYPQRpVCEjDCQ+fR2jucBEY1x0uTuONESXCPXDQbxrqbsnDibGfabJmxCa4bFeJnVsUvpjKon2Z4HpUD spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: cadence.com X-MS-Exchange-CrossTenant-Network-Message-Id: 125fb89b-dee8-4199-5616-08d65f9b71c6 X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Dec 2018 19:04:15.1436 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: d36035c5-6ce6-4662-a3dc-e762e61ae4c9 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR07MB5798 X-Proofpoint-SPF-Result: pass X-Proofpoint-SPF-Record: v=spf1 include:_spf.salesforce.com include:mktomail.com include:spf-0014ca01.pphosted.com include:spf.protection.outlook.com include:auth.msgapp.com include:spf.mandrillapp.com ~all X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-12-11_06:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_check_notspam policy=outbound_check score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1812110169 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi,=20 > >Pawel Laszczak writes: >> +static int cdns3_probe(struct platform_device *pdev) >> +{ >> + struct device *dev =3D &pdev->dev; >> + struct resource *res; >> + struct cdns3 *cdns; >> + void __iomem *regs; >> + int ret; >> + >> + cdns =3D devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL); >> + if (!cdns) >> + return -ENOMEM; >> + >> + cdns->dev =3D dev; >> + >> + platform_set_drvdata(pdev, cdns); >> + >> + res =3D platform_get_resource(pdev, IORESOURCE_IRQ, 0); >> + if (!res) { >> + dev_err(dev, "missing IRQ\n"); >> + return -ENODEV; >> + } >> + cdns->irq =3D res->start; >> + >> + cdns->xhci_res[0] =3D *res; >> + >> + /* >> + * Request memory region >> + * region-0: xHCI >> + * region-1: Peripheral >> + * region-2: OTG registers >> + */ >> + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); >> + cdns->xhci_res[1] =3D *res; >> + >> + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 1); >> + regs =3D devm_ioremap_resource(dev, res); >> + if (IS_ERR(regs)) >> + return PTR_ERR(regs); >> + cdns->dev_regs =3D regs; >> + >> + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 2); >> + regs =3D devm_ioremap_resource(dev, res); >> + if (IS_ERR(regs)) >> + return PTR_ERR(regs); >> + cdns->otg_regs =3D regs; >> + >> + mutex_init(&cdns->mutex); >> + >> + cdns->phy =3D devm_phy_get(dev, "cdns3,usbphy"); >> + if (IS_ERR(cdns->phy)) { >> + ret =3D PTR_ERR(cdns->phy); >> + if (ret =3D=3D -ENOSYS || ret =3D=3D -ENODEV) { > >Are you sure you can get ENOSYS here? Have you checked output of >checkpatch --strict? Yes this error code can be returned by related to phy function if CONFIG_GE= NERIC_PHY is disabled.=20 I have seen this warning in output of checkpatch --strict . > >-:852: WARNING: ENOSYS means 'invalid syscall nr' and nothing else > >> +#ifdef CONFIG_PM_SLEEP >> +static int cdns3_suspend(struct device *dev) >> +{ >> + /* TODO: Implements this function. */ >> + return 0; >> +} >> + >> +static int cdns3_resume(struct device *dev) >> +{ >> + /* TODO: Implements this function. */ >> + return 0; >> +} >> +#endif /* CONFIG_PM_SLEEP */ >> +static int cdns3_runtime_suspend(struct device *dev) >> +{ /* TODO: Implements this function. */ >> + return 0; >> +} >> + >> +static int cdns3_runtime_resume(struct device *dev) >> +{ >> + /* TODO: Implements this function. */ >> + return 0; >> +} >> +#endif /* CONFIG_PM */ > >please no TODO stubs. Just get rid of your dev_pm_ops if you don't >implement them. Come up with a later patch adding a proper >implementation for PM. Ok.=20 > >> +static int __init cdns3_driver_platform_register(void) >> +{ >> + return platform_driver_register(&cdns3_driver); >> +} >> +module_init(cdns3_driver_platform_register); >> + >> +static void __exit cdns3_driver_platform_unregister(void) >> +{ >> + platform_driver_unregister(&cdns3_driver); >> +} >> +module_exit(cdns3_driver_platform_unregister); > >module_platform_driver() Ok, > >> diff --git a/drivers/usb/cdns3/debug.h b/drivers/usb/cdns3/debug.h >> new file mode 100644 >> index 000000000000..afb81d224718 >> --- /dev/null >> +++ b/drivers/usb/cdns3/debug.h >> @@ -0,0 +1,346 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +/* >> + * Cadence USBSS DRD Driver. >> + * Debug header file. >> + * >> + * Copyright (C) 2018 Cadence. >> + * >> + * Author: Pawel Laszczak >> + */ >> +#ifndef __LINUX_CDNS3_DEBUG >> +#define __LINUX_CDNS3_DEBUG >> +#include "gadget.h" >> + >> +static inline void cdns3_decode_get_status(u8 bRequestType, u16 wIndex, >> + u16 wLength, char *str) >> +{ >> + switch (bRequestType & USB_RECIP_MASK) { >> + case USB_RECIP_INTERFACE: >> + sprintf(str, "Get Interface Status Intf =3D %d, L: =3D %d", >> + wIndex, wLength); >> + break; >> + case USB_RECIP_ENDPOINT: >> + sprintf(str, "Get Endpoint Status ep%d%s", >> + wIndex & ~USB_DIR_IN, >> + wIndex & USB_DIR_IN ? "in" : "out"); >> + break; >> + } >> +} >> + >> +static inline const char *cdns3_decode_device_feature(u16 wValue) >> +{ >> + switch (wValue) { >> + case USB_DEVICE_SELF_POWERED: >> + return "Self Powered"; >> + case USB_DEVICE_REMOTE_WAKEUP: >> + return "Remote Wakeup"; >> + case USB_DEVICE_TEST_MODE: >> + return "Test Mode"; >> + case USB_DEVICE_U1_ENABLE: >> + return "U1 Enable"; >> + case USB_DEVICE_U2_ENABLE: >> + return "U2 Enable"; >> + case USB_DEVICE_LTM_ENABLE: >> + return "LTM Enable"; >> + default: >> + return "UNKNOWN"; >> + } >> +} >> + >> +static inline const char *cdns3_decode_test_mode(u16 wIndex) >> +{ >> + switch (wIndex) { >> + case TEST_J: >> + return ": TEST_J"; >> + case TEST_K: >> + return ": TEST_K"; >> + case TEST_SE0_NAK: >> + return ": TEST_SE0_NAK"; >> + case TEST_PACKET: >> + return ": TEST_PACKET"; >> + case TEST_FORCE_EN: >> + return ": TEST_FORCE_EN"; >> + default: >> + return ": UNKNOWN"; >> + } >> +} >> + >> +static inline void cdns3_decode_set_clear_feature(u8 bRequestType, u8 b= Request, >> + u16 wValue, u16 wIndex, >> + char *str) >> +{ >> + switch (bRequestType & USB_RECIP_MASK) { >> + case USB_RECIP_DEVICE: >> + sprintf(str, "%s Device Feature(%s%s)", >> + bRequest =3D=3D USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", >> + cdns3_decode_device_feature(wValue), >> + wValue =3D=3D USB_DEVICE_TEST_MODE ? >> + cdns3_decode_test_mode(wIndex) : ""); >> + break; >> + case USB_RECIP_INTERFACE: >> + sprintf(str, "%s Interface Feature(%s)", >> + bRequest =3D=3D USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", >> + wIndex =3D=3D USB_INTRF_FUNC_SUSPEND ? >> + "Function Suspend" : "UNKNOWN"); >> + break; >> + case USB_RECIP_ENDPOINT: >> + sprintf(str, "%s Endpoint Feature(%s ep%d%s)", >> + bRequest =3D=3D USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", >> + wIndex =3D=3D USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN", >> + wIndex & ~USB_DIR_IN, >> + wIndex & USB_DIR_IN ? "in" : "out"); >> + break; >> + } >> +} >> + >> +static inline const char *cdns3_decode_descriptor(u16 wValue) >> +{ >> + switch (wValue >> 8) { >> + case USB_DT_DEVICE: >> + return "Device"; >> + case USB_DT_CONFIG: >> + return "Configuration"; >> + case USB_DT_STRING: >> + return "String"; >> + case USB_DT_INTERFACE: >> + return "Interface"; >> + case USB_DT_ENDPOINT: >> + return "Endpoint"; >> + case USB_DT_DEVICE_QUALIFIER: >> + return "Device Qualifier"; >> + case USB_DT_OTHER_SPEED_CONFIG: >> + return "Other Speed Config"; >> + case USB_DT_INTERFACE_POWER: >> + return "Interface Power"; >> + case USB_DT_OTG: >> + return "OTG"; >> + case USB_DT_DEBUG: >> + return "Debug"; >> + case USB_DT_INTERFACE_ASSOCIATION: >> + return "Interface Association"; >> + case USB_DT_BOS: >> + return "BOS"; >> + case USB_DT_DEVICE_CAPABILITY: >> + return "Device Capability"; >> + case USB_DT_SS_ENDPOINT_COMP: >> + return "SS Endpoint Companion"; >> + case USB_DT_SSP_ISOC_ENDPOINT_COMP: >> + return "SSP Isochronous Endpoint Companion"; >> + default: >> + return "UNKNOWN"; >> + } >> +} >> + >> +/** >> + * cdns3_decode_ctrl - returns a string represetion of ctrl request >> + */ >> +static inline const char *cdns3_decode_ctrl(char *str, u8 bRequestType, >> + u8 bRequest, u16 wValue, >> + u16 wIndex, u16 wLength) >> +{ >> + switch (bRequest) { >> + case USB_REQ_GET_STATUS: >> + cdns3_decode_get_status(bRequestType, wIndex, >> + wLength, str); >> + break; >> + case USB_REQ_CLEAR_FEATURE: >> + case USB_REQ_SET_FEATURE: >> + cdns3_decode_set_clear_feature(bRequestType, bRequest, >> + wValue, wIndex, str); >> + break; >> + case USB_REQ_SET_ADDRESS: >> + sprintf(str, "Set Address Addr: %02x", wValue); >> + break; >> + case USB_REQ_GET_DESCRIPTOR: >> + sprintf(str, "GET %s Descriptor I: %d, L: %d", >> + cdns3_decode_descriptor(wValue), >> + wValue & 0xff, wLength); >> + break; >> + case USB_REQ_SET_DESCRIPTOR: >> + sprintf(str, "SET %s Descriptor I: %d, L: %d", >> + cdns3_decode_descriptor(wValue), >> + wValue & 0xff, wLength); >> + break; >> + case USB_REQ_GET_CONFIGURATION: >> + sprintf(str, "Get Configuration L: %d", wLength); >> + break; >> + case USB_REQ_SET_CONFIGURATION: >> + sprintf(str, "Set Configuration Config: %d ", wValue); >> + break; >> + case USB_REQ_GET_INTERFACE: >> + sprintf(str, "Get Interface Intf: %d, L: %d", wIndex, wLength); >> + break; >> + case USB_REQ_SET_INTERFACE: >> + sprintf(str, "Set Interface Intf: %d, Alt: %d", wIndex, wValue); >> + break; >> + case USB_REQ_SYNCH_FRAME: >> + sprintf(str, "Synch Frame Ep: %d, L: %d", wIndex, wLength); >> + break; >> + case USB_REQ_SET_SEL: >> + sprintf(str, "Set SEL L: %d", wLength); >> + break; >> + case USB_REQ_SET_ISOCH_DELAY: >> + sprintf(str, "Set Isochronous Delay Delay: %d ns", wValue); >> + break; >> + default: >> + sprintf(str, >> + "SETUP BRT: %02x BR: %02x V: %04x I: %04x L: %04x\n", >> + bRequestType, bRequest, >> + wValue, wIndex, wLength); >> + } >> + >> + return str; >> +} > >All of these are a flat out copy of dwc3's implementation. It's much, >much better to turn dwc3's implementation into a generic, reusable >library function then spinning your own as a duplicated effort. I agree,=20 It would be nice to have a set of decoding function in some generic librar= y. It could be used=20 also by other drivers. Who should do this ? > >> diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c >> new file mode 100644 >> index 000000000000..1ef0e9f73e3e >> --- /dev/null >> +++ b/drivers/usb/cdns3/ep0.c >> @@ -0,0 +1,864 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Cadence USBSS DRD Driver - gadget side. >> + * >> + * Copyright (C) 2018 Cadence Design Systems. >> + * Copyright (C) 2017-2018 NXP >> + * >> + * Authors: Pawel Jez , >> + * Pawel Laszczak >> + * Peter Chen >> + */ >> + >> +#include >> + >> +#include "gadget.h" >> +#include "trace.h" >> + >> +static struct usb_endpoint_descriptor cdns3_gadget_ep0_desc =3D { >> + .bLength =3D USB_DT_ENDPOINT_SIZE, >> + .bDescriptorType =3D USB_DT_ENDPOINT, >> + .bmAttributes =3D USB_ENDPOINT_XFER_CONTROL, >> +}; >> + >> +/** >> + * cdns3_ep0_run_transfer - Do transfer on default endpoint hardware >> + * @priv_dev: extended gadget object >> + * @dma_addr: physical address where data is/will be stored >> + * @length: data length >> + * @erdy: set it to 1 when ERDY packet should be sent - >> + * exit from flow control state >> + */ >> +static void cdns3_ep0_run_transfer(struct cdns3_device *priv_dev, >> + dma_addr_t dma_addr, >> + unsigned int length, int erdy) >> +{ >> + struct cdns3_usb_regs __iomem *regs =3D priv_dev->regs; >> + struct cdns3_endpoint *priv_ep =3D ep_to_cdns3_ep(priv_dev->gadget.ep0= ); >> + >> + priv_dev->ep0_trb->buffer =3D TRB_BUFFER(dma_addr); >> + priv_dev->ep0_trb->length =3D TRB_LEN(length); >> + priv_dev->ep0_trb->control =3D TRB_CYCLE | TRB_IOC | TRB_TYPE(TRB_NORM= AL); >> + >> + trace_cdns3_prepare_trb(priv_ep, priv_dev->ep0_trb); >> + >> + cdns3_select_ep(priv_dev, priv_dev->ep0_data_dir); >> + >> + writel(EP_STS_TRBERR, ®s->ep_sts); >> + writel(EP_TRADDR_TRADDR(priv_dev->ep0_trb_dma), ®s->ep_traddr); >> + trace_cdns3_doorbell_ep0(priv_dev->ep0_data_dir ? "ep0in" : "ep0out"); >> + >> + /* TRB should be prepared before starting transfer */ >> + writel(EP_CMD_DRDY, ®s->ep_cmd); >> + >> + if (erdy) >> + writel(EP_CMD_ERDY, &priv_dev->regs->ep_cmd); >> +} >> + >> +/** >> + * cdns3_ep0_delegate_req - Returns status of handling setup packet >> + * Setup is handled by gadget driver >> + * @priv_dev: extended gadget object >> + * @ctrl_req: pointer to received setup packet >> + * >> + * Returns zero on success or negative value on failure >> + */ >> +static int cdns3_ep0_delegate_req(struct cdns3_device *priv_dev, >> + struct usb_ctrlrequest *ctrl_req) >> +{ >> + int ret; >> + >> + spin_unlock(&priv_dev->lock); >> + priv_dev->setup_pending =3D 1; >> + ret =3D priv_dev->gadget_driver->setup(&priv_dev->gadget, ctrl_req); >> + priv_dev->setup_pending =3D 0; >> + spin_lock(&priv_dev->lock); >> + return ret; >> +} >> + >> +static void cdns3_prepare_setup_packet(struct cdns3_device *priv_dev) >> +{ >> + priv_dev->ep0_data_dir =3D 0; >> + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, >> + sizeof(struct usb_ctrlrequest), 0); >> +} >> + >> +/** >> + * cdns3_req_ep0_set_configuration - Handling of SET_CONFIG standard US= B request >> + * @priv_dev: extended gadget object >> + * @ctrl_req: pointer to received setup packet >> + * >> + * Returns 0 if success, USB_GADGET_DELAYED_STATUS on deferred status s= tage, >> + * error code on error >> + */ >> +static int cdns3_req_ep0_set_configuration(struct cdns3_device *priv_de= v, >> + struct usb_ctrlrequest *ctrl_req) >> +{ >> + enum usb_device_state device_state =3D priv_dev->gadget.state; >> + struct cdns3_endpoint *priv_ep; >> + u32 config =3D le16_to_cpu(ctrl_req->wValue); >> + int result =3D 0; >> + int i; >> + >> + switch (device_state) { >> + case USB_STATE_ADDRESS: >> + /* Configure non-control EPs */ >> + for (i =3D 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) { >> + priv_ep =3D priv_dev->eps[i]; >> + if (!priv_ep) >> + continue; >> + >> + if (priv_ep->flags & EP_CLAIMED) >> + cdns3_ep_config(priv_ep); >> + } >> + >> + result =3D cdns3_ep0_delegate_req(priv_dev, ctrl_req); >> + >> + if (result) >> + return result; >> + >> + if (config) { >> + cdns3_set_hw_configuration(priv_dev); >> + } else { >> + cdns3_gadget_unconfig(priv_dev); >> + usb_gadget_set_state(&priv_dev->gadget, >> + USB_STATE_ADDRESS); > >this is wrong. If address is zero, state should be default, not >addressed. Addressed would be used on the other branch here, when you >have a non-zero address If address is zero then state should be USB_STATE_DEFAULT. Driver enters to= this branch=20 only if gadget.state =3D USB_STATE_ADDRESS (address !=3D 0). This state ca= n be changed in composite.c file=20 after delegating request to gadget driver. Because this state could be chan= ged driver simple restore USB_STATE_ADDRESS if config =3D 0.=20 > >> + } >> + break; >> + case USB_STATE_CONFIGURED: > >where do you set this state? It's set in set_config in composite.c file.=20 > >> +static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_de= v, >> + struct usb_ctrlrequest *ctrl, >> + int set) >> +{ >> + enum usb_device_state state; >> + enum usb_device_speed speed; >> + int ret =3D 0; >> + u32 wValue; >> + u32 wIndex; >> + u16 tmode; >> + >> + wValue =3D le16_to_cpu(ctrl->wValue); >> + wIndex =3D le16_to_cpu(ctrl->wIndex); >> + state =3D priv_dev->gadget.state; >> + speed =3D priv_dev->gadget.speed; >> + >> + switch (ctrl->wValue) { >> + case USB_DEVICE_REMOTE_WAKEUP: >> + priv_dev->wake_up_flag =3D !!set; >> + break; >> + case USB_DEVICE_U1_ENABLE: >> + if (state !=3D USB_STATE_CONFIGURED || speed !=3D USB_SPEED_SUPER) >> + return -EINVAL; >> + >> + priv_dev->u1_allowed =3D !!set; >> + break; >> + case USB_DEVICE_U2_ENABLE: >> + if (state !=3D USB_STATE_CONFIGURED || speed !=3D USB_SPEED_SUPER) >> + return -EINVAL; >> + >> + priv_dev->u2_allowed =3D !!set; >> + break; >> + case USB_DEVICE_LTM_ENABLE: >> + ret =3D -EINVAL; >> + break; >> + case USB_DEVICE_TEST_MODE: >> + if (state !=3D USB_STATE_CONFIGURED || speed > USB_SPEED_HIGH) >> + return -EINVAL; >> + >> + tmode =3D le16_to_cpu(ctrl->wIndex); >> + >> + if (!set || (tmode & 0xff) !=3D 0) >> + return -EINVAL; >> + >> + switch (tmode >> 8) { >> + case TEST_J: >> + case TEST_K: >> + case TEST_SE0_NAK: >> + case TEST_PACKET: >> + cdns3_set_register_bit(&priv_dev->regs->usb_cmd, >> + USB_CMD_STMODE | >> + USB_STS_TMODE_SEL(tmode - 1)); > >I'm 90% sure this won't work. There's a reason why we only enter the >requested test mode from status stage. How have you tested this? From USB spec: "The transition to test mode must be complete no later than 3 ms after the = completion of the status stage of the request." But I don't remember any issues with this test on other ours drivers. Maybe= status stage=20 is armed in this case by controller. I have to confirm how it works with ha= rdware team.=20 Driver doesn't know when status stage was completed. We don't have=20 any event on status stage completion. I haven't checked it yet with tester= on this driver. =20 > >> diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c >> new file mode 100644 >> index 000000000000..a021eaf07aee >> --- /dev/null >> +++ b/drivers/usb/cdns3/gadget.c > > > >> +struct usb_request *cdns3_next_request(struct list_head *list) >> +{ >> + if (list_empty(list)) >> + return NULL; >> + return list_first_entry(list, struct usb_request, list); > >list_first_entry_or_null() Ok. > >> +void cdns3_gadget_unconfig(struct cdns3_device *priv_dev) >> +{ >> + /* RESET CONFIGURATION */ >> + writel(USB_CONF_CFGRST, &priv_dev->regs->usb_conf); >> + >> + cdns3_allow_enable_l1(priv_dev, 0); >> + priv_dev->hw_configured_flag =3D 0; >> + priv_dev->onchip_mem_allocated_size =3D 0; > >clear all test modes? Reset ep0 max_packet_size to 512? Test mode should be reset automatically on exit.=20 W can't clear this mode in register. It's WAC (write only and auto clear) = bit. This function only reset endpoint configuration in controller register.=20 Ep0 max_packet_size should be unchanged here. Ep0 max_packet it's updated = on=20 Connect/Disconnect/Reset events. =20 Maybe this function should be called cdns3_hw_reset_eps_config.=20 It doesn't unconfigure whole gadget but only reset endpoints configuration = kept by=20 controller. I will change this function.=20 > >> +static irqreturn_t cdns3_device_irq_handler(int irq, void *data) >> +{ >> + struct cdns3_device *priv_dev; >> + struct cdns3 *cdns =3D data; >> + irqreturn_t ret =3D IRQ_NONE; >> + unsigned long flags; >> + u32 reg; >> + >> + priv_dev =3D cdns->gadget_dev; >> + spin_lock_irqsave(&priv_dev->lock, flags); > >you're already running in hardirq context. Why do you need this lock at >all? I would be better to use the hardirq handler to mask your >interrupts, so they don't fire again, then used the top-half (softirq) >handler to actually handle the interrupts. Yes, spin_lock_irqsave is not necessary here.=20 Do you mean replacing devm_request_irq with a request_threaded_irq ? I have single interrupt line shared between Host, Driver, DRD/OTG.=20 I'm not sure if it will work more efficiently.=20 > >> + /* check USB device interrupt */ >> + reg =3D readl(&priv_dev->regs->usb_ists); >> + writel(reg, &priv_dev->regs->usb_ists); >> + >> + if (reg) { >> + dev_dbg(priv_dev->dev, "IRQ: usb_ists: %08X\n", reg); > >I strongly advise against using dev_dbg() for debugging. Even more so >inside your IRQ handler. Ok, It's not necessary in this place, especially, that there is invoked tra= ce point=20 inside cdns3_check_usb_interrupt_proceed which makes the same. > >> + cdns3_check_usb_interrupt_proceed(priv_dev, reg); >> + ret =3D IRQ_HANDLED; >> + } >> + >> + /* check endpoint interrupt */ >> + reg =3D readl(&priv_dev->regs->ep_ists); >> + >> + /* handle default endpoint OUT */ >> + if (reg & EP_ISTS_EP_OUT0) { >> + cdns3_check_ep0_interrupt_proceed(priv_dev, USB_DIR_OUT); >> + ret =3D IRQ_HANDLED; >> + } >> + >> + /* handle default endpoint IN */ >> + if (reg & EP_ISTS_EP_IN0) { >> + cdns3_check_ep0_interrupt_proceed(priv_dev, USB_DIR_IN); >> + ret =3D IRQ_HANDLED; >> + } >> + >> + /* check if interrupt from non default endpoint, if no exit */ >> + reg &=3D ~(EP_ISTS_EP_OUT0 | EP_ISTS_EP_IN0); >> + if (!reg) >> + goto irqend; >> + >> + do { >> + unsigned int bit_pos =3D ffs(reg); >> + u32 bit_mask =3D 1 << (bit_pos - 1); >> + int index; >> + >> + index =3D cdns3_ep_reg_pos_to_index(bit_pos); >> + cdns3_check_ep_interrupt_proceed(priv_dev->eps[index]); >> + reg &=3D ~bit_mask; >> + ret =3D IRQ_HANDLED; >> + } while (reg); > >use for_each_set_bit() here. Ok > >> +void cdns3_ep_config(struct cdns3_endpoint *priv_ep) >> +{ >> + bool is_iso_ep =3D (priv_ep->type =3D=3D USB_ENDPOINT_XFER_ISOC); >> + struct cdns3_device *priv_dev =3D priv_ep->cdns3_dev; >> + u32 bEndpointAddress =3D priv_ep->num | priv_ep->dir; >> + u32 interrupt_mask =3D EP_STS_EN_TRBERREN; >> + u32 max_packet_size =3D 0; >> + u32 ep_cfg =3D 0; >> + int ret; >> + >> + if (!priv_ep->dir) >> + interrupt_mask |=3D EP_STS_EN_DESCMISEN; >> + >> + if (priv_ep->type =3D=3D USB_ENDPOINT_XFER_INT) { > >you can turn tis into a switch statement. It'll look nicer Ok. > >> + ep_cfg =3D EP_CFG_EPTYPE(USB_ENDPOINT_XFER_INT); >> + } else if (priv_ep->type =3D=3D USB_ENDPOINT_XFER_BULK) { >> + ep_cfg =3D EP_CFG_EPTYPE(USB_ENDPOINT_XFER_BULK); >> + } else { >> + ep_cfg =3D EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC); >> + interrupt_mask =3D 0xFFFFFFFF; >> + } >> + >> + switch (priv_dev->gadget.speed) { >> + case USB_SPEED_FULL: >> + max_packet_size =3D is_iso_ep ? 1023 : 64; >> + break; >> + case USB_SPEED_HIGH: >> + max_packet_size =3D is_iso_ep ? 1024 : 512; >> + break; >> + case USB_SPEED_SUPER: >> + max_packet_size =3D 1024; >> + break; >> + default: >> + /* all other speed are not supported */ >> + return; >> + } >> + >> + ret =3D cdns3_ep_onchip_buffer_reserve(priv_dev, CDNS3_EP_BUF_SIZE); >> + if (ret) { >> + dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n"); >> + return; >> + } >> + >> + ep_cfg |=3D EP_CFG_MAXPKTSIZE(max_packet_size) | >> + EP_CFG_BUFFERING(CDNS3_EP_BUF_SIZE - 1) | >> + EP_CFG_MAXBURST(priv_ep->endpoint.maxburst); >> + >> + cdns3_select_ep(priv_dev, bEndpointAddress); >> + >> + writel(ep_cfg, &priv_dev->regs->ep_cfg); >> + writel(interrupt_mask, &priv_dev->regs->ep_sts_en); >> + >> + dev_dbg(priv_dev->dev, "Configure %s: with val %08x\n", >> + priv_ep->name, ep_cfg); >> + >> + /* enable interrupt for selected endpoint */ >> + cdns3_set_register_bit(&priv_dev->regs->ep_ien, >> + cdns3_ep_addr_to_bit_pos(bEndpointAddress)); >> +} > >-- Thanks=20 Pawell