Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v3] phy: Add new Exynos5 USB 3.0 PHY driver
From: Vivek Gautam @ 2014-01-30  4:19 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Vivek Gautam, Linux USB Mailing List,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Greg KH, Kukjin Kim,
	Felipe Balbi, Tomasz Figa, Kamil Debski, Sylwester Nawrocki,
	Julius Werner, Jingoo Han
In-Reply-To: <52E61F63.1090200-l0cyMroinI0@public.gmane.org>

Hi Kishon,


On Mon, Jan 27, 2014 at 2:27 PM, Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org> wrote:
> Hi,

Thanks for review. Please find my answers inline below.

>
> On Monday 20 January 2014 07:12 PM, Vivek Gautam wrote:
>> Add a new driver for the USB 3.0 PHY on Exynos5 series of SoCs.
>> The new driver uses the generic PHY framework and will interact
>> with DWC3 controller present on Exynos5 series of SoCs.
>> Thereby, removing old phy-samsung-usb3 driver and related code
>> used untill now which was based on usb/phy framework.
>>
>> Signed-off-by: Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>> ---
>>
>> Changes from v2:
>> 1) Added support for multiple PHYs (UTMI+ and PIPE3) and
>>    related changes in the driver structuring.
>> 2) Added a xlate function to get the required phy out of
>>    number of PHYs in mutiple PHY scenerio.
>> 3) Changed the names of few structures and variables to
>>    have a clearer meaning.
>> 4) Added 'usb3phy_config' structure to take care of mutiple
>>    phys for a SoC having 'exynos5_usb3phy_drv_data' driver data.
>> 5) Not deleting support for old driver 'phy-samsung-usb3' until
>>    required support for generic phy is added to DWC3.
>>
>>  .../devicetree/bindings/phy/samsung-phy.txt        |   49 ++
>>  drivers/phy/Kconfig                                |    8 +
>>  drivers/phy/Makefile                               |    1 +
>>  drivers/phy/phy-exynos5-usb3.c                     |  621 ++++++++++++++++++++
>>  4 files changed, 679 insertions(+)
>>  create mode 100644 drivers/phy/phy-exynos5-usb3.c
[snip]

>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index 330ef2d..32f9f38 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -51,4 +51,12 @@ config PHY_EXYNOS_DP_VIDEO
>>       help
>>         Support for Display Port PHY found on Samsung EXYNOS SoCs.
>>
>> +config PHY_EXYNOS5_USB3
>> +     tristate "Exynos5 SoC series USB 3.0 PHY driver"
>> +     depends on ARCH_EXYNOS5
>> +     select GENERIC_PHY
>> +     select MFD_SYSCON
>
> add depends on 'HAS_IOMEM'. Someone reported getting
> undefined reference to `devm_ioremap_resource' with it.

Ok will add it.

>> +     help
>> +       Enable USB 3.0 PHY support for Exynos 5 SoC series
>> +
>>  endmenu
[snip]

>> diff --git a/drivers/phy/phy-exynos5-usb3.c b/drivers/phy/phy-exynos5-usb3.c
>> new file mode 100644
>> index 0000000..24efed0
>> --- /dev/null
>> +++ b/drivers/phy/phy-exynos5-usb3.c
>> @@ -0,0 +1,621 @@
>> +/*
>> + * Samsung EXYNOS5 SoC series USB 3.0 PHY driver
>> + *
>> + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
>> + * Author: Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/mutex.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/regmap.h>
>> +
>> +/* Exynos USB PHY registers */
>> +#define EXYNOS5_FSEL_9MHZ6           0x0
>> +#define EXYNOS5_FSEL_10MHZ           0x1
>> +#define EXYNOS5_FSEL_12MHZ           0x2
>> +#define EXYNOS5_FSEL_19MHZ2          0x3
>> +#define EXYNOS5_FSEL_20MHZ           0x4
>> +#define EXYNOS5_FSEL_24MHZ           0x5
>> +#define EXYNOS5_FSEL_50MHZ           0x7
>> +
>> +/* EXYNOS5: USB 3.0 DRD PHY registers */
>> +#define EXYNOS5_DRD_LINKSYSTEM                       (0x04)
>> +
>> +#define LINKSYSTEM_FLADJ_MASK                        (0x3f << 1)
>> +#define LINKSYSTEM_FLADJ(_x)                 ((_x) << 1)
>> +#define LINKSYSTEM_XHCI_VERSION_CONTROL              (0x1 << 27)
>> +
>> +#define EXYNOS5_DRD_PHYUTMI                  (0x08)
>> +
>> +#define PHYUTMI_OTGDISABLE                   (0x1 << 6)
>> +#define PHYUTMI_FORCESUSPEND                 (0x1 << 1)
>> +#define PHYUTMI_FORCESLEEP                   (0x1 << 0)
>
> use BIT macro here and below?

Ok.

>> +
>> +#define EXYNOS5_DRD_PHYPIPE                  (0x0c)
>> +
>> +#define EXYNOS5_DRD_PHYCLKRST                        (0x10)
>> +
>> +#define PHYCLKRST_EN_UTMISUSPEND             (0x1 << 31)
>> +
>> +#define PHYCLKRST_SSC_REFCLKSEL_MASK         (0xff << 23)
>> +#define PHYCLKRST_SSC_REFCLKSEL(_x)          ((_x) << 23)
>> +
>> +#define PHYCLKRST_SSC_RANGE_MASK             (0x03 << 21)
>> +#define PHYCLKRST_SSC_RANGE(_x)                      ((_x) << 21)
>> +
>> +#define PHYCLKRST_SSC_EN                     (0x1 << 20)
>> +#define PHYCLKRST_REF_SSP_EN                 (0x1 << 19)
>> +#define PHYCLKRST_REF_CLKDIV2                        (0x1 << 18)
>> +
>> +#define PHYCLKRST_MPLL_MULTIPLIER_MASK               (0x7f << 11)
>> +#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF (0x19 << 11)
>> +#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF    (0x32 << 11)
>> +#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF  (0x68 << 11)
>> +#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF  (0x7d << 11)
>> +#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF       (0x02 << 11)
>> +
>> +#define PHYCLKRST_FSEL_MASK                  (0x3f << 5)
>> +#define PHYCLKRST_FSEL(_x)                   ((_x) << 5)
>> +#define PHYCLKRST_FSEL_PAD_100MHZ            (0x27 << 5)
>> +#define PHYCLKRST_FSEL_PAD_24MHZ             (0x2a << 5)
>> +#define PHYCLKRST_FSEL_PAD_20MHZ             (0x31 << 5)
>> +#define PHYCLKRST_FSEL_PAD_19_2MHZ           (0x38 << 5)
>> +
>> +#define PHYCLKRST_RETENABLEN                 (0x1 << 4)
>> +
>> +#define PHYCLKRST_REFCLKSEL_MASK             (0x03 << 2)
>> +#define PHYCLKRST_REFCLKSEL_PAD_REFCLK               (0x2 << 2)
>> +#define PHYCLKRST_REFCLKSEL_EXT_REFCLK               (0x3 << 2)
>> +
>> +#define PHYCLKRST_PORTRESET                  (0x1 << 1)
>> +#define PHYCLKRST_COMMONONN                  (0x1 << 0)
>> +
>> +#define EXYNOS5_DRD_PHYREG0                  (0x14)
>> +#define EXYNOS5_DRD_PHYREG1                  (0x18)
>> +
>> +#define EXYNOS5_DRD_PHYPARAM0                        (0x1c)
>> +
>> +#define PHYPARAM0_REF_USE_PAD                        (0x1 << 31)
>> +#define PHYPARAM0_REF_LOSLEVEL_MASK          (0x1f << 26)
>> +#define PHYPARAM0_REF_LOSLEVEL                       (0x9 << 26)
>> +
>> +#define EXYNOS5_DRD_PHYPARAM1                        (0x20)
>> +
>> +#define PHYPARAM1_PCS_TXDEEMPH_MASK          (0x1f << 0)
>> +#define PHYPARAM1_PCS_TXDEEMPH                       (0x1c)
>> +
>> +#define EXYNOS5_DRD_PHYTERM                  (0x24)
>> +
>> +#define EXYNOS5_DRD_PHYTEST                  (0x28)
>> +
>> +#define PHYTEST_POWERDOWN_SSP                        (0x1 << 3)
>> +#define PHYTEST_POWERDOWN_HSP                        (0x1 << 2)
>> +
>> +#define EXYNOS5_DRD_PHYADP                   (0x2c)
>> +
>> +#define EXYNOS5_DRD_PHYBATCHG                        (0x30)
>> +
>> +#define PHYBATCHG_UTMI_CLKSEL                        (0x1 << 2)
>> +
>> +#define EXYNOS5_DRD_PHYRESUME                        (0x34)
>> +#define EXYNOS5_DRD_LINKPORT                 (0x44)
>> +
>> +/* Power isolation defined in power management unit */
>> +#define EXYNOS5_USB3DRD_PHY_PMU_REG_OFFSET   (0x704)
>> +#define EXYNOS5_USB3DRD_PMU_ISOL             (1 << 0)
>> +
>> +#define KHZ  1000
>> +#define MHZ  (KHZ * KHZ)
>> +
>> +enum exynos5_usb3phy_id {
>> +     EXYNOS5_USB3PHY_UTMI,
>> +     EXYNOS5_USB3PHY_PIPE3,
>> +     EXYNOS5_USB3PHYS_NUM,
>> +};
>> +
>> +struct usb3phy_config {
>> +     u32 id;
>> +     u32 reg_pmu_offset;
>> +     void (*phy_isol)(struct phy *phy, u32 on);
>> +};
>> +
>> +struct exynos5_usb3phy_drv_data {
>> +     bool has_usb30_sclk;
>> +     bool has_multi_controller;
>> +     const struct usb3phy_config *phy_cfg;
>> +};
>> +
>> +/**
>> + * struct exynos5_usb3phy_driver - driver data for USB 3.0 PHY
>
> Is this really a driver data? I think it should be just exynos5_usb3phy.
Yes, not a driver data, rather just 'exynos_usb3phy' structure. will
modify the name

>> + * @dev: pointer to device instance of this platform device
>> + * @reg_phy: usb phy controller register memory base
>> + * @clk: phy clock for register access
>> + * @usb30_sclk: additional special clock for phy operations
>> + * @drv_data: pointer to SoC level driver data structure
>> + * @phys[]: array for 'EXYNOS5_USB3PHYS_NUM' number of PHY
>> + *       instances each with its 'phy' and 'phy_cfg'.
>> + * @extrefclk: frequency select settings when using 'separate
>> + *          reference clocks' for SS and HS operations
>> + * @rate: rate of reference clock to PHY block
>> + * @channel: number of PHY channels present in SoC
>> + */
>> +struct exynos5_usb3phy_driver {
>> +     struct device *dev;
>> +     void __iomem *reg_phy;
>> +     struct clk *clk;
>> +     struct clk *usb30_sclk;
>> +     const struct exynos5_usb3phy_drv_data *drv_data;
>> +     struct phy_usb_instance {
>> +             struct phy *phy;
>> +             u32 index;
>> +             struct regmap *reg_isol;
>> +             const struct usb3phy_config *phy_cfg;
>> +     } phys[EXYNOS5_USB3PHYS_NUM];
>> +     u32 extrefclk;
>> +     unsigned long rate;
>> +     u32 channel;
>> +};
>> +
>> +#define to_usb3phy_driver(inst) \
>> +     container_of((inst), struct exynos5_usb3phy_driver, \
>> +                  phys[(inst)->index]);
>> +
>> +/*
>> + * exynos5_rate_to_clk() converts the supplied clock rate to the value that
>> + * can be written to the phy register.
>> + */
>> +static u32 exynos5_rate_to_clk(unsigned long rate)
>> +{
>> +     unsigned int clksel;
>> +
>> +     /* EXYNOS5_FSEL_MASK */
>> +
>> +     switch (rate) {
>> +     case 9600 * KHZ:
>> +             clksel = EXYNOS5_FSEL_9MHZ6;
>> +             break;
>> +     case 10 * MHZ:
>> +             clksel = EXYNOS5_FSEL_10MHZ;
>> +             break;
>> +     case 12 * MHZ:
>> +             clksel = EXYNOS5_FSEL_12MHZ;
>> +             break;
>> +     case 19200 * KHZ:
>> +             clksel = EXYNOS5_FSEL_19MHZ2;
>> +             break;
>> +     case 20 * MHZ:
>> +             clksel = EXYNOS5_FSEL_20MHZ;
>> +             break;
>> +     case 24 * MHZ:
>> +             clksel = EXYNOS5_FSEL_24MHZ;
>> +             break;
>> +     case 50 * MHZ:
>> +             clksel = EXYNOS5_FSEL_50MHZ;
>> +             break;
>> +     default:
>> +             clksel = -EINVAL;
>> +     }
>> +
>> +     return clksel;
>> +}
>> +
>> +static void exynos5_usb3phy_isol(struct phy *phy, unsigned int on)
>> +{
>> +     u32 pmu_offset;
>> +     struct phy_usb_instance *inst = phy_get_drvdata(phy);
>> +     struct exynos5_usb3phy_driver *drv = to_usb3phy_driver(inst);
>> +
>> +     pmu_offset = inst->phy_cfg->reg_pmu_offset;
>> +     if (!inst->reg_isol)
>> +             return;
>> +
>> +     switch (drv->channel) {
>> +     case 1:
>> +             /* Channel 1 is at 0x708 offset */
>> +             pmu_offset += sizeof(&pmu_offset);
>> +             break;
>> +     case 0:
>> +     default:
>> +             /* Channel 0 is at 0x704 offset */
>> +             break;
>> +     }
>
> This can be in a simple 'if' stmt no?
What if there are systems with more channels? In that case also we
will have to fall back to a switch-case statement ?

>> +
>> +     regmap_update_bits(inst->reg_isol, pmu_offset,
>> +                        EXYNOS5_USB3DRD_PMU_ISOL, ~on);
>> +}
>> +
>> +/*
>> + * Sets the phy clk as EXTREFCLK (XXTI) which is internal clock from clock core.
>> + */
>> +static u32 exynos5_usb3phy_set_refclk(struct exynos5_usb3phy_driver *drv)
>> +{
>> +     u32 reg;
>> +
>> +     reg = PHYCLKRST_REFCLKSEL_EXT_REFCLK |
>> +           PHYCLKRST_FSEL(drv->extrefclk);
>> +
>> +     switch (drv->extrefclk) {
>> +     case EXYNOS5_FSEL_50MHZ:
>> +             reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF |
>> +                     PHYCLKRST_SSC_REFCLKSEL(0x00));
>> +             break;
>> +     case EXYNOS5_FSEL_24MHZ:
>> +             reg |= (PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF |
>> +                     PHYCLKRST_SSC_REFCLKSEL(0x88));
>> +             break;
>> +     case EXYNOS5_FSEL_20MHZ:
>> +             reg |= (PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF |
>> +                     PHYCLKRST_SSC_REFCLKSEL(0x00));
>> +             break;
>> +     case EXYNOS5_FSEL_19MHZ2:
>> +             reg |= (PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF |
>> +                     PHYCLKRST_SSC_REFCLKSEL(0x88));
>> +             break;
>> +     default:
>> +             dev_dbg(drv->dev, "unsupported ref clk\n");
>> +             break;
>> +     }
>> +
>> +     return reg;
>> +}
>> +
>> +static int exynos5_usb3phy_init(struct phy *phy)
>> +{
>> +     int ret;
>> +     u32 phyparam0;
>> +     u32 phyparam1;
>> +     u32 linksystem;
>> +     u32 phybatchg;
>> +     u32 phytest;
>> +     u32 phyclkrst;
>
> instead you can define a single variable 'u32 reg' for register read and writes.

Right.

>> +     struct phy_usb_instance *inst = phy_get_drvdata(phy);
>> +     struct exynos5_usb3phy_driver *drv = to_usb3phy_driver(inst);
>> +
>> +     ret = clk_prepare_enable(drv->clk);
>> +     if (ret)
>> +             return ret;
>> +
>> +     drv->extrefclk = exynos5_rate_to_clk(drv->rate);
>> +     if (drv->extrefclk == -EINVAL) {
>> +             dev_err(drv->dev, "Clock rate (%ld) not supported\n",
>> +                                             drv->rate);
>> +             return -EINVAL;
>> +     }
>> +
>> +     /* Reset USB 3.0 PHY */
>> +     writel(0x0, drv->reg_phy + EXYNOS5_DRD_PHYREG0);
>> +
>> +     phyparam0 = readl(drv->reg_phy + EXYNOS5_DRD_PHYPARAM0);
>> +     /* Select PHY CLK source */
>> +     phyparam0 &= ~PHYPARAM0_REF_USE_PAD;
>> +     /* Set Loss-of-Signal Detector sensitivity */
>> +     phyparam0 &= ~PHYPARAM0_REF_LOSLEVEL_MASK;
>> +     phyparam0 |= PHYPARAM0_REF_LOSLEVEL;
>> +     writel(phyparam0, drv->reg_phy + EXYNOS5_DRD_PHYPARAM0);
>> +
>> +     writel(0x0, drv->reg_phy + EXYNOS5_DRD_PHYRESUME);
>> +
>> +     /*
>> +      * Setting the Frame length Adj value[6:1] to default 0x20
>> +      * See xHCI 1.0 spec, 5.2.4
>> +      */
>> +     linksystem = LINKSYSTEM_XHCI_VERSION_CONTROL |
>> +                  LINKSYSTEM_FLADJ(0x20);
>> +     writel(linksystem, drv->reg_phy + EXYNOS5_DRD_LINKSYSTEM);
>> +
>> +     phyparam1 = readl(drv->reg_phy + EXYNOS5_DRD_PHYPARAM1);
>> +     /* Set Tx De-Emphasis level */
>> +     phyparam1 &= ~PHYPARAM1_PCS_TXDEEMPH_MASK;
>> +     phyparam1 |= PHYPARAM1_PCS_TXDEEMPH;
>> +     writel(phyparam1, drv->reg_phy + EXYNOS5_DRD_PHYPARAM1);
>> +
>> +     phybatchg = readl(drv->reg_phy + EXYNOS5_DRD_PHYBATCHG);
>> +     phybatchg |= PHYBATCHG_UTMI_CLKSEL;
>> +     writel(phybatchg, drv->reg_phy + EXYNOS5_DRD_PHYBATCHG);
>> +
>> +     /* PHYTEST POWERDOWN Control */
>> +     phytest = readl(drv->reg_phy + EXYNOS5_DRD_PHYTEST);
>> +     phytest &= ~(PHYTEST_POWERDOWN_SSP |
>> +                  PHYTEST_POWERDOWN_HSP);
>> +     writel(phytest, drv->reg_phy + EXYNOS5_DRD_PHYTEST);
>> +
>> +     /* UTMI Power Control */
>> +     writel(PHYUTMI_OTGDISABLE, drv->reg_phy + EXYNOS5_DRD_PHYUTMI);
>
> All these UTMI configuration should be done in usb2 init.
Ok, will move this to separate function.

>> +
>> +     phyclkrst = exynos5_usb3phy_set_refclk(drv);
>> +
>> +     phyclkrst |= PHYCLKRST_PORTRESET |
>> +                  /* Digital power supply in normal operating mode */
>> +                  PHYCLKRST_RETENABLEN |
>> +                  /* Enable ref clock for SS function */
>> +                  PHYCLKRST_REF_SSP_EN |
>> +                  /* Enable spread spectrum */
>> +                  PHYCLKRST_SSC_EN |
>> +                  /* Power down HS Bias and PLL blocks in suspend mode */
>> +                  PHYCLKRST_COMMONONN;
>> +
>> +     writel(phyclkrst, drv->reg_phy + EXYNOS5_DRD_PHYCLKRST);
>> +
>> +     udelay(10);
>> +
>> +     phyclkrst &= ~PHYCLKRST_PORTRESET;
>> +     writel(phyclkrst, drv->reg_phy + EXYNOS5_DRD_PHYCLKRST);
>> +
>> +     clk_disable_unprepare(drv->clk);
>> +
>> +     return 0;
>> +}
>> +
>> +static int exynos5_usb3phy_exit(struct phy *phy)
>> +{
>> +     int ret;
>> +     u32 phyutmi;
>> +     u32 phyclkrst;
>> +     u32 phytest;
>
> same here..
right, will do it.

>> +     struct phy_usb_instance *inst = phy_get_drvdata(phy);
>> +     struct exynos5_usb3phy_driver *drv = to_usb3phy_driver(inst);
>> +
>> +     ret = clk_prepare_enable(drv->clk);
>> +     if (ret)
>> +             return ret;
>> +
>> +     phyutmi = PHYUTMI_OTGDISABLE |
>> +               PHYUTMI_FORCESUSPEND |
>> +               PHYUTMI_FORCESLEEP;
>> +     writel(phyutmi, drv->reg_phy + EXYNOS5_DRD_PHYUTMI);
>
> here too.. UTMI configuration should be part of USB2.
ok.

>> +
[snip]

>> +
>> +static struct phy_ops exynos5_usb3phy_ops = {
>> +     .init           = exynos5_usb3phy_init,
>> +     .exit           = exynos5_usb3phy_exit,
>> +     .power_on       = exynos5_usb3phy_power_on,
>> +     .power_off      = exynos5_usb3phy_power_off,
>> +     .owner          = THIS_MODULE,
>> +};
>> +
>> +const struct usb3phy_config exynos5_usb3phy_cfg[] = {
>> +     {
>> +             .id             = EXYNOS5_USB3PHY_UTMI,
>
> This should be USB2 no?
Actually the thought was to have similar naming for enums.
EXYNOS5_USB3PHY_UTMI
EXYNOS5_USB3PHY_PIPE3

Since the entire driver was going that way.
But will change these to a more common name
EXYNOS5_DRDPHY_UTMI
EXYNOS5_DRDPHY_PIPE3,
in the same fashion the register names are defined.
Will that be fine ?

>> +             .reg_pmu_offset = EXYNOS5_USB3DRD_PHY_PMU_REG_OFFSET,
>> +             .phy_isol       = exynos5_usb3phy_isol,
>> +     },
>> +     {
>> +             .id             = EXYNOS5_USB3PHY_PIPE3,
>> +             .reg_pmu_offset = EXYNOS5_USB3DRD_PHY_PMU_REG_OFFSET,
>> +             .phy_isol       = exynos5_usb3phy_isol,
>> +     },
>> +     {},
>> +};
>> +
>> +const struct exynos5_usb3phy_drv_data exynos5420_usb3phy = {
>> +     .has_usb30_sclk         = true,
>> +     .has_multi_controller   = true,
>> +     .phy_cfg                = exynos5_usb3phy_cfg,
>> +};
>> +
>> +const struct exynos5_usb3phy_drv_data exynos5250_usb3phy = {
>> +     .has_usb30_sclk         = false,
>> +     .has_multi_controller   = false,
>> +     .phy_cfg                = exynos5_usb3phy_cfg,
>> +};
>> +
>> +static const struct of_device_id exynos5_usb3phy_of_match[] = {
>> +     {
>> +             .compatible = "samsung,exynos5250-usb3phy",
>> +             .data = &exynos5250_usb3phy
>> +     }, {
>> +             .compatible = "samsung,exynos5420-usb3phy",
>> +             .data = &exynos5420_usb3phy
>> +     },
>> +     { },
>> +};
>> +
>> +static int exynos5_usb3phy_probe(struct platform_device *pdev)
>> +{
>> +     struct device *dev = &pdev->dev;
>> +     struct device_node *node = dev->of_node;
>> +     struct exynos5_usb3phy_driver *drv;
>> +     struct phy_provider *phy_provider;
>> +     struct resource *res;
>> +     struct clk *clk;
>> +     const struct of_device_id *match;
>> +     const struct exynos5_usb3phy_drv_data *drv_data;
>> +     struct regmap *reg_isol;
>> +     int i;
>> +
>> +     /*
>> +      * Exynos systems are completely DT enabled,
>> +      * so lets not have any platform data support for this driver.
>> +      */
>
> Then you should add depend on OF for this driver.
Right. depends on CONFIG_OF. Will add one.

>> +     if (!node) {
>> +             dev_err(dev, "no device node found\n");
>> +             return -ENODEV;
>> +     }
>> +
>> +     match = of_match_node(exynos5_usb3phy_of_match, pdev->dev.of_node);
>> +     if (!match) {
>> +             dev_err(dev, "of_match_node() failed\n");
>> +             return -EINVAL;
>> +     }
>> +     drv_data = match->data;
>> +
>> +     drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
>> +     if (!drv) {
>> +             dev_err(dev, "Failed to allocate memory\n");
>
> dev_err is not needed here.

Right, will remove it.

>> +             return -ENOMEM;
>> +     }
>> +
[snip]

>> +     dev_dbg(dev, "Creating usb3drd phy\n");
> dev_vdbg?

Sure.

>
> Cheers
> Kishon
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Best Regards
Vivek Gautam
Samsung R&D Institute, Bangalore
India
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] of: add vendor prefix for Allwinner Technology
From: Emilio López @ 2014-01-30  1:36 UTC (permalink / raw)
  To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, rob-VoJi6FS/r0vR7s880joybQ,
	mark.rutland-5wv7dgnIgG8, Maxime Ripard
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Emilio López

We have been using the "allwinner" prefix for everything so far; let's
document it here.

Signed-off-by: Emilio López <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index edbb8d8..5a2904b 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -7,6 +7,7 @@ ad	Avionic Design GmbH
 adi	Analog Devices, Inc.
 aeroflexgaisler	Aeroflex Gaisler AB
 ak	Asahi Kasei Corp.
+allwinner	Allwinner Technology Co., Ltd.
 altr	Altera Corp.
 amcc	Applied Micro Circuits Corporation (APM, formally AMCC)
 apm	Applied Micro Circuits Corporation (APM)
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH v2 3/5] spi: sunxi: Add Allwinner A31 SPI controller driver
From: Emilio López @ 2014-01-30  1:20 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Mark Brown, Mike Turquette,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kevin.z.m.zh-Re5JQEeQqe8AvxtiuMwx3w,
	sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
	shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
	zhuzhenhua-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf
In-Reply-To: <1390993850-9054-4-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Hi Maxime,

El 29/01/14 08:10, Maxime Ripard escribió:
> The Allwinner A31 has a new SPI controller IP compared to the older Allwinner
> SoCs.
>
> It supports DMA, but the driver only does PIO for now, and DMA will be
> supported eventually.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
(snip)
> +	struct sun6i_spi *sspi = spi_master_get_devdata(master);
> +	int ret;
> +
> +	ret = clk_prepare_enable(sspi->hclk);
> +	if (ret) {
> +		dev_err(dev, "Couldn't enable clock 'ahb spi'\n");
> +		goto out;
> +	}
> +
> +	ret = clk_prepare_enable(sspi->mclk);
> +	if (ret) {
> +		dev_err(dev, "Couldn't enable clock 'ahb spi'\n");

A different message would be nice :)

Cheers,

Emilio

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.

^ permalink raw reply

* Re: [RFC PATCH V3 0/4] APM X-Gene PCIe controller
From: Tanmay Inamdar @ 2014-01-30  0:40 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dann Frazier, Arnd Bergmann, Jason Gunthorpe, Grant Likely,
	Rob Herring, Catalin Marinas, Rob Landley,
	linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-arm,
	linux-doc, linux-kernel@vger.kernel.org, patches, Jon Masters
In-Reply-To: <CAErSpo7Dfd4NJBEDuVe1VCvZObFq1YvV2x77S60Z4-CZq89QJw@mail.gmail.com>

On Wed, Jan 29, 2014 at 4:18 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Sat, Jan 25, 2014 at 9:09 AM, Dann Frazier
> <dann.frazier@canonical.com> wrote:
>> On Fri, Jan 24, 2014 at 2:32 PM, Tanmay Inamdar <tinamdar@apm.com> wrote:
>>> This patch adds support for AppliedMicro X-Gene PCIe host controller. The
>>> driver is tested on X-Gene platform with different gen1/2/3 PCIe endpoint
>>> cards.
>>>
>>> X-Gene PCIe controller driver has depedency on the pcie arch support for
>>> arm64. The arm64 pcie arch support is not yet part of mainline Linux kernel
>>> and approach for arch support is under discussion with arm64 maintainers.
>>> The reference patch can be found here --> https://lkml.org/lkml/2013/10/23/244
>>
>> The reference patch looks corrupted (pcibios.c has no includes, etc),
>> would you mind reposting?
>
> When you repost, please make sure you fix whatever problem is
> preventing your email from appearing on the vger mailing lists.  I
> won't apply things that haven't appeared on the linux-pci list,
> because that list is the opportunity for other people to review them.
>
You are absolutely right. If the patches are not reaching mailing
list, they should not appear on archive list as well. However I am
seeing my patches recorded on archives. So I am not sure if they are
actually getting dropped on linux-pci or any other mailing list.

http://www.spinics.net/lists/linux-pci/msg28198.html
http://article.gmane.org/gmane.linux.kernel.pci/28442/match=tanmay+inamdar

> Bjorn

^ permalink raw reply

* Re: [RFC PATCH V3 0/4] APM X-Gene PCIe controller
From: Bjorn Helgaas @ 2014-01-30  0:18 UTC (permalink / raw)
  To: Dann Frazier
  Cc: Tanmay Inamdar, Arnd Bergmann, Jason Gunthorpe, Grant Likely,
	Rob Herring, Catalin Marinas, Rob Landley,
	linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-arm,
	linux-doc, linux-kernel@vger.kernel.org, patches, Jon Masters
In-Reply-To: <CALdTtnsEo74UeYgoQ0DF7=LN074b_0bL0vg6Bxs02B9nDkRTNA@mail.gmail.com>

On Sat, Jan 25, 2014 at 9:09 AM, Dann Frazier
<dann.frazier@canonical.com> wrote:
> On Fri, Jan 24, 2014 at 2:32 PM, Tanmay Inamdar <tinamdar@apm.com> wrote:
>> This patch adds support for AppliedMicro X-Gene PCIe host controller. The
>> driver is tested on X-Gene platform with different gen1/2/3 PCIe endpoint
>> cards.
>>
>> X-Gene PCIe controller driver has depedency on the pcie arch support for
>> arm64. The arm64 pcie arch support is not yet part of mainline Linux kernel
>> and approach for arch support is under discussion with arm64 maintainers.
>> The reference patch can be found here --> https://lkml.org/lkml/2013/10/23/244
>
> The reference patch looks corrupted (pcibios.c has no includes, etc),
> would you mind reposting?

When you repost, please make sure you fix whatever problem is
preventing your email from appearing on the vger mailing lists.  I
won't apply things that haven't appeared on the linux-pci list,
because that list is the opportunity for other people to review them.

Bjorn

^ permalink raw reply

* [PATCH V5 5/5] Documentation: power: reset: Add documentation for generic SYSCON reboot driver
From: Feng Kan @ 2014-01-30  0:03 UTC (permalink / raw)
  To: patches, linux-arm-kernel, linux-kernel, devicetree; +Cc: Feng Kan
In-Reply-To: <1391040198-14185-1-git-send-email-fkan@apm.com>

Add documentation for generic SYSCON reboot driver.

Signed-off-by: Feng Kan <fkan@apm.com>
---
 .../bindings/power/reset/syscon-reboot.txt         |   23 ++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/reset/syscon-reboot.txt

diff --git a/Documentation/devicetree/bindings/power/reset/syscon-reboot.txt b/Documentation/devicetree/bindings/power/reset/syscon-reboot.txt
new file mode 100644
index 0000000..963f3c3
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/syscon-reboot.txt
@@ -0,0 +1,23 @@
+Generic SYSCON mapped register reset driver
+
+This is a generic reset driver using syscon to map the reset register.
+The reset is generally performed with a write to the reset register
+defined by the register map pointed by syscon reference plus the offset
+with the mask defined in the reboot node.
+
+Required properties:
+- compatible: should contain "syscon-reboot"
+- regmap: this is phandle to the register map node 
+- offset: offset in the register map for the reboot register (in bytes)
+- mask: the reset value written to the reboot register (32 bit access)
+
+Default will be little endian mode, 32 bit access only.
+
+Examples:
+
+	reboot {
+	   compatible = "syscon-reboot";
+	   regmap = <&regmapnode>;
+	   offset = <0x0>;
+	   mask = <0x1>;
+	};
-- 
1.7.6.1

^ permalink raw reply related

* [PATCH V5 4/5] arm64: Select reboot driver for X-Gene platform
From: Feng Kan @ 2014-01-30  0:03 UTC (permalink / raw)
  To: patches, linux-arm-kernel, linux-kernel, devicetree; +Cc: Feng Kan
In-Reply-To: <1391040198-14185-1-git-send-email-fkan@apm.com>

Select reboot driver for X-Gene platform.

Signed-off-by: Feng Kan <fkan@apm.com>
---
 arch/arm64/Kconfig |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index dd4327f..f43820f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -123,6 +123,8 @@ config ARCH_VEXPRESS
 
 config ARCH_XGENE
 	bool "AppliedMicro X-Gene SOC Family"
+	select MFD_SYSCON
+	select POWER_RESET_SYSCON
 	help
 	  This enables support for AppliedMicro X-Gene SOC Family
 
-- 
1.7.6.1

^ permalink raw reply related

* [PATCH V5 3/5] arm64: dts: Add X-Gene reboot driver dts node
From: Feng Kan @ 2014-01-30  0:03 UTC (permalink / raw)
  To: patches-qTEPVZfXA3Y,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Feng Kan
In-Reply-To: <1391040198-14185-1-git-send-email-fkan-qTEPVZfXA3Y@public.gmane.org>

Add X-Gene platform reboot driver dts node.

Signed-off-by: Feng Kan <fkan-qTEPVZfXA3Y@public.gmane.org>
---
 arch/arm64/boot/dts/apm-storm.dtsi |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
index d37d736..4ef9d26 100644
--- a/arch/arm64/boot/dts/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
@@ -103,6 +103,11 @@
 		#size-cells = <2>;
 		ranges;
 
+		scu: system-clk-controller@17000000 {
+			compatible = "apm,xgene-scu","syscon";
+			reg = <0x0 0x17000000 0x0 0x400>;
+		};
+
 		clocks {
 			#address-cells = <2>;
 			#size-cells = <2>;
@@ -187,5 +192,13 @@
 			interrupt-parent = <&gic>;
 			interrupts = <0x0 0x4c 0x4>;
 		};
+
+		reboot@17000014 {
+			compatible = "syscon-reboot";
+			regmap = <&scu>;
+			offset = <0x14>;
+			mask = <0x1>;
+		};
+
 	};
 };
-- 
1.7.6.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH V5 2/5] power: reset: Remove X-Gene reboot driver
From: Feng Kan @ 2014-01-30  0:03 UTC (permalink / raw)
  To: patches-qTEPVZfXA3Y,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Feng Kan
In-Reply-To: <1391040198-14185-1-git-send-email-fkan-qTEPVZfXA3Y@public.gmane.org>

Remove X-Gene reboot driver.

Signed-off-by: Feng Kan <fkan-qTEPVZfXA3Y@public.gmane.org>
---
 drivers/power/reset/Kconfig        |    7 ---
 drivers/power/reset/Makefile       |    1 -
 drivers/power/reset/xgene-reboot.c |  103 ------------------------------------
 3 files changed, 0 insertions(+), 111 deletions(-)
 delete mode 100644 drivers/power/reset/xgene-reboot.c

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 4501c02..13a5191 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -45,13 +45,6 @@ config POWER_RESET_VEXPRESS
 	  Power off and reset support for the ARM Ltd. Versatile
 	  Express boards.
 
-config POWER_RESET_XGENE
-	bool "APM SoC X-Gene reset driver"
-	depends on ARM64
-	depends on POWER_RESET
-	help
-	  Reboot support for the APM SoC X-Gene Eval boards.
-
 config POWER_RESET_SYSCON
 	bool "Generic SYSCON regmap reset driver"
 	depends on MFD_SYSCON
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index f2c0327..a3137ff 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -3,5 +3,4 @@ obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
 obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
 obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
-obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o
 obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o
diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
deleted file mode 100644
index ecd55f8..0000000
--- a/drivers/power/reset/xgene-reboot.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * AppliedMicro X-Gene SoC Reboot Driver
- *
- * Copyright (c) 2013, Applied Micro Circuits Corporation
- * Author: Feng Kan <fkan-qTEPVZfXA3Y@public.gmane.org>
- * Author: Loc Ho <lho-qTEPVZfXA3Y@public.gmane.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * This driver provides system reboot functionality for APM X-Gene SoC.
- * For system shutdown, this is board specify. If a board designer
- * implements GPIO shutdown, use the gpio-poweroff.c driver.
- */
-#include <linux/io.h>
-#include <linux/of_device.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
-#include <asm/system_misc.h>
-
-struct xgene_reboot_context {
-	struct platform_device *pdev;
-	void *csr;
-	u32 mask;
-};
-
-static struct xgene_reboot_context *xgene_restart_ctx;
-
-static void xgene_restart(char str, const char *cmd)
-{
-	struct xgene_reboot_context *ctx = xgene_restart_ctx;
-	unsigned long timeout;
-
-	/* Issue the reboot */
-	if (ctx)
-		writel(ctx->mask, ctx->csr);
-
-	timeout = jiffies + HZ;
-	while (time_before(jiffies, timeout))
-		cpu_relax();
-
-	dev_emerg(&ctx->pdev->dev, "Unable to restart system\n");
-}
-
-static int xgene_reboot_probe(struct platform_device *pdev)
-{
-	struct xgene_reboot_context *ctx;
-
-	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
-	if (!ctx) {
-		dev_err(&pdev->dev, "out of memory for context\n");
-		return -ENODEV;
-	}
-
-	ctx->csr = of_iomap(pdev->dev.of_node, 0);
-	if (!ctx->csr) {
-		devm_kfree(&pdev->dev, ctx);
-		dev_err(&pdev->dev, "can not map resource\n");
-		return -ENODEV;
-	}
-
-	if (of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask))
-		ctx->mask = 0xFFFFFFFF;
-
-	ctx->pdev = pdev;
-	arm_pm_restart = xgene_restart;
-	xgene_restart_ctx = ctx;
-
-	return 0;
-}
-
-static struct of_device_id xgene_reboot_of_match[] = {
-	{ .compatible = "apm,xgene-reboot" },
-	{}
-};
-
-static struct platform_driver xgene_reboot_driver = {
-	.probe = xgene_reboot_probe,
-	.driver = {
-		.name = "xgene-reboot",
-		.of_match_table = xgene_reboot_of_match,
-	},
-};
-
-static int __init xgene_reboot_init(void)
-{
-	return platform_driver_register(&xgene_reboot_driver);
-}
-device_initcall(xgene_reboot_init);
-- 
1.7.6.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH V5 1/5] power: reset: Add generic SYSCON register mapped reset
From: Feng Kan @ 2014-01-30  0:03 UTC (permalink / raw)
  To: patches-qTEPVZfXA3Y,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Feng Kan
In-Reply-To: <1391040198-14185-1-git-send-email-fkan-qTEPVZfXA3Y@public.gmane.org>

Add a generic SYSCON register mapped reset mechanism.

Signed-off-by: Feng Kan <fkan-qTEPVZfXA3Y@public.gmane.org>
---
 drivers/power/reset/Kconfig         |    7 +++
 drivers/power/reset/Makefile        |    1 +
 drivers/power/reset/syscon-reboot.c |  100 +++++++++++++++++++++++++++++++++++
 3 files changed, 108 insertions(+), 0 deletions(-)
 create mode 100644 drivers/power/reset/syscon-reboot.c

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 9b3ea53..4501c02 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -51,3 +51,10 @@ config POWER_RESET_XGENE
 	depends on POWER_RESET
 	help
 	  Reboot support for the APM SoC X-Gene Eval boards.
+
+config POWER_RESET_SYSCON
+	bool "Generic SYSCON regmap reset driver"
+	depends on MFD_SYSCON
+	depends on POWER_RESET
+	help
+	  Reboot support for generic SYSCON mapped register reset.
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 3e6ed88..f2c0327 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
 obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
 obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o
+obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o
diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c
new file mode 100644
index 0000000..29ed908
--- /dev/null
+++ b/drivers/power/reset/syscon-reboot.c
@@ -0,0 +1,100 @@
+/*
+ * Generic Syscon Reboot Driver
+ *
+ * Copyright (c) 2013, Applied Micro Circuits Corporation
+ * Author: Feng Kan <fkan-qTEPVZfXA3Y@public.gmane.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * This driver provides system reboot functionality for APM X-Gene SoC.
+ * For system shutdown, this is board specify. If a board designer
+ * implements GPIO shutdown, use the gpio-poweroff.c driver.
+ */
+#include <linux/io.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/reboot.h>
+#include <asm/system_misc.h>
+
+struct syscon_reboot_context {
+	struct regmap *map;
+	u32 offset;
+	u32 mask;
+};
+
+static struct syscon_reboot_context *syscon_reboot_ctx;
+
+static void syscon_restart(enum reboot_mode reboot_mode, const char *cmd)
+{
+	struct syscon_reboot_context *ctx = syscon_reboot_ctx;
+	unsigned long timeout;
+
+	/* Issue the reboot */
+	if (ctx->map)
+		regmap_write(ctx->map, ctx->offset, ctx->mask);
+
+	timeout = jiffies + HZ;
+	while (time_before(jiffies, timeout))
+		cpu_relax();
+
+	pr_emerg("Unable to restart system\n");
+}
+
+static int syscon_reboot_probe(struct platform_device *pdev)
+{
+	struct syscon_reboot_context *ctx;
+	struct device *dev = &pdev->dev;
+
+	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx) {
+		dev_err(&pdev->dev, "out of memory for context\n");
+		return -ENOMEM;
+	}
+
+	ctx->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
+	if (IS_ERR(ctx->map))
+		return PTR_ERR(ctx->map);
+
+	if (of_property_read_u32(pdev->dev.of_node, "offset", &ctx->offset))
+		return -EINVAL;
+
+	if (of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask))
+		return -EINVAL;
+
+	arm_pm_restart = syscon_restart;
+	syscon_reboot_ctx = ctx;
+
+	return 0;
+}
+
+static struct of_device_id syscon_reboot_of_match[] = {
+	{ .compatible = "syscon-reboot" },
+	{}
+};
+
+static struct platform_driver syscon_reboot_driver = {
+	.probe = syscon_reboot_probe,
+	.driver = {
+		.name = "syscon-reboot",
+		.of_match_table = syscon_reboot_of_match,
+	},
+};
+module_platform_driver(syscon_reboot_driver);
-- 
1.7.6.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH V5 0/5] Add X-Gene platform reboot mechanism
From: Feng Kan @ 2014-01-30  0:03 UTC (permalink / raw)
  To: patches-qTEPVZfXA3Y,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Feng Kan

Enable reboot driver for the X-Gene platform. Add generic syscon reboot
driver.

V5 Change:
	- Documentation update, endian and access size.

V4 Change:
	- Remove old X-Gene reboot driver
	- Add generic syscon reboot driver
	- Add DTS and Kconfig for X-Gene reboot using syscon method

V3 Change:
	- Remove the reboot driver's use of acpi resource patch.
	- Change the reboot driver to use syscon to parse out 
	  system clock register. Remove the old method of getting
	  register from the reboot driver directly.
	- Remove documentation since its now simple.

V2 Change:
	- Add support for using ACPI resource.

Feng Kan (5):
  power: reset: Add generic SYSCON register mapped reset
  power: reset: Remove X-Gene reboot driver
  arm64: dts: Add X-Gene reboot driver dts node
  arm64: Select reboot driver for X-Gene platform
  Documentation: power: reset: Add documentation for generic SYSCON
    reboot driver

 .../bindings/power/reset/syscon-reboot.txt         |   23 +++++
 arch/arm64/Kconfig                                 |    2 +
 arch/arm64/boot/dts/apm-storm.dtsi                 |   13 +++
 drivers/power/reset/Kconfig                        |    8 +-
 drivers/power/reset/Makefile                       |    2 +-
 drivers/power/reset/syscon-reboot.c                |  100 +++++++++++++++++++
 drivers/power/reset/xgene-reboot.c                 |  103 --------------------
 7 files changed, 143 insertions(+), 108 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/reset/syscon-reboot.txt
 create mode 100644 drivers/power/reset/syscon-reboot.c
 delete mode 100644 drivers/power/reset/xgene-reboot.c

-- 
1.7.6.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2] DT: net: document Ethernet bindings in one place
From: Sergei Shtylyov @ 2014-01-29 23:48 UTC (permalink / raw)
  To: Rob Herring
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	devicetree@vger.kernel.org, Rob Landley,
	linux-doc@vger.kernel.org, Max Filippov
In-Reply-To: <CAL_JsqLJrS2w0idwpi0Ar4RyuZ050sb0eYVyzM1HE4df4FxdZQ@mail.gmail.com>

Hello.

On 01/29/2014 07:16 PM, Rob Herring wrote:

>>>> This patch is an attempt to gather the Ethernet related bindings in one
>>>> file,
>>>> like it's done in the MMC and some other subsystems. It should save some
>>>> of
>>>> the trouble of documenting several properties over and over in each
>>>> binding
>>>> document, instead only making reference to the main file.

> [snip]

>>>>    - compatible: should be "allwinner,sun4i-emac".
>>>>    - reg: address and length of the register set for the device.
>>>>    - interrupts: interrupt for the device
>>>> -- phy: A phandle to a phy node defining the PHY address (as the reg
>>>> -  property, a single integer).
>>>> +- phy: see ethernet.txt file in the same directory.
>>>>    - clocks: A phandle to the reference clock for this device
>>>>
>>>>    Optional properties:
>>>> -- (local-)mac-address: mac address to be used by this driver
>>>> +- [local-]mac-address: see ethernet.txt file in the same directory

>>> Sorry, but I meant you should just have a single statement like:

>>> This binding uses standard ethernet properties defined in ethernet.txt.

>>     This way it won't be clear which of the properties are used and which are
>> not, no?

> You're right. For the phy properties we need to specify which ones are
> used. This could be done only for bindings using the not recommended
> properties.

    Sigh, the issue with e.g. "phy-mode" is I can't un-recommend it yet as the 
patch adding "phy-connection-type" parsing to of_get_phy_mode() seems to have 
been lost in transit. :-/

> For optional properties like local-mac-address, I don't think these
> need to be listed. They can be used for all devices and whether or not
> a given Linux driver supports using the property is not really the
> concern of the binding documentation. An exception could be a device

    Hm, this gets somewhat complicated... but let's try.

> that requires a optional property (i.e. a NIC with no eeprom to store
> a MAC address).

    Can't remember an example of such device from the top of my head anyways 
(as it requires the boot loader to fill in this property which is still a 
problem).

> Rob

WBR, Sergei


^ permalink raw reply

* [PATCH 4/4] ARM: dts: DRA7: Add device nodes for ABB
From: Nishanth Menon @ 2014-01-29 23:46 UTC (permalink / raw)
  To: Benoît Cousson, Tony Lindgren
  Cc: devicetree, linux-arm-kernel, linux-kernel, linux-omap,
	Nishanth Menon
In-Reply-To: <1391039177-25284-1-git-send-email-nm@ti.com>

Add ABB device nodes for DRA7 family of devices. Data is based on
DRA7 Technical Reference Manual revision I (Sept 2013)

Signed-off-by: Nishanth Menon <nm@ti.com>
---
Depends on https://patchwork.kernel.org/patch/3530111/

 arch/arm/boot/dts/dra7.dtsi |  132 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 1fd75aa..23a2a11 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -559,6 +559,138 @@
 			status = "disabled";
 		};
 
+		abb_mpu: regulator-abb-mpu {
+			compatible = "ti,abb-v3";
+			regulator-name = "abb_mpu";
+			#address-cells = <0>;
+			#size-cells = <0>;
+			clocks = <&sys_clkin1>;
+			ti,settling-time = <50>;
+			ti,clock-cycles = <16>;
+
+			reg = <0x4ae07ddc 0x4>, <0x4ae07de0 0x4>,
+			      <0x4ae06014 0x4>, <0x4a003b20 0x8>,
+			      <0x4ae0c158 0x4>;
+			reg-names = "setup-address", "control-address",
+				    "int-address", "efuse-address",
+				    "ldo-address";
+			ti,tranxdone-status-mask = <0x80>;
+			/* LDOVBBMPU_FBB_MUX_CTRL */
+			ti,ldovbb-override-mask = <0x400>;
+			/* LDOVBBMPU_FBB_VSET_OUT */
+			ti,ldovbb-vset-mask = <0x1F>;
+
+			/*
+			 * NOTE: only FBB mode used but actual vset will
+			 * determine final biasing
+			 */
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m fbb_m	vset_m*/
+			1060000		0	0x0	0 0x02000000 0x01F00000
+			1160000		0	0x4	0 0x02000000 0x01F00000
+			1210000		0	0x8	0 0x02000000 0x01F00000
+			>;
+		};
+
+		abb_ivahd: regulator-abb-ivahd {
+			compatible = "ti,abb-v3";
+			regulator-name = "abb_ivahd";
+			#address-cells = <0>;
+			#size-cells = <0>;
+			clocks = <&sys_clkin1>;
+			ti,settling-time = <50>;
+			ti,clock-cycles = <16>;
+
+			reg = <0x4ae07e34 0x4>, <0x4ae07e24 0x4>,
+			      <0x4ae06010 0x4>, <0x4a0025cc 0x8>,
+			      <0x4a002470 0x4>;
+			reg-names = "setup-address", "control-address",
+				    "int-address", "efuse-address",
+				    "ldo-address";
+			ti,tranxdone-status-mask = <0x40000000>;
+			/* LDOVBBIVA_FBB_MUX_CTRL */
+			ti,ldovbb-override-mask = <0x400>;
+			/* LDOVBBIVA_FBB_VSET_OUT */
+			ti,ldovbb-vset-mask = <0x1F>;
+
+			/*
+			 * NOTE: only FBB mode used but actual vset will
+			 * determine final biasing
+			 */
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m fbb_m	vset_m*/
+			1055000		0	0x0	0 0x02000000 0x01F00000
+			1150000		0	0x4	0 0x02000000 0x01F00000
+			1250000		0	0x8	0 0x02000000 0x01F00000
+			>;
+		};
+
+		abb_dspeve: regulator-abb-dspeve {
+			compatible = "ti,abb-v3";
+			regulator-name = "abb_dspeve";
+			#address-cells = <0>;
+			#size-cells = <0>;
+			clocks = <&sys_clkin1>;
+			ti,settling-time = <50>;
+			ti,clock-cycles = <16>;
+
+			reg = <0x4ae07e30 0x4>, <0x4ae07e20 0x4>,
+			      <0x4ae06010 0x4>, <0x4a0025e0 0x8>,
+			      <0x4a00246c 0x4>;
+			reg-names = "setup-address", "control-address",
+				    "int-address", "efuse-address",
+				    "ldo-address";
+			ti,tranxdone-status-mask = <0x20000000>;
+			/* LDOVBBDSPEVE_FBB_MUX_CTRL */
+			ti,ldovbb-override-mask = <0x400>;
+			/* LDOVBBDSPEVE_FBB_VSET_OUT */
+			ti,ldovbb-vset-mask = <0x1F>;
+
+			/*
+			 * NOTE: only FBB mode used but actual vset will
+			 * determine final biasing
+			 */
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m fbb_m	vset_m*/
+			1055000		0	0x0	0 0x02000000 0x01F00000
+			1150000		0	0x4	0 0x02000000 0x01F00000
+			1250000		0	0x8	0 0x02000000 0x01F00000
+			>;
+		};
+
+		abb_gpu: regulator-abb-gpu {
+			compatible = "ti,abb-v3";
+			regulator-name = "abb_gpu";
+			#address-cells = <0>;
+			#size-cells = <0>;
+			clocks = <&sys_clkin1>;
+			ti,settling-time = <50>;
+			ti,clock-cycles = <16>;
+
+			reg = <0x4ae07de4 0x4>, <0x4ae07de8 0x4>,
+			      <0x4ae06010 0x4>, <0x4a003b08 0x8>,
+			      <0x4ae0c154 0x4>;
+			reg-names = "setup-address", "control-address",
+				    "int-address", "efuse-address",
+				    "ldo-address";
+			ti,tranxdone-status-mask = <0x10000000>;
+			/* LDOVBBGPU_FBB_MUX_CTRL */
+			ti,ldovbb-override-mask = <0x400>;
+			/* LDOVBBGPU_FBB_VSET_OUT */
+			ti,ldovbb-vset-mask = <0x1F>;
+
+			/*
+			 * NOTE: only FBB mode used but actual vset will
+			 * determine final biasing
+			 */
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m fbb_m	vset_m*/
+			1090000		0	0x0	0 0x02000000 0x01F00000
+			1210000		0	0x4	0 0x02000000 0x01F00000
+			1280000		0	0x8	0 0x02000000 0x01F00000
+			>;
+		};
+
 		mcspi1: spi@48098000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x48098000 0x200>;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 3/4] ARM: dts: OMAP5: Add device nodes for ABB
From: Nishanth Menon @ 2014-01-29 23:46 UTC (permalink / raw)
  To: Benoît Cousson, Tony Lindgren
  Cc: Nishanth Menon, devicetree, Andrii.Tseglytskyi, linux-kernel,
	linux-omap, linux-arm-kernel
In-Reply-To: <1391039177-25284-1-git-send-email-nm@ti.com>

From: "Andrii.Tseglytskyi" <andrii.tseglytskyi@ti.com>

Add ABB device nodes for OMAP5 family of devices. Data is based on
OMAP543x Technical Reference Manual revision U (April 2013).
NOTE: clock node has been disabled in this patch due to the lack of
OMAP5 clock data.

[nm@ti.com: co-developer]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Andrii.Tseglytskyi <andrii.tseglytskyi@ti.com>
---
 arch/arm/boot/dts/omap5.dtsi |   63 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index a72813a..6159f20 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -801,6 +801,69 @@
 
 			#thermal-sensor-cells = <1>;
 		};
+
+		abb_mpu: regulator-abb-mpu {
+			compatible = "ti,abb-v2";
+			regulator-name = "abb_mpu";
+			#address-cells = <0>;
+			#size-cells = <0>;
+			clocks = <&sys_clkin>;
+			ti,settling-time = <50>;
+			ti,clock-cycles = <16>;
+
+			reg = <0x4ae07cdc 0x8>, <0x4ae06014 0x4>,
+			      <0x4a0021ac 0x18>, <0x4ae0C318 0x4>;
+			reg-names = "base-address", "int-address",
+				    "efuse-address", "ldo-address";
+			ti,tranxdone-status-mask = <0x80>;
+			/* LDOVBBMPU_MUX_CTRL */
+			ti,ldovbb-override-mask = <0x400>;
+			/* LDOVBBMPU_VSET_OUT */
+			ti,ldovbb-vset-mask = <0x1F>;
+
+			/*
+			 * NOTE: only FBB mode used but actual vset will
+			 * determine final biasing
+			 */
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m fbb_m	vset_m*/
+			880000		0	0x4	0 0x20000000 0x1F000000
+			1060000		0	0x8	0 0x20000000 0x1F000000
+			1250000		0	0x10	0 0x20000000 0x1F000000
+			1260000		1	0x14	0 0x20000000 0x1F000000
+			>;
+		};
+
+		abb_mm: regulator-abb-mm {
+			compatible = "ti,abb-v2";
+			regulator-name = "abb_mm";
+			#address-cells = <0>;
+			#size-cells = <0>;
+			clocks = <&sys_clkin>;
+			ti,settling-time = <50>;
+			ti,clock-cycles = <16>;
+
+			reg = <0x4ae07ce4 0x8>, <0x4ae06010 0x4>,
+			      <0x4a002194 0x14>, <0x4ae0C314 0x4>;
+			reg-names = "base-address", "int-address",
+				    "efuse-address", "ldo-address";
+			ti,tranxdone-status-mask = <0x80000000>;
+			/* LDOVBBMM_MUX_CTRL */
+			ti,ldovbb-override-mask = <0x400>;
+			/* LDOVBBMM_VSET_OUT */
+			ti,ldovbb-vset-mask = <0x1F>;
+
+			/*
+			 * NOTE: only FBB mode used but actual vset will
+			 * determine final biasing
+			 */
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m fbb_m	vset_m*/
+			880000		0	0x4	0 0x20000000 0x1F000000
+			1025000		0	0x8	0 0x20000000 0x1F000000
+			1120000		1	0x10	0 0x20000000 0x1F000000
+			>;
+		};
 	};
 };
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 2/4] ARM: dts: OMAP4: Add device nodes for ABB
From: Nishanth Menon @ 2014-01-29 23:46 UTC (permalink / raw)
  To: Benoît Cousson, Tony Lindgren
  Cc: devicetree, linux-arm-kernel, linux-kernel, linux-omap,
	Andrii.Tseglytskyi, Nishanth Menon
In-Reply-To: <1391039177-25284-1-git-send-email-nm@ti.com>

From: "Andrii.Tseglytskyi" <andrii.tseglytskyi@ti.com>

Add ABB device nodes for OMAP443x family of devices. abb_iva is
populated, but disabled as it is not used on current OMAP443x family,
but the node is used on OMAP446x family. Data is based on OMAP443x
Technical Reference Manual revision AN (April 2013).

ABB device nodes for OMAP4460 device Data is based on OMAP4460
Technical Reference Manual revision Z (April 2013)

[nm@ti.com: co-developer]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Andrii.Tseglytskyi <andrii.tseglytskyi@ti.com>
---
 arch/arm/boot/dts/omap4.dtsi    |   26 ++++++++++++++++++++++++++
 arch/arm/boot/dts/omap443x.dtsi |   26 ++++++++++++++++++++++++++
 arch/arm/boot/dts/omap4460.dtsi |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+)

diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index d3f8a6e..72e6bd7 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -757,6 +757,32 @@
 			dmas = <&sdma 117>, <&sdma 116>;
 			dma-names = "tx", "rx";
 		};
+
+		abb_mpu: regulator-abb-mpu {
+			compatible = "ti,abb-v2";
+			regulator-name = "abb_mpu";
+			#address-cells = <0>;
+			#size-cells = <0>;
+			ti,tranxdone-status-mask = <0x80>;
+			clocks = <&sys_clkin_ck>;
+			ti,settling-time = <50>;
+			ti,clock-cycles = <16>;
+
+			status = "disabled";
+		};
+
+		abb_iva: regulator-abb-iva {
+			compatible = "ti,abb-v2";
+			regulator-name = "abb_iva";
+			#address-cells = <0>;
+			#size-cells = <0>;
+			ti,tranxdone-status-mask = <0x80000000>;
+			clocks = <&sys_clkin_ck>;
+			ti,settling-time = <50>;
+			ti,clock-cycles = <16>;
+
+			status = "disabled";
+		};
 	};
 };
 
diff --git a/arch/arm/boot/dts/omap443x.dtsi b/arch/arm/boot/dts/omap443x.dtsi
index 8c1cfad..0adfa1d 100644
--- a/arch/arm/boot/dts/omap443x.dtsi
+++ b/arch/arm/boot/dts/omap443x.dtsi
@@ -43,6 +43,32 @@
 			#thermal-sensor-cells = <0>;
 		};
 	};
+
+	ocp {
+		abb_mpu: regulator-abb-mpu {
+			status = "okay";
+
+			reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>;
+			reg-names = "base-address", "int-address";
+
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m	fbb_m	vset_m*/
+			1025000		0	0	0	0	0
+			1200000		0	0	0	0	0
+			1313000		0	0	0	0	0
+			1375000		1	0	0	0	0
+			1389000		1	0	0	0	0
+			>;
+		};
+
+		/* Default unused, just provide register info for record */
+		abb_iva: regulator-abb-iva {
+			reg = <0x4a307bd8 0x8>, <0x4a306010 0x4>;
+			reg-names = "base-address", "int-address";
+		};
+
+	};
+
 };
 
 /include/ "omap443x-clocks.dtsi"
diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi
index 6b32f52..194f9ef 100644
--- a/arch/arm/boot/dts/omap4460.dtsi
+++ b/arch/arm/boot/dts/omap4460.dtsi
@@ -50,7 +50,44 @@
 
 			#thermal-sensor-cells = <0>;
 		};
+
+		abb_mpu: regulator-abb-mpu {
+			status = "okay";
+
+			reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>,
+			      <0x4A002268 0x4>;
+			reg-names = "base-address", "int-address",
+				    "efuse-address";
+
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m	fbb_m	vset_m*/
+			1025000		0	0	0	0	0
+			1200000		0	0	0	0	0
+			1313000		0	0	0x100000 0x40000 0
+			1375000		1	0	0	0	0
+			1389000		1	0	0	0	0
+			>;
+		};
+
+		abb_iva: regulator-abb-iva {
+			status = "okay";
+
+			reg = <0x4a307bd8 0x8>, <0x4a306010 0x4>,
+			      <0x4A002268 0x4>;
+			reg-names = "base-address", "int-address",
+				    "efuse-address";
+
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m	fbb_m	vset_m*/
+			950000		0	0	0	0	0
+			1140000		0	0	0	0	0
+			1291000		0	0	0x200000 0	0
+			1375000		1	0	0	0	0
+			1376000		1	0	0	0	0
+			>;
+		};
 	};
+
 };
 
 /include/ "omap446x-clocks.dtsi"
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/4] ARM: dts: OMAP36xx: Add device node for ABB
From: Nishanth Menon @ 2014-01-29 23:46 UTC (permalink / raw)
  To: Benoît Cousson, Tony Lindgren
  Cc: devicetree, linux-arm-kernel, linux-kernel, linux-omap,
	Andrii.Tseglytskyi, Nishanth Menon
In-Reply-To: <1391039177-25284-1-git-send-email-nm@ti.com>

From: "Andrii.Tseglytskyi" <andrii.tseglytskyi@ti.com>

Add ABB device node for OMAP36xx family of devices. Data is based on
OMAP36XX Technical Reference Manual revision AB (Dec 2012).

[nm@ti.com: co-developer]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Andrii.Tseglytskyi <andrii.tseglytskyi@ti.com>
---
 arch/arm/boot/dts/omap36xx.dtsi |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi
index 7e8dee9..ba077cd 100644
--- a/arch/arm/boot/dts/omap36xx.dtsi
+++ b/arch/arm/boot/dts/omap36xx.dtsi
@@ -39,6 +39,26 @@
 			clock-frequency = <48000000>;
 		};
 
+		abb_mpu_iva: regulator-abb-mpu {
+			compatible = "ti,abb-v1";
+			regulator-name = "abb_mpu_iva";
+			#address-cell = <0>;
+			#size-cells = <0>;
+			reg = <0x483072f0 0x8>, <0x48306818 0x4>;
+			reg-names = "base-address", "int-address";
+			ti,tranxdone-status-mask = <0x4000000>;
+			clocks = <&sys_ck>;
+			ti,settling-time = <30>;
+			ti,clock-cycles = <8>;
+			ti,abb_info = <
+			/*uV		ABB	efuse	rbb_m	fbb_m	vset_m*/
+			1012500		0	0	0	0	0
+			1200000		0	0	0	0	0
+			1325000		0	0	0	0	0
+			1375000		1	0	0	0	0
+			>;
+		};
+
 		omap3_pmx_core2: pinmux@480025a0 {
 			compatible = "ti,omap3-padconf", "pinctrl-single";
 			reg = <0x480025a0 0x5c>;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 0/4] ARM: dts: OMAP3630+: Add ABB device nodes
From: Nishanth Menon @ 2014-01-29 23:46 UTC (permalink / raw)
  To: Benoît Cousson, Tony Lindgren
  Cc: devicetree, linux-arm-kernel, linux-kernel, linux-omap,
	Nishanth Menon

Now that clock nodes have been merged to master,
refresh of the series meant for all TI platforms using ABB.
Originally posted [1], I will restart with v1.

dt bindings and driver is already in upstream, and only the dt node is missing.

NOTE: dra7 support depends on [2] - but dt can get sequenced as needed.

This series is based on:
master     0e47c96 Merge tag 'for-linus-20140127' of git://git.infradead.org/linux-mtd
Testing was performed on next-20140123[3]

Andrii.Tseglytskyi (3):
  ARM: dts: OMAP36xx: Add device node for ABB
  ARM: dts: OMAP4: Add device nodes for ABB
  ARM: dts: OMAP5: Add device nodes for ABB

Nishanth Menon (1):
  ARM: dts: DRA7: Add device nodes for ABB

 arch/arm/boot/dts/dra7.dtsi     |  132 +++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/omap36xx.dtsi |   20 ++++++
 arch/arm/boot/dts/omap4.dtsi    |   26 ++++++++
 arch/arm/boot/dts/omap443x.dtsi |   26 ++++++++
 arch/arm/boot/dts/omap4460.dtsi |   37 +++++++++++
 arch/arm/boot/dts/omap5.dtsi    |   63 +++++++++++++++++++
 6 files changed, 304 insertions(+)

[1] http://marc.info/?l=linux-omap&m=136751535923806&w=2
[2] https://git.kernel.org/cgit/linux/kernel/git/broonie/regulator.git/log/?h=topic/ti-abb
[3] https://patchwork.kernel.org/patch/3530111/

-- 
1.7.9.5

^ permalink raw reply

* Re: [PATCH 2/2] ARM: dts: OMAP3+: add clock nodes for CPU
From: Nishanth Menon @ 2014-01-29 23:32 UTC (permalink / raw)
  To: Robert Nelson
  Cc: devicetree, Mike Turquette, Tony Lindgren, linux kernel,
	Tero Kristo, Benoît Cousson, linux-omap@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <CAOCHtYjaCBn2oOk66ef9wiz_GJnVwHDyx446_mrkipPoENaeUQ@mail.gmail.com>

On 01/29/2014 01:29 PM, Robert Nelson wrote:
> On Wed, Jan 29, 2014 at 12:19 PM, Nishanth Menon <nm@ti.com> wrote:
>> OMAP34xx, AM3517 and OMAP36xx platforms use dpll1 clock.
>>
>> OMAP443x, OMAP446x, OMAP447x, OMAP5, DRA7, AM43xx platforms use
>> dpll_mpu clock.
>>
>> Latency used is the generic latency defined in omap-cpufreq
>> driver.
>>
>> Signed-off-by: Nishanth Menon <nm@ti.com>
> 
> Hi Nishanth,
> 
> After this patch, do you see any limitation to finally enabling 1Ghz
> operation on the beagle-xm by default? Or are we still missing a
> dependicy somewhere?

yes, there is:
a) ABB dt series - i will repost this in a few mins
b) AVS conversion from non-dt mode to dt supported mode. (which by
itself depends on VC/VP conversion).
c) clk notifier based dvfs for cpufreq-cpu0 -> this allows us to
introduce the necessary plumbing for mpu voltage domain such that the
TWL4030 regulator, AVS and ABB are rightly sequenced.

What you have done in the patch below is to introduce ABB regulator -
but no one is actually using it -> this might actually work on certain
samples at 1GHz, but prolonged operation will either damage the device
or fail on other samples - I have tried numerous times Internally to
get approval for non ABB/AVS configuration for 1GHz - but I have a
clear feedback that it cannot be done with the constraints of
DM3730/OMAP3630.

Lets do this a series at a time and build up the necessary support -
we get clock nodes for dvfs (using i2c1) here with cpufreq-cpu0 with
this series. If folks can ack and queue this up, we can get in ABB dts
nodes in place - allowing us to work on the next set -> sequencing
using clock notifier. in parallel we could work on converting AVS back
to dt based solution.

yes, the road is long.

-- 
Regards,
Nishanth Menon

^ permalink raw reply

* Re: [PATCH] DT: net: document Ethernet bindings in one place
From: Sergei Shtylyov @ 2014-01-29 23:04 UTC (permalink / raw)
  To: Florian Fainelli, Rob Herring
  Cc: netdev, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, devicetree@vger.kernel.org, Rob Landley,
	linux-doc@vger.kernel.org, Grant Likely
In-Reply-To: <52DEE465.9000202@cogentembedded.com>

Hello.

On 01/22/2014 12:19 AM, Sergei Shtylyov wrote:

>>>>>     I'm afraid that's too late, it has spread very far, so that
>>>>> of_get_phy_mode() handles that property, not "phy-connection-type".

>>>> Uggg, I guess this is a case of a defacto standard then if the kernel
>>>> doesn't even support it.

>>> Maybe I forgot to CC you on patch sent to Grant only, I sent a patch a
>>> while ago for of_get_phy_mode() to look for both "phy-mode" and
>>> "phy-connection-type" since the former has been a Linux invention, but
>>> the latter is ePAPR specified.

>> Here is a link to the actual patch in question, not sure which tree
>> Grant applied it to though:

>> http://lkml.indiana.edu/hypermail/linux/kernel/1311.2/00048.html

>     It's not the patch mail, it's Grant's "applied" reply, patch is mangled in
> this reply, and I couldn't follow the thread. Here's the actual patch mail:

> http://marc.info/?l=devicetree&m=138449662807254

    Florian, I didn't find this patch in Grant's official tree, so maybe you 
should ask him where is the patch already?

WBR, Sergei


^ permalink raw reply

* Re: [PATCH 0/2] DT: net: davinci_emac: couple more properties actually optional
From: Sergei Shtylyov @ 2014-01-29 22:42 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rob, devicetree, linux-doc, davinci-linux-open-source
In-Reply-To: <20140128.234315.2164810932256158473.davem@davemloft.net>

Hello.

On 01/29/2014 10:43 AM, David Miller wrote:

>>     Though described as required, couple more properties in the DaVinci EMAC
>> binding are actually optional, as the driver will happily function without them.
>> The patchset is against DaveM's 'net.git' tree this time.

>> [1/2] DT: net: davinci_emac: "ti,davinci-rmii-en" property is actually optional
>> [2/2] DT: net: davinci_emac: "ti,davinci-no-bd-ram" property is actually optional

> Series applied with the "has/have" thing fixed.

> Thanks.

    Thank you!
    Unfortunately, this driver presents a bad example of DT bindings overall 
(caused in its turn by a misuse of the platform data for the EMAC type 
differing instead of the platform device IDs).

WBR, Sergei


^ permalink raw reply

* Re: Re: [RFC PATCH v2 09/14] mtd: nand: add sunxi NFC dt bindings doc
From: Henrik Nordström @ 2014-01-29 22:37 UTC (permalink / raw)
  To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
  Cc: Boris BREZILLON, Maxime Ripard, Rob Landley, Russell King,
	David Woodhouse, Grant Likely, Brian Norris, Jason Gunthorpe,
	Arnd Bergmann, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	dev-3kdeTeqwOZ9EV1b7eY7vFQ
In-Reply-To: <CAL_JsqLVr1gSLArqtfOiHce+u6ZK8FiKMX0o9bvMrMoGGhATvg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

ons 2014-01-29 klockan 11:11 -0600 skrev Rob Herring:

> Isn't allwinner,rb implied by a lack of rb-gpios property. Or no R/B
> pin is an option? If so, don't you need some fixed time delay
> properties like max erase time?
> 
> rb-gpios could be added to the generic nand binding as well.

The Allwinner NAND controller have dedicated RB pins when NAND is
enabled, only MUXed with other functions when NAND is not enabled.

Leaving RB unconnected is not a valid hardware configuration. The
controller internal timing engine depends on being able to sense RB to
sequence NAND commands properly.

Regards
Henrik

^ permalink raw reply

* [PATCH 5/5] ARM: dts: AM33XX: Add ecap interrupt properties
From: Matt Porter @ 2014-01-29 20:59 UTC (permalink / raw)
  To: Jonathan Cameron, Grant Likely, Rob Herring, Benoit Cousson,
	Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Thierry Reding
  Cc: linux-iio, Linux Kernel Mailing List, Devicetree List, linux-pwm,
	Linux OMAP List, Linux ARM Kernel List, Linaro Patches
In-Reply-To: <1391029199-3670-1-git-send-email-mporter@linaro.org>

Add missing interrupt properties to the ecap0, ecap1, and ecap2
nodes.

Signed-off-by: Matt Porter <mporter@linaro.org>
---
 arch/arm/boot/dts/am33xx.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 6d95d3d..b4139ba 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -582,6 +582,8 @@
 				compatible = "ti,am33xx-ecap";
 				#pwm-cells = <3>;
 				reg = <0x48300100 0x80>;
+				interrupts = <31>;
+				interrupt-names = "ecap0";
 				ti,hwmods = "ecap0";
 				status = "disabled";
 			};
@@ -610,6 +612,8 @@
 				compatible = "ti,am33xx-ecap";
 				#pwm-cells = <3>;
 				reg = <0x48302100 0x80>;
+				interrupts = <47>;
+				interrupt-names = "ecap1";
 				ti,hwmods = "ecap1";
 				status = "disabled";
 			};
@@ -638,6 +642,8 @@
 				compatible = "ti,am33xx-ecap";
 				#pwm-cells = <3>;
 				reg = <0x48304100 0x80>;
+				interrupts = <61>;
+				interrupt-names = "ecap2";
 				ti,hwmods = "ecap2";
 				status = "disabled";
 			};
-- 
1.8.4


^ permalink raw reply related

* [PATCH 4/5] pwm: enable TI PWMSS if the IIO tiecap driver is selected
From: Matt Porter @ 2014-01-29 20:59 UTC (permalink / raw)
  To: Jonathan Cameron, Grant Likely, Rob Herring, Benoit Cousson,
	Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Thierry Reding
  Cc: linux-iio, Linux Kernel Mailing List, Devicetree List, linux-pwm,
	Linux OMAP List, Linux ARM Kernel List, Linaro Patches
In-Reply-To: <1391029199-3670-1-git-send-email-mporter@linaro.org>

The IIO TI ECAP driver depends on the TI PWMSS management
driver in this subsystem. Enable PWMSS when the IIO TI ECAP
driver is selected.

Signed-off-by: Matt Porter <mporter@linaro.org>
---
 drivers/pwm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 22f2f28..bd3cc65 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -219,7 +219,7 @@ config  PWM_TIEHRPWM
 
 config  PWM_TIPWMSS
 	bool
-	default y if SOC_AM33XX && (PWM_TIECAP || PWM_TIEHRPWM)
+	default y if SOC_AM33XX && (IIO_TIECAP || PWM_TIECAP || PWM_TIEHRPWM)
 	help
 	  PWM Subsystem driver support for AM33xx SOC.
 
-- 
1.8.4

^ permalink raw reply related

* [PATCH 3/5] iio: enable selection and build of pulse drivers
From: Matt Porter @ 2014-01-29 20:59 UTC (permalink / raw)
  To: Jonathan Cameron, Grant Likely, Rob Herring, Benoit Cousson,
	Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Thierry Reding
  Cc: linux-iio, Linux Kernel Mailing List, Devicetree List, linux-pwm,
	Linux OMAP List, Linux ARM Kernel List, Linaro Patches
In-Reply-To: <1391029199-3670-1-git-send-email-mporter@linaro.org>

Add the pulse driver subdirectory when configuring and building
IIO.

Signed-off-by: Matt Porter <mporter@linaro.org>
---
 drivers/iio/Kconfig  | 1 +
 drivers/iio/Makefile | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 5dd0e12..286acc3 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -74,6 +74,7 @@ if IIO_TRIGGER
    source "drivers/iio/trigger/Kconfig"
 endif #IIO_TRIGGER
 source "drivers/iio/pressure/Kconfig"
+source "drivers/iio/pulse/Kconfig"
 source "drivers/iio/temperature/Kconfig"
 
 endif # IIO
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index 887d390..9a953c9 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -24,5 +24,6 @@ obj-y += light/
 obj-y += magnetometer/
 obj-y += orientation/
 obj-y += pressure/
+obj-y += pulse/
 obj-y += temperature/
 obj-y += trigger/
-- 
1.8.4

^ permalink raw reply related

* [PATCH 2/5] iio: pulse: add TI ECAP driver
From: Matt Porter @ 2014-01-29 20:59 UTC (permalink / raw)
  To: Jonathan Cameron, Grant Likely, Rob Herring, Benoit Cousson,
	Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Thierry Reding
  Cc: linux-iio, Linux Kernel Mailing List, Devicetree List, linux-pwm,
	Linux OMAP List, Linux ARM Kernel List, Linaro Patches
In-Reply-To: <1391029199-3670-1-git-send-email-mporter@linaro.org>

Adds support for capturing PWM signals using the TI ECAP peripheral.
This driver supports triggered buffer capture of pulses on multiple
ECAP instances. In addition, the driver supports configurable polarity
of the signal to be captured.

Signed-off-by: Matt Porter <mporter@linaro.org>
---
 drivers/iio/pulse/Kconfig  |  20 ++
 drivers/iio/pulse/Makefile |   6 +
 drivers/iio/pulse/tiecap.c | 493 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 519 insertions(+)
 create mode 100644 drivers/iio/pulse/Kconfig
 create mode 100644 drivers/iio/pulse/Makefile
 create mode 100644 drivers/iio/pulse/tiecap.c

diff --git a/drivers/iio/pulse/Kconfig b/drivers/iio/pulse/Kconfig
new file mode 100644
index 0000000..9864d4b
--- /dev/null
+++ b/drivers/iio/pulse/Kconfig
@@ -0,0 +1,20 @@
+#
+# Pulse Capture Devices
+#
+# When adding new entries keep the list in alphabetical order
+
+menu "Pulse Capture Devices"
+
+config IIO_TIECAP
+	tristate "TI ECAP Pulse Capture"
+	depends on SOC_AM33XX
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	 If you say yes here you get support for the TI ECAP peripheral
+	 in pulse capture mode.
+
+	 This driver can also be built as a module.  If so, the module
+	 will be called tiecap
+
+endmenu
diff --git a/drivers/iio/pulse/Makefile b/drivers/iio/pulse/Makefile
new file mode 100644
index 0000000..94d4b00
--- /dev/null
+++ b/drivers/iio/pulse/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for IIO PWM Capture Devices
+#
+
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_IIO_TIECAP)	+= tiecap.o
diff --git a/drivers/iio/pulse/tiecap.c b/drivers/iio/pulse/tiecap.c
new file mode 100644
index 0000000..8e2b3a0
--- /dev/null
+++ b/drivers/iio/pulse/tiecap.c
@@ -0,0 +1,493 @@
+/*
+ * ECAP IIO pulse capture driver
+ *
+ * Copyright (C) 2014 Linaro Limited
+ * Author: Matt Porter <mporter@linaro.org>
+ *
+ * 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/clk.h>
+#include <linux/err.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "../../pwm/pwm-tipwmss.h"
+
+/* ECAP regs and bits */
+#define CAP1			0x08
+#define CAP2			0x0c
+#define ECCTL1			0x28
+#define ECCTL1_RUN_FREE		BIT(15)
+#define ECCTL1_CAPLDEN		BIT(8)
+#define ECCTL1_CAP2POL		BIT(2)
+#define ECCTL1_CTRRST1		BIT(1)
+#define ECCTL1_CAP1POL		BIT(0)
+#define ECCTL2			0x2a
+#define ECCTL2_SYNCO_SEL_DIS	BIT(7)
+#define ECCTL2_TSCTR_FREERUN	BIT(4)
+#define ECCTL2_REARM		BIT(3)
+#define ECCTL2_STOP_WRAP_2	BIT(1)
+#define ECEINT			0x2c
+#define ECFLG			0x2e
+#define ECCLR			0x30
+#define ECINT_CTRCMP		BIT(7)
+#define ECINT_CTRPRD		BIT(6)
+#define ECINT_CTROVF		BIT(5)
+#define ECINT_CEVT4		BIT(4)
+#define ECINT_CEVT3		BIT(3)
+#define ECINT_CEVT2		BIT(2)
+#define ECINT_CEVT1		BIT(1)
+#define ECINT_ALL		(ECINT_CTRCMP |	\
+				ECINT_CTRPRD |	\
+				ECINT_CTROVF |	\
+				ECINT_CEVT4 |	\
+				ECINT_CEVT3 |	\
+				ECINT_CEVT2 |	\
+				ECINT_CEVT1)
+
+/* ECAP driver flags */
+#define ECAP_POLARITY_HIGH	BIT(1)
+#define ECAP_ENABLED		BIT(0)
+
+struct ecap_context {
+	u32	cap1;
+	u32	cap2;
+	u16	ecctl1;
+	u16	ecctl2;
+	u16	eceint;
+};
+
+struct ecap_state {
+	unsigned long		flags;
+	unsigned int		clk_rate;
+	void __iomem		*regs;
+	u32			*buf;
+	struct ecap_context	ctx;
+};
+
+#define dev_to_ecap_state(d)	iio_priv(dev_to_iio_dev(d))
+
+static const struct iio_chan_spec ecap_channels[] = {
+	{
+		.type		= IIO_PULSE,
+		.channel	= 0,
+		.info_mask_separate =
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+		.scan_index	= 0,
+		.scan_type = {
+			.sign		= 'u',
+			.realbits	= 32,
+			.storagebits	= 32,
+			.endianness	= IIO_LE,
+		},
+		.modified = 0,
+	},
+	IIO_CHAN_SOFT_TIMESTAMP(1)
+};
+
+static ssize_t ecap_attr_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct ecap_state *state = dev_to_ecap_state(dev);
+
+	return sprintf(buf, "%d\n",
+		       test_bit(ECAP_POLARITY_HIGH, &state->flags));
+}
+
+static ssize_t ecap_attr_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf,
+			       size_t len)
+{
+	int ret;
+	bool val;
+	struct ecap_state *state = dev_to_ecap_state(dev);
+
+	if (test_bit(ECAP_ENABLED, &state->flags))
+		return -EINVAL;
+
+	ret = strtobool(buf, &val);
+	if (ret)
+		return ret;
+
+	if (val)
+		set_bit(ECAP_POLARITY_HIGH, &state->flags);
+	else
+		clear_bit(ECAP_POLARITY_HIGH, &state->flags);
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(in_pulse_polarity, S_IRUGO | S_IWUSR,
+	ecap_attr_show, ecap_attr_store, 0);
+
+static struct attribute *ecap_attributes[] = {
+	&iio_dev_attr_in_pulse_polarity.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ecap_attribute_group = {
+	.attrs = ecap_attributes,
+};
+
+static int ecap_read_raw(struct iio_dev *idev,
+			struct iio_chan_spec const *ch, int *val,
+			int *val2, long mask)
+{
+	struct ecap_state *state = iio_priv(idev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		/*
+		 * Always return 0 as a pulse width sample
+		 * is only valid in a triggered condition
+		 */
+		*val = 0;
+		*val2 = 0;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 0;
+		*val2 = NSEC_PER_SEC / state->clk_rate;
+		return IIO_VAL_INT_PLUS_NANO;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct iio_info ecap_info = {
+	.driver_module = THIS_MODULE,
+	.attrs = &ecap_attribute_group,
+	.read_raw = &ecap_read_raw,
+};
+
+static irqreturn_t ecap_trigger_handler(int irq, void *private)
+{
+	struct iio_poll_func *pf = private;
+	struct iio_dev *idev = pf->indio_dev;
+	struct ecap_state *state = iio_priv(idev);
+
+	/* Read pulse counter value */
+	*state->buf = readl(state->regs + CAP2);
+
+	iio_push_to_buffers_with_timestamp(idev, state->buf, iio_get_time_ns());
+
+	iio_trigger_notify_done(idev->trig);
+
+	return IRQ_HANDLED;
+};
+
+
+static const struct iio_trigger_ops iio_interrupt_trigger_ops = {
+	.owner = THIS_MODULE,
+};
+
+static irqreturn_t ecap_interrupt_handler(int irq, void *private)
+{
+	struct iio_dev *idev = private;
+	struct ecap_state *state = iio_priv(idev);
+	u16 ints;
+
+	iio_trigger_poll(idev->trig, 0);
+
+	/* Clear CAP2 interrupt */
+	ints = readw(state->regs + ECFLG);
+	if (ints & ECINT_CEVT2)
+		writew(ECINT_CEVT2, state->regs + ECCLR);
+	else
+		dev_warn(&idev->dev, "unhandled interrupt flagged: %04x\n",
+			 ints);
+
+	return IRQ_HANDLED;
+}
+
+static int ecap_buffer_predisable(struct iio_dev *idev)
+{
+	struct ecap_state *state = iio_priv(idev);
+	int ret = 0;
+	u16 ecctl2;
+
+	/* Stop capture */
+	clear_bit(ECAP_ENABLED, &state->flags);
+	ecctl2 = readw(state->regs + ECCTL2) & ~ECCTL2_TSCTR_FREERUN;
+	writew(ecctl2, state->regs + ECCTL2);
+
+	/* Disable and clear all interrupts */
+	writew(0, state->regs + ECEINT);
+	writew(ECINT_ALL, state->regs + ECCLR);
+
+	ret = iio_triggered_buffer_predisable(idev);
+
+	pm_runtime_put_sync(idev->dev.parent);
+
+	return ret;
+}
+
+static int ecap_buffer_postenable(struct iio_dev *idev)
+{
+	struct ecap_state *state = iio_priv(idev);
+	int ret = 0;
+	u16 ecctl1, ecctl2;
+
+	pm_runtime_get_sync(idev->dev.parent);
+
+	/* Configure pulse polarity */
+	ecctl1 = readw(state->regs + ECCTL1);
+	if (test_bit(ECAP_POLARITY_HIGH, &state->flags)) {
+		/* CAP1 rising, CAP2 falling */
+		ecctl1 |= ECCTL1_CAP2POL;
+		ecctl1 &= ~ECCTL1_CAP1POL;
+	} else {
+		/* CAP1 falling, CAP2 rising */
+		ecctl1 &= ~ECCTL1_CAP2POL;
+		ecctl1 |= ECCTL1_CAP1POL;
+	}
+	writew(ecctl1, state->regs + ECCTL1);
+
+	/* Enable CAP2 interrupt */
+	writew(ECINT_CEVT2, state->regs + ECEINT);
+
+	/* Enable capture */
+	ecctl2 = readw(state->regs + ECCTL2);
+	ecctl2 |= ECCTL2_TSCTR_FREERUN | ECCTL2_REARM;
+	writew(ecctl2, state->regs + ECCTL2);
+	set_bit(ECAP_ENABLED, &state->flags);
+
+	ret = iio_triggered_buffer_postenable(idev);
+
+	return ret;
+}
+
+static const struct iio_buffer_setup_ops ecap_buffer_setup_ops = {
+	.postenable = &ecap_buffer_postenable,
+	.predisable = &ecap_buffer_predisable,
+};
+
+static void ecap_init_hw(struct iio_dev *idev)
+{
+	struct ecap_state *state = iio_priv(idev);
+
+	clear_bit(ECAP_ENABLED, &state->flags);
+	set_bit(ECAP_POLARITY_HIGH, &state->flags);
+
+	writew(ECCTL1_RUN_FREE | ECCTL1_CAPLDEN |
+	       ECCTL1_CAP2POL | ECCTL1_CTRRST1,
+	       state->regs + ECCTL1);
+
+	writew(ECCTL2_SYNCO_SEL_DIS | ECCTL2_STOP_WRAP_2,
+	       state->regs + ECCTL2);
+}
+
+static const struct of_device_id ecap_of_ids[] = {
+	{ .compatible	= "ti,am33xx-ecap" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ecap_of_ids);
+
+static int ecap_probe(struct platform_device *pdev)
+{
+	int irq, ret;
+	struct iio_dev *idev;
+	struct ecap_state *state;
+	struct resource *r;
+	struct clk *clk;
+	struct iio_trigger *trig;
+	u16 status;
+
+	idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct ecap_state));
+	if (!idev)
+		return -ENOMEM;
+
+	state = iio_priv(idev);
+
+	clk = devm_clk_get(&pdev->dev, "fck");
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "failed to get clock\n");
+		return PTR_ERR(clk);
+	}
+
+	state->clk_rate = clk_get_rate(clk);
+	if (!state->clk_rate) {
+		dev_err(&pdev->dev, "failed to get clock rate\n");
+		return -EINVAL;
+	}
+
+	platform_set_drvdata(pdev, idev);
+
+	idev->dev.parent = &pdev->dev;
+	idev->name = dev_name(&pdev->dev);
+	idev->modes = INDIO_DIRECT_MODE;
+	idev->info = &ecap_info;
+	idev->channels = ecap_channels;
+	/* One h/w capture and one s/w timestamp channel per instance */
+	idev->num_channels = 2;
+
+	trig = devm_iio_trigger_alloc(&pdev->dev, "%s-dev%d",
+				      idev->name, idev->id);
+	if (!trig)
+		return -ENOMEM;
+	trig->dev.parent = idev->dev.parent;
+	iio_trigger_set_drvdata(trig, idev);
+	trig->ops = &iio_interrupt_trigger_ops;
+
+	ret = iio_trigger_register(trig);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register trigger\n");
+		return ret;
+	}
+
+	ret = iio_triggered_buffer_setup(idev, NULL,
+					 &ecap_trigger_handler,
+					 &ecap_buffer_setup_ops);
+	if (ret)
+		return ret;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "no irq is specified\n");
+		return irq;
+	}
+	ret = devm_request_irq(&pdev->dev, irq,
+				&ecap_interrupt_handler,
+				0, dev_name(&pdev->dev), idev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to request irq\n");
+		goto uninit_buffer;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	state->regs = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(state->regs)) {
+		dev_err(&pdev->dev, "unable to remap registers\n");
+		ret = PTR_ERR(state->regs);
+		goto uninit_buffer;
+	};
+
+	ret = iio_device_register(idev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to register device\n");
+		goto uninit_buffer;
+	}
+
+	state->buf = devm_kzalloc(&idev->dev, idev->scan_bytes, GFP_KERNEL);
+	if (!state->buf) {
+		ret = -ENOMEM;
+		goto uninit_buffer;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
+
+	status = pwmss_submodule_state_change(pdev->dev.parent,
+			PWMSS_ECAPCLK_EN);
+	if (!(status & PWMSS_ECAPCLK_EN_ACK)) {
+		dev_err(&pdev->dev, "failed to enable PWMSS config space clock\n");
+		ret = -EINVAL;
+		goto pwmss_clk_failure;
+	}
+
+	ecap_init_hw(idev);
+
+	pm_runtime_put_sync(&pdev->dev);
+
+	return 0;
+
+pwmss_clk_failure:
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	iio_device_unregister(idev);
+
+uninit_buffer:
+	iio_triggered_buffer_cleanup(idev);
+
+	return ret;
+}
+
+static int ecap_remove(struct platform_device *pdev)
+{
+	struct iio_dev *idev = platform_get_drvdata(pdev);
+
+	pm_runtime_get_sync(&pdev->dev);
+
+	pwmss_submodule_state_change(pdev->dev.parent, PWMSS_ECAPCLK_STOP_REQ);
+
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	iio_device_unregister(idev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ecap_suspend(struct device *dev)
+{
+	struct ecap_state *state = dev_to_ecap_state(dev);
+
+	pm_runtime_get_sync(dev);
+	state->ctx.cap1 = readl(state->regs + CAP1);
+	state->ctx.cap2 = readl(state->regs + CAP2);
+	state->ctx.eceint = readw(state->regs + ECEINT);
+	state->ctx.ecctl1 = readw(state->regs + ECCTL1);
+	state->ctx.ecctl2 = readw(state->regs + ECCTL2);
+	pm_runtime_put_sync(dev);
+
+	/* If capture was active, disable ECAP */
+	if (test_bit(ECAP_ENABLED, &state->flags))
+		pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+static int ecap_resume(struct device *dev)
+{
+	struct ecap_state *state = dev_to_ecap_state(dev);
+
+	/* If capture was active, enable ECAP */
+	if (test_bit(ECAP_ENABLED, &state->flags))
+		pm_runtime_get_sync(dev);
+
+	pm_runtime_get_sync(dev);
+	writel(state->ctx.cap1, state->regs + CAP1);
+	writel(state->ctx.cap2, state->regs + CAP2);
+	writew(state->ctx.eceint, state->regs + ECEINT);
+	writew(state->ctx.ecctl1, state->regs + ECCTL1);
+	writew(state->ctx.ecctl2, state->regs + ECCTL2);
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(ecap_pm_ops, ecap_suspend, ecap_resume);
+
+static struct platform_driver ecap_iio_driver = {
+	.driver = {
+		.name		= "ecap",
+		.owner		= THIS_MODULE,
+		.of_match_table = of_match_ptr(ecap_of_ids),
+		.pm		= &ecap_pm_ops,
+	},
+	.probe = ecap_probe,
+	.remove = ecap_remove,
+};
+
+module_platform_driver(ecap_iio_driver);
+
+MODULE_DESCRIPTION("ECAP IIO pulse capture driver");
+MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
+MODULE_LICENSE("GPL");
-- 
1.8.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox