* [PATCH 2/6] usb: add devicetree helpers for determining dr_mode and phy_type
From: Sascha Hauer @ 2013-01-31 8:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130131023034.GF9777@nchen-desktop>
On Thu, Jan 31, 2013 at 10:30:36AM +0800, Peter Chen wrote:
> On Wed, Jan 30, 2013 at 04:29:38PM +0100, Sascha Hauer wrote:
> > From: Michael Grzeschik <m.grzeschik@pengutronix.de>
> >
> > This adds two little devicetree helper functions for determining the
> > dr_mode (host, peripheral, otg) and phy_type (utmi, ulpi,...) from
> > the devicetree.
> >
> > Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
> > Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > drivers/usb/usb-common.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++
> > include/linux/usb/of.h | 27 ++++++++++++++++++
> > include/linux/usb/otg.h | 7 +++++
> > include/linux/usb/phy.h | 9 ++++++
> > 4 files changed, 112 insertions(+)
> > create mode 100644 include/linux/usb/of.h
> >
> > diff --git a/drivers/usb/usb-common.c b/drivers/usb/usb-common.c
> > index d29503e..1c0292c 100644
> > --- a/drivers/usb/usb-common.c
> > +++ b/drivers/usb/usb-common.c
> > @@ -14,6 +14,9 @@
> > #include <linux/kernel.h>
> > #include <linux/module.h>
> > #include <linux/usb/ch9.h>
> > +#include <linux/of.h>
> > +#include <linux/usb/of.h>
> > +#include <linux/usb/otg.h>
> >
> > const char *usb_speed_string(enum usb_device_speed speed)
> > {
> > @@ -32,4 +35,70 @@ const char *usb_speed_string(enum usb_device_speed speed)
> > }
> > EXPORT_SYMBOL_GPL(usb_speed_string);
> >
> > +#ifdef CONFIG_OF
> > +static const char *usb_dr_modes[] = {
> > + [USB_DR_MODE_UNKNOWN] = "",
> > + [USB_DR_MODE_HOST] = "host",
> > + [USB_DR_MODE_PERIPHERAL] = "peripheral",
> > + [USB_DR_MODE_OTG] = "otg",
> > +};
> > +
> > +/**
> > + * of_usb_get_dr_mode - Get dual role mode for given device_node
> > + * @np: Pointer to the given device_node
> > + *
> > + * The function gets phy interface string from property 'dr_mode',
> > + * and returns the correspondig enum usb_phy_dr_mode
> > + */
> > +enum usb_phy_dr_mode of_usb_get_dr_mode(struct device_node *np)
> The word "phy" at usb_phy_dr_mode may cause misunderstand, just usb_dr_mode
> is ok
ok, changed.
> > +{
> > + const char *dr_mode;
> > + int err, i;
> > +
> > + err = of_property_read_string(np, "dr_mode", &dr_mode);
> > + if (err < 0)
> > + return USB_DR_MODE_UNKNOWN;
> > +
> > + for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
> > + if (!strcasecmp(dr_mode, usb_dr_modes[i]))
> > + return i;
> Just curious, why not using strcmp?
Probably because this is based on drivers/of/of_net.c which uses
strcasecmp. I never heard that devicetrees are case insensitive, so
I'll change this to strcmp.
> > +
> > + return USB_DR_MODE_UNKNOWN;
> > +}
> > +
> > +#ifdef CONFIG_OF
> > +enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np);
> > +enum usb_phy_dr_mode of_usb_get_dr_mode(struct device_node *np);
> > +#else
> > +static inline enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np)
> > +{
> > + return USBPHY_INTERFACE_MODE_NA;
> > +}
> > +
> > +static inline enum usb_phy_dr_mode of_usb_get_dr_mode(struct device_node *np)
> > +{
> > + return USB_DR_MODE_UNKNOWN;
> > +}
> For, dr_mode, if value has not existed, you use *_UNKNOWN, why
> for usbphy, you use *_NA. It is better uniform.
yup, fixed.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 2/6] usb: add devicetree helpers for determining dr_mode and phy_type
From: kishon @ 2013-01-31 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130131074337.GI1906@pengutronix.de>
On Thursday 31 January 2013 01:13 PM, Sascha Hauer wrote:
> On Thu, Jan 31, 2013 at 11:44:21AM +0530, kishon wrote:
>> Hi,
>>
>> On Wednesday 30 January 2013 08:59 PM, Sascha Hauer wrote:
>>> From: Michael Grzeschik <m.grzeschik@pengutronix.de>
>>>
>>> This adds two little devicetree helper functions for determining the
>>> dr_mode (host, peripheral, otg) and phy_type (utmi, ulpi,...) from
>>> the devicetree.
>>>
>>> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
>>> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>> ---
>>> drivers/usb/usb-common.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++
>>> include/linux/usb/of.h | 27 ++++++++++++++++++
>>> include/linux/usb/otg.h | 7 +++++
>>> include/linux/usb/phy.h | 9 ++++++
>>> 4 files changed, 112 insertions(+)
>>> create mode 100644 include/linux/usb/of.h
>>>
>>> diff --git a/drivers/usb/usb-common.c b/drivers/usb/usb-common.c
>>> index d29503e..1c0292c 100644
>>> --- a/drivers/usb/usb-common.c
>>> +++ b/drivers/usb/usb-common.c
>>> @@ -14,6 +14,9 @@
>>> #include <linux/kernel.h>
>>> #include <linux/module.h>
>>> #include <linux/usb/ch9.h>
>>> +#include <linux/of.h>
>>> +#include <linux/usb/of.h>
>>> +#include <linux/usb/otg.h>
>>>
>>> const char *usb_speed_string(enum usb_device_speed speed)
>>> {
>>> @@ -32,4 +35,70 @@ const char *usb_speed_string(enum usb_device_speed speed)
>>> }
>>> EXPORT_SYMBOL_GPL(usb_speed_string);
>>>
>>> +#ifdef CONFIG_OF
>>> +static const char *usb_dr_modes[] = {
>>> + [USB_DR_MODE_UNKNOWN] = "",
>>> + [USB_DR_MODE_HOST] = "host",
>>> + [USB_DR_MODE_PERIPHERAL] = "peripheral",
>>> + [USB_DR_MODE_OTG] = "otg",
>>> +};
>>> +
>>> +/**
>>> + * of_usb_get_dr_mode - Get dual role mode for given device_node
>>> + * @np: Pointer to the given device_node
>>> + *
>>> + * The function gets phy interface string from property 'dr_mode',
>>> + * and returns the correspondig enum usb_phy_dr_mode
>>> + */
>>> +enum usb_phy_dr_mode of_usb_get_dr_mode(struct device_node *np)
>>> +{
>>> + const char *dr_mode;
>>> + int err, i;
>>> +
>>> + err = of_property_read_string(np, "dr_mode", &dr_mode);
>>> + if (err < 0)
>>> + return USB_DR_MODE_UNKNOWN;
>>> +
>>> + for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
>>> + if (!strcasecmp(dr_mode, usb_dr_modes[i]))
>>> + return i;
>>> +
>>> + return USB_DR_MODE_UNKNOWN;
>>> +}
>>> +EXPORT_SYMBOL_GPL(of_usb_get_dr_mode);
>>> +
>>> +static const char *usbphy_modes[] = {
>>> + [USBPHY_INTERFACE_MODE_NA] = "",
>>> + [USBPHY_INTERFACE_MODE_UTMI] = "utmi",
>>> + [USBPHY_INTERFACE_MODE_UTMIW] = "utmi_wide",
>>> + [USBPHY_INTERFACE_MODE_ULPI] = "ulpi",
>>> + [USBPHY_INTERFACE_MODE_SERIAL] = "serial",
>>> + [USBPHY_INTERFACE_MODE_HSIC] = "hsic",
>>> +};
>>> +
>>> +/**
>>> + * of_get_usbphy_mode - Get phy mode for given device_node
>>
>> %s/of_get_usbphy_mode/of_usb_get_phy_mode
>>> + * @np: Pointer to the given device_node
>>> + *
>>> + * The function gets phy interface string from property 'phy_type',
>>> + * and returns the correspondig enum usb_phy_interface
>>> + */
>>> +enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np)
>>> +{
>>
>> You agreed to move this function inside usb/phy.. no?
>
> Yes, I did, but as mentioned in the introduction mail, the chipidea
> driver has to determine the phy type even when phy support (aka
> CONFIG_USB_OTG_UTILS) is disabled, so I can't put it in phy/phy.c.
>
> I could add a phy/of.c though. Would that be better?
Yes. I think that would be better.
Thanks
Kishon
^ permalink raw reply
* [alsa-devel] [PATCH 1/2] ASoC: tlv320aic3x: Convert mic bias to a supply widget
From: Hebbar, Gururaja @ 2013-01-31 8:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510A250E.4000706@ti.com>
On Thu, Jan 31, 2013 at 13:32:22, Ujfalusi, Peter wrote:
> On 01/30/2013 02:22 PM, Hebbar Gururaja wrote:
> > @@ -1493,6 +1544,28 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
> > aic3x->setup = ai3x_setup;
> > }
> >
> > + if (!of_property_read_u32(np, "ai3x-micbias-vg", &value)) {
> > + switch (value) {
> > + case 1 :
> > + aic3x->micbias_vg = AIC3X_MICBIAS_2_0V;
> > + break;
> > + case 2 :
> > + aic3x->micbias_vg = AIC3X_MICBIAS_2_5V;
> > + break;
> > + case 3 :
> > + aic3x->micbias_vg = AIC3X_MICBIAS_AVDDV;
> > + break;
> > + default :
> > + aic3x->micbias_vg = AIC3X_MICBIAS_OFF;
> > + dev_err(&i2c->dev, "Unsuitable MicBias voltage "
> > + "found in DT\n");
> > + }
> > + } else {
> > + dev_warn(&i2c->dev, "No MicBias voltage found in DT - "
> > + "using default\n");
>
> Since "ai3x-micbias-vg" property is optional I don't think it is appropriate
> to print anything here. If you really want a note about this it should be
> dev_info().
Ok. I will remove this warning.
>
> > + aic3x->micbias_vg = AIC3X_MICBIAS_OFF;
> > + }
> > +
> > } else {
> > aic3x->gpio_reset = -1;
> > }
> > diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
> > index 6db3c41..e521ac3 100644
> > --- a/sound/soc/codecs/tlv320aic3x.h
> > +++ b/sound/soc/codecs/tlv320aic3x.h
> > @@ -238,6 +238,10 @@
> > /* Default input volume */
> > #define DEFAULT_GAIN 0x20
> >
> > +/* MICBIAS Control Register */
> > +#define MICBIAS_LEVEL_SHIFT (6)
> > +#define MICBIAS_LEVEL_MASK (3 << 6)
> > +
> > /* headset detection / button API */
> >
> > /* The AIC3x supports detection of stereo headsets (GND + left + right signal)
> >
>
>
> --
> P?ter
>
Regards,
Gururaja
^ permalink raw reply
* [PATCH v3] ARM: OMAP2: am33xx-hwmod: Fix "register offset NULL check" bug
From: Hebbar, Gururaja @ 2013-01-31 8:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <D0DE2843-AA5C-4DFA-ADBE-61BC11D24836@dominion.thruhere.net>
On Thu, Jan 31, 2013 at 12:58:36, Koen Kooi wrote:
>
> Op 30 jan. 2013, om 15:39 heeft Hebbar Gururaja <gururaja.hebbar@ti.com> het volgende geschreven:
>
> > am33xx_cm_wait_module_ready() checks if register offset is NULL.
> >
> > int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs)
> > {
> > int i = 0;
> >
> > if (!clkctrl_offs)
> > return 0;
> >
> > In case of AM33xx, CLKCTRL register offset for different clock domains
> > are not uniformly placed. An example of this would be the RTC clock
> > domain with CLKCTRL offset at 0x00.
> > In such cases the module ready check is skipped which leads to a data
> > abort during boot-up when RTC registers is accessed.
> >
> > Remove this check here to avoid checking module readiness for modules
> > with clkctrl register offset at 0x00.
> >
> > Signed-off-by: Hebbar Gururaja <gururaja.hebbar@ti.com>
>
> I can confirm that this fixes the crash on boot with CONFIG_RTC_DRV_OMAP=y with 3.8-rc5
Could you please share the crash log for my reference?
>
> regards,
>
> Koen
Regards,
Gururaja
^ permalink raw reply
* [PATCH 1/2] ARM i.MX6: Add regulator delay support
From: Shawn Guo @ 2013-01-31 8:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359585224-11304-1-git-send-email-b20788@freescale.com>
On Wed, Jan 30, 2013 at 05:33:44PM -0500, Anson Huang wrote:
> For ANATOP LDOs, vddcpu, vddsoc and vddpu
> have step time settings in the misc2 register, need
> to add necessary step time info for these three LDOs,
> then regulator driver can add necessary delay based on
> these settings.
>
> offset 0x170:
> bit [24-25]: vddcpu
> bit [26-27]: vddpu
> bit [28-29]: vddsoc
>
> field definition:
> 0'b00: 64 cycles of 24M clock;
> 0'b01: 128 cycles of 24M clock;
> 0'b02: 256 cycles of 24M clock;
> 0'b03: 512 cycles of 24M clock;
>
> Signed-off-by: Anson Huang <b20788@freescale.com>
Applied, thanks.
^ permalink raw reply
* [PATCH 5/5] drm/exynos: don't include plat/gpio-cfg.h
From: Rahul Sharma @ 2013-01-31 8:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359127711-19070-6-git-send-email-arnd@arndb.de>
Hi Arnd Bergmann,
It looks good to me. My patch caused this issue.
Thanks for the fix.
regards,
Rahul Sharma.
On Fri, Jan 25, 2013 at 8:58 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> Patch 9eb3e9e6f3 "drm/exynos: add support for ARCH_MULTIPLATFORM"
> allowed building the exynos hdmi driver on non-samsung platforms,
> which unfortunately broke compilation in combination with 22c4f42897
> "drm: exynos: hdmi: add support for exynos5 hdmi", which added
> an inclusion of the samsung-specific plat/gpio-cfg.h header file.
>
> Fortunately, that header file is not required any more here, so
> we can simply revert the inclusion in order to build the ARM
> allyesconfig again without getting this error:
>
> drivers/gpu/drm/exynos/exynos_hdmi.c:37:27: fatal error: plat/gpio-cfg.h: No such file or directory
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Cc: Rob Clark <rob@ti.com>
> Cc: Inki Dae <inki.dae@samsung.com>
> Cc: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Rahul Sharma <rahul.sharma@samsung.com>
> ---
> drivers/gpu/drm/exynos/exynos_hdmi.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index 41ff79d..b5f5119 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -34,7 +34,6 @@
> #include <linux/regulator/consumer.h>
> #include <linux/io.h>
> #include <linux/of_gpio.h>
> -#include <plat/gpio-cfg.h>
>
> #include <drm/exynos_drm.h>
>
> --
> 1.8.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] arm: mvebu: support for the new Armada XP evaluation board(DB-MV784MP-GP)
From: Gregory CLEMENT @ 2013-01-31 8:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2206499.VqjeY6AxuS@bender>
On 01/30/2013 08:30 PM, Florian Fainelli wrote:
> On Wednesday 30 January 2013 18:26:14 Gregory CLEMENT wrote:
>> This is the new Armada XP evaluation board from Marvell. It comes with
>> a RS232 port over USB, a SATA link, an internal SSD, 4 Ethernet
>> Gigabit links.
>>
>> Support for USB (Host and device), SDIO, PCIe will be added as drivers
>> when they become available for Armada XP in mainline.
>>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>
> Tested-by: Florian Fainelli <florian@openwrt.org>
>
> The PHY mapping you have is the right one, besides the minor naming in model
> and header comment, this is good, thanks a lot!
>
Thanks!
So I am waiting for the official Tested-by from Simon, and I will send a V2
patch with the name fixed and with your tested-by.
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* OMAP4 PM bootloader dependency problems
From: Tero Kristo @ 2013-01-31 9:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1301301706580.17105@utopia.booyaka.com>
On Wed, 2013-01-30 at 17:15 +0000, Paul Walmsley wrote:
> Hi Tero et al.,
>
> On Tue, 22 Jan 2013, Paul Walmsley wrote:
>
> > As we've discussed, there are known bootloader dependencies with the OMAP4
> > PM retention idle code, introduced in v3.8. Boards booted with u-boot
> > versions even as recent as 2011 won't enter retention idle correctly; for
> > example:
> >
> > http://www.pwsan.com/omap/testlogs/test_v3.8-rc4/20130120122039/pm/4430es2panda/4430es2panda_log.txt
>
> ...
>
> > Barring that, what I'd like to see is a patch for v3.8-rc fixes that adds
> > a warning, printed to the kernel console, during boot. The warning should
> > state that the OMAP4 PM code only works with certain bootloaders, and
> > should identify the minimum u-boot release needed for OMAP4 full-chip
> > retention idle to work.
>
> Any progress on this one? Time is getting very short to get this into
> v3.8-rc fixes, and it's important to get this into v3.8 so we don't
> have users expecting chip power management to work correctly with most
> u-boot versions that are out in the field.
>
> All we should need for v3.8-rc are a few pr_warn()s that execute during
> OMAP4 PM init, noting that the OMAP4 chip power management doesn't work
> correctly with many bootloaders, due to missing code in the kernel to
> properly reset and initialize some devices, and noting the first u-boot
> version that is known to work correctly.
Personally I don't like too much to have just extra spam during boot,
which in many cases is even unnecessary (e.g. people who actually have
good u-boot in use.) Personally I would like to have some sort of test
during boot which detects broken PM and maybe prevents core idle
completely if this is the case. Alternatively we can add extra info to
the failed suspend dump and mention a good u-boot to try out (v2012-07
or newer.)
If we could detect boot loader version from kernel side, that would work
also.
-Tero
>
> Otherwise there's a very real risk that folks out there will waste lots of
> time trying to figure out why power management doesn't work as they
> expect. To respect our users, we shouldn't put them in that situation.
>
>
> - Paul
^ permalink raw reply
* [PATCH v2] Add USB of helpers and use them in the chipidea driver
From: Sascha Hauer @ 2013-01-31 9:01 UTC (permalink / raw)
To: linux-arm-kernel
changes since v1:
- move phy specific of helper to drivers/usb/phy/of.c
- use strcmp instead of strcasecmp for matching property values
- change usb_phy_dr_mode to usb_dr_mode
- change USBPHY_INTERFACE_MODE_NA to USBPHY_INTERFACE_MODE_UNKNOWN
- add copyright header to new files
- chipidea: drop mdelay at end of PTS/PTW setup
- chipidea: implement lpm core type handling for PTS/PTW
Sascha
----------------------------------------------------------------
Michael Grzeschik (3):
USB: add devicetree helpers for determining dr_mode and phy_type
USB: chipidea: ci13xxx-imx: create dynamic platformdata
USB: chipidea: add PTW and PTS handling
Sascha Hauer (3):
USB: move bulk of otg/otg.c to phy/phy.c
USB chipidea: introduce dual role mode pdata flags
USB chipidea i.MX: introduce dr_mode property
.../devicetree/bindings/usb/ci13xxx-imx.txt | 6 +
drivers/usb/chipidea/bits.h | 14 +-
drivers/usb/chipidea/ci13xxx_imx.c | 29 +-
drivers/usb/chipidea/core.c | 60 ++-
drivers/usb/otg/otg.c | 423 -------------------
drivers/usb/phy/Makefile | 2 +
drivers/usb/phy/phy.c | 434 ++++++++++++++++++++
drivers/usb/usb-common.c | 36 ++
include/linux/usb/chipidea.h | 3 +-
include/linux/usb/of.h | 27 ++
include/linux/usb/otg.h | 7 +
include/linux/usb/phy.h | 9 +
12 files changed, 609 insertions(+), 441 deletions(-)
create mode 100644 drivers/usb/phy/phy.c
create mode 100644 include/linux/usb/of.h
^ permalink raw reply
* [PATCH 1/6] USB: move bulk of otg/otg.c to phy/phy.c
From: Sascha Hauer @ 2013-01-31 9:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-1-git-send-email-s.hauer@pengutronix.de>
Most of otg/otg.c is not otg specific, but phy specific, so move it
to the phy directory.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reported-by: kishon <kishon@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
---
drivers/usb/otg/otg.c | 423 ---------------------------------------------
drivers/usb/phy/Makefile | 1 +
drivers/usb/phy/phy.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 425 insertions(+), 423 deletions(-)
create mode 100644 drivers/usb/phy/phy.c
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c
index e181439..358cfd9 100644
--- a/drivers/usb/otg/otg.c
+++ b/drivers/usb/otg/otg.c
@@ -8,432 +8,9 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-
-#include <linux/kernel.h>
#include <linux/export.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-
#include <linux/usb/otg.h>
-static LIST_HEAD(phy_list);
-static LIST_HEAD(phy_bind_list);
-static DEFINE_SPINLOCK(phy_lock);
-
-static struct usb_phy *__usb_find_phy(struct list_head *list,
- enum usb_phy_type type)
-{
- struct usb_phy *phy = NULL;
-
- list_for_each_entry(phy, list, head) {
- if (phy->type != type)
- continue;
-
- return phy;
- }
-
- return ERR_PTR(-ENODEV);
-}
-
-static struct usb_phy *__usb_find_phy_dev(struct device *dev,
- struct list_head *list, u8 index)
-{
- struct usb_phy_bind *phy_bind = NULL;
-
- list_for_each_entry(phy_bind, list, list) {
- if (!(strcmp(phy_bind->dev_name, dev_name(dev))) &&
- phy_bind->index == index) {
- if (phy_bind->phy)
- return phy_bind->phy;
- else
- return ERR_PTR(-EPROBE_DEFER);
- }
- }
-
- return ERR_PTR(-ENODEV);
-}
-
-static struct usb_phy *__of_usb_find_phy(struct device_node *node)
-{
- struct usb_phy *phy;
-
- list_for_each_entry(phy, &phy_list, head) {
- if (node != phy->dev->of_node)
- continue;
-
- return phy;
- }
-
- return ERR_PTR(-ENODEV);
-}
-
-static void devm_usb_phy_release(struct device *dev, void *res)
-{
- struct usb_phy *phy = *(struct usb_phy **)res;
-
- usb_put_phy(phy);
-}
-
-static int devm_usb_phy_match(struct device *dev, void *res, void *match_data)
-{
- return res == match_data;
-}
-
-/**
- * devm_usb_get_phy - find the USB PHY
- * @dev - device that requests this phy
- * @type - the type of the phy the controller requires
- *
- * Gets the phy using usb_get_phy(), and associates a device with it using
- * devres. On driver detach, release function is invoked on the devres data,
- * then, devres data is freed.
- *
- * For use by USB host and peripheral drivers.
- */
-struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type)
-{
- struct usb_phy **ptr, *phy;
-
- ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return NULL;
-
- phy = usb_get_phy(type);
- if (!IS_ERR(phy)) {
- *ptr = phy;
- devres_add(dev, ptr);
- } else
- devres_free(ptr);
-
- return phy;
-}
-EXPORT_SYMBOL(devm_usb_get_phy);
-
-/**
- * usb_get_phy - find the USB PHY
- * @type - the type of the phy the controller requires
- *
- * Returns the phy driver, after getting a refcount to it; or
- * -ENODEV if there is no such phy. The caller is responsible for
- * calling usb_put_phy() to release that count.
- *
- * For use by USB host and peripheral drivers.
- */
-struct usb_phy *usb_get_phy(enum usb_phy_type type)
-{
- struct usb_phy *phy = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&phy_lock, flags);
-
- phy = __usb_find_phy(&phy_list, type);
- if (IS_ERR(phy)) {
- pr_err("unable to find transceiver of type %s\n",
- usb_phy_type_string(type));
- goto err0;
- }
-
- get_device(phy->dev);
-
-err0:
- spin_unlock_irqrestore(&phy_lock, flags);
-
- return phy;
-}
-EXPORT_SYMBOL(usb_get_phy);
-
- /**
- * devm_usb_get_phy_by_phandle - find the USB PHY by phandle
- * @dev - device that requests this phy
- * @phandle - name of the property holding the phy phandle value
- * @index - the index of the phy
- *
- * Returns the phy driver associated with the given phandle value,
- * after getting a refcount to it, -ENODEV if there is no such phy or
- * -EPROBE_DEFER if there is a phandle to the phy, but the device is
- * not yet loaded. While at that, it also associates the device with
- * the phy using devres. On driver detach, release function is invoked
- * on the devres data, then, devres data is freed.
- *
- * For use by USB host and peripheral drivers.
- */
-struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
- const char *phandle, u8 index)
-{
- struct usb_phy *phy = ERR_PTR(-ENOMEM), **ptr;
- unsigned long flags;
- struct device_node *node;
-
- if (!dev->of_node) {
- dev_dbg(dev, "device does not have a device node entry\n");
- return ERR_PTR(-EINVAL);
- }
-
- node = of_parse_phandle(dev->of_node, phandle, index);
- if (!node) {
- dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle,
- dev->of_node->full_name);
- return ERR_PTR(-ENODEV);
- }
-
- ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr) {
- dev_dbg(dev, "failed to allocate memory for devres\n");
- goto err0;
- }
-
- spin_lock_irqsave(&phy_lock, flags);
-
- phy = __of_usb_find_phy(node);
- if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
- phy = ERR_PTR(-EPROBE_DEFER);
- devres_free(ptr);
- goto err1;
- }
-
- *ptr = phy;
- devres_add(dev, ptr);
-
- get_device(phy->dev);
-
-err1:
- spin_unlock_irqrestore(&phy_lock, flags);
-
-err0:
- of_node_put(node);
-
- return phy;
-}
-EXPORT_SYMBOL(devm_usb_get_phy_by_phandle);
-
-/**
- * usb_get_phy_dev - find the USB PHY
- * @dev - device that requests this phy
- * @index - the index of the phy
- *
- * Returns the phy driver, after getting a refcount to it; or
- * -ENODEV if there is no such phy. The caller is responsible for
- * calling usb_put_phy() to release that count.
- *
- * For use by USB host and peripheral drivers.
- */
-struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
-{
- struct usb_phy *phy = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&phy_lock, flags);
-
- phy = __usb_find_phy_dev(dev, &phy_bind_list, index);
- if (IS_ERR(phy)) {
- pr_err("unable to find transceiver\n");
- goto err0;
- }
-
- get_device(phy->dev);
-
-err0:
- spin_unlock_irqrestore(&phy_lock, flags);
-
- return phy;
-}
-EXPORT_SYMBOL(usb_get_phy_dev);
-
-/**
- * devm_usb_get_phy_dev - find the USB PHY using device ptr and index
- * @dev - device that requests this phy
- * @index - the index of the phy
- *
- * Gets the phy using usb_get_phy_dev(), and associates a device with it using
- * devres. On driver detach, release function is invoked on the devres data,
- * then, devres data is freed.
- *
- * For use by USB host and peripheral drivers.
- */
-struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index)
-{
- struct usb_phy **ptr, *phy;
-
- ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return NULL;
-
- phy = usb_get_phy_dev(dev, index);
- if (!IS_ERR(phy)) {
- *ptr = phy;
- devres_add(dev, ptr);
- } else
- devres_free(ptr);
-
- return phy;
-}
-EXPORT_SYMBOL(devm_usb_get_phy_dev);
-
-/**
- * devm_usb_put_phy - release the USB PHY
- * @dev - device that wants to release this phy
- * @phy - the phy returned by devm_usb_get_phy()
- *
- * destroys the devres associated with this phy and invokes usb_put_phy
- * to release the phy.
- *
- * For use by USB host and peripheral drivers.
- */
-void devm_usb_put_phy(struct device *dev, struct usb_phy *phy)
-{
- int r;
-
- r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy);
- dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
-}
-EXPORT_SYMBOL(devm_usb_put_phy);
-
-/**
- * usb_put_phy - release the USB PHY
- * @x: the phy returned by usb_get_phy()
- *
- * Releases a refcount the caller received from usb_get_phy().
- *
- * For use by USB host and peripheral drivers.
- */
-void usb_put_phy(struct usb_phy *x)
-{
- if (x)
- put_device(x->dev);
-}
-EXPORT_SYMBOL(usb_put_phy);
-
-/**
- * usb_add_phy - declare the USB PHY
- * @x: the USB phy to be used; or NULL
- * @type - the type of this PHY
- *
- * This call is exclusively for use by phy drivers, which
- * coordinate the activities of drivers for host and peripheral
- * controllers, and in some cases for VBUS current regulation.
- */
-int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
-{
- int ret = 0;
- unsigned long flags;
- struct usb_phy *phy;
-
- if (x->type != USB_PHY_TYPE_UNDEFINED) {
- dev_err(x->dev, "not accepting initialized PHY %s\n", x->label);
- return -EINVAL;
- }
-
- spin_lock_irqsave(&phy_lock, flags);
-
- list_for_each_entry(phy, &phy_list, head) {
- if (phy->type == type) {
- ret = -EBUSY;
- dev_err(x->dev, "transceiver type %s already exists\n",
- usb_phy_type_string(type));
- goto out;
- }
- }
-
- x->type = type;
- list_add_tail(&x->head, &phy_list);
-
-out:
- spin_unlock_irqrestore(&phy_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(usb_add_phy);
-
-/**
- * usb_add_phy_dev - declare the USB PHY
- * @x: the USB phy to be used; or NULL
- *
- * This call is exclusively for use by phy drivers, which
- * coordinate the activities of drivers for host and peripheral
- * controllers, and in some cases for VBUS current regulation.
- */
-int usb_add_phy_dev(struct usb_phy *x)
-{
- struct usb_phy_bind *phy_bind;
- unsigned long flags;
-
- if (!x->dev) {
- dev_err(x->dev, "no device provided for PHY\n");
- return -EINVAL;
- }
-
- spin_lock_irqsave(&phy_lock, flags);
- list_for_each_entry(phy_bind, &phy_bind_list, list)
- if (!(strcmp(phy_bind->phy_dev_name, dev_name(x->dev))))
- phy_bind->phy = x;
-
- list_add_tail(&x->head, &phy_list);
-
- spin_unlock_irqrestore(&phy_lock, flags);
- return 0;
-}
-EXPORT_SYMBOL(usb_add_phy_dev);
-
-/**
- * usb_remove_phy - remove the OTG PHY
- * @x: the USB OTG PHY to be removed;
- *
- * This reverts the effects of usb_add_phy
- */
-void usb_remove_phy(struct usb_phy *x)
-{
- unsigned long flags;
- struct usb_phy_bind *phy_bind;
-
- spin_lock_irqsave(&phy_lock, flags);
- if (x) {
- list_for_each_entry(phy_bind, &phy_bind_list, list)
- if (phy_bind->phy == x)
- phy_bind->phy = NULL;
- list_del(&x->head);
- }
- spin_unlock_irqrestore(&phy_lock, flags);
-}
-EXPORT_SYMBOL(usb_remove_phy);
-
-/**
- * usb_bind_phy - bind the phy and the controller that uses the phy
- * @dev_name: the device name of the device that will bind to the phy
- * @index: index to specify the port number
- * @phy_dev_name: the device name of the phy
- *
- * Fills the phy_bind structure with the dev_name and phy_dev_name. This will
- * be used when the phy driver registers the phy and when the controller
- * requests this phy.
- *
- * To be used by platform specific initialization code.
- */
-int __init usb_bind_phy(const char *dev_name, u8 index,
- const char *phy_dev_name)
-{
- struct usb_phy_bind *phy_bind;
- unsigned long flags;
-
- phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL);
- if (!phy_bind) {
- pr_err("phy_bind(): No memory for phy_bind");
- return -ENOMEM;
- }
-
- phy_bind->dev_name = dev_name;
- phy_bind->phy_dev_name = phy_dev_name;
- phy_bind->index = index;
-
- spin_lock_irqsave(&phy_lock, flags);
- list_add_tail(&phy_bind->list, &phy_bind_list);
- spin_unlock_irqrestore(&phy_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(usb_bind_phy);
-
const char *otg_state_string(enum usb_otg_state state)
{
switch (state) {
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index b13faa1..9fa6327 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -4,6 +4,7 @@
ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
+obj-$(CONFIG_USB_OTG_UTILS) += phy.o
obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
obj-$(CONFIG_OMAP_USB3) += omap-usb3.o
obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
new file mode 100644
index 0000000..ef35eb0
--- /dev/null
+++ b/drivers/usb/phy/phy.c
@@ -0,0 +1,424 @@
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include <linux/usb/phy.h>
+
+static LIST_HEAD(phy_list);
+static LIST_HEAD(phy_bind_list);
+static DEFINE_SPINLOCK(phy_lock);
+
+static struct usb_phy *__usb_find_phy(struct list_head *list,
+ enum usb_phy_type type)
+{
+ struct usb_phy *phy = NULL;
+
+ list_for_each_entry(phy, list, head) {
+ if (phy->type != type)
+ continue;
+
+ return phy;
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+
+static struct usb_phy *__usb_find_phy_dev(struct device *dev,
+ struct list_head *list, u8 index)
+{
+ struct usb_phy_bind *phy_bind = NULL;
+
+ list_for_each_entry(phy_bind, list, list) {
+ if (!(strcmp(phy_bind->dev_name, dev_name(dev))) &&
+ phy_bind->index == index) {
+ if (phy_bind->phy)
+ return phy_bind->phy;
+ else
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+
+static struct usb_phy *__of_usb_find_phy(struct device_node *node)
+{
+ struct usb_phy *phy;
+
+ list_for_each_entry(phy, &phy_list, head) {
+ if (node != phy->dev->of_node)
+ continue;
+
+ return phy;
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+
+static void devm_usb_phy_release(struct device *dev, void *res)
+{
+ struct usb_phy *phy = *(struct usb_phy **)res;
+
+ usb_put_phy(phy);
+}
+
+static int devm_usb_phy_match(struct device *dev, void *res, void *match_data)
+{
+ return res == match_data;
+}
+
+/**
+ * devm_usb_get_phy - find the USB PHY
+ * @dev - device that requests this phy
+ * @type - the type of the phy the controller requires
+ *
+ * Gets the phy using usb_get_phy(), and associates a device with it using
+ * devres. On driver detach, release function is invoked on the devres data,
+ * then, devres data is freed.
+ *
+ * For use by USB host and peripheral drivers.
+ */
+struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type)
+{
+ struct usb_phy **ptr, *phy;
+
+ ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ phy = usb_get_phy(type);
+ if (!IS_ERR(phy)) {
+ *ptr = phy;
+ devres_add(dev, ptr);
+ } else
+ devres_free(ptr);
+
+ return phy;
+}
+EXPORT_SYMBOL(devm_usb_get_phy);
+
+/**
+ * usb_get_phy - find the USB PHY
+ * @type - the type of the phy the controller requires
+ *
+ * Returns the phy driver, after getting a refcount to it; or
+ * -ENODEV if there is no such phy. The caller is responsible for
+ * calling usb_put_phy() to release that count.
+ *
+ * For use by USB host and peripheral drivers.
+ */
+struct usb_phy *usb_get_phy(enum usb_phy_type type)
+{
+ struct usb_phy *phy = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&phy_lock, flags);
+
+ phy = __usb_find_phy(&phy_list, type);
+ if (IS_ERR(phy)) {
+ pr_err("unable to find transceiver of type %s\n",
+ usb_phy_type_string(type));
+ goto err0;
+ }
+
+ get_device(phy->dev);
+
+err0:
+ spin_unlock_irqrestore(&phy_lock, flags);
+
+ return phy;
+}
+EXPORT_SYMBOL(usb_get_phy);
+
+ /**
+ * devm_usb_get_phy_by_phandle - find the USB PHY by phandle
+ * @dev - device that requests this phy
+ * @phandle - name of the property holding the phy phandle value
+ * @index - the index of the phy
+ *
+ * Returns the phy driver associated with the given phandle value,
+ * after getting a refcount to it, -ENODEV if there is no such phy or
+ * -EPROBE_DEFER if there is a phandle to the phy, but the device is
+ * not yet loaded. While at that, it also associates the device with
+ * the phy using devres. On driver detach, release function is invoked
+ * on the devres data, then, devres data is freed.
+ *
+ * For use by USB host and peripheral drivers.
+ */
+struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
+ const char *phandle, u8 index)
+{
+ struct usb_phy *phy = ERR_PTR(-ENOMEM), **ptr;
+ unsigned long flags;
+ struct device_node *node;
+
+ if (!dev->of_node) {
+ dev_dbg(dev, "device does not have a device node entry\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ node = of_parse_phandle(dev->of_node, phandle, index);
+ if (!node) {
+ dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle,
+ dev->of_node->full_name);
+ return ERR_PTR(-ENODEV);
+ }
+
+ ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr) {
+ dev_dbg(dev, "failed to allocate memory for devres\n");
+ goto err0;
+ }
+
+ spin_lock_irqsave(&phy_lock, flags);
+
+ phy = __of_usb_find_phy(node);
+ if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
+ phy = ERR_PTR(-EPROBE_DEFER);
+ devres_free(ptr);
+ goto err1;
+ }
+
+ *ptr = phy;
+ devres_add(dev, ptr);
+
+ get_device(phy->dev);
+
+err1:
+ spin_unlock_irqrestore(&phy_lock, flags);
+
+err0:
+ of_node_put(node);
+
+ return phy;
+}
+EXPORT_SYMBOL(devm_usb_get_phy_by_phandle);
+
+/**
+ * usb_get_phy_dev - find the USB PHY
+ * @dev - device that requests this phy
+ * @index - the index of the phy
+ *
+ * Returns the phy driver, after getting a refcount to it; or
+ * -ENODEV if there is no such phy. The caller is responsible for
+ * calling usb_put_phy() to release that count.
+ *
+ * For use by USB host and peripheral drivers.
+ */
+struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
+{
+ struct usb_phy *phy = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&phy_lock, flags);
+
+ phy = __usb_find_phy_dev(dev, &phy_bind_list, index);
+ if (IS_ERR(phy)) {
+ pr_err("unable to find transceiver\n");
+ goto err0;
+ }
+
+ get_device(phy->dev);
+
+err0:
+ spin_unlock_irqrestore(&phy_lock, flags);
+
+ return phy;
+}
+EXPORT_SYMBOL(usb_get_phy_dev);
+
+/**
+ * devm_usb_get_phy_dev - find the USB PHY using device ptr and index
+ * @dev - device that requests this phy
+ * @index - the index of the phy
+ *
+ * Gets the phy using usb_get_phy_dev(), and associates a device with it using
+ * devres. On driver detach, release function is invoked on the devres data,
+ * then, devres data is freed.
+ *
+ * For use by USB host and peripheral drivers.
+ */
+struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index)
+{
+ struct usb_phy **ptr, *phy;
+
+ ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ phy = usb_get_phy_dev(dev, index);
+ if (!IS_ERR(phy)) {
+ *ptr = phy;
+ devres_add(dev, ptr);
+ } else
+ devres_free(ptr);
+
+ return phy;
+}
+EXPORT_SYMBOL(devm_usb_get_phy_dev);
+
+/**
+ * devm_usb_put_phy - release the USB PHY
+ * @dev - device that wants to release this phy
+ * @phy - the phy returned by devm_usb_get_phy()
+ *
+ * destroys the devres associated with this phy and invokes usb_put_phy
+ * to release the phy.
+ *
+ * For use by USB host and peripheral drivers.
+ */
+void devm_usb_put_phy(struct device *dev, struct usb_phy *phy)
+{
+ int r;
+
+ r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy);
+ dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
+}
+EXPORT_SYMBOL(devm_usb_put_phy);
+
+/**
+ * usb_put_phy - release the USB PHY
+ * @x: the phy returned by usb_get_phy()
+ *
+ * Releases a refcount the caller received from usb_get_phy().
+ *
+ * For use by USB host and peripheral drivers.
+ */
+void usb_put_phy(struct usb_phy *x)
+{
+ if (x)
+ put_device(x->dev);
+}
+EXPORT_SYMBOL(usb_put_phy);
+
+/**
+ * usb_add_phy - declare the USB PHY
+ * @x: the USB phy to be used; or NULL
+ * @type - the type of this PHY
+ *
+ * This call is exclusively for use by phy drivers, which
+ * coordinate the activities of drivers for host and peripheral
+ * controllers, and in some cases for VBUS current regulation.
+ */
+int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
+{
+ int ret = 0;
+ unsigned long flags;
+ struct usb_phy *phy;
+
+ if (x->type != USB_PHY_TYPE_UNDEFINED) {
+ dev_err(x->dev, "not accepting initialized PHY %s\n", x->label);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&phy_lock, flags);
+
+ list_for_each_entry(phy, &phy_list, head) {
+ if (phy->type == type) {
+ ret = -EBUSY;
+ dev_err(x->dev, "transceiver type %s already exists\n",
+ usb_phy_type_string(type));
+ goto out;
+ }
+ }
+
+ x->type = type;
+ list_add_tail(&x->head, &phy_list);
+
+out:
+ spin_unlock_irqrestore(&phy_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(usb_add_phy);
+
+/**
+ * usb_add_phy_dev - declare the USB PHY
+ * @x: the USB phy to be used; or NULL
+ *
+ * This call is exclusively for use by phy drivers, which
+ * coordinate the activities of drivers for host and peripheral
+ * controllers, and in some cases for VBUS current regulation.
+ */
+int usb_add_phy_dev(struct usb_phy *x)
+{
+ struct usb_phy_bind *phy_bind;
+ unsigned long flags;
+
+ if (!x->dev) {
+ dev_err(x->dev, "no device provided for PHY\n");
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&phy_lock, flags);
+ list_for_each_entry(phy_bind, &phy_bind_list, list)
+ if (!(strcmp(phy_bind->phy_dev_name, dev_name(x->dev))))
+ phy_bind->phy = x;
+
+ list_add_tail(&x->head, &phy_list);
+
+ spin_unlock_irqrestore(&phy_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(usb_add_phy_dev);
+
+/**
+ * usb_remove_phy - remove the OTG PHY
+ * @x: the USB OTG PHY to be removed;
+ *
+ * This reverts the effects of usb_add_phy
+ */
+void usb_remove_phy(struct usb_phy *x)
+{
+ unsigned long flags;
+ struct usb_phy_bind *phy_bind;
+
+ spin_lock_irqsave(&phy_lock, flags);
+ if (x) {
+ list_for_each_entry(phy_bind, &phy_bind_list, list)
+ if (phy_bind->phy == x)
+ phy_bind->phy = NULL;
+ list_del(&x->head);
+ }
+ spin_unlock_irqrestore(&phy_lock, flags);
+}
+EXPORT_SYMBOL(usb_remove_phy);
+
+/**
+ * usb_bind_phy - bind the phy and the controller that uses the phy
+ * @dev_name: the device name of the device that will bind to the phy
+ * @index: index to specify the port number
+ * @phy_dev_name: the device name of the phy
+ *
+ * Fills the phy_bind structure with the dev_name and phy_dev_name. This will
+ * be used when the phy driver registers the phy and when the controller
+ * requests this phy.
+ *
+ * To be used by platform specific initialization code.
+ */
+int __init usb_bind_phy(const char *dev_name, u8 index,
+ const char *phy_dev_name)
+{
+ struct usb_phy_bind *phy_bind;
+ unsigned long flags;
+
+ phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL);
+ if (!phy_bind) {
+ pr_err("phy_bind(): No memory for phy_bind");
+ return -ENOMEM;
+ }
+
+ phy_bind->dev_name = dev_name;
+ phy_bind->phy_dev_name = phy_dev_name;
+ phy_bind->index = index;
+
+ spin_lock_irqsave(&phy_lock, flags);
+ list_add_tail(&phy_bind->list, &phy_bind_list);
+ spin_unlock_irqrestore(&phy_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usb_bind_phy);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/6] USB: add devicetree helpers for determining dr_mode and phy_type
From: Sascha Hauer @ 2013-01-31 9:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-1-git-send-email-s.hauer@pengutronix.de>
From: Michael Grzeschik <m.grzeschik@pengutronix.de>
This adds two little devicetree helper functions for determining the
dr_mode (host, peripheral, otg) and phy_type (utmi, ulpi,...) from
the devicetree.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/phy/Makefile | 1 +
drivers/usb/phy/phy.c | 10 ++++++++++
drivers/usb/usb-common.c | 36 ++++++++++++++++++++++++++++++++++++
include/linux/usb/of.h | 27 +++++++++++++++++++++++++++
include/linux/usb/otg.h | 7 +++++++
include/linux/usb/phy.h | 9 +++++++++
6 files changed, 90 insertions(+)
create mode 100644 include/linux/usb/of.h
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 9fa6327..e1be1e8 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -5,6 +5,7 @@
ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
obj-$(CONFIG_USB_OTG_UTILS) += phy.o
+obj-$(CONFIG_OF) += of.o
obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
obj-$(CONFIG_OMAP_USB3) += omap-usb3.o
obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index ef35eb0..3ad4b5c 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -1,3 +1,13 @@
+/*
+ * phy.c -- USB phy handling
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/err.h>
diff --git a/drivers/usb/usb-common.c b/drivers/usb/usb-common.c
index d29503e..ad4d87d 100644
--- a/drivers/usb/usb-common.c
+++ b/drivers/usb/usb-common.c
@@ -14,6 +14,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb/ch9.h>
+#include <linux/of.h>
+#include <linux/usb/of.h>
+#include <linux/usb/otg.h>
const char *usb_speed_string(enum usb_device_speed speed)
{
@@ -32,4 +35,37 @@ const char *usb_speed_string(enum usb_device_speed speed)
}
EXPORT_SYMBOL_GPL(usb_speed_string);
+#ifdef CONFIG_OF
+static const char *usb_dr_modes[] = {
+ [USB_DR_MODE_UNKNOWN] = "",
+ [USB_DR_MODE_HOST] = "host",
+ [USB_DR_MODE_PERIPHERAL] = "peripheral",
+ [USB_DR_MODE_OTG] = "otg",
+};
+
+/**
+ * of_usb_get_dr_mode - Get dual role mode for given device_node
+ * @np: Pointer to the given device_node
+ *
+ * The function gets phy interface string from property 'dr_mode',
+ * and returns the correspondig enum usb_dr_mode
+ */
+enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
+{
+ const char *dr_mode;
+ int err, i;
+
+ err = of_property_read_string(np, "dr_mode", &dr_mode);
+ if (err < 0)
+ return USB_DR_MODE_UNKNOWN;
+
+ for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
+ if (!strcmp(dr_mode, usb_dr_modes[i]))
+ return i;
+
+ return USB_DR_MODE_UNKNOWN;
+}
+EXPORT_SYMBOL_GPL(of_usb_get_dr_mode);
+#endif
+
MODULE_LICENSE("GPL");
diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h
new file mode 100644
index 0000000..4681a20
--- /dev/null
+++ b/include/linux/usb/of.h
@@ -0,0 +1,27 @@
+/*
+ * OF helpers for usb devices.
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_USB_OF_H
+#define __LINUX_USB_OF_H
+
+#include <linux/usb/phy.h>
+
+#ifdef CONFIG_OF
+enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np);
+enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np);
+#else
+static inline enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np)
+{
+ return USBPHY_INTERFACE_MODE_UNKNOWN;
+}
+
+static inline enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
+{
+ return USB_DR_MODE_UNKNOWN;
+}
+#endif
+
+#endif /* __LINUX_USB_OF_H */
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
index e8a5fe8..4e8bfbb 100644
--- a/include/linux/usb/otg.h
+++ b/include/linux/usb/otg.h
@@ -99,4 +99,11 @@ otg_start_srp(struct usb_otg *otg)
/* for OTG controller drivers (and maybe other stuff) */
extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
+enum usb_dr_mode {
+ USB_DR_MODE_UNKNOWN,
+ USB_DR_MODE_HOST,
+ USB_DR_MODE_PERIPHERAL,
+ USB_DR_MODE_OTG,
+};
+
#endif /* __LINUX_USB_OTG_H */
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index 15847cb..5edddb1 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -12,6 +12,15 @@
#include <linux/notifier.h>
#include <linux/usb.h>
+enum usb_phy_interface {
+ USBPHY_INTERFACE_MODE_UNKNOWN,
+ USBPHY_INTERFACE_MODE_UTMI,
+ USBPHY_INTERFACE_MODE_UTMIW,
+ USBPHY_INTERFACE_MODE_ULPI,
+ USBPHY_INTERFACE_MODE_SERIAL,
+ USBPHY_INTERFACE_MODE_HSIC,
+};
+
enum usb_phy_events {
USB_EVENT_NONE, /* no events or cable disconnected */
USB_EVENT_VBUS, /* vbus valid event */
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/6] USB: chipidea: ci13xxx-imx: create dynamic platformdata
From: Sascha Hauer @ 2013-01-31 9:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-1-git-send-email-s.hauer@pengutronix.de>
From: Michael Grzeschik <m.grzeschik@pengutronix.de>
This patch removes the limitation of having only one instance of the
ci13xxx-imx platformdata and makes different configurations possible.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/chipidea/ci13xxx_imx.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c
index 8c29122..69024e0 100644
--- a/drivers/usb/chipidea/ci13xxx_imx.c
+++ b/drivers/usb/chipidea/ci13xxx_imx.c
@@ -85,17 +85,10 @@ EXPORT_SYMBOL_GPL(usbmisc_get_init_data);
/* End of common functions shared by usbmisc drivers*/
-static struct ci13xxx_platform_data ci13xxx_imx_platdata = {
- .name = "ci13xxx_imx",
- .flags = CI13XXX_REQUIRE_TRANSCEIVER |
- CI13XXX_PULLUP_ON_VBUS |
- CI13XXX_DISABLE_STREAMING,
- .capoffset = DEF_CAPOFFSET,
-};
-
static int ci13xxx_imx_probe(struct platform_device *pdev)
{
struct ci13xxx_imx_data *data;
+ struct ci13xxx_platform_data *pdata;
struct platform_device *plat_ci, *phy_pdev;
struct device_node *phy_np;
struct resource *res;
@@ -107,6 +100,18 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
&& !usbmisc_ops)
return -EPROBE_DEFER;
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "Failed to allocate CI13xxx-IMX pdata!\n");
+ return -ENOMEM;
+ }
+
+ pdata->name = "ci13xxx_imx";
+ pdata->capoffset = DEF_CAPOFFSET;
+ pdata->flags = CI13XXX_REQUIRE_TRANSCEIVER |
+ CI13XXX_PULLUP_ON_VBUS |
+ CI13XXX_DISABLE_STREAMING;
+
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data) {
dev_err(&pdev->dev, "Failed to allocate CI13xxx-IMX data!\n");
@@ -168,7 +173,7 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
reg_vbus = NULL;
}
- ci13xxx_imx_platdata.phy = data->phy;
+ pdata->phy = data->phy;
if (!pdev->dev.dma_mask) {
pdev->dev.dma_mask = devm_kzalloc(&pdev->dev,
@@ -193,7 +198,7 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
plat_ci = ci13xxx_add_device(&pdev->dev,
pdev->resource, pdev->num_resources,
- &ci13xxx_imx_platdata);
+ pdata);
if (IS_ERR(plat_ci)) {
ret = PTR_ERR(plat_ci);
dev_err(&pdev->dev,
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/6] USB: chipidea: add PTW and PTS handling
From: Sascha Hauer @ 2013-01-31 9:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-1-git-send-email-s.hauer@pengutronix.de>
From: Michael Grzeschik <m.grzeschik@pengutronix.de>
This patch makes it possible to configure the PTW and PTS bits inside
the portsc register for host and device mode before the driver starts
and the phy can be addressed as hardware implementation is designed.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
.../devicetree/bindings/usb/ci13xxx-imx.txt | 5 +++
drivers/usb/chipidea/bits.h | 14 ++++++-
drivers/usb/chipidea/ci13xxx_imx.c | 3 ++
drivers/usb/chipidea/core.c | 39 ++++++++++++++++++++
include/linux/usb/chipidea.h | 1 +
5 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
index 5778b9c..dd42ccd 100644
--- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
+++ b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
@@ -5,6 +5,11 @@ Required properties:
- reg: Should contain registers location and length
- interrupts: Should contain controller interrupt
+Recommended properies:
+- phy_type: the type of the phy connected to the core. Should be one
+ of "utmi", "utmi_wide", "ulpi", "serial" or "hsic". Without this
+ property the PORTSC register won't be touched
+
Optional properties:
- fsl,usbphy: phandler of usb phy that connects to the only one port
- fsl,usbmisc: phandler of non-core register device, with one argument
diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 050de85..d8ffc2f 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -48,10 +48,22 @@
#define PORTSC_SUSP BIT(7)
#define PORTSC_HSP BIT(9)
#define PORTSC_PTC (0x0FUL << 16)
+/* PTS and PTW for non lpm version only */
+#define PORTSC_PTS(d) ((((d) & 0x3) << 30) | (((d) & 0x4) ? BIT(25) : 0))
+#define PORTSC_PTW BIT(28)
/* DEVLC */
#define DEVLC_PSPD (0x03UL << 25)
-#define DEVLC_PSPD_HS (0x02UL << 25)
+#define DEVLC_PSPD_HS (0x02UL << 25)
+#define DEVLC_PTW BIT(27)
+#define DEVLC_STS BIT(28)
+#define DEVLC_PTS(d) (((d) & 0x7) << 29)
+
+/* Encoding for DEVLC_PTS and PORTSC_PTS */
+#define PTS_UTMI 0
+#define PTS_ULPI 2
+#define PTS_SERIAL 3
+#define PTS_HSIC 4
/* OTGSC */
#define OTGSC_IDPU BIT(5)
diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c
index 69024e0..ebc1148 100644
--- a/drivers/usb/chipidea/ci13xxx_imx.c
+++ b/drivers/usb/chipidea/ci13xxx_imx.c
@@ -21,6 +21,7 @@
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/usb/of.h>
#include "ci.h"
#include "ci13xxx_imx.h"
@@ -112,6 +113,8 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
CI13XXX_PULLUP_ON_VBUS |
CI13XXX_DISABLE_STREAMING;
+ pdata->phy_mode = of_usb_get_phy_mode(pdev->dev.of_node);
+
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data) {
dev_err(&pdev->dev, "Failed to allocate CI13xxx-IMX data!\n");
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 57cae1f..a3ec29d 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -67,6 +67,8 @@
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/usb/chipidea.h>
+#include <linux/usb/of.h>
+#include <linux/phy.h>
#include "ci.h"
#include "udc.h"
@@ -211,6 +213,41 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base)
return 0;
}
+static void hw_phymode_configure(struct ci13xxx *ci)
+{
+ u32 portsc, lpm;
+
+ switch (ci->platdata->phy_mode) {
+ case USBPHY_INTERFACE_MODE_UTMI:
+ portsc = PORTSC_PTS(PTS_UTMI);
+ lpm = DEVLC_PTS(PTS_UTMI);
+ break;
+ case USBPHY_INTERFACE_MODE_UTMIW:
+ portsc = PORTSC_PTS(PTS_UTMI) | PORTSC_PTW;
+ lpm = DEVLC_PTS(PTS_UTMI) | DEVLC_PTW;
+ break;
+ case USBPHY_INTERFACE_MODE_ULPI:
+ portsc = PORTSC_PTS(PTS_ULPI);
+ lpm = DEVLC_PTS(PTS_ULPI);
+ break;
+ case USBPHY_INTERFACE_MODE_SERIAL:
+ portsc = PORTSC_PTS(PTS_SERIAL);
+ lpm = DEVLC_PTS(PTS_SERIAL);
+ break;
+ case USBPHY_INTERFACE_MODE_HSIC:
+ portsc = PORTSC_PTS(PTS_HSIC);
+ lpm = DEVLC_PTS(PTS_HSIC);
+ break;
+ default:
+ return;
+ }
+
+ if (ci->hw_bank.lpm)
+ hw_write(ci, OP_PORTSC, DEVLC_PTS(7) | DEVLC_PTW, lpm);
+ else
+ hw_write(ci, OP_PORTSC, PORTSC_PTS(7) | PORTSC_PTW, portsc);
+}
+
/**
* hw_device_reset: resets chip (execute without interruption)
* @ci: the controller
@@ -476,6 +513,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
: CI_ROLE_GADGET;
}
+ hw_phymode_configure(ci);
+
ret = ci_role_start(ci, ci->role);
if (ret) {
dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 544825d..1a2aa18 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -14,6 +14,7 @@ struct ci13xxx_platform_data {
uintptr_t capoffset;
unsigned power_budget;
struct usb_phy *phy;
+ enum usb_phy_interface phy_mode;
unsigned long flags;
#define CI13XXX_REGS_SHARED BIT(0)
#define CI13XXX_REQUIRE_TRANSCEIVER BIT(1)
--
1.7.10.4
^ permalink raw reply related
* [PATCH 5/6] USB chipidea: introduce dual role mode pdata flags
From: Sascha Hauer @ 2013-01-31 9:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-1-git-send-email-s.hauer@pengutronix.de>
Even if a chipidea core is otg capable the board may not. This allows
to explicitly set the core to host/peripheral mode. Without these
flags the driver falls back to the old behaviour.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/usb/chipidea/core.c | 21 +++++++++++++++------
include/linux/usb/chipidea.h | 2 +-
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index a3ec29d..b2dbf55 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -435,6 +435,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
struct resource *res;
void __iomem *base;
int ret;
+ int dr_mode;
if (!dev->platform_data) {
dev_err(dev, "platform data missing\n");
@@ -487,14 +488,22 @@ static int ci_hdrc_probe(struct platform_device *pdev)
return -ENODEV;
}
+ dr_mode = ci->platdata->dr_mode;
+ if (dr_mode == USB_DR_MODE_UNKNOWN)
+ dr_mode = USB_DR_MODE_OTG;
+
/* initialize role(s) before the interrupt is requested */
- ret = ci_hdrc_host_init(ci);
- if (ret)
- dev_info(dev, "doesn't support host\n");
+ if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
+ ret = ci_hdrc_host_init(ci);
+ if (ret)
+ dev_info(dev, "doesn't support host\n");
+ }
- ret = ci_hdrc_gadget_init(ci);
- if (ret)
- dev_info(dev, "doesn't support gadget\n");
+ if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
+ ret = ci_hdrc_gadget_init(ci);
+ if (ret)
+ dev_info(dev, "doesn't support gadget\n");
+ }
if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
dev_err(dev, "no supported roles\n");
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 1a2aa18..b314647 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -20,7 +20,7 @@ struct ci13xxx_platform_data {
#define CI13XXX_REQUIRE_TRANSCEIVER BIT(1)
#define CI13XXX_PULLUP_ON_VBUS BIT(2)
#define CI13XXX_DISABLE_STREAMING BIT(3)
-
+ enum usb_dr_mode dr_mode;
#define CI13XXX_CONTROLLER_RESET_EVENT 0
#define CI13XXX_CONTROLLER_STOPPED_EVENT 1
void (*notify_event) (struct ci13xxx *ci, unsigned event);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 6/6] USB chipidea i.MX: introduce dr_mode property
From: Sascha Hauer @ 2013-01-31 9:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-1-git-send-email-s.hauer@pengutronix.de>
The dr_mode devicetree property allows to explicitly specify the
host/peripheral/otg mode. This is necessary for boards without proper
ID pin handling.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Documentation/devicetree/bindings/usb/ci13xxx-imx.txt | 1 +
drivers/usb/chipidea/ci13xxx_imx.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
index dd42ccd..493a414 100644
--- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
+++ b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
@@ -9,6 +9,7 @@ Recommended properies:
- phy_type: the type of the phy connected to the core. Should be one
of "utmi", "utmi_wide", "ulpi", "serial" or "hsic". Without this
property the PORTSC register won't be touched
+- dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg"
Optional properties:
- fsl,usbphy: phandler of usb phy that connects to the only one port
diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c
index ebc1148..b598bb8f 100644
--- a/drivers/usb/chipidea/ci13xxx_imx.c
+++ b/drivers/usb/chipidea/ci13xxx_imx.c
@@ -114,6 +114,7 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
CI13XXX_DISABLE_STREAMING;
pdata->phy_mode = of_usb_get_phy_mode(pdev->dev.of_node);
+ pdata->dr_mode = of_usb_get_dr_mode(pdev->dev.of_node);
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data) {
--
1.7.10.4
^ permalink raw reply related
* [PATCH 5/5] ARM: OMAP3: Update clocksource timer selection
From: Igor Grinberg @ 2013-01-31 9:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359565471-30721-6-git-send-email-jon-hunter@ti.com>
On 01/30/13 19:04, Jon Hunter wrote:
> When booting with device-tree for OMAP3 and AM335x devices and a gptimer
> is used as the clocksource (which is always the case for AM335x), a
> gptimer located in a power domain that is not always-on is selected.
> Ideally we should use a gptimer located in a power domain that is always
> on (such as the wake-up domain) so that time can be maintained during a
> kernel suspend without keeping on additional power domains unnecessarily.
>
> In order to fix this so that we can select a gptimer located in a power
> domain that is always-on, the following changes were made ...
> 1. Currently, only when selecting a gptimer to use for a clockevent
> timer, do we pass a timer property that can be used to select a
> specific gptimer. Change this so that we can pass a property when
> selecting a gptimer to use for a clocksource timer too.
> 2. Currently, when selecting either a gptimer to use for a clockevent
> timer or a clocksource timer and no timer property is passed, then
> the first available timer is selected regardless of the properties
> it has. Change this so that if no properties are passed, then a timer
> that does not have additional features (such as always-on, dsp-irq,
> pwm, and secure) is selected.
>
> Please note that using a gptimer for both clocksource and clockevents
> can have a system power impact during idle. The reason being is that
> OMAP and AMxxx devices typically only have one gptimer in a power domain
> that is always-on. Therefore when the kernel is idle both the clocksource
> and clockevent timers will be active and this will keep additional power
> domains on. During kernel suspend, only the clocksource timer is active
> and therefore, it is better to use a gptimer in a power domain that is
> always-on for clocksource.
This should explain the gptimer number switch in the
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
section below, right?
I would really like to see that clearly stated in the commit message.
For instance:
... it is better to use a gptimer in a power domain that is
always-on for clocksource. Therefore we switch to use the first gptimer
for clocksource and the second for clockevents.
>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Apart from above,
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
> ---
> arch/arm/mach-omap2/timer.c | 32 +++++++++++++++++++++-----------
> 1 file changed, 21 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index af20be7..acf9f82 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
[...]
> @@ -557,19 +567,19 @@ void __init omap##name##_sync32k_timer_init(void) \
> #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP4) || \
> defined(CONFIG_SOC_OMAP5)
> OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon",
> - 2, "timer_sys_ck");
> + 2, "timer_sys_ck", NULL);
> #endif
>
> #ifdef CONFIG_ARCH_OMAP3
> OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon",
> - 2, "timer_sys_ck");
> + 2, "timer_sys_ck", NULL);
> OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure",
> - 2, "timer_sys_ck");
> + 2, "timer_sys_ck", NULL);
> #endif /* CONFIG_ARCH_OMAP3 */
>
> #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
> -OMAP_SYS_GP_TIMER_INIT(3, 1, "timer_sys_ck", "ti,timer-alwon",
> - 2, "timer_sys_ck");
> +OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL,
> + 1, "timer_sys_ck", "ti,timer-alwon");
> #endif
>
> #ifdef CONFIG_ARCH_OMAP4
>
--
Regards,
Igor.
^ permalink raw reply
* [PATCH 4/5] ARM: OMAP2+: Simplify system timers definitions
From: Igor Grinberg @ 2013-01-31 9:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359565471-30721-5-git-send-email-jon-hunter@ti.com>
On 01/30/13 19:04, Jon Hunter wrote:
> There is a lot of redundancy in the definitions for the various system
> timers for OMAP2+ devices. For example, the omap3_am33xx_gptimer_timer_init()
> function is the same as the omap3_gp_gptimer_timer_init() function and the
> function omap2_sync32k_timer_init() can be re-used for OMAP4/5 devices.
> Therefore, consolidate the definitions to simplify the code.
>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
--
Regards,
Igor.
^ permalink raw reply
* [PATCH 2/6] USB: add devicetree helpers for determining dr_mode and phy_type
From: kishon @ 2013-01-31 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-3-git-send-email-s.hauer@pengutronix.de>
Hi,
On Thursday 31 January 2013 02:31 PM, Sascha Hauer wrote:
> From: Michael Grzeschik <m.grzeschik@pengutronix.de>
>
> This adds two little devicetree helper functions for determining the
> dr_mode (host, peripheral, otg) and phy_type (utmi, ulpi,...) from
> the devicetree.
>
> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/usb/phy/Makefile | 1 +
> drivers/usb/phy/phy.c | 10 ++++++++++
> drivers/usb/usb-common.c | 36 ++++++++++++++++++++++++++++++++++++
> include/linux/usb/of.h | 27 +++++++++++++++++++++++++++
> include/linux/usb/otg.h | 7 +++++++
> include/linux/usb/phy.h | 9 +++++++++
> 6 files changed, 90 insertions(+)
> create mode 100644 include/linux/usb/of.h
>
> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
> index 9fa6327..e1be1e8 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -5,6 +5,7 @@
> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>
> obj-$(CONFIG_USB_OTG_UTILS) += phy.o
> +obj-$(CONFIG_OF) += of.o
You've missed doing "git add ..usb/phy/of.c".
> obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
> obj-$(CONFIG_OMAP_USB3) += omap-usb3.o
> obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o
> diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
> index ef35eb0..3ad4b5c 100644
> --- a/drivers/usb/phy/phy.c
> +++ b/drivers/usb/phy/phy.c
> @@ -1,3 +1,13 @@
> +/*
> + * phy.c -- USB phy handling
> + *
> + * Copyright (C) 2004 Texas Instruments
it's 2013 already :-P
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
But your *MODULE_LICENSE("GPL")* below tells it's only GPL.
> + */
.
.
<snip>
.
.
> MODULE_LICENSE("GPL");
Thanks
Kishon
^ permalink raw reply
* [PATCH 4/6] usb: chipidea: add PTW and PTS handling
From: Matthieu CASTET @ 2013-01-31 9:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130130193327.GA1906@pengutronix.de>
Sascha Hauer a ?crit :
> On Wed, Jan 30, 2013 at 05:54:54PM +0100, Matthieu CASTET wrote:
>>> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
>>> index 57cae1f..dcb650f 100644
>>> --- a/drivers/usb/chipidea/core.c
>>> +++ b/drivers/usb/chipidea/core.c
>>> @@ -67,6 +67,8 @@
>>> #include <linux/usb/gadget.h>
>>> #include <linux/usb/otg.h>
>>> #include <linux/usb/chipidea.h>
>>> +#include <linux/usb/of.h>
>>> +#include <linux/phy.h>
>>>
>>> #include "ci.h"
>>> #include "udc.h"
>>> @@ -211,6 +213,42 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base)
>>> return 0;
>>> }
>>>
>>> +static void hw_phymode_configure(struct ci13xxx *ci)
>>> +{
>>> + u32 portsc;
>>> +
>>> + /*
>>> + * The lpm version has the corresponding bits in the devlc register.
>>> + * Currently not implemented.
>>> + */
>>> + if (ci->hw_bank.lpm)
>>> + return;
>> Why you don't implement it ?
>>
>> If you don't implement it, I believe you should add a warning in order to catch
>> it when used with lpm devices.
>
> I'm against adding a warning because current users seem to go well
> without this setting. Adding a warning would lead to more confusion than
> it would help.
>
> I could try and implement it, though I'm unsure about the register
> layout.
>
> What I know from an earlier post from you is this:
>
> #define LPM_PTS(d) (((d)>>29)&7)
> #define LPM_STS BIT(28) /* serial transceiver select */
> #define LPM_PTW BIT(27) /* parallel transceiver width */
>
> Do you also know how LPM_PTS is decoded?
I will say the same as not lpm device :
PTS is made up from PORTSCx bits 25, 30 and 31.
PTS is made up from devlc bits 31, 30 and 29.
Also in my datasheet, they give a way to check if the bits are read only or read
write [1]. I don't know if it is worth the trouble to check it.
Matthieu
[1]
PTS
This register bit pair is used in conjunction with the configuration constant
VUSB_HS_PHY_TYPE to control which parallel transceiver interface is selected. If
VUSB_HS_PHY_TYPE is set for 0, 1, 2, 3, 8 or 10 then this bit is read only. If
VUSB_HS_PHY_TYPE is 4, 5, 6, 7, 9 or 11 then this bit is read/write.
This field is reset to:
'000b' if VUSB_HS_PHY_TYPE = 0, 4 ? UTMI/UTMI+
'001b' if VUSB_HS_PHY_TYPE = 1, 5 ? ULPI DDR
'010b' if VUSB_HS_PHY_TYPE = 2, 6 ? ULPI
'011b' if VUSB_HS_PHY_TYPE = 3, 7, 8, 9 ? Serial/1.1 PHY/IC_USB (FS Only)
'100b' if VUSB_HS_PHY_TYPE = 10, 11 ? UTMI for HSIC PHY
^ permalink raw reply
* [PATCH 1/6] USB: move bulk of otg/otg.c to phy/phy.c
From: kishon @ 2013-01-31 9:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-2-git-send-email-s.hauer@pengutronix.de>
Hi,
On Thursday 31 January 2013 02:31 PM, Sascha Hauer wrote:
> Most of otg/otg.c is not otg specific, but phy specific, so move it
> to the phy directory.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Reported-by: kishon <kishon@ti.com>
Kishon Vijay Abraham I <kishon@ti.com> pls..
Thanks
Kishon
^ permalink raw reply
* Failure to boot...
From: Russell King - ARM Linux @ 2013-01-31 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301302312030.6300@xanadu.home>
On Wed, Jan 30, 2013 at 11:19:40PM -0500, Nicolas Pitre wrote:
> Better yet (IMHO): just enable the zboot command in U-Boot to let you
> boot a zImage binary directly.
I wish it were that easy but it isn't. I've no idea where to get a
version of uboot for my boards which supports that; TI have always
supplied updates to uboot for me, and with the current state of TI
being afaict in chaos.
TI have always supplied a replacement X-Loader with each uboot update.
I've no idea what X-Loader is or why both get updated together, but...
Moreover, I doubt that the 3430LDP, of which there are multiple versions,
will ever see a uboot update. It already suffers from a lack of correct
kernel support due to random wiring changes between these versions (the
keypad doesn't work correctly) and I've yet to indentify which version
it is despite downloading the circuits. So trying to locate the right
uboot will be impossible there.
So, I'm _stuck_ with uImages for these platforms.
^ permalink raw reply
* [PATCH] arm: mvebu: support for the new Armada XP evaluation board(DB-MV784MP-GP)
From: Simon Guinot @ 2013-01-31 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359566774-27669-2-git-send-email-gregory.clement@free-electrons.com>
On Wed, Jan 30, 2013 at 06:26:14PM +0100, Gregory CLEMENT wrote:
> This is the new Armada XP evaluation board from Marvell. It comes with
> a RS232 port over USB, a SATA link, an internal SSD, 4 Ethernet
> Gigabit links.
>
> Support for USB (Host and device), SDIO, PCIe will be added as drivers
> when they become available for Armada XP in mainline.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/armada-xp-gp.dts | 94 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 95 insertions(+)
> create mode 100644 arch/arm/boot/dts/armada-xp-gp.dts
It works fine for me. Thank you for the patch.
Tested-by: Simon Guinot <simon.guinot@sequanux.org>
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 5ebb44f..51aab4b 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -78,6 +78,7 @@ dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \
> dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
> armada-370-mirabox.dtb \
> armada-xp-db.dtb \
> + armada-xp-gp.dtb \
> armada-xp-openblocks-ax3-4.dtb
> dtb-$(CONFIG_ARCH_MXC) += imx51-babbage.dtb \
> imx53-ard.dtb \
> diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
> new file mode 100644
> index 0000000..85ba642
> --- /dev/null
> +++ b/arch/arm/boot/dts/armada-xp-gp.dts
> @@ -0,0 +1,94 @@
> +/*
> + * Device Tree file for Marvell Armada XP evaluation board
> + * (RD-MV784MP-GP)
> + *
> + * Copyright (C) 2013 Marvell
> + *
> + * Lior Amsalem <alior@marvell.com>
> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +/include/ "armada-xp-mv78460.dtsi"
> +
> +/ {
> + model = "Marvell Armada XP Evaluation Board: RD-MV784MP-GP";
> + compatible = "marvell,axp-db", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
> +
> + chosen {
> + bootargs = "console=ttyS0,115200 earlyprintk";
> + };
> +
> + memory {
> + device_type = "memory";
> + reg = <0x00000000 0xC0000000>; /* 3 GB */
> + };
> +
> + soc {
> + serial at d0012000 {
> + clock-frequency = <250000000>;
> + status = "okay";
> + };
> + serial at d0012100 {
> + clock-frequency = <250000000>;
> + status = "okay";
> + };
> + serial at d0012200 {
> + clock-frequency = <250000000>;
> + status = "okay";
> + };
> + serial at d0012300 {
> + clock-frequency = <250000000>;
> + status = "okay";
> + };
> +
> + sata at d00a0000 {
> + nr-ports = <2>;
> + status = "okay";
> + };
> +
> + mdio {
> + phy0: ethernet-phy at 0 {
> + reg = <16>;
> + };
> +
> + phy1: ethernet-phy at 1 {
> + reg = <17>;
> + };
> +
> + phy2: ethernet-phy at 2 {
> + reg = <18>;
> + };
> +
> + phy3: ethernet-phy at 3 {
> + reg = <19>;
> + };
> + };
> +
> + ethernet at d0070000 {
> + status = "okay";
> + phy = <&phy0>;
> + phy-mode = "rgmii-id";
> + };
> + ethernet at d0074000 {
> + status = "okay";
> + phy = <&phy1>;
> + phy-mode = "rgmii-id";
> + };
> + ethernet at d0030000 {
> + status = "okay";
> + phy = <&phy2>;
> + phy-mode = "rgmii-id";
> + };
> + ethernet at d0034000 {
> + status = "okay";
> + phy = <&phy3>;
> + phy-mode = "rgmii-id";
> + };
> + };
> +};
> --
> 1.7.9.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130131/3ecbb08e/attachment.sig>
^ permalink raw reply
* [PATCH 2/6] USB: add devicetree helpers for determining dr_mode and phy_type
From: Greg KH @ 2013-01-31 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359622873-23345-3-git-send-email-s.hauer@pengutronix.de>
On Thu, Jan 31, 2013 at 10:01:09AM +0100, Sascha Hauer wrote:
> From: Michael Grzeschik <m.grzeschik@pengutronix.de>
>
> This adds two little devicetree helper functions for determining the
> dr_mode (host, peripheral, otg) and phy_type (utmi, ulpi,...) from
> the devicetree.
>
> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/usb/phy/Makefile | 1 +
> drivers/usb/phy/phy.c | 10 ++++++++++
> drivers/usb/usb-common.c | 36 ++++++++++++++++++++++++++++++++++++
> include/linux/usb/of.h | 27 +++++++++++++++++++++++++++
> include/linux/usb/otg.h | 7 +++++++
> include/linux/usb/phy.h | 9 +++++++++
> 6 files changed, 90 insertions(+)
> create mode 100644 include/linux/usb/of.h
>
> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
> index 9fa6327..e1be1e8 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -5,6 +5,7 @@
> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>
> obj-$(CONFIG_USB_OTG_UTILS) += phy.o
> +obj-$(CONFIG_OF) += of.o
> obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
> obj-$(CONFIG_OMAP_USB3) += omap-usb3.o
> obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o
> diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
> index ef35eb0..3ad4b5c 100644
> --- a/drivers/usb/phy/phy.c
> +++ b/drivers/usb/phy/phy.c
> @@ -1,3 +1,13 @@
> +/*
> + * phy.c -- USB phy handling
> + *
> + * Copyright (C) 2004 Texas Instruments
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
Do you really mean to change the license of the file from GPLv2 to
GPLv2+? Did TI agree to that licening change? I need some
documentation from some TI people before I can ever accept something
like this.
thanks,
greg k-h
^ permalink raw reply
* [PATCH RFC] davinci: poll for sleep completion in resume routine.
From: Vishwanathrao Badarkhe, Manish @ 2013-01-31 9:23 UTC (permalink / raw)
To: linux-arm-kernel
As per OMAP-L138 TRM, Software must poll for
SLEEPCOMPLETE bit until it is set to 1 before clearing
SLEEPENABLE bit in DEEPSLEEP register in resume routine.
Modifications are as per datasheet:
http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf
See sections 10.10.2.2 and 11.5.21 for more detailed
explanation.
Tested on da850-evm.
Signed-off-by: Vishwanathrao Badarkhe, Manish <manishv.b@ti.com>
---
:100644 100644 d4e9316... 976f096... M arch/arm/mach-davinci/sleep.S
arch/arm/mach-davinci/sleep.S | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S
index d4e9316..976f096 100644
--- a/arch/arm/mach-davinci/sleep.S
+++ b/arch/arm/mach-davinci/sleep.S
@@ -35,6 +35,7 @@
#define PLL_LOCK_CYCLES (PLL_LOCK_TIME * 25)
#define DEEPSLEEP_SLEEPENABLE_BIT BIT(31)
+#define DEEPSLEEP_SLEEPCOMPLETE_BIT BIT(30)
.text
/*
@@ -110,6 +111,13 @@ ENTRY(davinci_cpu_suspend)
/* Wake up from sleep */
+ /* wait for sleep complete */
+sleep_complete:
+ ldr ip, [r4]
+ and ip, ip, #DEEPSLEEP_SLEEPCOMPLETE_BIT
+ cmp ip, #DEEPSLEEP_SLEEPCOMPLETE_BIT
+ bne sleep_complete
+
/* Clear sleep enable */
ldr ip, [r4]
bic ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
--
1.7.4.1
^ permalink raw reply related
* [PATCH RFC] davinci: poll for sleep completion in resume routine.
From: Vishwanathrao Badarkhe, Manish @ 2013-01-31 9:26 UTC (permalink / raw)
To: linux-arm-kernel
As per OMAP-L138 TRM, Software must poll for
SLEEPCOMPLETE bit until it is set to 1 before clearing
SLEEPENABLE bit in DEEPSLEEP register in resume routine.
Modifications are as per datasheet:
http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf
See sections 10.10.2.2 and 11.5.21 for more detailed
explanation.
Tested on da850-evm.
Signed-off-by: Vishwanathrao Badarkhe, Manish <manishv.b@ti.com>
---
:100644 100644 d4e9316... 976f096... M arch/arm/mach-davinci/sleep.S
arch/arm/mach-davinci/sleep.S | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S
index d4e9316..976f096 100644
--- a/arch/arm/mach-davinci/sleep.S
+++ b/arch/arm/mach-davinci/sleep.S
@@ -35,6 +35,7 @@
#define PLL_LOCK_CYCLES (PLL_LOCK_TIME * 25)
#define DEEPSLEEP_SLEEPENABLE_BIT BIT(31)
+#define DEEPSLEEP_SLEEPCOMPLETE_BIT BIT(30)
.text
/*
@@ -110,6 +111,13 @@ ENTRY(davinci_cpu_suspend)
/* Wake up from sleep */
+ /* wait for sleep complete */
+sleep_complete:
+ ldr ip, [r4]
+ and ip, ip, #DEEPSLEEP_SLEEPCOMPLETE_BIT
+ cmp ip, #DEEPSLEEP_SLEEPCOMPLETE_BIT
+ bne sleep_complete
+
/* Clear sleep enable */
ldr ip, [r4]
bic ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
--
1.7.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox