Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH net-next v2 07/10] net: bcmgenet: add MDIO routines
From: Mark Rutland @ 2014-02-13 11:50 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev@vger.kernel.org, davem@davemloft.net, cernekee@gmail.com,
	devicetree@vger.kernel.org
In-Reply-To: <1392269395-23513-8-git-send-email-f.fainelli@gmail.com>

On Thu, Feb 13, 2014 at 05:29:52AM +0000, Florian Fainelli wrote:
> This patch adds support for configuring the port multiplexer hardware
> which resides in front of the GENET Ethernet MAC controller. This allows
> us to support:
> 
> - internal PHYs (using drivers/net/phy/bcm7xxx.c)
> - MoCA PHYs which are an entirely separate hardware block not covered
>   here
> - external PHYs and switches
> 
> Note that MoCA and switches are currently supported using the emulated
> "fixed PHY" driver.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> Changes since v1:
> - fixed MDIO crash/warning when Device Tree probing fails
> - removed the use of priv->phy_type and use priv->phy_interface
>   directly
> 
>  drivers/net/ethernet/broadcom/genet/bcmmii.c | 481 +++++++++++++++++++++++++++
>  1 file changed, 481 insertions(+)
>  create mode 100644 drivers/net/ethernet/broadcom/genet/bcmmii.c

[...]

> +static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
> +{
> +       struct device_node *dn = priv->pdev->dev.of_node;
> +       struct device *kdev = &priv->pdev->dev;
> +       struct device_node *mdio_dn;
> +       const __be32 *fixed_link;

This looks a bit odd. Could we not have a common parser for fixed-link
properties?

> +       u32 propval;
> +       int ret, sz;
> +
> +       mdio_dn = of_get_next_child(dn, NULL);
> +       if (!mdio_dn) {
> +               dev_err(kdev, "unable to find MDIO bus node\n");
> +               return -ENODEV;
> +       }

Could you please check that this is the node you expect (by looking at
the compatible string list).

> +
> +       ret = of_mdiobus_register(priv->mii_bus, mdio_dn);
> +       if (ret) {
> +               dev_err(kdev, "failed to register MDIO bus\n");
> +               return ret;
> +       }
> +
> +       /* Check if we have an internal or external PHY */
> +       priv->phy_dn = of_parse_phandle(dn, "phy-handle", 0);
> +       if (priv->phy_dn) {
> +               if (!of_property_read_u32(priv->phy_dn, "max-speed", &propval))
> +                       priv->phy_speed = propval;

Is there no way to find this out without reading values directly off of
the PHY? It seems like something we should have an abstraction for.

> +       } else {
> +               /* Read the link speed from the fixed-link property */
> +               fixed_link = of_get_property(dn, "fixed-link", &sz);
> +               if (!fixed_link || sz < sizeof(*fixed_link)) {
> +                       ret = -ENODEV;
> +                       goto out;
> +               }
> +
> +               priv->phy_speed = be32_to_cpu(fixed_link[2]);

Similarly can we not have a common fixed-link parser? Or abstraction
such that you query the phy regardless of what it is and how its binding
represents this?

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH net-next v2 06/10] net: bcmgenet: add main driver file
From: Mark Rutland @ 2014-02-13 11:38 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev@vger.kernel.org, davem@davemloft.net, cernekee@gmail.com,
	devicetree@vger.kernel.org
In-Reply-To: <1392269395-23513-7-git-send-email-f.fainelli@gmail.com>

On Thu, Feb 13, 2014 at 05:29:51AM +0000, Florian Fainelli wrote:
> This patch adds the BCMGENET main driver file which supports the
> following:
>
> - GENET hardware from V1 to V4
> - support for reading the UniMAC MIB counters statistics
> - support for the 5 transmit queues
> - support for RX/TX checksum offload and SG
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> Changes since v1:
> - use module_platform_driver boilerplate macro
> - renamed bcmgenet_plat_drv to bcmgenet_driver
> - renamed bcmgenet_drv_{probe,remove} to bcmgenet_{probe,remove}
> - removed priv->phy_type usage and use priv->phy_interface which
>   contains the exact same value
> - removed debug module parameters, unused
> - added MODULDE_{AUTHOR,ALIAS,DESCRIPTION} macros
> - remove hardcoded queue index check in bcmgenet_xmit

[...]

> +static int bcmgenet_probe(struct platform_device *pdev)
> +{
> +       struct device_node *dn = pdev->dev.of_node;
> +       struct bcmgenet_priv *priv;
> +       struct net_device *dev;
> +       const void *macaddr;
> +       struct resource *r;
> +       int err = -EIO;
> +
> +       /* Up to GENET_MAX_MQ_CNT + 1 TX queues and a single RX queue */
> +       dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, 1);
> +       if (!dev) {
> +               dev_err(&pdev->dev, "can't allocate net device\n");
> +               return -ENOMEM;
> +       }
> +
> +       priv = netdev_priv(dev);
> +       priv->irq0 = platform_get_irq(pdev, 0);
> +       priv->irq1 = platform_get_irq(pdev, 1);
> +       if (!priv->irq0 || !priv->irq1) {
> +               dev_err(&pdev->dev, "can't find IRQs\n");
> +               err = -EINVAL;
> +               goto err;
> +       }

The binding did not describe that there were two interrupts. What are
each of them for? Are they named in the documentation?

> +
> +       macaddr = of_get_mac_address(dn);
> +       if (!macaddr) {
> +               dev_err(&pdev->dev, "can't find MAC address\n");
> +               err = -EINVAL;
> +               goto err;
> +       }
> +
> +       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       priv->base = devm_request_and_ioremap(&pdev->dev, r);
> +       if (!priv->base) {
> +               dev_err(&pdev->dev, "can't ioremap\n");
> +               err = -EINVAL;
> +               goto err;
> +       }
> +
> +       dev->base_addr = (unsigned long)priv->base;

Does the net core actually need this?

I can't see anywhere else it's used in this file.

[...]

> +       if (of_device_is_compatible(dn, "brcm,genet-v4"))
> +               priv->version = GENET_V4;
> +       else if (of_device_is_compatible(dn, "brcm,genet-v3"))
> +               priv->version = GENET_V3;
> +       else if (of_device_is_compatible(dn, "brcm,genet-v2"))
> +               priv->version = GENET_V2;
> +       else if (of_device_is_compatible(dn, "brcm,genet-v1"))
> +               priv->version = GENET_V1;
> +       else {
> +               dev_err(&pdev->dev, "unknown GENET version\n");
> +               err = -EINVAL;
> +               goto err;

Surely you can't have probed if none of these are in the compatible
list?

Might it make more sense to place this value in of_device_id::data? You
can get it it with of_match_node, and you only have to place the strings
in one place, so no possible typo issues.

> +       }
> +
> +       bcmgenet_set_hw_params(priv);
> +
> +       spin_lock_init(&priv->lock);
> +       spin_lock_init(&priv->bh_lock);
> +       mutex_init(&priv->mib_mutex);
> +       /* Mii wait queue */
> +       init_waitqueue_head(&priv->wq);
> +       /* Always use RX_BUF_LENGTH (2KB) buffer for all chips */
> +       priv->rx_buf_len = RX_BUF_LENGTH;
> +       INIT_WORK(&priv->bcmgenet_irq_work, bcmgenet_irq_task);
> +
> +       priv->clk = devm_clk_get(&priv->pdev->dev, "enet");
> +       if (IS_ERR(priv->clk))
> +               dev_warn(&priv->pdev->dev, "failed to get enet clock\n");

This wasn't in the binding.

> +
> +       priv->clk_wol = devm_clk_get(&priv->pdev->dev, "enet-wol");
> +       if (IS_ERR(priv->clk_wol))
> +               dev_warn(&priv->pdev->dev, "failed to get enet-wol clock\n");

This is also missing from the binding.

> +       /* Turn off the clocks */
> +       if (!IS_ERR(priv->clk))
> +               clk_disable_unprepare(priv->clk);

Either the comment is misleading (s/clocks/clock/), or you're forgetting
about the enet-wol clock here.

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH 1/2] mfd: da9055: Add DT support for PMIC
From: Lee Jones @ 2014-02-13 11:36 UTC (permalink / raw)
  To: Adam Thomson
  Cc: Samuel Ortiz, Rob Herring, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Mark Brown
In-Reply-To: <e11bde69763b77a6b17b851c7d18a892d193411f.1392286537.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>

> Signed-off-by: Adam Thomson <Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/mfd/da9055-i2c.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
> index 8103e43..d4d4c16 100644
> --- a/drivers/mfd/da9055-i2c.c
> +++ b/drivers/mfd/da9055-i2c.c
> @@ -15,6 +15,8 @@
>  #include <linux/device.h>
>  #include <linux/i2c.h>
>  #include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> 
>  #include <linux/mfd/da9055/core.h>
> 
> @@ -66,6 +68,11 @@ static struct i2c_device_id da9055_i2c_id[] = {
>  };
>  MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
> 
> +static const struct of_device_id da9055_of_match[] = {
> +       { .compatible = "dlg,da9055-pmic", },
> +       { }
> +};
> +
>  static struct i2c_driver da9055_i2c_driver = {
>         .probe = da9055_i2c_probe,
>         .remove = da9055_i2c_remove,
> @@ -73,6 +80,7 @@ static struct i2c_driver da9055_i2c_driver = {
>         .driver = {
>                 .name = "da9055-pmic",
>                 .owner = THIS_MODULE,
> +               .of_match_table = of_match_ptr(da9055_of_match),
>         },
>  };

Patch looks okay to me, but needs an Ack from the DT guys.

Acked-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
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] pci: Add support for creating a generic host_bridge from device tree
From: Arnd Bergmann @ 2014-02-13 11:27 UTC (permalink / raw)
  To: linaro-kernel
  Cc: Jingoo Han, 'Tanmay Inamdar', devicetree,
	'Catalin Marinas', 'LKML', 'linux-pci',
	'Bjorn Helgaas', 'LAKML'
In-Reply-To: <000001cf2899$a6eb75b0$f4c26110$%han@samsung.com>

On Thursday 13 February 2014 17:57:41 Jingoo Han wrote:
> I want to use 'drivers/pci/host/pcie-designware.c' for both arm32
> and arm64, without any code changes. However, it looks impossible.

It is impossible at the moment, and I agree we have to fix that.

> I made 'drivers/pci/host/pcie-designware.c' based on 32bit arm PCI
> support. Then, with Liviu's patch, do I have to make new code for arm64,
> even though the same HW PCIe IP is used?
> 
> - For arm32
>   drivers/pci/host/pcie-designware.c
> 
> - For arm64
>   drivers/pci/host/pcie-designware-arm64.c

As a start, I'd suggest using "#ifdef CONFIG_ARM" in the driver,
but sharing as much code as you can. We should try to make the #else
section of the #ifdef architecture independent and get have the arm64
implementation shared with any architecture that doesn't have or want
its own pcibios32.c implementation.

> > > I am reviewing and compiling your patch.
> > > Would you consider adding 'struct pci_sys_data' and 'struct hw_pci'?

I would rather get rid of struct hw_pci for architecture independent
drivers and add a different registration method on arm32 that is
compatible with what we come up with on arm64. The main purpose of
hw_pci is to allow multiple PCI controllers to be initialized at
once, but we don't actually need that for any of the "modern" platforms
where we already have a probe function that gets called once for
each controller.

As a start, we could add a pci_host_bridge_register() function like
the one below to arm32 and migrate the drivers/pci/host/ drivers
over to use it with little effort. Instead of filling out hw_pci,
these drivers would allocate (by embedding in their device struct)
and fill out pci_sys_data directly. After that, we can gradually
move more code out of the arm32 implementation into common code, if
it doesn't already exist there, up to the point where a host driver
no longer has to call any function in bios32.c.

	Arnd

diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 317da88..12c2178 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -514,6 +514,26 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 	}
 }
 
+static void pci_common_bus_probe(struct pci_bus *bus)
+{
+	if (!pci_has_flag(PCI_PROBE_ONLY)) {
+		/*
+		 * Size the bridge windows.
+		 */
+		pci_bus_size_bridges(bus);
+
+		/*
+		 * Assign resources.
+		 */
+		pci_bus_assign_resources(bus);
+	}
+
+	/*
+	 * Tell drivers about devices found.
+	 */
+	pci_bus_add_devices(bus);
+}
+
 void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
 {
 	struct pci_sys_data *sys;
@@ -528,27 +548,38 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
 
 	pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
 
-	list_for_each_entry(sys, &head, node) {
-		struct pci_bus *bus = sys->bus;
+	list_for_each_entry(sys, &head, node)
+		pci_common_bus_probe(sys->bus);
+}
 
-		if (!pci_has_flag(PCI_PROBE_ONLY)) {
-			/*
-			 * Size the bridge windows.
-			 */
-			pci_bus_size_bridges(bus);
 
-			/*
-			 * Assign resources.
-			 */
-			pci_bus_assign_resources(bus);
-		}
 
-		/*
-		 * Tell drivers about devices found.
-		 */
-		pci_bus_add_devices(bus);
-	}
+
+int pci_host_bridge_register(struct device *parent, struct pci_sys_data *sys, struct pci_ops *ops, int (*setup)(int nr, struct pci_sys_data *))
+{
+	int ret;
+
+	pci_add_flags(PCI_REASSIGN_ALL_RSRC);
+	INIT_LIST_HEAD(&sys->resources);
+
+	ret = setup(0, sys);
+	if (ret)
+		return ret;
+
+	ret = pcibios_init_resources(0, sys);
+	if (ret)
+		return ret;
+
+	sys->bus = pci_scan_root_bus(parent, sys->busnr, ops, sys, &sys->resources);
+	if (!sys->bus)
+		return -ENODEV;
+
+	pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
+
+	pci_common_bus_probe(sys->bus);
+	return ret;
 }
+EXPORT_SYMBOL_GPL(pci_host_bridge_register);
 
 #ifndef CONFIG_PCI_HOST_ITE8152
 void pcibios_set_master(struct pci_dev *dev)

^ permalink raw reply related

* Re: [PATCH 2/2] mfd: da9055: Add DT binding documentation for PMIC
From: Mark Brown @ 2014-02-13 11:17 UTC (permalink / raw)
  To: Adam Thomson
  Cc: Lee Jones, Samuel Ortiz, Rob Herring,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <574af9f46ca08e66f6e9bda8ef3a51e7c5c5178b.1392286537.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 230 bytes --]

On Thu, Feb 13, 2014 at 10:45:52AM +0000, Adam Thomson wrote:
> Signed-off-by: Adam Thomson <Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>

Acked-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH net-next v2 09/10] Documentation: add Device tree bindings for Broadcom GENET
From: Mark Rutland @ 2014-02-13 11:13 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
	cernekee-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1392269395-23513-10-git-send-email-f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Thu, Feb 13, 2014 at 05:29:54AM +0000, Florian Fainelli wrote:
> This patch adds the Device Tree bindings for the Broadcom GENET Gigabit
> Ethernet controller. A bunch of examples are provided to illustrate the
> versatile aspect of the hardare.
> 
> Signed-off-by: Florian Fainelli <f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> Changes since v1:
> - rebased
> 
>  .../devicetree/bindings/net/broadcom-bcmgenet.txt  | 111 +++++++++++++++++++++
>  1 file changed, 111 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt
> 
> diff --git a/Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt b/Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt
> new file mode 100644
> index 0000000..93c58e9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt
> @@ -0,0 +1,111 @@
> +* Broadcom BCM7xxx Ethernet Controller (GENET)
> +
> +Required properties:
> +- compatible: should be "brcm,genet-v1", "brcm,genet-v2", "brcm,genet-v3",
> +  "brcm,genet-v4".

Presumably "should contain one of" is a better description than "should
be"?

Are the newer revisions compatible with older revisions?

> +- reg: address and length of the register set for the device.
> +- interrupts: interrupt for the device
> +- mdio bus node: this node should always be present regarless of the PHY
> +  configuration of the GENET instance

Nit: a node is not a property, list it after properties.

> +- phy-mode: The interface between the SoC and the PHY (a string that
> +  of_get_phy_mode() can understand).

Do we not have a document under bindings listing these? I really don't
like referring to code in bindings docs.

> +
> +MDIO bus node required properties:
> +
> +- compatible: should be "brcm,genet-v<N>-mdio"

Where N is? Could this not be an explicit list as above? It helps when
searching for bindings.

> +- reg: address and length relative to the parent node base register address

The parent node will require #address-cells and #size-cells too then.

> +- address-cells: address cell for MDIO bus addressing, should be 1
> +- size-cells: size of the cells for MDIO bus addressing, should be 0
> +
> +Optional properties:
> +- phy-handle: A phandle to a phy node defining the PHY address (as the reg
> +  property, a single integer), used to describe configurations where a PHY
> +  (internal or external) is used.

Is there not a phy binding you could refer to instead?

> +
> +- fixed-link: When the GENET interface is connected to a MoCA hardware block
> +  or when operating in a RGMII to RGMII type of connection, or when the
> +  MDIO bus is voluntarily disabled, this property should be used to describe
> +  the "fixed link", the property is described as follows:
> +
> +  fixed-link: <a b c d e> where a is emulated phy id - choose any,
> +  but unique to the all specified fixed-links, b is duplex - 0 half,
> +  1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no
> +  pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause.

Is this not documented elsewhere such that it can be referred to?

> +
> +Internal Gigabit PHY example:
> +
> +ethernet@f0b60000 {
> +	phy-mode = "internal";
> +	phy-handle = <&phy1>;
> +	mac-address = [ 00 10 18 36 23 1a ];
> +	compatible = "brcm,genet-v4";
> +	#address-cells = <0x1>;
> +	#size-cells = <0x1>;
> +	device_type = "ethernet";

What's this needed by? I can't see any other devices with this
device_type, and I was under the impression that we didn't want new
device_type properties cropping up.

> +	reg = <0xf0b60000 0xfc4c>;
> +	interrupts = <0x0 0x14 0x0 0x0 0x15 0x0>;

How many? The binding implied only one, and I'm not away of any
interrupt controller bindings with #interrupt-cells = <6>.

Cheers,
Mark.
--
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 v3 7/7] devicetree: bindings: Document PM8921/8058 PMICs
From: Lee Jones @ 2014-02-13 11:06 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Samuel Ortiz, linux-kernel, linux-arm-msm, linux-arm-kernel,
	devicetree
In-Reply-To: <20140213053813.GB14769@codeaurora.org>

> > > +- interrupts:
> > > +	Usage: required
> > > +	Value type: <prop-encoded-array>
> > 
> > Either provide an example or a comment to see the description of
> > #interrupt-cells 
> 
> It is part of the example. We also state that the format is
> defined by the interrupt parent binding.

Okay, fair enough.

> > > +	Definition: specifies the interrupt that indicates a subdevice
> > > +		    has generated an interrupt (summary interrupt). The
> > > +		    format of the specifier is defined by the binding document
> > > +		    describing the node's interrupt parent.
> > > +
> > > +- #interrupt-cells:
> > > +	Usage: required
> > > +	Value type : <u32>
> > > +	Definition: must be 2. Specifies the number of cells needed to encode
> > > +		    an interrupt source. The 1st cell contains the interrupt
> > > +		    number. The 2nd cell is the trigger type and level flags
> > > +		    encoded as follows:
> > > +
> > > +			1 = low-to-high edge triggered
> > > +			2 = high-to-low edge triggered
> > > +			4 = active high level-sensitive
> > > +			8 = active low level-sensitive
> > 
> > Actually I'd prefer if you used the definitions in:
> >   dt-bindings/interrupt-controller/irq.h
> 
> These match the #defines in that file. I'd like to be explicit
> about the numbers to prevent people from thinking they have to
> use #defines and to match what other irq controllers have done
> (gic, atmel-aic, etc.)

I believe people _do_ have to use the #defines? Is there a good reason
for you not wanting to use them?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* Re: [PATCH 1/4] phy: miphy365x: Add Device Tree bindings for the MiPHY365x
From: Lee Jones @ 2014-02-13 11:03 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, alexandre.torgue@st.com,
	devicetree@vger.kernel.org, Srinivas Kandagatla
In-Reply-To: <20140212164019.GE25957@e106331-lin.cambridge.arm.com>

> > The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
> > devices. It has 2 ports which it can use for either; both SATA, both
> > PCIe or one of each in any configuration.
> > 
> > Cc: devicetree@vger.kernel.org
> > Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> > ---
> >  .../devicetree/bindings/phy/phy-miphy365x.txt      | 43 ++++++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/phy/phy-miphy365x.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
> > new file mode 100644
> > index 0000000..fdfa7ca
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
> > @@ -0,0 +1,43 @@
> > +STMicroelectronics STi MIPHY365x PHY binding
> > +============================================
> > +
> > +This binding describes a miphy device that is used to control PHY hardware
> > +for SATA and PCIe.
> > +
> > +Required properties:
> > +- compatible: Should be "st,miphy365x-phy"
> > +- #phy-cells: Should be 2 (See example)
> 
> The first example has #phy-cells = <1>.

Right, will fix. Should be 2.

> What do the cells mean? What are the expected values?

http://www.spinics.net/lists/arm-kernel/msg307209.html

> > +- reg:	      Address and length of the register set for the device
> > +- reg-names:  The names of the register addresses corresponding to the
> > +	      registers filled in "reg".
> 
> Whenever there is a ${PROP}-names property, there should be a list of
> explicit values, and a description of how it relates to ${PROP}. Without
> that it's a bit useless.
> 
> Please provide an explicit list of expected names here.
> 
> I assume here what you want is something like:
> 
> - reg: a list of address + length pairs, one for each entry in reg-names
> - reg-names: should contain:
>   * "sata0" for the sata0 control registers...
>   * "sata1" ...
>   * "pcie0" ...
>   * "pcie1" ...

Can do.

> > +- st,syscfg : Should be a phandle of the syscfg node.
> 
> What's this used for?

It's used to gain access to the system configuration
registers. Specifically in this case the bits to choose between PCI or
SATA mode.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* Re: [PATCH net-next v2 06/10] net: bcmgenet: add main driver file
From: Joe Perches @ 2014-02-13 10:58 UTC (permalink / raw)
  To: Francois Romieu; +Cc: Florian Fainelli, netdev, davem, cernekee, devicetree
In-Reply-To: <20140213103506.GB14941@electric-eye.fr.zoreil.com>

On Thu, 2014-02-13 at 11:35 +0100, Francois Romieu wrote:
> Florian Fainelli <f.fainelli@gmail.com> :
> [...]
> > diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
[]
> > +static int bcmgenet_set_rx_csum(struct net_device *dev,
> > +				netdev_features_t wanted)
> > +{
> > +	struct bcmgenet_priv *priv = netdev_priv(dev);
> > +	u32 rbuf_chk_ctrl;
> > +	int rx_csum_en;
> > +
> > +	rx_csum_en = !!(wanted & NETIF_F_RXCSUM);
> 
> It's a bool.

It could be a bool.

The struct definition has:

+	unsigned int desc_rxchk_en;

but perhaps a lot of these members could be bool.

It'd be nicer if the variable types were the same.

> > +	spin_lock_bh(&priv->bh_lock);
> > +	rbuf_chk_ctrl = bcmgenet_rbuf_readl(priv, RBUF_CHK_CTRL);
> > +
> > +	/* enable rx checksumming */
> > +	if (!rx_csum_en)
> > +		rbuf_chk_ctrl &= ~RBUF_RXCHK_EN;
> > +	else
> > +		rbuf_chk_ctrl |= RBUF_RXCHK_EN;

This is more normally written with a positive test like:

	if (rx_csum_en)
		rbuf_chk_ctrl |= RBUF_RXCHK_EN;
	else
		rbuf_chk_ctrl &= RBUF_RXCHK_EN;

> > +	priv->desc_rxchk_en = rx_csum_en;

^ permalink raw reply

* [PATCH 2/2] mfd: da9055: Add DT binding documentation for PMIC
From: Adam Thomson @ 2014-02-13 10:45 UTC (permalink / raw)
  To: Lee Jones, Samuel Ortiz, Rob Herring; +Cc: linux-kernel, devicetree, Mark Brown
In-Reply-To: <cover.1392286537.git.Adam.Thomson.Opensource@diasemi.com>

Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
---
 Documentation/devicetree/bindings/mfd/da9055.txt |   73 ++++++++++++++++++++++
 1 files changed, 73 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/da9055.txt

diff --git a/Documentation/devicetree/bindings/mfd/da9055.txt b/Documentation/devicetree/bindings/mfd/da9055.txt
new file mode 100644
index 0000000..f903c3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/da9055.txt
@@ -0,0 +1,73 @@
+* Dialog DA9055 Power Management Integrated Circuit (PMIC)
+
+DA9055 consists of a large and varied group of sub-devices (I2C Only):
+
+Device			 Supply Names	 Description
+------			 ------------	 -----------
+da9055-gpio		:		: GPIOs
+da9055-regulator	:		: Regulators
+da9055-onkey		:		: On key
+da9055-rtc		:		: RTC
+da9055-hwmon		:		: ADC
+da9055-watchdog		:		: Watchdog
+
+The CODEC device in DA9055 has a separate, configurable I2C address and so
+is instantiated separately from the PMIC.
+
+For details on accompanying CODEC I2C device, see the following:
+Documentation/devicetree/bindings/sound/da9055.txt
+
+======
+
+Required properties:
+- compatible : Should be "dlg,da9055-pmic"
+- reg: Specifies the I2C slave address (defaults to 0x5a but can be modified)
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+  the IRQs from da9055 are delivered to.
+- interrupts: IRQ line info for da9055 chip.
+- interrupt-controller: da9055 has internal IRQs (has own IRQ domain).
+- #interrupt-cells: Should be 1, is the local IRQ number for da9055.
+
+Sub-nodes:
+- regulators : Contain the regulator nodes. The DA9055 regulators are
+  bound using their names as listed below:
+
+    buck1     : regulator BUCK1
+    buck2     : regulator BUCK2
+    ldo1      : regulator LDO1
+    ldo2      : regulator LDO2
+    ldo3      : regulator LDO3
+    ldo4      : regulator LDO4
+    ldo5      : regulator LDO5
+    ldo6      : regulator LDO6
+
+  The bindings details of individual regulator device can be found in:
+  Documentation/devicetree/bindings/regulator/regulator.txt
+
+
+Example:
+
+	pmic: da9055-pmic@5a {
+		compatible = "dlg,da9055-pmic";
+		reg = <0x5a>;
+		interrupt-parent = <&intc>;
+		interrupts = <5 0x8>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		regulators {
+			buck1: BUCK1 {
+				regulator-min-microvolt = <725000>;
+				regulator-max-microvolt = <2075000>;
+			};
+
+			buck2: BUCK2 {
+				regulator-min-microvolt = <925000>;
+				regulator-max-microvolt = <2500000>;
+			};
+			ldo1: LDO1 {
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <3300000>;
+			};
+		};
+	};
--
1.7.0.4

^ permalink raw reply related

* [PATCH 1/2] mfd: da9055: Add DT support for PMIC
From: Adam Thomson @ 2014-02-13 10:45 UTC (permalink / raw)
  To: Lee Jones, Samuel Ortiz, Rob Herring; +Cc: linux-kernel, devicetree, Mark Brown
In-Reply-To: <cover.1392286537.git.Adam.Thomson.Opensource@diasemi.com>

Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
---
 drivers/mfd/da9055-i2c.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
index 8103e43..d4d4c16 100644
--- a/drivers/mfd/da9055-i2c.c
+++ b/drivers/mfd/da9055-i2c.c
@@ -15,6 +15,8 @@
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>

 #include <linux/mfd/da9055/core.h>

@@ -66,6 +68,11 @@ static struct i2c_device_id da9055_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);

+static const struct of_device_id da9055_of_match[] = {
+       { .compatible = "dlg,da9055-pmic", },
+       { }
+};
+
 static struct i2c_driver da9055_i2c_driver = {
        .probe = da9055_i2c_probe,
        .remove = da9055_i2c_remove,
@@ -73,6 +80,7 @@ static struct i2c_driver da9055_i2c_driver = {
        .driver = {
                .name = "da9055-pmic",
                .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(da9055_of_match),
        },
 };

--
1.7.0.4

Legal Disclaimer: This e-mail communication (and any attachment/s) is confidential and contains proprietary information, some or all of which may be legally privileged. It is intended solely for the use of the individual or entity to which it is addressed. Access to this email by anyone else is unauthorized. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited and may be unlawful.

Please consider the environment before printing this e-mail

^ permalink raw reply related

* [PATCH 0/2] mfd: da9055: Add DT support & documentation for PMIC
From: Adam Thomson @ 2014-02-13 10:45 UTC (permalink / raw)
  To: Lee Jones, Samuel Ortiz, Rob Herring; +Cc: linux-kernel, devicetree, Mark Brown

This patch set adds DT support for the MFD core of the da9055 PMIC, and adds
the accompanying DT binding documentation for the device.

Adam Thomson (2):
  mfd: da9055: Add DT support for PMIC
  mfd: da9055: Add DT binding documentation for PMIC

 Documentation/devicetree/bindings/mfd/da9055.txt |   73 ++++++++++++++++++++++
 drivers/mfd/da9055-i2c.c                         |    8 +++
 2 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/da9055.txt

^ permalink raw reply

* Re: [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Russell King - ARM Linux @ 2014-02-13 10:42 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Ulf Hansson, Tomasz Figa, Tomasz Figa, Olof Johansson, linux-mmc,
	devicetree, linux-arm-kernel@lists.infradead.org, robh+dt,
	mark.rutland, Pawel Moll, Ian Campbell, Kumar Gala, Chris Ball,
	Sascha Hauer, Fabio Estevam
In-Reply-To: <201401281148.10670.arnd@arndb.de>

On Tue, Jan 28, 2014 at 11:48:10AM +0100, Arnd Bergmann wrote:
> I think there is another option, which does have its own pros and cons:
> We could move all the power handling back into the sdio function driver
> if we allow a secondary detection path using DT rather than the probing
> of the SDIO bus.

No thanks.

What if we have a platform where things subtly change, like for instance,
the wiring on the SD slot to fix a problem with UHS-1 cards, which means
you don't have UHS-1 support for some platforms but do for others.

What if you have a platform which uses a brcm4329 chip for Wifi, but then
later in the production run switch to using a different Wifi chipset?

With this information encoded into DT, the number of DT files quickly
increases, and then this presents its own problem - how do users get to
know which DT file should be used for their platform when all they see
externally is "a product of type A"?

Let's say that the board folk were kind enough to set some kind of
identifing feature for the first but not the second (why would they,
it's probe-able, damn it).

The "we can do it in DT" approach just makes things unnecessarily more
difficult from the _user_ and _hardware_ point of view.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* Re: [PATCH 0/3] RFC/RFT: Powering on MMC Wifi/BT modules in MMC core
From: Russell King - ARM Linux @ 2014-02-13 10:36 UTC (permalink / raw)
  To: Olof Johansson, Chris Ball
  Cc: mark.rutland, devicetree, pawel.moll, linux-mmc, robh+dt,
	ijc+devicetree, galak, linux-arm-kernel
In-Reply-To: <20140201161420.GA26684@n2100.arm.linux.org.uk>

Any comments on this?

On Sat, Feb 01, 2014 at 04:14:20PM +0000, Russell King - ARM Linux wrote:
> On Thu, Jan 30, 2014 at 09:49:17PM +0000, Russell King - ARM Linux wrote:
> > On Sun, Jan 19, 2014 at 07:56:52PM -0800, Olof Johansson wrote:
> > > This is a small series enhancing the MMC core code to power on modules
> > > before the host in cases where needed, and the corresponding DT bindings
> > > changes.
> > > 
> > > I've got some other issues to debug on the Chromebook, i.e. the interface
> > > doens't actually work. So far it seems unrelated to this patch set so
> > > it's worth posting this and get things going since others need the same
> > > functionality (i.e Cubox-i).
> > > 
> > > As mentioned in the patch in the series, I haven't implemented power-down
> > > yet, I wanted to make sure that the power-on side will be adequate for
> > > those who are looking to use it right away.
> > > 
> > > Comments/test reports/etc welcome.
> > 
> > So, I thought I'd give this a go on the Cubox-i4, and... it doesn't work
> > there.  It's not your patches, it's down to sdhci-esdhc-imx.c not using
> > mmc_of_parse() at all, so those new properties have no way to be used
> > there.
> > 
> > It doesn't look like it could in its current form use mmc_of_parse(),
> > as the imx code manually parses some of the generic properties to hand
> > them into the sdhci layer.  This looks icky, and it looks like something
> > that should be fixed - why should drivers be parsing the core attributes
> > themselves?
> 
> Here's an illustration of why it's icky.
> 
> If we call mmc_of_parse() in the sdhci-esdhc-imx driver (which we'd need to
> do in order to get information on how to configure the card detection etc)
> then this fills in mmc->f_max.
> 
> However, the subsequent call to sdhci_add_host() computes the maximum clock
> from the sdhci capabilities, and then does this:
> 
>         host->max_clk *= 1000000;
>         if (host->max_clk == 0 || host->quirks &
>                         SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) {
>                 if (!host->ops->get_max_clock) {
>                         pr_err("%s: Hardware doesn't specify base clock "
>                                "frequency.\n", mmc_hostname(mmc));
>                         return -ENODEV;
>                 }
>                 host->max_clk = host->ops->get_max_clock(host);
>         }
> ...
>         /*
>          * Set host parameters.
>          */
>         mmc->ops = &sdhci_ops;
>         mmc->f_max = host->max_clk;
> 
> which would have the effect of overwriting a previously set f_max from
> the OF data.
> 
> There's also the whole "cd-gpios" thing which would need sorting out -
> the imx sdhci driver already parses this property itself, and sets its
> own internal data (so it knows whether it has to use the controller
> based card detect or the gpio card detect) and simply adding a call to
> mmc_of_parse() would result in the gpio slot stuff being setup twice.
> 
> The obvious solution here is to rewrite the sdhci initialisation such
> that it uses the generic infrastructure, but I don't have the motivation
> to do that (I've already plenty of patches to deal with that I don't
> need any more at the moment.)
> 
> A simpler solution would be to split mmc_of_parse() so that the new bits
> are a separate function, which the generic MMC core always calls for
> every host - taking the decision over whether this is supported completely
> away from hosts.  I think that makes a lot of sense, especially as this
> has nothing to do with the facilities found on any particular host.
> 
> There's another issue here about resets.  Let's take the case where the
> external card is powered off, but has active high resets.  At the moment,
> the sequence is this:
> 
> power: _____/~~~~~~~~~~~~
> reset: __/~~~~\__________
> 
> That's not particularly nice, as the reset signal will tend do drive power
> into the device before it's powered up via the clamping diodes in the case.
> Generally, devices are not designed to be powered in this way.  However,
> this is a relatively minor issue though compared to this one, which is what
> happens if the card uses active low reset:
> 
> power: _____/~~~~~~~~~~~~
> reset: ~~\_____/~~~~~~~~~
> 
> This is definitely not good, because it means that the reset is higher for
> longer, which may result in unacceptable dissapation in the package from
> those clamping diodes.  What we need instead is for active low reset is:
> 
> power: _____/~~~~~~~~~~~~
> reset: ________/~~~~~~~~~
> 
> So, we need the GPIO layer to tell us whether the output is active high or
> active low and adjust the initial setting accordingly.  Basically, whenever
> the attached device is powered down, GPIOs to it should be held at low level
> or high impedance (with a pull-down to reduce the risks of ESD damage.)
> 
> I've seen designs get this wrong in the past - Intel Assabet is a good one
> where the UDA1341 audio codec ends up illuminating a LED by being powered
> not via it's supply pin, but by a CPLD output driving one of the I2S pins
> high.  The result is that the CPLD output sources quite a bit of current
> into the UDA1341, which then holds other pins on the SA1110 around mid-rail,
> which is the /worst/ thing you can do with CMOS.  Powering chips via their
> inputs is basically a big no-no.
> 
> So, I think something like the below is needed on top of your patches.
> Note that I added -EPROBE_DEFER handling too (which fixes a bug, because
> regulator_get() returns pointer-errors):
> 
>  drivers/mmc/core/host.c            | 90 +++++++++++++++++++++++++++-----------
>  1 files changed, 65 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index e6b850b3241f..64942eb495b6 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -316,7 +316,7 @@ int mmc_of_parse(struct mmc_host *host)
>  	u32 bus_width;
>  	bool explicit_inv_wp, gpio_inv_wp = false;
>  	enum of_gpio_flags flags;
> -	int i, len, ret, gpio;
> +	int len, ret, gpio;
>  
>  	if (!host->parent || !host->parent->of_node)
>  		return 0;
> @@ -419,30 +419,6 @@ int mmc_of_parse(struct mmc_host *host)
>  	if (explicit_inv_wp ^ gpio_inv_wp)
>  		host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
>  
> -	/* Parse card power/reset/clock control */
> -	if (of_find_property(np, "card-reset-gpios", NULL)) {
> -		struct gpio_desc *gpd;
> -		for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
> -			gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
> -			if (IS_ERR(gpd))
> -				break;
> -			gpiod_direction_output(gpd, 0);
> -			host->card_reset_gpios[i] = gpd;
> -		}
> -
> -		gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
> -		if (!IS_ERR(gpd)) {
> -			dev_warn(host->parent, "More reset gpios than we can handle");
> -			gpiod_put(gpd);
> -		}
> -	}
> -
> -	host->card_clk = of_clk_get_by_name(np, "card_ext_clock");
> -	if (IS_ERR(host->card_clk))
> -		host->card_clk = NULL;
> -
> -	host->card_regulator = regulator_get(host->parent, "card-external-vcc");
> -
>  	if (of_find_property(np, "cap-sd-highspeed", &len))
>  		host->caps |= MMC_CAP_SD_HIGHSPEED;
>  	if (of_find_property(np, "cap-mmc-highspeed", &len))
> @@ -467,6 +443,66 @@ int mmc_of_parse(struct mmc_host *host)
>  
>  EXPORT_SYMBOL(mmc_of_parse);
>  
> +static int mmc_of_parse_child(struct mmc_host *host)
> +{
> +	struct device_node *np;
> +	struct clk *clk;
> +	int i;
> +
> +	if (!host->parent || !host->parent->of_node)
> +		return 0;
> +
> +	np = host->parent->of_node;
> +
> +	host->card_regulator = regulator_get(host->parent, "card-external-vcc");
> +	if (IS_ERR(host->card_regulator)) {
> +		if (PTR_ERR(host->card_regulator) == -EPROBE_DEFER)
> +			return PTR_ERR(host->card_regulator);
> +		host->card_regulator = NULL;
> +	}
> +
> +	/* Parse card power/reset/clock control */
> +	if (of_find_property(np, "card-reset-gpios", NULL)) {
> +		struct gpio_desc *gpd;
> +		int level = 0;
> +
> +		/*
> +		 * If the regulator is enabled, then we can hold the
> +		 * card in reset with an active high resets.  Otherwise,
> +		 * hold the resets low.
> +		 */
> +		if (host->card_regulator && regulator_is_enabled(host->card_regulator))
> +			level = 1;
> +
> +		for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
> +			gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
> +			if (IS_ERR(gpd)) {
> +				if (PTR_ERR(gpd) == -EPROBE_DEFER)
> +					return PTR_ERR(gpd);
> +				break;
> +			}
> +			gpiod_direction_output(gpd, gpiod_is_active_low(gpd) | level);
> +			host->card_reset_gpios[i] = gpd;
> +		}
> +
> +		gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
> +		if (!IS_ERR(gpd)) {
> +			dev_warn(host->parent, "More reset gpios than we can handle");
> +			gpiod_put(gpd);
> +		}
> +	}
> +
> +	clk = of_clk_get_by_name(np, "card_ext_clock");
> +	if (IS_ERR(clk)) {
> +		if (PTR_ERR(clk) == -EPROBE_DEFER)
> +			return PTR_ERR(clk);
> +		clk = NULL;
> +	}
> +	host->card_clk = clk;
> +
> +	return 0;
> +}
> +
>  /**
>   *	mmc_alloc_host - initialise the per-host structure.
>   *	@extra: sizeof private data structure
> @@ -546,6 +582,10 @@ int mmc_add_host(struct mmc_host *host)
>  {
>  	int err;
>  
> +	err = mmc_of_parse_child(host);
> +	if (err)
> +		return err;
> +
>  	WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
>  		!host->ops->enable_sdio_irq);
>  
> 
> -- 
> FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
> in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
> Estimate before purchase was "up to 13.2Mbit".
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* Re: [PATCH net-next v2 06/10] net: bcmgenet: add main driver file
From: Francois Romieu @ 2014-02-13 10:35 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: netdev, davem, cernekee, devicetree
In-Reply-To: <1392269395-23513-7-git-send-email-f.fainelli@gmail.com>

Florian Fainelli <f.fainelli@gmail.com> :
[...]
> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> new file mode 100644
> index 0000000..ab71e81
> --- /dev/null
> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
[...]
> +static int bcmgenet_set_rx_csum(struct net_device *dev,
> +				netdev_features_t wanted)
> +{
> +	struct bcmgenet_priv *priv = netdev_priv(dev);
> +	u32 rbuf_chk_ctrl;
> +	int rx_csum_en;
> +
> +	rx_csum_en = !!(wanted & NETIF_F_RXCSUM);

It's a bool.

> +
> +	spin_lock_bh(&priv->bh_lock);
> +	rbuf_chk_ctrl = bcmgenet_rbuf_readl(priv, RBUF_CHK_CTRL);
> +
> +	/* enable rx checksumming */
> +	if (!rx_csum_en)
> +		rbuf_chk_ctrl &= ~RBUF_RXCHK_EN;
> +	else
> +		rbuf_chk_ctrl |= RBUF_RXCHK_EN;
> +	priv->desc_rxchk_en = rx_csum_en;
> +	bcmgenet_rbuf_writel(priv, rbuf_chk_ctrl, RBUF_CHK_CTRL);
> +
> +	spin_unlock_bh(&priv->bh_lock);
> +
> +	return 0;
> +}
> +static int bcmgenet_set_tx_csum(struct net_device *dev,

Missing empty line.

[...]
> +static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv)
> +{
> +	int i, j = 0;
> +
> +	for (i = 0; i < BCMGENET_STATS_LEN; i++) {
> +		const struct bcmgenet_stats *s;
> +		u32 val = 0;
> +		char *p;
> +		u8 offset = 0;

Xmas tree please.

[...]
> +static void bcmgenet_get_ethtool_stats(struct net_device *dev,
> +					struct ethtool_stats *stats,
> +					u64 *data)
> +{
> +	struct bcmgenet_priv *priv = netdev_priv(dev);
> +	int i;
> +
> +	mutex_lock(&priv->mib_mutex);
> +	if (netif_running(dev))
> +		bcmgenet_update_mib_counters(priv);
> +
> +	for (i = 0; i < BCMGENET_STATS_LEN; i++) {
> +		const struct bcmgenet_stats *s;
> +		char *p;
> +
> +		s = &bcmgenet_gstrings_stats[i];
> +		if (s->type == BCMGENET_STAT_NETDEV)
> +			p = (char *)&dev->stats;
> +		else
> +			p = (char *)priv;
> +		p += s->stat_offset;
> +		data[i] = *(u32 *)p;
> +	}
> +	mutex_unlock(&priv->mib_mutex);

The mutex is not used anywhere else and dev_ethtool runs under RTNL.

[...]
> +/* Assign skb to RX DMA descriptor. */
> +static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv)
> +{
> +	struct enet_cb *cb;

Wrong scope.

> +	int ret = 0;
> +	int i;
> +	u32 reg;
> +
> +	netif_dbg(priv, hw, priv->dev, "%s:\n", __func__);
> +
> +	/* This function may be called from irq bottom-half. */
> +	spin_lock_bh(&priv->bh_lock);

The Rx part of the NAPI handler directly calls bcmgenet_rx_refill through
bcmgenet_desc_rx. bcmgenet_poll does not sync with bh_lock.

Either some factoring was forgotten or some legacy locking / comment was
left in place (there should not be any ->open vs ->poll race)

> +
> +	/* loop here for each buffer needing assign */
> +	for (i = 0; i < priv->num_rx_bds; i++) {
> +		cb = &priv->rx_cbs[priv->rx_bd_assign_index];
> +		if (cb->skb)
> +			continue;
> +
> +		/* set the DMA descriptor length once and for all
> +		 * it will only change if we support dynamically sizing
> +		 * priv->rx_buf_len, but we do not
> +		 */
> +		dmadesc_set_length_status(priv, priv->rx_bd_assign_ptr,
> +				priv->rx_buf_len << DMA_BUFLENGTH_SHIFT);
> +
> +		ret = bcmgenet_rx_refill(priv, cb);
> +		if (ret)
> +			break;
> +
> +	}
> +
> +	/* Enable rx DMA incase it was disabled due to running out of rx BD */

Nit: nothing proves even a single descriptor suceeded allocation.

[...]
> +static int reset_umac(struct bcmgenet_priv *priv)
> +{
> +	struct device *kdev = &priv->pdev->dev;
> +	unsigned int timeout = 0;
> +	u32 reg;
> +
> +	/* 7358a0/7552a0: bad default in RBUF_FLUSH_CTRL.umac_sw_rst */
> +	bcmgenet_rbuf_ctrl_set(priv, 0);
> +	udelay(10);
> +
> +	/* disable MAC while updating its registers */
> +	bcmgenet_umac_writel(priv, 0, UMAC_CMD);
> +
> +	/* issue soft reset, wait for it to complete */
> +	bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD);
> +	while (timeout++ < 1000) {
> +		reg = bcmgenet_umac_readl(priv, UMAC_CMD);
> +		if (!(reg & CMD_SW_RESET))
> +			break;

			return 0;

> +		udelay(1);
> +	}
> +
> +	if (timeout == 1000) {
> +		dev_err(kdev,
> +			"timeout waiting for MAC to come out of resetn\n");
> +		return -ETIMEDOUT;
> +	}
> +
> +	return 0;
> +}
> +
> +/* init_umac: Initializes the uniMac controller */

Useless.

> +static int init_umac(struct bcmgenet_priv *priv)
> +{
[...]
> +static void bcmgenet_init_multiq(struct net_device *dev)
> +{
> +	struct bcmgenet_priv *priv = netdev_priv(dev);
> +	unsigned int i, dma_enable;
> +	u32 reg, dma_ctrl, ring_cfg = 0, dma_priority = 0;
> +
> +	if (!netif_is_multiqueue(dev)) {
> +		netdev_warn(dev, "called with non multi queue aware HW\n");
> +		return;
> +	}
> +
> +	dma_ctrl = bcmgenet_tdma_readl(priv, DMA_CTRL);
> +	dma_enable = dma_ctrl & DMA_EN;
> +	dma_ctrl &= ~DMA_EN;
> +	bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL);
> +
> +	/* Enable strict priority arbiter mode */
> +	bcmgenet_tdma_writel(priv, DMA_ARBITER_SP, DMA_ARB_CTRL);
> +
> +	for (i = 0; i < priv->hw_params->tx_queues; i++) {
> +		/* first 64 tx_cbs are reserved for default tx queue
> +		 * (ring 16)
> +		 */
> +		bcmgenet_init_tx_ring(priv, i, priv->hw_params->bds_cnt,
> +					i * priv->hw_params->bds_cnt,
> +					(i + 1) * priv->hw_params->bds_cnt);
> +
> +		/* Configure ring as decriptor ring and setup priority */
> +		ring_cfg |= (1 << i);
> +		dma_priority |= ((GENET_Q0_PRIORITY + i) <<
> +				(GENET_MAX_MQ_CNT + 1) * i);
> +		dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));

Excess parenthesis.

[...]
> +/* NAPI polling method*/
> +static int bcmgenet_poll(struct napi_struct *napi, int budget)
> +{
> +	struct bcmgenet_priv *priv = container_of(napi,
> +			struct bcmgenet_priv, napi);
> +	unsigned int work_done;
> +
> +	work_done = bcmgenet_desc_rx(priv, budget);
> +
> +	/* tx reclaim */
> +	bcmgenet_tx_reclaim(priv->dev, &priv->tx_rings[DESC_INDEX]);

You may move the quick Tx reclaim before the slower Rx protocol processing.

> +	/* Advancing our consumer index*/
> +	priv->rx_c_index += work_done;
> +	priv->rx_c_index &= DMA_C_INDEX_MASK;
> +	bcmgenet_rdma_ring_writel(priv, DESC_INDEX,
> +				priv->rx_c_index, RDMA_CONS_INDEX);
> +	if (work_done < budget) {
> +		napi_complete(napi);
> +		bcmgenet_intrl2_0_writel(priv,
> +			UMAC_IRQ_RXDMA_BDONE, INTRL2_CPU_MASK_CLEAR);
> +	}
> +
> +	return work_done;
> +}
> +
> +/* Interrupt bottom half */
> +static void bcmgenet_irq_task(struct work_struct *work)
> +{
> +	struct bcmgenet_priv *priv = container_of(
> +			work, struct bcmgenet_priv, bcmgenet_irq_work);
> +	struct net_device *dev;

	struct net_device *dev = priv->dev;

> +	u32 reg;
> +
> +	dev = priv->dev;
> +
> +	netif_dbg(priv, intr, dev, "%s\n", __func__);
> +	/* Cable plugged/unplugged event */
> +	if (priv->phy_interface == PHY_INTERFACE_MODE_INTERNAL) {
> +		if (priv->irq0_stat & UMAC_IRQ_PHY_DET_R) {
> +			priv->irq0_stat &= ~UMAC_IRQ_PHY_DET_R;
> +			netif_crit(priv, link, dev,
> +				"cable plugged in, powering up\n");
> +			bcmgenet_power_up(priv, GENET_POWER_CABLE_SENSE);
> +		} else if (priv->irq0_stat & UMAC_IRQ_PHY_DET_F) {
> +			priv->irq0_stat &= ~UMAC_IRQ_PHY_DET_F;
> +			netif_crit(priv, link, dev,
> +				"cable unplugged, powering down\n");
> +			bcmgenet_power_down(priv, GENET_POWER_CABLE_SENSE);
> +		}
> +	}
> +	if (priv->irq0_stat & UMAC_IRQ_MPD_R) {
> +		priv->irq0_stat &= ~UMAC_IRQ_MPD_R;
> +		netif_crit(priv, wol, dev,
> +			"magic packet detected, waking up\n");
> +		/* disable mpd interrupt */
> +		bcmgenet_intrl2_0_writel(priv,
> +			UMAC_IRQ_MPD_R, INTRL2_CPU_MASK_SET);
> +		/* disable CRC forward.*/
> +		reg = bcmgenet_umac_readl(priv, UMAC_CMD);
> +		reg &= ~CMD_CRC_FWD;
> +		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
> +		priv->crc_fwd_en = 0;
> +		bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
> +
> +	} else if (priv->irq0_stat & (UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM)) {
> +		priv->irq0_stat &= ~(UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM);
> +		netif_crit(priv, wol, dev,
> +			"ACPI pattern matched, waking up\n");
> +		/* disable HFB match interrupts */
> +		bcmgenet_intrl2_0_writel(priv,
> +			UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM, INTRL2_CPU_MASK_SET);
> +		bcmgenet_power_up(priv, GENET_POWER_WOL_ACPI);
> +	}

It smells of half-backed wol / runtime power support. Imvho it deserves
some comment in the changelog message to hint about its maturity.

> +
> +	/* Link UP/DOWN event */
> +	if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
> +		(priv->irq0_stat & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) {
> +		if (priv->phydev)
> +			phy_mac_interrupt(priv->phydev,
> +				(priv->irq0_stat & UMAC_IRQ_LINK_UP));
> +		priv->irq0_stat &= ~(UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN);
> +	}
> +}
> +
> +/* bcmgenet_isr1: interrupt handler for ring buffer. */
> +static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
> +{
> +	struct bcmgenet_priv *priv = dev_id;
> +	unsigned int index;

Wrong scope.

> +
> +	/* Save irq status for bottom-half processing. */
> +	priv->irq1_stat =
> +		bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) &
> +		~priv->int1_mask;
> +	/* clear inerrupts*/
> +	bcmgenet_intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR);
> +
> +	netif_dbg(priv, intr, priv->dev,
> +		"%s: IRQ=0x%x\n", __func__, priv->irq1_stat);
> +	/* Check the MBDONE interrupts.
> +	 * packet is done, reclaim descriptors
> +	 */
> +	if (priv->irq1_stat & 0x0000ffff) {
> +		index = 0;
> +		for (index = 0; index < 16; index++) {

Proofread patrol alert :o)

(...]
> +static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
> +{
> +	int timeout = 0;
> +	u32 reg;
> +
> +	/* Disable TDMA to stop add more frames in TX DMA */
> +	reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
> +	reg &= ~DMA_EN;
> +	bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
> +
> +	/* Check TDMA status register to confirm TDMA is disabled */
> +	while (!(bcmgenet_tdma_readl(priv, DMA_STATUS) & DMA_DISABLED)) {
> +		if (timeout++ == 5000) {
> +			netdev_warn(priv->dev,
> +				"Timed out while disabling TX DMA\n");
> +			return -ETIMEDOUT;
> +		}
> +		udelay(1);
> +	}

On the stylistic side, the driver hesitates between "while", "for" timeout
and conditions loop. I'd go for the boring "int i; for (i = 0; i < max; i++)"
style but it's your call.

On the worrying side, even if Tx DMA does not stop, the driver should
try to disable Rx DMA.

> +
> +	/* Wait 10ms for packet drain in both tx and rx dma */
> +	usleep_range(10000, 20000);
> +
> +	/* Disable RDMA */
> +	reg = bcmgenet_rdma_readl(priv, DMA_CTRL);
> +	reg &= ~DMA_EN;
> +	bcmgenet_rdma_writel(priv, reg, DMA_CTRL);
> +
> +	timeout = 0;
> +	/* Check RDMA status register to confirm RDMA is disabled */
> +	while (!(bcmgenet_rdma_readl(priv, DMA_STATUS) & DMA_DISABLED)) {
> +		if (timeout++ == 5000) {
> +			netdev_warn(priv->dev,
> +				"Timed out while disabling RX DMA\n");
> +			return -ETIMEDOUT;
> +		}
> +		udelay(1);
> +	}
> +
> +	return 0;
> +}
[...]
> +static void bcmgenet_timeout(struct net_device *dev)
> +{
> +	struct bcmgenet_priv *priv = netdev_priv(dev);
> +
> +	BUG_ON(dev == NULL);

dev == NULL should be noticed quickly.

> +
> +	netif_dbg(priv, tx_err, dev, "bcmgenet_timeout\n");
> +
> +	dev->trans_start = jiffies;
> +
> +	dev->stats.tx_errors++;
> +
> +	netif_tx_wake_all_queues(dev);

dev_watchdog already complains (loudly).

Is it really supposed to recover ?

> +}
> +
> +#define MAX_MC_COUNT	16
> +
> +static inline void bcmgenet_set_mdf_addr(struct bcmgenet_priv *priv,
> +					 unsigned char *addr,
> +					 int *i,
> +					 int *mc)
> +{
> +	u32 reg;
> +
> +	bcmgenet_umac_writel(priv, addr[0] << 8 | addr[1],
> +			UMAC_MDF_ADDR + (*i * 4));
> +	bcmgenet_umac_writel(priv,
> +			addr[2] << 24 | addr[3] << 16 |
> +			addr[4] << 8 | addr[5],
> +			UMAC_MDF_ADDR + ((*i + 1) * 4));

I would not expect such an indent to pass beyond davem.

> +	reg = bcmgenet_umac_readl(priv, UMAC_MDF_CTRL);
> +	reg |= (1 << (MAX_MC_COUNT - *mc));
> +	bcmgenet_umac_writel(priv, reg, UMAC_MDF_CTRL);
> +	*i += 2;
> +	(*mc)++;
> +}
> +
> +static void bcmgenet_set_rx_mode(struct net_device *dev)
> +{
> +	struct bcmgenet_priv *priv = netdev_priv(dev);
> +	struct netdev_hw_addr *ha;
> +	int i, mc;
> +	u32 reg;
> +
> +	netif_dbg(priv, hw, dev, "%s: %08X\n", __func__, dev->flags);
> +
> +	/* Promiscous mode */
> +	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
> +	if (dev->flags & IFF_PROMISC) {
> +		reg |= CMD_PROMISC;
> +		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
> +		bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL);
> +		return;
> +	} else {
> +		reg &= ~CMD_PROMISC;
> +		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
> +	}
> +
> +	/* UniMac doesn't support ALLMULTI */
> +	if (dev->flags & IFF_ALLMULTI)
> +		return;

The driver did not fulfill the request. It could complain to help user.

[...]
> +static int bcmgenet_set_mac_addr(struct net_device *dev, void *p)
> +{
> +	struct sockaddr *addr = p;
> +
> +	if (netif_running(dev))
> +		return -EBUSY;

Add a comment to specify if it is a hardware shortcoming or something else ?

> +
> +	ether_addr_copy(dev->dev_addr, addr->sa_data);
> +
> +	return 0;
> +}

[...]
> +static const struct net_device_ops bcmgenet_netdev_ops = {
> +	.ndo_open = bcmgenet_open,
> +	.ndo_stop = bcmgenet_close,
> +	.ndo_start_xmit = bcmgenet_xmit,
> +	.ndo_select_queue = bcmgenet_select_queue,
> +	.ndo_tx_timeout = bcmgenet_timeout,
> +	.ndo_set_rx_mode = bcmgenet_set_rx_mode,
> +	.ndo_set_mac_address = bcmgenet_set_mac_addr,
> +	.ndo_do_ioctl = bcmgenet_ioctl,
> +	.ndo_set_features = bcmgenet_set_features,
> +};

Please use tabs before '=' to line things up.

[...]
> +static int bcmgenet_probe(struct platform_device *pdev)
> +{
> +	struct device_node *dn = pdev->dev.of_node;
> +	struct bcmgenet_priv *priv;
> +	struct net_device *dev;
> +	const void *macaddr;
> +	struct resource *r;
> +	int err = -EIO;
> +
> +	/* Up to GENET_MAX_MQ_CNT + 1 TX queues and a single RX queue */
> +	dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, 1);
> +	if (!dev) {
> +		dev_err(&pdev->dev, "can't allocate net device\n");
> +		return -ENOMEM;
> +	}
> +
> +	priv = netdev_priv(dev);
> +	priv->irq0 = platform_get_irq(pdev, 0);
> +	priv->irq1 = platform_get_irq(pdev, 1);
> +	if (!priv->irq0 || !priv->irq1) {
> +		dev_err(&pdev->dev, "can't find IRQs\n");
> +		err = -EINVAL;
> +		goto err;
> +	}
> +
> +	macaddr = of_get_mac_address(dn);
> +	if (!macaddr) {
> +		dev_err(&pdev->dev, "can't find MAC address\n");
> +		err = -EINVAL;
> +		goto err;
> +	}
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	priv->base = devm_request_and_ioremap(&pdev->dev, r);
> +	if (!priv->base) {
> +		dev_err(&pdev->dev, "can't ioremap\n");
> +		err = -EINVAL;
> +		goto err;
> +	}
> +
> +	dev->base_addr = (unsigned long)priv->base;

base_addr in net_device is a legacy hack.

> +	SET_NETDEV_DEV(dev, &pdev->dev);
> +	dev_set_drvdata(&pdev->dev, dev);
> +	ether_addr_copy(dev->dev_addr, macaddr);
> +	dev->irq = priv->irq0;

And so is irq.

-- 
Ueimor

^ permalink raw reply

* Re: [PATCH net-next v2 04/10] net: phy: add Broadcom BCM7xxx internal PHY driver
From: Francois Romieu @ 2014-02-13 10:34 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: netdev, davem, cernekee, devicetree
In-Reply-To: <1392269395-23513-5-git-send-email-f.fainelli@gmail.com>

Florian Fainelli <f.fainelli@gmail.com> :
[...]
> diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
> new file mode 100644
> index 0000000..6aea6e2
> --- /dev/null
> +++ b/drivers/net/phy/bcm7xxx.c
[...]
> +static int bcm7445_config_init(struct phy_device *phydev)
> +{
> +	int ret;

It could be declared after 'i' below.

> +	const struct bcm7445_regs {

static const

> +		int reg;
> +		u16 value;
> +	} bcm7445_regs_cfg[] = {
> +		/* increases ADC latency by 24ns */
> +		{ 0x17, 0x0038 },
> +		{ 0x15, 0xAB95 },
> +		/* increases internal 1V LDO voltage by 5% */
> +		{ 0x17, 0x2038 },
> +		{ 0x15, 0xBB22 },
> +		/* reduce RX low pass filter corner frequency */
> +		{ 0x17, 0x6038 },
> +		{ 0x15, 0xFFC5 },
> +		/* reduce RX high pass filter corner frequency */
> +		{ 0x17, 0x003a },
> +		{ 0x15, 0x2002 },
> +	};
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(bcm7445_regs_cfg); i++) {
> +		ret = phy_write(phydev,
> +				bcm7445_regs_cfg[i].reg,
> +				bcm7445_regs_cfg[i].value);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static void phy_write_exp(struct phy_device *phydev,
> +					u16 reg, u16 value)

static void phy_write_exp(struct phy_device *phydev, u16 reg, u16 value)

> +{
> +	phy_write(phydev, 0x17, 0xf00 | reg);
> +	phy_write(phydev, 0x15, value);
> +}
> +
> +static void phy_write_misc(struct phy_device *phydev,
> +					u16 reg, u16 chl, u16 value)
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ all tabs that don't line up

static void phy_write_misc(struct phy_device *phydev,
			   u16 reg, u16 chl, u16 value)

static void phy_write_misc(struct phy_device *phydev, u16 reg, u16 chl,
			   u16 value)

static void phy_write_misc(struct phy_device *phydev, u16 reg, u16 chl, u16 val)


> +{
> +	int tmp;
> +
> +	phy_write(phydev, 0x18, 0x7);
> +
> +	tmp = phy_read(phydev, 0x18);
> +	tmp |= 0x800;
> +	phy_write(phydev, 0x18, tmp);
> +
> +	tmp = (chl * 0x2000) | reg;
> +	phy_write(phydev, 0x17, tmp);
> +
> +	phy_write(phydev, 0x15, value);

You may use some #define for the 0x15, 0x17 and 0x18 values.

> +}
> +
> +static int bcm7xxx_28nm_afe_config_init(struct phy_device *phydev)
> +{
> +	/* write AFE_RXCONFIG_0 */
> +	phy_write_misc(phydev, 0x38, 0x0000, 0xeb19);
> +
> +	/* write AFE_RXCONFIG_1 */
> +	phy_write_misc(phydev, 0x38, 0x0001, 0x9a3f);
> +
> +	/* write AFE_RX_LP_COUNTER */
> +	phy_write_misc(phydev, 0x38, 0x0003, 0x7fc7);
> +
> +	/* write AFE_HPF_TRIM_OTHERS */
> +	phy_write_misc(phydev, 0x3A, 0x0000, 0x000b);
> +
> +	/* write AFTE_TX_CONFIG */
> +	phy_write_misc(phydev, 0x39, 0x0000, 0x0800);

Some #define may be welcome to replace the comments.

[...]
> +static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
> +{
> +	int ret;
> +
> +	ret = bcm7445_config_init(phydev);
> +	if (ret)
> +		return ret;
> +
> +	return bcm7xxx_28nm_afe_config_init(phydev);
> +}
> +
> +static int phy_set_clr_bits(struct phy_device *dev, int location,
> +					int set_mask, int clr_mask)
> +{
> +	int v, ret;
> +
> +	v = phy_read(dev, location);
> +	if (v < 0)
> +		return v;
> +
> +	v &= ~clr_mask;
> +	v |= set_mask;
> +
> +	ret = phy_write(dev, location, v);
> +	if (ret < 0)
> +		return ret;
> +
> +	return v;
> +}
> +
> +static int bcm7xxx_config_init(struct phy_device *phydev)
> +{
> +	/* Enable 64 clock MDIO */
> +	phy_write(phydev, 0x1d, 0x1000);
> +	phy_read(phydev, 0x1d);
> +
> +	/* Workaround only required for 100Mbits/sec */
> +	if (!(phydev->dev_flags & PHY_BRCM_100MBPS_WAR))
> +		return 0;
> +
> +	/* set shadow mode 2 */
> +	phy_set_clr_bits(phydev, 0x1f, 0x0004, 0x0004);

phy_set_clr_bits returned status code is not checked.

> +
> +	/* set iddq_clkbias */
> +	phy_write(phydev, 0x14, 0x0F00);
> +	udelay(10);
> +
> +	/* reset iddq_clkbias */
> +	phy_write(phydev, 0x14, 0x0C00);
> +
> +	phy_write(phydev, 0x13, 0x7555);
> +
> +	/* reset shadow mode 2 */
> +	phy_set_clr_bits(phydev, 0x1f, 0x0004, 0);

phy_set_clr_bits returned status code is not checked.

> +
> +	return 0;
> +}
> +
> +/* Workaround for putting the PHY in IDDQ mode, required
> + * for all BCM7XXX PHYs
> + */
> +static int bcm7xxx_suspend(struct phy_device *phydev)

Factor out with bcm7445_config_init and some helper ?

> +{
> +	int ret;
> +	const struct bcm7xxx_regs {
> +		int reg;
> +		u16 value;
> +	} bcm7xxx_suspend_cfg[] = {
> +		{ 0x1f, 0x008b },
> +		{ 0x10, 0x01c0 },
> +		{ 0x14, 0x7000 },
> +		{ 0x1f, 0x000f },
> +		{ 0x10, 0x20d0 },
> +		{ 0x1f, 0x000b },
> +	};
> +	unsigned int i;

-- 
Ueimor

^ permalink raw reply

* Re: [PATCH] dt: platform driver: Fill the resources before probe and defer if needed
From: Jean-Jacques Hiblot @ 2014-02-13 10:06 UTC (permalink / raw)
  To: Jean-Jacques Hiblot
  Cc: gregkh, grant.likely, robh+dt, Linux Kernel Mailing List,
	devicetree, Gregory CLEMENT, linux-arm-kernel@lists.infradead.org
In-Reply-To: <1392285429-9325-1-git-send-email-jjhiblot@traphandler.com>

Hi all,

I forgot to add the link to the discussion that lead to this patch:
https://lkml.org/lkml/2014/2/12/306.

Jean-Jacques

2014-02-13 10:57 GMT+01:00 Jean-Jacques Hiblot <jjhiblot@traphandler.com>:
> The goal of this patch is to allow drivers to be probed even if at the time of
> the DT parsing some of their ressources are not available yet.
>
> In the current situation, the resource of a platform device are filled from the
> DT at the time the device is created (of_device_alloc()). The drawbackof this
> is that a device sitting close to the top of the DT (ahb for example) but
> depending on ressources that are initialized later (IRQ domain dynamically
> created for example)  will fail to probe because the ressources don't exist
> at this time.
>
> This patch fills the resource structure only before the device is probed and
> will defer the probe if the resource are not available yet.
>
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  drivers/base/platform.c     |  6 ++++
>  drivers/of/platform.c       | 71 +++++++++++++++++++++++++++++----------------
>  include/linux/of_platform.h | 10 +++++++
>  3 files changed, 62 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index bc78848..8e37d8b 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -481,6 +481,12 @@ static int platform_drv_probe(struct device *_dev)
>         struct platform_device *dev = to_platform_device(_dev);
>         int ret;
>
> +       if (_dev->of_node) {
> +               ret = of_platform_device_populate_resources(dev);
> +               if (ret < 0)
> +                       return drv->prevent_deferred_probe ? ret : -EPROBE_DEFER;
> +       }
> +
>         if (ACPI_HANDLE(_dev))
>                 acpi_dev_pm_attach(_dev, true);
>
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 404d1da..64a8eb8 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -141,36 +141,11 @@ struct platform_device *of_device_alloc(struct device_node *np,
>                                   struct device *parent)
>  {
>         struct platform_device *dev;
> -       int rc, i, num_reg = 0, num_irq;
> -       struct resource *res, temp_res;
>
>         dev = platform_device_alloc("", -1);
>         if (!dev)
>                 return NULL;
>
> -       /* count the io and irq resources */
> -       if (of_can_translate_address(np))
> -               while (of_address_to_resource(np, num_reg, &temp_res) == 0)
> -                       num_reg++;
> -       num_irq = of_irq_count(np);
> -
> -       /* Populate the resource table */
> -       if (num_irq || num_reg) {
> -               res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
> -               if (!res) {
> -                       platform_device_put(dev);
> -                       return NULL;
> -               }
> -
> -               dev->num_resources = num_reg + num_irq;
> -               dev->resource = res;
> -               for (i = 0; i < num_reg; i++, res++) {
> -                       rc = of_address_to_resource(np, i, res);
> -                       WARN_ON(rc);
> -               }
> -               WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq);
> -       }
> -
>         dev->dev.of_node = of_node_get(np);
>  #if defined(CONFIG_MICROBLAZE)
>         dev->dev.dma_mask = &dev->archdata.dma_mask;
> @@ -233,6 +208,52 @@ static struct platform_device *of_platform_device_create_pdata(
>         return dev;
>  }
>
> +int of_platform_device_populate_resources(struct platform_device *dev)
> +{
> +       struct device_node *np;
> +       int rc = 0, i, nreg = 0, nirq;
> +
> +       np = dev->dev.of_node;
> +
> +       /* count the io and irq resources */
> +       if (of_can_translate_address(np)) {
> +               struct resource temp_res;
> +               while (of_address_to_resource(np, nreg, &temp_res) == 0)
> +                       nreg++;
> +       }
> +       nirq = of_irq_count(np);
> +
> +       /* Populate the resource table */
> +       if (nirq || nreg) {
> +               struct resource *res;
> +
> +               res = krealloc(dev->resource, sizeof(*res) * (nirq + nreg),
> +                              GFP_KERNEL);
> +               if (!res) {
> +                       kfree(dev->resource);
> +                       dev->resource = NULL;
> +                       return -ENOMEM;
> +               }
> +               memset(res, 0, sizeof(*res) * (nirq + nreg));
> +               dev->resource = res;
> +               dev->num_resources = nreg + nirq;
> +
> +               for (i = 0; i < nreg; i++, res++) {
> +                       rc = of_address_to_resource(np, i, res);
> +                       WARN_ON(rc);
> +                       if (rc)
> +                               break;
> +               }
> +
> +               if (!rc && of_irq_to_resource_table(np, res, nirq) != nirq) {
> +                       rc = -ENOENT;
> +                       WARN_ON(rc);
> +               }
> +       }
> +       return rc;
> +}
> +EXPORT_SYMBOL(of_platform_device_populate_resources);
> +
>  /**
>   * of_platform_device_create - Alloc, initialize and register an of_device
>   * @np: pointer to node to create device for
> diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
> index 05cb4a9..315e1e3 100644
> --- a/include/linux/of_platform.h
> +++ b/include/linux/of_platform.h
> @@ -53,6 +53,16 @@ struct of_dev_auxdata {
>
>  extern const struct of_device_id of_default_bus_match_table[];
>
> +/* Populate the resource for a platform device */
> +#ifdef CONFIG_OF
> +int of_platform_device_populate_resources(struct platform_device *dev);
> +#else
> +static inline int of_platform_device_populate_resources(
> +       struct platform_device *)
> +{
> +       return -ENOSYS;
> +}
> +#endif
>  /* Platform drivers register/unregister */
>  extern struct platform_device *of_device_alloc(struct device_node *np,
>                                          const char *bus_id,
> --
> 1.8.5.3
>

^ permalink raw reply

* [PATCH] dt: platform driver: Fill the resources before probe and defer if needed
From: Jean-Jacques Hiblot @ 2014-02-13  9:57 UTC (permalink / raw)
  To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Jean-Jacques Hiblot

The goal of this patch is to allow drivers to be probed even if at the time of
the DT parsing some of their ressources are not available yet.

In the current situation, the resource of a platform device are filled from the
DT at the time the device is created (of_device_alloc()). The drawbackof this
is that a device sitting close to the top of the DT (ahb for example) but
depending on ressources that are initialized later (IRQ domain dynamically
created for example)  will fail to probe because the ressources don't exist
at this time.

This patch fills the resource structure only before the device is probed and
will defer the probe if the resource are not available yet.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot-dLKeG7h1OhBDOHtkgc7UlQ@public.gmane.org>
Reviewed-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/base/platform.c     |  6 ++++
 drivers/of/platform.c       | 71 +++++++++++++++++++++++++++++----------------
 include/linux/of_platform.h | 10 +++++++
 3 files changed, 62 insertions(+), 25 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index bc78848..8e37d8b 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -481,6 +481,12 @@ static int platform_drv_probe(struct device *_dev)
 	struct platform_device *dev = to_platform_device(_dev);
 	int ret;
 
+	if (_dev->of_node) {
+		ret = of_platform_device_populate_resources(dev);
+		if (ret < 0)
+			return drv->prevent_deferred_probe ? ret : -EPROBE_DEFER;
+	}
+
 	if (ACPI_HANDLE(_dev))
 		acpi_dev_pm_attach(_dev, true);
 
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 404d1da..64a8eb8 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -141,36 +141,11 @@ struct platform_device *of_device_alloc(struct device_node *np,
 				  struct device *parent)
 {
 	struct platform_device *dev;
-	int rc, i, num_reg = 0, num_irq;
-	struct resource *res, temp_res;
 
 	dev = platform_device_alloc("", -1);
 	if (!dev)
 		return NULL;
 
-	/* count the io and irq resources */
-	if (of_can_translate_address(np))
-		while (of_address_to_resource(np, num_reg, &temp_res) == 0)
-			num_reg++;
-	num_irq = of_irq_count(np);
-
-	/* Populate the resource table */
-	if (num_irq || num_reg) {
-		res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
-		if (!res) {
-			platform_device_put(dev);
-			return NULL;
-		}
-
-		dev->num_resources = num_reg + num_irq;
-		dev->resource = res;
-		for (i = 0; i < num_reg; i++, res++) {
-			rc = of_address_to_resource(np, i, res);
-			WARN_ON(rc);
-		}
-		WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq);
-	}
-
 	dev->dev.of_node = of_node_get(np);
 #if defined(CONFIG_MICROBLAZE)
 	dev->dev.dma_mask = &dev->archdata.dma_mask;
@@ -233,6 +208,52 @@ static struct platform_device *of_platform_device_create_pdata(
 	return dev;
 }
 
+int of_platform_device_populate_resources(struct platform_device *dev)
+{
+	struct device_node *np;
+	int rc = 0, i, nreg = 0, nirq;
+
+	np = dev->dev.of_node;
+
+	/* count the io and irq resources */
+	if (of_can_translate_address(np)) {
+		struct resource temp_res;
+		while (of_address_to_resource(np, nreg, &temp_res) == 0)
+			nreg++;
+	}
+	nirq = of_irq_count(np);
+
+	/* Populate the resource table */
+	if (nirq || nreg) {
+		struct resource *res;
+
+		res = krealloc(dev->resource, sizeof(*res) * (nirq + nreg),
+			       GFP_KERNEL);
+		if (!res) {
+			kfree(dev->resource);
+			dev->resource = NULL;
+			return -ENOMEM;
+		}
+		memset(res, 0, sizeof(*res) * (nirq + nreg));
+		dev->resource = res;
+		dev->num_resources = nreg + nirq;
+
+		for (i = 0; i < nreg; i++, res++) {
+			rc = of_address_to_resource(np, i, res);
+			WARN_ON(rc);
+			if (rc)
+				break;
+		}
+
+		if (!rc && of_irq_to_resource_table(np, res, nirq) != nirq) {
+			rc = -ENOENT;
+			WARN_ON(rc);
+		}
+	}
+	return rc;
+}
+EXPORT_SYMBOL(of_platform_device_populate_resources);
+
 /**
  * of_platform_device_create - Alloc, initialize and register an of_device
  * @np: pointer to node to create device for
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 05cb4a9..315e1e3 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -53,6 +53,16 @@ struct of_dev_auxdata {
 
 extern const struct of_device_id of_default_bus_match_table[];
 
+/* Populate the resource for a platform device */
+#ifdef CONFIG_OF
+int of_platform_device_populate_resources(struct platform_device *dev);
+#else
+static inline int of_platform_device_populate_resources(
+	struct platform_device *)
+{
+	return -ENOSYS;
+}
+#endif
 /* Platform drivers register/unregister */
 extern struct platform_device *of_device_alloc(struct device_node *np,
 					 const char *bus_id,
-- 
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: [RFC] dt: bindings: add bindings for Broadcom bcm43xx sdio devices
From: Chen-Yu Tsai @ 2014-02-13  9:28 UTC (permalink / raw)
  To: Tomasz Figa; +Cc: Arend van Spriel, Rob Herring, devicetree, linux-kernel
In-Reply-To: <52FC8CB3.4090305-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Hi,

On Thu, Feb 13, 2014 at 5:13 PM, Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hi Arend,
>
>
> On 10.02.2014 20:17, Arend van Spriel wrote:
>>
>> The Broadcom bcm43xx sdio devices are fullmac devices that may be
>> integrated in ARM platforms. Currently, the brcmfmac driver for
>> these devices support use of platform data. This patch specifies
>> the bindings that allow this platform data to be expressed in the
>> devicetree.
>>
>> Cc: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>> Cc: Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Reviewed-by: Hante Meuleman <meuleman-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
>> Reviewed-by: Pieter-Paul Giesberts <pieterpg-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
>> Signed-off-by: Arend van Spriel <arend-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
>> ---
>> This devicetree binding proposal is intended for platforms with
>> Broadcom wireless device in MMC sdio slot. These devices may
>> have their own interrupt and power line. Also the SDIO drive
>> strength is often hardware dependent and expressed in this
>> binding.
>>
>> Not sure if this should go in staging or not. Feel free to
>> comment on this proposal.
>>
>> Regards,
>> Arend
>> ---
>>   .../staging/net/wireless/brcm,bcm43xx-fmac.txt     |   37
>> ++++++++++++++++++++
>>   1 file changed, 37 insertions(+)
>>   create mode 100644
>> Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt
>>
>> diff --git
>> a/Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt
>> b/Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt
>> new file mode 100644
>> index 0000000..535f343
>> --- /dev/null
>> +++
>> b/Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt
>> @@ -0,0 +1,37 @@
>> +Broadcom BCM43xx Fullmac wireless SDIO devices
>> +
>> +This node provides properties for controlling the Broadcom wireless
>> device. The
>> +node is expected to be specified as a child node to the MMC controller
>> that
>> +connects the device to the system.
>> +
>> +Required properties:
>> +
>> + - compatible : Should be "brcm,bcm43xx-fmac".
>> + - wlan-supply : phandle for fixed regulator used to control power for
>> +       the device/module.
>
>
> The BCM43xx WLAN chips I used to work always have been controlled by a
> simple power enable GPIO of the chip itself. Has this changed in newer
> chips?

Actually some (I only have one kind) of the chips have 2 GPIO lines,
but they are almost always tied together in the module or on the
board.

> If you need to simply toggle a GPIO to control the power, you don't need to
> use the regulator API at all, controlling the GPIO directly.
>
>
>> +
>> +Optional properties:
>> + - drive-strength : drive strength used for SDIO pins on device (default
>> = 6mA).
>
>
> This should be a part of the MMC binding, I think. Probably also moved under
> MMC controller's node, since it's a board-specific property altering the
> parameters of the MMC controller, not the WLAN chip.

AFAIK, this controls the drive strength for MMC on the WLAN chip's MMC
controller.

>> + - interrupt-parent : the phandle for the interrupt controller to which
>> the
>> +       device interrupt (HOST_WAKE) is connected.
>> + - interrupts : interrupt specifier encoded according the interrupt
>> controller
>> +       specified by interrupt-parent property.
>
>
> I would also add a clock here, since the BCM43xx chips usually need a 32k
> clock to operate (or at least the ones I used to work with did). It can be
> optional, as not all systems can control this clock.

2, the main oscillator (MHz range) and the low power clock (32.768 KHz).
In the other thread, someone mentioned they had to enable the main
oscillator separately.

>> +
>> +Example:
>> +
>> +mmc3: mmc@01c20000 {
>> +       pinctrl-0 = <&mmc3_pins>;
>> +       pinctrl-1 = <&wifi_host_wake>;
>
>
> WLAN_HOST_WAKE pin (aka the OOB interrupt) is specific to the WLAN chip, so
> this should be rather configured in a pinctrl state of the WLAN chip itself.

AFAIK, the pinctrl in tied to the device node, and is selected when the device
is registered. The MMC subsystem currently does not register child nodes, so
this would be useless.

brcmfmac actually has to walk the whole DT to find the node with the right
compatible.

>> +       vmmc-supply = <&mmc3_supply>;
>> +       bus-width = <4>;
>> +
>> +       bcm4335: bcm4335@0 {
>
>
> nit: Why @0, if there is no reg property under this node?

Off chance that you have 2 or more nodes with the same name?
The node name should be more generic, too.

This brings about a different problem, how should driver in its current
state, differentiate between the two? And brcmfmac only supports one set
of platform data ATM.


Cheers
ChenYu


> Best regards,
> Tomasz
>
>
>> +               compatible = "brcm,bcm43xx-fmac";
>> +               wlan-supply = <&wlan-reg>;
>> +               drive-strength = <4>;
>> +               interrupt-parent = <&gpx2>;
>> +               interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
>> +               interrupt-names = "HOST_WAKE";
>> +       };
>> +};
>> +
>>
>
--
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

* [PATCH v2 12/14] Documentation: mfd/regulator: s2mps11: Document the "op_mode" bindings
From: Krzysztof Kozlowski @ 2014-02-13  9:14 UTC (permalink / raw)
  To: Sangbeom Kim, Samuel Ortiz, Lee Jones, linux-kernel,
	linux-samsung-soc
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Krzysztof Kozlowski, Chanwoo Choi, Mark Brown, Liam Girdwood,
	Tomasz Figa, devicetree, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala
In-Reply-To: <1392282847-25444-1-git-send-email-k.kozlowski@samsung.com>

Document the "op_mode" properties parsed from DTS by s2mps11 driver.

S2MPS11/S2MPS14 regulators support different modes of operation:
 - Always off;
 - On/Off controlled by pin/GPIO (PWREN/LDOEN/EMMCEN);
 - Always on;

This is very similar to S5M8767 regulator driver which also supports
opmodes (although S5M8767 have also low-power mode).

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Tomasz Figa <t.figa@samsung.com>
Cc: devicetree@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
---
 Documentation/devicetree/bindings/mfd/s2mps11.txt |   46 +++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
index f69bec294f02..ffad6bfe2ebf 100644
--- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
+++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
@@ -54,6 +54,15 @@ BUCK[3, 4], and BUCK[7, 8, 10]
 The regulator constraints inside the regulator nodes use the standard regulator
 bindings which are documented elsewhere.
 
+On S2MPS14 chipset the driver additionally supports "op_mode" properties for
+each regulator.
+ - op_mode: describes the different operating modes of the regulators with
+	power mode change in SOC. The different possible values are,
+		0 - always off mode
+		1 - on in normal mode
+		3 - suspend mode
+		(NOTE: value of 2 is reserved)
+
 The following are the names of the regulators that the s2mps11 pmic block
 supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
 as per the datasheet of s2mps11.
@@ -112,3 +121,40 @@ Example:
 			};
 		};
 	};
+
+	s2mps14_pmic@66 {
+		compatible = "samsung,s2mps14-pmic";
+		reg = <0x66>;
+
+		s2m_osc: clocks {
+			compatible = "samsung,s2mps14-clk";
+			#clock-cells = 1;
+			clock-output-names = "xx", "", "zz";
+		};
+
+		regulators {
+			ldo1_reg: LDO1 {
+				regulator-name = "VAP_ALIVE_1.0V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				op_mode = <1>; /* Normal Mode */
+			};
+
+			ldo2_reg: LDO2 {
+				regulator-name = "VAP_M1_1.2V";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				op_mode = <1>; /* Normal Mode */
+			};
+
+			buck1_reg: BUCK1 {
+				regulator-name = "VAP_MIF_1.0V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				op_mode = <3>; /* Standby Mode */
+			};
+		};
+	};
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v2 10/14] Documentation: mfd: s2mps11: Document support for S2MPS14
From: Krzysztof Kozlowski @ 2014-02-13  9:14 UTC (permalink / raw)
  To: Sangbeom Kim, Samuel Ortiz, Lee Jones, linux-kernel,
	linux-samsung-soc
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Krzysztof Kozlowski, Mark Brown, Liam Girdwood, Tomasz Figa,
	devicetree, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala
In-Reply-To: <1392282847-25444-1-git-send-email-k.kozlowski@samsung.com>

Add bindings documentation for S2MPS14 device to the s2mps11 driver.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Tomasz Figa <t.figa@samsung.com>
Cc: devicetree@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
---
 Documentation/devicetree/bindings/mfd/s2mps11.txt |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
index 15ee89c3cc7b..f69bec294f02 100644
--- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
+++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
@@ -1,5 +1,5 @@
 
-* Samsung S2MPS11 Voltage and Current Regulator
+* Samsung S2MPS11 and S2MPS14 Voltage and Current Regulator
 
 The Samsung S2MPS11 is a multi-function device which includes voltage and
 current regulators, RTC, charger controller and other sub-blocks. It is
@@ -7,7 +7,7 @@ interfaced to the host controller using an I2C interface. Each sub-block is
 addressed by the host system using different I2C slave addresses.
 
 Required properties:
-- compatible: Should be "samsung,s2mps11-pmic".
+- compatible: Should be "samsung,s2mps11-pmic" or "samsung,s2mps14-pmic".
 - reg: Specifies the I2C slave address of the pmic block. It should be 0x66.
 
 Optional properties:
@@ -59,10 +59,14 @@ supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
 as per the datasheet of s2mps11.
 
 	- LDOn
-		  - valid values for n are 1 to 38
+		  - valid values for n are:
+			- S2MPS11: 1 to 38
+			- S2MPS14: 1 to 25
 		  - Example: LDO1, LD02, LDO28
 	- BUCKn
-		  - valid values for n are 1 to 10.
+		  - valid values for n are:
+			- S2MPS11: 1 to 10
+			- S2MPS14: 1 to 5
 		  - Example: BUCK1, BUCK2, BUCK9
 
 Example:
-- 
1.7.9.5

^ permalink raw reply related

* Re: [RFC] dt: bindings: add bindings for Broadcom bcm43xx sdio devices
From: Tomasz Figa @ 2014-02-13  9:13 UTC (permalink / raw)
  To: Arend van Spriel, Rob Herring
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Chen-Yu Tsai
In-Reply-To: <1392059868-8782-1-git-send-email-arend-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>

Hi Arend,

On 10.02.2014 20:17, Arend van Spriel wrote:
> The Broadcom bcm43xx sdio devices are fullmac devices that may be
> integrated in ARM platforms. Currently, the brcmfmac driver for
> these devices support use of platform data. This patch specifies
> the bindings that allow this platform data to be expressed in the
> devicetree.
>
> Cc: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> Cc: Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Reviewed-by: Hante Meuleman <meuleman-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Pieter-Paul Giesberts <pieterpg-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Arend van Spriel <arend-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> ---
> This devicetree binding proposal is intended for platforms with
> Broadcom wireless device in MMC sdio slot. These devices may
> have their own interrupt and power line. Also the SDIO drive
> strength is often hardware dependent and expressed in this
> binding.
>
> Not sure if this should go in staging or not. Feel free to
> comment on this proposal.
>
> Regards,
> Arend
> ---
>   .../staging/net/wireless/brcm,bcm43xx-fmac.txt     |   37 ++++++++++++++++++++
>   1 file changed, 37 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt
>
> diff --git a/Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt b/Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt
> new file mode 100644
> index 0000000..535f343
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt
> @@ -0,0 +1,37 @@
> +Broadcom BCM43xx Fullmac wireless SDIO devices
> +
> +This node provides properties for controlling the Broadcom wireless device. The
> +node is expected to be specified as a child node to the MMC controller that
> +connects the device to the system.
> +
> +Required properties:
> +
> + - compatible : Should be "brcm,bcm43xx-fmac".
> + - wlan-supply : phandle for fixed regulator used to control power for
> +	the device/module.

The BCM43xx WLAN chips I used to work always have been controlled by a 
simple power enable GPIO of the chip itself. Has this changed in newer 
chips?

If you need to simply toggle a GPIO to control the power, you don't need 
to use the regulator API at all, controlling the GPIO directly.

> +
> +Optional properties:
> + - drive-strength : drive strength used for SDIO pins on device (default = 6mA).

This should be a part of the MMC binding, I think. Probably also moved 
under MMC controller's node, since it's a board-specific property 
altering the parameters of the MMC controller, not the WLAN chip.

> + - interrupt-parent : the phandle for the interrupt controller to which the
> +	device interrupt (HOST_WAKE) is connected.
> + - interrupts : interrupt specifier encoded according the interrupt controller
> +	specified by interrupt-parent property.

I would also add a clock here, since the BCM43xx chips usually need a 
32k clock to operate (or at least the ones I used to work with did). It 
can be optional, as not all systems can control this clock.

> +
> +Example:
> +
> +mmc3: mmc@01c20000 {
> +	pinctrl-0 = <&mmc3_pins>;
> +	pinctrl-1 = <&wifi_host_wake>;

WLAN_HOST_WAKE pin (aka the OOB interrupt) is specific to the WLAN chip, 
so this should be rather configured in a pinctrl state of the WLAN chip 
itself.

> +	vmmc-supply = <&mmc3_supply>;
> +	bus-width = <4>;
> +
> +	bcm4335: bcm4335@0 {

nit: Why @0, if there is no reg property under this node?

Best regards,
Tomasz

> +		compatible = "brcm,bcm43xx-fmac";
> +		wlan-supply = <&wlan-reg>;
> +		drive-strength = <4>;
> +		interrupt-parent = <&gpx2>;
> +		interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-names = "HOST_WAKE";
> +	};
> +};
> +
>
--
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 1/2] ARM: shmobile: r8a7778/r8a7779 dtsi: Improve and correct HSPI bindings
From: Kuninori Morimoto @ 2014-02-13  9:02 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Simon Horman, Kuninori Morimoto, devicetree@vger.kernel.org,
	linux-spi, Linux-sh list, Geert Uytterhoeven, Mark Brown
In-Reply-To: <CAMuHMdX9H5Nvvwy4J=UYE=82nx1nm+v5be2JHLWrUp2xkCO=Hg@mail.gmail.com>


Hi Geert
CC Simon

Thank you for your help

>  * Based on the value of the compatible property, this routine will attempt
>  * to choose an appropriate modalias value for a particular device tree node.
>  * It does this by stripping the manufacturer prefix (as delimited by a ',')
>  * from the first entry in the compatible list property.
> 
> Which is used by drivers/spi/spi.c:of_register_spi_devices().
> 
> >    So, I quick-hacked this issue in my local environment.
> 
> Was there anything else you needed to do, besides adding support for
> s25fl008k to m25p80.c?

I re-tested cleanly this patch.
Yes, indeed, my local-hack was not needed.
It was my fault.

> > 2) it needs Geert's this patch
> >
> >    Subject: [PATCH] mtd: m25p80: add support for the Spansion s25fl008k chip
> >    Date:        Tue, 11 Feb 2014 09:51:18 +0100
> >
> >    Kernel will hung-up without this patch
> 
> Hang up? Not just ignoring the device?

It works without Hang-up in my re-test now.
My previous test seems something wrong.
Thank you

Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Best regards
---
Kuninori Morimoto

^ permalink raw reply

* Re: [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Tomasz Figa @ 2014-02-13  9:01 UTC (permalink / raw)
  To: Ulf Hansson, Arnd Bergmann
  Cc: Tomasz Figa, Olof Johansson, linux-mmc, devicetree,
	Russell King - ARM Linux, linux-arm-kernel@lists.infradead.org,
	robh+dt, mark.rutland, Pawel Moll, Ian Campbell, Kumar Gala,
	Chris Ball, Sascha Hauer, Fabio Estevam
In-Reply-To: <CAPDyKFo9Xpxe0XzevPEeaofLeCNivnf3R_RttToP2h3aFyB4Yw@mail.gmail.com>



On 13.02.2014 09:56, Ulf Hansson wrote:
> On 28 January 2014 11:48, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Tuesday 28 January 2014, Ulf Hansson wrote:
>>> On 28 January 2014 01:59, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>>>> On 27.01.2014 11:19, Ulf Hansson wrote:
>>>>> There is already a host capability that I think we could use to handle
>>>>> this. MMC_CAP_NONREMOVABLE, the corresponding DT binding string is
>>>>> "non-removable", and it may be set per host device.
>>>>>
>>>>> Using this cap means the mmc_rescan process that runs to detect new
>>>>> cards, will only be executed once and during boot. So, we need to make
>>>>> sure all resources and powers are provided to the card at this point.
>>>>> Otherwise the card will not be detected.
>>>>
>>>> I don't quite like this requirement, especially if you consider
>>>> multi-platform kernels where a lot of drivers is going to be provided as
>>>> modules. WLAN drivers are especially good candidates. This means that even
>>>> if the card is powered off at boot-up, if user (or init system) loads
>>>> appropriate module, which powers the chip on, MMC core must be able to
>>>> notice this.
>>>
>>> To be able to detect the card, the WLAN driver doesn't have to be
>>> probed, only the "power controller" driver. I suppose this is were it
>>> becomes a bit tricky.
>>>
>>> Somehow the mmc core needs to be involved in the probe process of the
>>> power controller driver. Could perhaps the power controller bus be
>>> located in the mmc core and thus the power controller driver needs to
>>> register itself by using a new API from the mmc core? Similar how SDIO
>>> func driver's register themselves.
>>
>> I think there is another option, which does have its own pros and cons:
>> We could move all the power handling back into the sdio function driver
>> if we allow a secondary detection path using DT rather than the probing
>> of the SDIO bus. Essentially you'd have to list the class/vendor/device
>> ID for each function that cannot be autodetected in DT, and have the
>> SDIO core pretend that it found the device just by looking at the
>> device nodes, and register the struct sdio_func so it can be bound to
>> the driver. The driver then does all the power handling in a device
>> specific way. At some point the hardware gets registered at the
>> mmc host, and the sdio core connects the bus state to the already present
>> sdio_func, possibly notifying the function driver that it has become
>> usable.
>
> It seems like an option we could try.
>
> There are some tricky parts that needs to be taken care of by the
> mmc/sdio core, regarding the probe/removal and the suspend/resume
> sequence, but I suppose it should be possible.
>
> A minor concern is how do we handle devices that are fully powered at
> boot? Unless the sdio func driver will be loaded we can't power off
> them, right? Do we need to cover this case, do you think?
>
>>
>> Obviously, this can only work for CAP_NONREMOVABLE devices, but those
>> are exactly the ones we are worried about here. The advantage is that
>> the power sequencing for a particular device can then be in device
>> specific code and can have an arbitrarily complex in the driver without
>> needing the mmc code to handle all possible corner cases.
>
> Agree!
>
> I think a removable SDIO card won't l need this additional power
> controller mechanism.

Yes, sounds good to me too. It will be more tricky to implement than the 
solution I initially proposed, but should end up being much cleaner and 
possibly cover more cases.

Best regards,
Tomasz

^ permalink raw reply

* [PATCH 4/4] clk: ti: omap4: set default-parents and default-rates using DT
From: Tero Kristo @ 2014-02-13  9:00 UTC (permalink / raw)
  To: linux-omap, mturquette; +Cc: linux-arm-kernel, devicetree
In-Reply-To: <1392282048-6284-1-git-send-email-t-kristo@ti.com>

Setup dpll_usb_ck and dpll_abe_ck using DT properties instead of hardcoding
the parents and rates in kernel.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/boot/dts/omap4.dtsi |   12 ++++++++++++
 drivers/clk/ti/clk-44xx.c    |   42 ------------------------------------------
 2 files changed, 12 insertions(+), 42 deletions(-)

diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index d3f8a6e..282ce66 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -761,3 +761,15 @@
 };
 
 /include/ "omap44xx-clocks.dtsi"
+
+&dpll_usb_ck {
+	default-rate = <960000000>;
+};
+
+&dpll_abe_ck {
+	default-rate = <98304000>;
+};
+
+&abe_dpll_refclk_mux_ck {
+	ti,default-parent = <&sys_32k_ck>;
+};
diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index ae00218..bc14a49 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -16,21 +16,6 @@
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
 
-/*
- * OMAP4 ABE DPLL default frequency. In OMAP4460 TRM version V, section
- * "3.6.3.2.3 CM1_ABE Clock Generator" states that the "DPLL_ABE_X2_CLK
- * must be set to 196.608 MHz" and hence, the DPLL locked frequency is
- * half of this value.
- */
-#define OMAP4_DPLL_ABE_DEFFREQ				98304000
-
-/*
- * OMAP4 USB DPLL default frequency. In OMAP4430 TRM version V, section
- * "3.6.3.9.5 DPLL_USB Preferred Settings" shows that the preferred
- * locked frequency for the USB DPLL is 960MHz.
- */
-#define OMAP4_DPLL_USB_DEFFREQ				960000000
-
 static struct ti_dt_clk omap44xx_clks[] = {
 	DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"),
 	DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"),
@@ -281,36 +266,9 @@ static struct ti_dt_clk omap44xx_clks[] = {
 
 int __init omap4xxx_dt_clk_init(void)
 {
-	int rc;
-	struct clk *abe_dpll_ref, *abe_dpll, *sys_32k_ck, *usb_dpll;
-
 	ti_dt_clocks_register(omap44xx_clks);
 
 	omap2_clk_disable_autoidle_all();
 
-	/*
-	 * Lock USB DPLL on OMAP4 devices so that the L3INIT power
-	 * domain can transition to retention state when not in use.
-	 */
-	usb_dpll = clk_get_sys(NULL, "dpll_usb_ck");
-	rc = clk_set_rate(usb_dpll, OMAP4_DPLL_USB_DEFFREQ);
-	if (rc)
-		pr_err("%s: failed to configure USB DPLL!\n", __func__);
-
-	/*
-	 * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power
-	 * state when turning the ABE clock domain. Workaround this by
-	 * locking the ABE DPLL on boot.
-	 * Lock the ABE DPLL in any case to avoid issues with audio.
-	 */
-	abe_dpll_ref = clk_get_sys(NULL, "abe_dpll_refclk_mux_ck");
-	sys_32k_ck = clk_get_sys(NULL, "sys_32k_ck");
-	rc = clk_set_parent(abe_dpll_ref, sys_32k_ck);
-	abe_dpll = clk_get_sys(NULL, "dpll_abe_ck");
-	if (!rc)
-		rc = clk_set_rate(abe_dpll, OMAP4_DPLL_ABE_DEFFREQ);
-	if (rc)
-		pr_err("%s: failed to configure ABE DPLL!\n", __func__);
-
 	return 0;
 }
-- 
1.7.9.5


^ 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