From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752169AbcFZH3F (ORCPT ); Sun, 26 Jun 2016 03:29:05 -0400 Received: from mail-pf0-f181.google.com ([209.85.192.181]:35614 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752067AbcFZH2q (ORCPT ); Sun, 26 Jun 2016 03:28:46 -0400 From: Stephen Boyd To: linux-usb@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Andy Gross , Bjorn Andersson , Neil Armstrong , Arnd Bergmann , Felipe Balbi , Greg Kroah-Hartman , Heikki Krogerus Subject: [PATCH 03/21] usb: ulpi: Avoid reading/writing in device creation with OF devices Date: Sun, 26 Jun 2016 00:28:20 -0700 Message-Id: <20160626072838.28082-4-stephen.boyd@linaro.org> X-Mailer: git-send-email 2.9.0.rc2.8.ga28705d In-Reply-To: <20160626072838.28082-1-stephen.boyd@linaro.org> References: <20160626072838.28082-1-stephen.boyd@linaro.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org ULPI devices are matched up against ULPI drivers by reading the vendor id and product id registers in the ULPI address space. Before we try to read those registers we'll do a scratch write to test the interface. Unfortunately, this doesn't work well if the ULPI device is not powered at the time of device creation. In that case, the scratch register writes fail and product and vendor ids can't be read. If the ULPI spec had some way to describe generic power requirements for the scratch, product, and vendor registers we could but power sequencing into the ULPI bus layer and power up the device before touching the hardware. Unfortunately this doesn't exist. Furthermore, the power information is device specific, so it varies from device to device and is not standard. Let's punt on doing the reads/writes here when we're using DT backed ULPI devices. This avoids any problems where we need to power on the device but haven't figured out which device it is yet to know what sort of regulators, clks, etc. that need to be turned on for it to work. Cc: Greg Kroah-Hartman Cc: Heikki Krogerus Signed-off-by: Stephen Boyd --- drivers/usb/common/ulpi.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index 980af672bfe3..a6b2a150b176 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -197,25 +197,7 @@ static int ulpi_of_register(struct ulpi *ulpi) static int ulpi_register(struct device *dev, struct ulpi *ulpi) { - int ret; - - /* Test the interface */ - ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa); - if (ret < 0) - return ret; - - ret = ulpi_read(ulpi, ULPI_SCRATCH); - if (ret < 0) - return ret; - - if (ret != 0xaa) - return -ENODEV; - - ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW); - ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8; - - ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW); - ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8; + int ret = -ENODEV; ulpi->dev.parent = dev; ulpi->dev.bus = &ulpi_bus; @@ -230,6 +212,26 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi) return ret; } + if (ret) { + /* Test the interface */ + ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa); + if (ret < 0) + return ret; + + ret = ulpi_read(ulpi, ULPI_SCRATCH); + if (ret < 0) + return ret; + + if (ret != 0xaa) + return -ENODEV; + + ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW); + ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8; + + ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW); + ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8; + } + if (of_device_request_module(&ulpi->dev)) request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product); -- 2.9.0.rc2.8.ga28705d