Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1167717AbcKAHDY (ORCPT ); Tue, 1 Nov 2016 03:03:24 -0400 Received: from relmlor2.renesas.com ([210.160.252.172]:38214 "EHLO relmlie1.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1165526AbcKAHDV (ORCPT ); Tue, 1 Nov 2016 03:03:21 -0400 X-IronPort-AV: E=Sophos;i="5.31,430,1473087600"; d="scan'";a="224486048" Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=<>; From: Yoshihiro Shimoda To: CC: , , , , , , Yoshihiro Shimoda Subject: [PATCH v2] phy: rcar-gen3-usb2: add sysfs for usb role swap Date: Tue, 1 Nov 2016 16:01:58 +0900 Message-ID: <1477983718-4145-1-git-send-email-yoshihiro.shimoda.uh@renesas.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [211.11.155.144] X-ClientProxiedBy: OS1PR01CA0001.jpnprd01.prod.outlook.com (10.161.225.139) To HKXPR06MB0550.apcprd06.prod.outlook.com (10.161.177.140) X-MS-Office365-Filtering-Correlation-Id: 94a19f80-c75d-4f36-5e41-08d402252656 X-Microsoft-Exchange-Diagnostics: 1;HKXPR06MB0550;2:OsYjum+HK1w9K2mkGSdRJjYYsG6EKKDnw3vriT5Y2m3/IXK6DU3wTWyG+DrlU300ROVV6+8jgsyMQrnu6rvwHEmeYJLWtTtAdpfexFJDL05ViNmmQ+hqNLKxayi5NHdbuhns4ZBgYTGo/sqy9wJI4rbJgTywjP+1Y8aPdhuc/HPFVT62Y7vHbMdQoRfatOpEML4upX4qXumdXK2WjgBRtQ==;3:zQM61z/uXKzTdl6k6/H2veHKgcPQO2G0SzJQzyTGcp5SNQ1OgzyL05RX0F1jMv2W3eVew5a1AIupyAMjHHUGgBZwoaBpfDhcZAXYobdb43btZctH/0EwCbOZv3li/fp0NAImqhJaBOFG3OJEAPyD6Q== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HKXPR06MB0550; X-Microsoft-Exchange-Diagnostics: 1;HKXPR06MB0550;25:j94BqQo7yFm8RcNWALfZV1XLHdV9DU9U+orbyPgO1EiySL1k+Q/x+3aYBR9IIYzXfrkoXL5HnUrHgHvFxz62izlWyc03Q/JsiVm/AbmbFBUyb8ofnEt/8IzmSYKbOtU80Ft5wnp5Sm43j98JJ4GYHHJKLjQHf/MQ7sLNF1D5Lsl9GkRCPFZqUn2+MQ3Scw72zIQkkl68UV4FBjz4bmZAiE5DLYBXyzyLubo9SF9C090aQMUuFQvY7ySbywxI/1EASWxOjB6W5a9uVTGTQfbssR5SahVKY6IoNuGmIqEiF+SEA3C3AfNoTXvdYAdqg5UKpU5mW95aPrBs5Q5S7dgMYi9wedRYcNHGR8A6GX1XMpFZk5u32AE2ijE1hcf4AzNs+YJ0EWUSWMnZbWxeTOBUnqGsDzKRb3sV8nm62dE12fjKUJ16fiNm0crbwXsFAWymacYH9YiKgDluzcoAxEuPEJSWpJAvFsOfys0Yg9Jy0g1a9XtZxiKPcZyw38K9p1EeOdgaDVxA/H+79YA8gX8gtkxISENMmOzflt3e/wc8eocDCwcQp+M1fST003ZTsmDDMWQe+Z7i+BJWQsCxZozeOvXW71stfA8XkDFbGRvlWVK8JEGT9iDvMYQgxwlFmGXF/i9b3K/oASZw16EACECsP4Deigdaf8Rrq3gnS1ItyPPvfCiygtBsBrjjBmHjLLmX34lmIQbhERHsbHZY/vR5jhTmOHI7xtG8p7mJSpalgIQR60mHVEZWsgKpRSNs/tOIDDE34rZZUgagPrPE9QhD2g== X-Microsoft-Exchange-Diagnostics: 1;HKXPR06MB0550;31:IPz3RYhPfAViVzNkIhLZnzH6An57yK2K3Q2S3zh7Ed6p4lXmS7BXc1/sMzW7AQHcZ4Z7b871QY2T2jLGCPE51nmA1GCQw91a1PN45roSAPZ4U3/wBqx4k5DJnSH4amtMzf7xgoL3Qn7AvvvmVJJ1DxI9BBJ0wLhh+EWteiIb50WSDX2BpHPEh308bUUskNT1oF5Nx5iJTpbvPq8TFBUnCycvec6TqQC685m5GvTaAo7cfSLZweajl//JAUOy8SS+dQPr4WbzA3R2RvyvYbTocw==;20:S5FnWuv/O2U6b+8wnpdYPfZcuTXbGTh03yAt9xcEMUotZ90OhCXxkBkT1ppV+YUD85XKWIvfhobiAnl6XZgHuIjhrD0u13JCSxV/YB6Y4FWY9m0kuaJYqOvYH9aFASfFsJbwqYPvDPtPKzIJa+dcJWC6RofDXtpr3SOM4s7xmszv76np/Qij+lRJS5lrYpI05SbxUU+Dd0MZsCLn5Xwuof8TqLweDiMJZd2x1UXp5YitFw3ZiMRXwTnYJldACP1G0AFsLdP+aVV83D54R8CShPhlNlKfJpd4CsMeMW+osbjgn++2AbkECsseV6CTfoiIwzs1EssB0M6Qw3F5Nd9ypHwlGLEydbjYRqIy/DoNBdDI8RLDxNDegtBfb69NiviuuTLQjeMllkwEG09igu9wmOmj5O4JLyGeQey25yHRnmCUCN8yVGM2vexOLW33T6nuEqQCZavN+LXcNbd8dTzuqQnUaegAxvRgaooXv/oNaAvMfPNp01ZkJ3Raj8SLD3VU X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(21532816269658); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026);SRVR:HKXPR06MB0550;BCL:0;PCL:0;RULEID:;SRVR:HKXPR06MB0550; X-Microsoft-Exchange-Diagnostics: 1;HKXPR06MB0550;4:WN+nOfc4sTaDc/Zn9obB3YwJWYuuZMHG6L4FG4UtNiHFJ+Zv3hGVMCm8pQ/CYGbqPW8TIsmckwrp3nCgi75J56CQdw2UK3u3B+K5qT2o5vC8q8F5kgVpWMoKRoSb2imMvr29oNLDj+zqoqpdUc5z8gDzWwGqk5kJqODVjkWnk0A7jYEyAn4yfiP0kH1gPT5/R1gqpBmf0+FPDZaDOozf8O1WJ71ZkB+b3yBzzAiXsBIcg0S4snYArlgND20EXFwkASFx7ZBakv7R/v0oCZsiAXv4OY+WyuF6649pRLOymasuAcnFPvV77qtxnfLYjyxxkVsLCPFx94Zh/PkZKxoz4+pKB/HERvKj7Ezi6ijcZKQfzGgUX94oLnXhjb45k15jBbBQnCniBCR7yj0oxw1NOI+/9post4OBORWKW7plSeCYuRHcxbVuMvNRT2wp+X/NUnd9QYELbOf2zTBXoxaI2Q== X-Forefront-PRVS: 01136D2D90 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6069001)(6009001)(7916002)(50944005)(199003)(189002)(47776003)(107886002)(5660300001)(66066001)(50986999)(42186005)(230783001)(101416001)(5003940100001)(19580405001)(92566002)(19580395003)(106356001)(2351001)(42882006)(6666003)(8676002)(6916009)(6116002)(586003)(3846002)(229853001)(81156014)(110136003)(105586002)(189998001)(36756003)(81166006)(50226002)(33646002)(7736002)(7846002)(50466002)(305945005)(78352004)(4001430100002)(4326007)(97736004)(2906002)(68736007)(48376002)(77096005)(8666005)(7059030);DIR:OUT;SFP:1102;SCL:1;SRVR:HKXPR06MB0550;H:localhost.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;A:0;MX:0;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;HKXPR06MB0550;23:1DCOVFBewOJhsLnL28cJJ29VLwIGCn7l0uEfgDWQp?= =?us-ascii?Q?gEssBsiz9Z+40qhnowOGBRgSM+0cf33EFouUKQJYMJ7tENwBcSKfiTHoWy7o?= =?us-ascii?Q?eKzN96KQ16x3SI2AlaW4pevyFObSTGJDeN051/vn65r/ywnLucsoGQn07ty8?= =?us-ascii?Q?36NBPeYticyvmbHKnFosT8bba4ZKjNzSdRoDZMF46XA42nXnVuyytlwx9Cpy?= =?us-ascii?Q?4rEArQJWAb57t3PFjH66JJl2rqTlu424iLaT3PQDNNOea6i7nyjIsCYV8eEX?= =?us-ascii?Q?dqG4p9EciJ4STQaCp3NvdwbIvnCqX+Wp7JJjjJOOgSZxOA/sPBfBVZpZVMVk?= =?us-ascii?Q?0vN+HVyR9TmPOKomAmaLFUhDjWmnuYuj86KitCNHjznUdaJvfP0pxBr8YoWC?= =?us-ascii?Q?8PYhc5YZcz644IJ+srcdjo3huwj09luJSVnQkbInnQKhE3Vn5aNxb+GsDk8L?= =?us-ascii?Q?C9I5WHP9cHJ3btgzqxjOmMABLcRl5WUF2klcWJfH05k8UqWrWjkG4AKkj9xa?= =?us-ascii?Q?Q3ETTM+MNvuLrQxjlZobANh7ph+A8jy6U2pOLDk7h+FwLPl/szcdm7q8iiyf?= =?us-ascii?Q?AQ2SMeH0WzWJCwHU2rW5PUzk4X67/YxRsWmuz8TJ+BliqP3NcytkaD/Xpiut?= =?us-ascii?Q?ID8pmZ8cVYbEVnnWXDdLW7QKNc52iOVOheaugwC8DkuuDTs+Z/tZBKmSUC66?= =?us-ascii?Q?plhVUA72eeds7Zm+2QyIR4ryJfnllj77H//dkLPgO7Oy6P67i0ba8K7L5leP?= =?us-ascii?Q?dSjWyKHjQNdbj6Do7fJLRqM2GIeDiiNML8Yyroz0uh8YAIU8vs9cRqEw/k5Q?= =?us-ascii?Q?tLi0gPyn5gd01QBhKHqIXjB93fOCi9A6ZEWnYFI1PCdRVZtxFNj8Wjf95PTp?= =?us-ascii?Q?Bagq5+yVax5kx17fV29XFv+2zXTdPC2fKjYcCdbbgLHTocdprFi13rzwhrRi?= =?us-ascii?Q?xmZzdY7sdqDa+1xuOPgLjXJAZJO6IMCUhvq8qMsO5C70YJQiW96cXfLjF570?= =?us-ascii?Q?NS8KKbkRS2dAGSWaZJN2HcKWLXQ0Acy7z5jdETCuPQMZEBycWItwKibC84sR?= =?us-ascii?Q?XJdaXaYHjFL6ZgOycfijVkmx4FkaHSpeMu2wz+OPu5K4zGZL2zR57TTqNxTp?= =?us-ascii?Q?89qNBEannG5qkGE8jnDILD+GP0aNEd2+ugrKqF/p15VI1A3DZ9o1ONNKqLvi?= =?us-ascii?Q?oP+lCpKzKouku4EatDzZrYLq+f+OjmqmGXLaKxOVhONLbr3i7sK2Y3z5gxBD?= =?us-ascii?Q?xhH7xVya9fu6QkLeeMW4twRYYrl/2todLXqyGf7?= X-Microsoft-Exchange-Diagnostics: 1;HKXPR06MB0550;6:uqy1I22tRu/xFzD9vQPOJRemBEO9Cl/82U+Ae4e0Bq/D/SzMbsO3u9fXNRFVjy5Pp4mLlyLraO4eq9qsPTBe5rfsNtLbQ5FkJjsPfGyWxduJjn3zIl61JIjJnkyw5PpsGcfz41H7cTdAb35hNbTaNDZnV/+yrCw9fWnNMo1dak1olkmiw/mqslzp+ltkeplOC5ob8n6oPWQ9yaPMDsZRqLu9tesweJJj8oHq05ZAS3uxkYrSKRDIs2M0jSVVmlEk9QtFdlhfg9Ygbr1zRnADp4A4PIgy/23DjeGZlDy8uo1fpnNoVSpN+ifLb2uW/eg8uxkYyFo3nAnzn0LeBRUhhxSuq3XcpbM3VuI3SN1hfg4=;5:HWC3zdJdCZR0P3KL+TbAx1g1Q2EOqWMUIDpF1VNcsZ6p20vjY5eZHrXM1rX1Slr81r57oDHroIBvPu7DU/Qq0VecgquZEfQtGjm3GUYgBRnj349EYrhW9KSTFEkX7zZj05rpiC8f8lt+fgXw+O9qrA==;24:+hFLcYYJ0UKGYyRHaqflus58J6bmi51j9+QABZ/bpv+HMQIPWTSz2OG6pMDmMvxAb8ovtEur+C+ngK2J0eTwaCDxEPNuSuYtWxNpX6EMB1Y= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;HKXPR06MB0550;7:gYGvE/HMlxY+Iv50F1DgWeSNYD+OZeXYOyFnhNb65TgpKZSAFgYGbJhd7Ub2+mjxE/gNyXSOtDRdx582lV0xnKucGgwn4XdIulnlOukT8OD2g5h8In17ghIAnLxrbK/Ia7uPrDt0v1+DjLnN82QtAr2yB1bOrK/HyD4H7KUTffZK8XQE+ZlT5bNjMb3GLl3aqD99eKaX/K7/JMVL5n5NXatRoK9TkhOzkQDu7NnTkQF9tE3MyV9JY7H9+mEVq8uHQdv9vhAj1qypTm/v2ztK9NcnAY/3npv1FcAyGNbgYalthMjLYWAQm0RAnNMK5jiqWnPiGF9+5thazuqa7bWA/Owwo3RhmwsQ6z/Mc244svE=;20:J98oJC5IB7BqOnfJISq5x/lm7h6Cw4AsVV90e50Fcwf6RI9pOIts60AK7+sRUorhYwY0y44zgt7qDjN939rDhLAedQ/+m3j5li9rJqy/MSIOjwydBpslNkmSJTyNZVxtCPpDNRXozETnAtq0v52ShRzyYnDzWk/zE33+SilXsCg= X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Nov 2016 07:03:13.8656 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HKXPR06MB0550 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7597 Lines: 227 This patch adds sysfs "otg_inputs" for usb role swap. This parameter is write-only and if you use them as the following, you can swap the usb role. For example: 1) connect a usb cable using 2 salvator-x boards 2) On A-device (as host), you input the following command: # echo a_bus_req/ > /sys/devices/platform/soc/ee080200.usb-phy/otg_inputs 3) On B-device (as peripheral), you input the following command: # echo b_bus_req > /sys/devices/platform/soc/ee080200.usb-phy/otg_inputs Then, the A-device acts as a peripheral (A-peripheral) and the B-device acts as a host (B-host). Please note that A-device must input the following command if you want the board to act as a host again. (even if you disconnect the usb cable, since id state may be the same, the condition keeps "A-peripheral".) # echo a_bus_drop > /sys/devices/platform/soc/ee080200.usb-phy/otg_inputs Also you can use the following command if you want the B-device board to act as a peripheral again. # echo b_bus_req/ > /sys/devices/platform/soc/ee080200.usb-phy/otg_inputs Signed-off-by: Yoshihiro Shimoda --- This patch is based on the latest linux-phy.git / next branch. (commit id = 7809cd2ce6abd4f431e4b14e6b1276a7cc842ac4) Since this patch is related to usb, I added email addresses of Greg, Felipe, Peter and USB ML as CC. (This patch doesn't use USB OTG FSM though.) Changed from v1: - rebase the latest next branch. .../ABI/testing/sysfs-platform-phy-rcar-gen3-usb2 | 11 ++ drivers/phy/phy-rcar-gen3-usb2.c | 124 ++++++++++++++++++++- 2 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-phy-rcar-gen3-usb2 diff --git a/Documentation/ABI/testing/sysfs-platform-phy-rcar-gen3-usb2 b/Documentation/ABI/testing/sysfs-platform-phy-rcar-gen3-usb2 new file mode 100644 index 0000000..c7e715af --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-phy-rcar-gen3-usb2 @@ -0,0 +1,11 @@ +What: /sys/devices/platform//otg-inputs +Date: October 2016 +KernelVersion: 4.10 +Contact: Yoshihiro Shimoda +Description: + This write-only file changes the phy mode for role swap of usb. + This file accepts the following strings: + "a_bus_req/" - switching from A-Host to A-Peripheral + "a_bus_drop" - switching from A-Peripheral to A-Host + "b_bus_req" - switching from B-Peripheral to B-Host + "b_bus_req/" - switching from B-Host to B-Peripheral diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c index 3d97ead..80f5bcc 100644 --- a/drivers/phy/phy-rcar-gen3-usb2.c +++ b/drivers/phy/phy-rcar-gen3-usb2.c @@ -70,6 +70,7 @@ #define USB2_LINECTRL1_DP_RPD BIT(18) #define USB2_LINECTRL1_DMRPD_EN BIT(17) #define USB2_LINECTRL1_DM_RPD BIT(16) +#define USB2_LINECTRL1_OPMODE_NODRV BIT(6) /* ADPCTRL */ #define USB2_ADPCTRL_OTGSESSVLD BIT(20) @@ -161,6 +162,43 @@ static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch) schedule_work(&ch->work); } +static void rcar_gen3_init_for_b_host(struct rcar_gen3_chan *ch) +{ + void __iomem *usb2_base = ch->base; + u32 val; + + val = readl(usb2_base + USB2_LINECTRL1); + writel(val | USB2_LINECTRL1_OPMODE_NODRV, usb2_base + USB2_LINECTRL1); + + rcar_gen3_set_linectrl(ch, 1, 1); + rcar_gen3_set_host_mode(ch, 1); + rcar_gen3_enable_vbus_ctrl(ch, 0); + + val = readl(usb2_base + USB2_LINECTRL1); + writel(val & ~USB2_LINECTRL1_OPMODE_NODRV, usb2_base + USB2_LINECTRL1); +} + +static void rcar_gen3_init_for_a_peri(struct rcar_gen3_chan *ch) +{ + rcar_gen3_set_linectrl(ch, 0, 1); + rcar_gen3_set_host_mode(ch, 0); + rcar_gen3_enable_vbus_ctrl(ch, 1); +} + +static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch) +{ + void __iomem *usb2_base = ch->base; + u32 val; + + val = readl(usb2_base + USB2_OBINTEN); + writel(val & ~USB2_OBINT_BITS, usb2_base + USB2_OBINTEN); + + rcar_gen3_enable_vbus_ctrl(ch, 0); + rcar_gen3_init_for_host(ch); + + writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN); +} + static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch) { return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); @@ -174,6 +212,71 @@ static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch) rcar_gen3_init_for_peri(ch); } +/* + * The following table is a state transition for usb phy mode: + * State Event Next state + * disconnected: E1 a_host + * E2 b_peripheral + * A-Device - a_host: E2 b_peripheral + * E3 disconnected + * E4 a_suspend + * A-Device - a_suspend: E2 b_peripheral + * E3 disconnected + * E5 a_host + * E6 a_peripheral + * A-Device - a_peripheral: E2 b_peripheral + * E3 disconnected + * E5 a_host + * B-Device - b_peripheral: E3 disconnected + * E7 b_wait_acon + * B-Device - b_wait_acon E3 disconnected + * E8 b_host + * B-Device - b_host: E3 disconnected + * E9 b_peripheral + * Events: + * E1: ID = 0 && Host detects D+ pull up, E2: ID = 1 && VBUS = 1 + * E3: VBUS = 0 || ID is changed, E4: a_bus_req/ + * E5: a_bus_drop, E6: Turns D+ pull up off + * E7: b_bus_req, E8: Detects D+ pull up + * E9: b_bus_req/ + */ +static ssize_t otg_inputs_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct rcar_gen3_chan *ch = dev_get_drvdata(dev); + bool is_host, is_b_device; + + if (!ch->has_otg || !ch->phy->init_count) + return -EIO; + + is_b_device = rcar_gen3_check_id(ch); /* true = B-Device */ + is_host = !(readl(ch->base + USB2_COMMCTRL) & USB2_COMMCTRL_OTG_PERI); + + if (!strncmp(buf, "a_bus_req/", strlen("a_bus_req/"))) { + if (is_b_device) /* fail if B-device */ + return -ENODEV; + rcar_gen3_init_for_a_peri(ch); + } else if (!strncmp(buf, "a_bus_drop", strlen("a_bus_drop"))) { + if (is_b_device || is_host) /* fail if B-device or A-host */ + return -ENODEV; + rcar_gen3_init_from_a_peri_to_a_host(ch); + } else if (!strncmp(buf, "b_bus_req/", strlen("b_bus_req/"))) { + if (!is_b_device || !is_host) /* fail if A-device or B-peri */ + return -ENODEV; + rcar_gen3_init_for_peri(ch); + } else if (!strncmp(buf, "b_bus_req", strlen("b_bus_req"))) { + if (!is_b_device) /* fail if A-device */ + return -ENODEV; + rcar_gen3_init_for_b_host(ch); + } else { + return -EINVAL; + } + + return count; +} +static DEVICE_ATTR_WO(otg_inputs); + static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch) { void __iomem *usb2_base = ch->base; @@ -351,21 +454,40 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) channel->vbus = NULL; } + platform_set_drvdata(pdev, channel); phy_set_drvdata(channel->phy, channel); provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(provider)) + if (IS_ERR(provider)) { dev_err(dev, "Failed to register PHY provider\n"); + } else if (channel->has_otg) { + int ret; + + ret = device_create_file(dev, &dev_attr_otg_inputs); + if (ret < 0) + return ret; + } return PTR_ERR_OR_ZERO(provider); } +static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev) +{ + struct rcar_gen3_chan *channel = platform_get_drvdata(pdev); + + if (channel->has_otg) + device_remove_file(&pdev->dev, &dev_attr_otg_inputs); + + return 0; +}; + static struct platform_driver rcar_gen3_phy_usb2_driver = { .driver = { .name = "phy_rcar_gen3_usb2", .of_match_table = rcar_gen3_phy_usb2_match_table, }, .probe = rcar_gen3_phy_usb2_probe, + .remove = rcar_gen3_phy_usb2_remove, }; module_platform_driver(rcar_gen3_phy_usb2_driver); -- 1.9.1