Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/4] dt/bindings: Add binding for the DA8xx MUSB driver
From: Rob Herring @ 2016-10-31  5:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477560847-8929-2-git-send-email-abailon@baylibre.com>

On Thu, Oct 27, 2016 at 11:34:04AM +0200, Alexandre Bailon wrote:
> From: Petr Kulhavy <petr@barix.com>
> 
> DT binding for the TI DA8xx/OMAP-L1x/AM17xx/AM18xx MUSB driver.
> 
> Signed-off-by: Petr Kulhavy <petr@barix.com>
> Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
> ---
>  .../devicetree/bindings/usb/da8xx-usb.txt          | 43 ++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/da8xx-usb.txt

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH V3 3/6] dt/bindings: Add bindings for Tegra GMI controller
From: Rob Herring @ 2016-10-31  5:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477576872-2665-4-git-send-email-mirza.krak@gmail.com>

On Thu, Oct 27, 2016 at 04:01:09PM +0200, Mirza Krak wrote:
> From: Mirza Krak <mirza.krak@gmail.com>
> 
> Document the devicetree bindings for the Generic Memory Interface (GMI)
> bus driver found on Tegra SOCs.
> 
> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> ---
> 
> Changes in v2:
> - Updated examples and some information based on comments from Jon Hunter.
> 
> Changes in v3:
> - Updates ranges description based on comments from Rob Herring
> 
>  .../devicetree/bindings/bus/nvidia,tegra20-gmi.txt | 132 +++++++++++++++++++++
>  1 file changed, 132 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
> 
> diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
> new file mode 100644
> index 0000000..49bda2f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
> @@ -0,0 +1,132 @@
> +Device tree bindings for NVIDIA Tegra Generic Memory Interface bus
> +
> +The Generic Memory Interface bus enables memory transfers between internal and
> +external memory. Can be used to attach various high speed devices such as
> +synchronous/asynchronous NOR, FPGA, UARTS and more.
> +
> +The actual devices are instantiated from the child nodes of a GMI node.
> +
> +Required properties:
> + - compatible : Should contain one of the following:
> +        For Tegra20 must contain "nvidia,tegra20-gmi".
> +        For Tegra30 must contain "nvidia,tegra30-gmi".
> + - reg: Should contain GMI controller registers location and length.
> + - clocks: Must contain an entry for each entry in clock-names.
> + - clock-names: Must include the following entries: "gmi"
> + - resets : Must contain an entry for each entry in reset-names.
> + - reset-names : Must include the following entries: "gmi"
> + - #address-cells: The number of cells used to represent physical base
> +   addresses in the GMI address space. Should be 2.
> + - #size-cells: The number of cells used to represent the size of an address
> +   range in the GMI address space. Should be 1.
> + - ranges: Must be set up to reflect the memory layout with three integer values
> +   for each chip-select line in use (only one entry is supported, see below
> +   comments):
> +   <cs-number> <offset> <physical address of mapping> <size>
> +
> +Note that the GMI controller does not have any internal chip-select address
> +decoding, because of that chip-selects either need to be managed via software
> +or by employing external chip-select decoding logic.
> +
> +If external chip-select logic is used to support multiple devices it is assumed
> +that the devices use the same timing and so are probably the same type. It also
> +assumes that they can fit in the 256MB address range. In this case only one
> +child device is supported which represents the active chip-select line, see
> +examples for more insight.
> +
> +The chip-select number is decoded from the child nodes second address cell of
> +'ranges' property, if 'ranges' property is not present or empty chip-select will
> +then be decoded from the first cell of the 'reg' property.
> +
> +Optional child cs node properties:
> +
> + - nvidia,snor-data-width-32bit: Use 32bit data-bus, default is 16bit.
> + - nvidia,snor-mux-mode: Enable address/data MUX mode.
> + - nvidia,snor-rdy-active-before-data: Assert RDY signal one cycle before data.
> +   If omitted it will be asserted with data.
> + - nvidia,snor-rdy-inv: RDY signal is active high
> + - nvidia,snor-adv-inv: ADV signal is active high
> + - nvidia,snor-oe-inv: WE/OE signal is active high
> + - nvidia,snor-cs-inv: CS signal is active high

Inverted is meaningless unless I know what not inverted state is. Name 
the properties using "active high".

With that,

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCHv2 1/4] dt-bindings: mfd: Add Altera Arria10 SR Monitor
From: Rob Herring @ 2016-10-31  5:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477598426-28125-2-git-send-email-tthayer@opensource.altera.com>

On Thu, Oct 27, 2016 at 03:00:23PM -0500, tthayer at opensource.altera.com wrote:
> From: Thor Thayer <tthayer@opensource.altera.com>
> 
> Add the Arria10 DevKit System Resource Chip register and state
> monitoring module to the MFD.
> 
> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
> ---
> Note: This needs to be applied to the bindings document that
> was Acked & Applied but didn't reach the for-next branch.
> See https://patchwork.ozlabs.org/patch/629397/
> ---
> v2  Change compatible string -mon to -monitor for clarity
> ---
>  Documentation/devicetree/bindings/mfd/altera-a10sr.txt | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/altera-a10sr.txt b/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
> index ea151f2..c47be28 100644
> --- a/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
> +++ b/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
> @@ -18,6 +18,7 @@ The A10SR consists of these sub-devices:
>  Device                   Description
>  ------                   ----------
>  a10sr_gpio               GPIO Controller

This should be just "gpio" BTW.

> +a10sr_monitor            Register and State Monitoring

s/_/-/ or maybe just "monitor". Not really a generic node name to use 
for this.

Rob

^ permalink raw reply

* [PATCH v2 2/3] dt-bindings: reset: Add K2G reset definitions
From: Rob Herring @ 2016-10-31  5:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161027214941.24641-3-afd@ti.com>

On Thu, Oct 27, 2016 at 04:49:40PM -0500, Andrew F. Davis wrote:
> Add identifiers for the K2G resets managed by the PMMC.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>  MAINTAINERS                     |  1 +
>  include/dt-bindings/reset/k2g.h | 22 ++++++++++++++++++++++
>  2 files changed, 23 insertions(+)
>  create mode 100644 include/dt-bindings/reset/k2g.h

This belongs with the previous patch. It is part of the binding 
definition.

Rob

^ permalink raw reply

* [PATCH v2 3/4] spi: sun6i: Add binding for Allwinner H3 SPI controller
From: Rob Herring @ 2016-10-31  6:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161028065412.23008-4-woogyom.kim@gmail.com>

On Fri, Oct 28, 2016 at 03:54:11PM +0900, Milo Kim wrote:
> H3 SPI has same architecture as A31 except FIFO capacity.
> To configure the buffer size separately, compatible property should be
> different. Optional DMA specifiers and example are added.
> 
> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Chen-Yu Tsai <wens@csie.org>
> Signed-off-by: Milo Kim <woogyom.kim@gmail.com>
> ---
>  .../devicetree/bindings/spi/spi-sun6i.txt          | 25 ++++++++++++++++++++--
>  1 file changed, 23 insertions(+), 2 deletions(-)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v2 2/5] doc: dt: add cyclone-spi binding document
From: Rob Herring @ 2016-10-31  6:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2de74f6d2f2689b8ef090a9017db2ffb3bd319cb.1477669745.git.stillcompiling@gmail.com>

On Fri, Oct 28, 2016 at 09:56:39AM -0700, Joshua Clayton wrote:
> Describe a cyclonei-ps-spi devicetree entry, required features
> 
> Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
> ---
>  .../bindings/fpga/cyclone-ps-spi-fpga-mgr.txt      | 23 ++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt
> 
> diff --git a/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt
> new file mode 100644
> index 0000000..c942281
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt
> @@ -0,0 +1,23 @@
> +Altera Cyclone Passive Serial SPI FPGA Manager
> +
> +Altera Cyclone FPGAs support a method of loading the bitstream over what is
> +referred to as "passive serial".
> +The passive serial link is not technically spi, and might require extra
> +circuits in order to play nicely with other spi slaves on the same bus.
> +
> +See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf
> +
> +Required properties:
> +- compatible  : should contain "altr,cyclone-ps-spi-fpga-mgr"
> +- reg         : spi slave id of the fpga
> +- config-gpio : config pin (referred to as nCONFIG in the cyclone manual)
> +- status-gpio : status pin (referred to as nSTATUS in the cyclone manual)

'-gpios' is the preferred form.

Looks like active low to me with nXXXX, but the example says active 
high. Please be specific here.

> +
> +Example:
> +	fpga_spi: evi-fpga-spi at 0 {
> +		compatible = "altr,cyclone-ps-spi-fpga-mgr";
> +		spi-max-frequency = <20000000>;
> +		reg = <0>;
> +		config-gpio = <&gpio4 9 GPIO_ACTIVE_HIGH>;
> +		status-gpio = <&gpio4 11 GPIO_ACTIVE_HIGH>;
> +	};
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH v2 3/6] Documentation: devicetree: net: add NS2 bindings to amac
From: Rob Herring @ 2016-10-31  6:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477688219-3871-4-git-send-email-jon.mason@broadcom.com>

On Fri, Oct 28, 2016 at 04:56:56PM -0400, Jon Mason wrote:
> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
> ---
>  Documentation/devicetree/bindings/net/brcm,amac.txt | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt
> index ba5ecc1..f2b194e 100644
> --- a/Documentation/devicetree/bindings/net/brcm,amac.txt
> +++ b/Documentation/devicetree/bindings/net/brcm,amac.txt
> @@ -2,11 +2,12 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings
>  -------------------------------------------------------------
>  
>  Required properties:
> - - compatible:	"brcm,amac" or "brcm,nsp-amac"
> + - compatible:	"brcm,amac", "brcm,nsp-amac", or "brcm,ns2-amac"

One per line is preferred.

>   - reg:		Address and length of the GMAC registers,
>  		Address and length of the GMAC IDM registers
> +		Address and length of the NIC Port Manager registers (optional)
>   - reg-names:	Names of the registers.  Must have both "amac_base" and
> -		"idm_base"
> +		"idm_base". "nicpm_base" is optional (required for NS2)

Is nicpm_base optional on some SoCs? If not just say which ones it 
applies to. A separate line will make that clearer.

_base is kind of redundant too, but it's already done.

>   - interrupts:	Interrupt number
>  
>  Optional properties:
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 03/11] ARM: shmobile: r8a7745: basic SoC support
From: Rob Herring @ 2016-10-31  6:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1638480.5pJxF7pUnz@wasted.cogentembedded.com>

On Sat, Oct 29, 2016 at 01:16:54AM +0300, Sergei Shtylyov wrote:
> Add minimal support for the RZ/G1E (R8A7745) SoC.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> 
> ---
>  Documentation/devicetree/bindings/arm/shmobile.txt |    2 ++

Acked-by: Rob Herring <robh@kernel.org>

>  arch/arm/mach-shmobile/Kconfig                     |    4 ++++
>  arch/arm/mach-shmobile/setup-rcar-gen2.c           |    1 +
>  3 files changed, 7 insertions(+)

^ permalink raw reply

* [PATCH 1/3] dt-bindings: firmware: scm: Add MSM8996 DT bindings
From: Rob Herring @ 2016-10-31  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477699729-18451-2-git-send-email-spjoshi@codeaurora.org>

On Fri, Oct 28, 2016 at 05:08:47PM -0700, Sarangdhar Joshi wrote:
> Add SCM DT bindings for Qualcomm's MSM8996 platform.
> 
> Signed-off-by: Sarangdhar Joshi <spjoshi@codeaurora.org>
> ---
>  Documentation/devicetree/bindings/firmware/qcom,scm.txt | 2 ++
>  1 file changed, 2 insertions(+)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v3 1/2] drm/bridge: dumb-vga-dac: Support a VDD regulator supply
From: Rob Herring @ 2016-10-31  6:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161029110611.28951-2-wens@csie.org>

On Sat, Oct 29, 2016 at 07:06:10PM +0800, Chen-Yu Tsai wrote:
> Some dumb VGA DACs are active components which require external power.
> Add support for specifying a regulator as its power supply.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  .../bindings/display/bridge/dumb-vga-dac.txt       |  2 ++

For the binding,

Acked-by: Rob Herring <robh@kernel.org>

One code comment below...

>  drivers/gpu/drm/bridge/dumb-vga-dac.c              | 35 ++++++++++++++++++++++
>  2 files changed, 37 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
> index 003bc246a270..164cbb15f04c 100644
> --- a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
> @@ -16,6 +16,8 @@ graph bindings specified in Documentation/devicetree/bindings/graph.txt.
>  - Video port 0 for RGB input
>  - Video port 1 for VGA output
>  
> +Optional properties:
> +- vdd-supply: Power supply for DAC
>  
>  Example
>  -------
> diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c
> index afec232185a7..59781e031220 100644
> --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
> +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
> @@ -12,6 +12,7 @@
>  
>  #include <linux/module.h>
>  #include <linux/of_graph.h>
> +#include <linux/regulator/consumer.h>
>  
>  #include <drm/drmP.h>
>  #include <drm/drm_atomic_helper.h>
> @@ -23,6 +24,7 @@ struct dumb_vga {
>  	struct drm_connector	connector;
>  
>  	struct i2c_adapter	*ddc;
> +	struct regulator	*vdd;
>  };
>  
>  static inline struct dumb_vga *
> @@ -124,8 +126,33 @@ static int dumb_vga_attach(struct drm_bridge *bridge)
>  	return 0;
>  }
>  
> +static void dumb_vga_enable(struct drm_bridge *bridge)
> +{
> +	struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
> +	int ret;
> +
> +	if (!IS_ERR(vga->vdd)) {

if (IS_ERR())
	return;

...will save some intentation.

> +		ret = regulator_enable(vga->vdd);
> +
> +		if (ret) {
> +			DRM_ERROR("Failed to enable vdd regulator: %d\n", ret);
> +			return;
> +		}
> +	}
> +}
> +
> +static void dumb_vga_disable(struct drm_bridge *bridge)
> +{
> +	struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
> +
> +	if (!IS_ERR(vga->vdd))
> +		regulator_disable(vga->vdd);
> +}
> +
>  static const struct drm_bridge_funcs dumb_vga_bridge_funcs = {
>  	.attach		= dumb_vga_attach,
> +	.enable		= dumb_vga_enable,
> +	.disable	= dumb_vga_disable,
>  };
>  
>  static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
> @@ -169,6 +196,14 @@ static int dumb_vga_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  	platform_set_drvdata(pdev, vga);
>  
> +	vga->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
> +	if (IS_ERR(vga->vdd)) {
> +		ret = PTR_ERR(vga->vdd);
> +		if (ret == -EPROBE_DEFER)
> +			return -EPROBE_DEFER;
> +		dev_dbg(&pdev->dev, "No vdd regulator found: %d\n", ret);
> +	}
> +
>  	vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev);
>  	if (IS_ERR(vga->ddc)) {
>  		if (PTR_ERR(vga->ddc) == -ENODEV) {
> -- 
> 2.9.3
> 

^ permalink raw reply

* [PATCH] ASoC: sun4i-codec: return error code instead of NULL when create_card fails
From: Chen-Yu Tsai @ 2016-10-31  6:42 UTC (permalink / raw)
  To: linux-arm-kernel

When sun4i_codec_create_card fails, we do not assign a proper error
code to the return value. The return value would be 0 from the previous
function call, or we would have bailed out sooner. This would confuse
the driver core into thinking the device probe succeeded, when in fact
it didn't, leaving various devres based resources lingering.

Make the create_card function pass back a meaningful error code, and
assign it to the return value.

Fixes: 45fb6b6f2aa3 ("ASoC: sunxi: add support for the on-chip codec on
		      early Allwinner SoCs")
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---

In practice this should be really hard to hit, as the only failures in
create_card are memory allocation failures.

Should we mark this for stable?

---
 sound/soc/sunxi/sun4i-codec.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index e047ec06d538..a60707761abf 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -765,11 +765,11 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
 
 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
 	if (!card)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
 	if (!card->dai_link)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	card->dev		= dev;
 	card->name		= "sun4i-codec";
@@ -876,7 +876,8 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	}
 
 	card = sun4i_codec_create_card(&pdev->dev);
-	if (!card) {
+	if (IS_ERR(card)) {
+		ret = PTR_ERR(card);
 		dev_err(&pdev->dev, "Failed to create our card\n");
 		goto err_unregister_codec;
 	}
-- 
2.10.1

^ permalink raw reply related

* [PATCH v14 1/4] clk: mediatek: Add MT2701 clock support
From: James Liao @ 2016-10-31  6:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161028011753.GS26139@codeaurora.org>

Hi Stephen,

On Thu, 2016-10-27 at 18:17 -0700, Stephen Boyd wrote:
> On 10/21, Erin Lo wrote:
> > diff --git a/drivers/clk/mediatek/clk-mt2701-bdp.c b/drivers/clk/mediatek/clk-mt2701-bdp.c
> > new file mode 100644
> > index 0000000..dbf6ab2
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt2701-bdp.c
> > @@ -0,0 +1,148 @@
> > +
> > +static int mtk_bdpsys_init(struct platform_device *pdev)
> > +{
> > +	struct clk_onecell_data *clk_data;
> > +	int r;
> > +	struct device_node *node = pdev->dev.of_node;
> > +
> > +	clk_data = mtk_alloc_clk_data(CLK_BDP_NR);
> > +
> > +	mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
> > +						clk_data);
> > +
> > +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > +	return r;
> > +}
> > +
> > +static const struct of_device_id of_match_clk_mt2701_bdp[] = {
> > +	{ .compatible = "mediatek,mt2701-bdpsys", },
> > +	{}
> > +};
> > +
> > +static int clk_mt2701_bdp_probe(struct platform_device *pdev)
> > +{
> > +	int r;
> > +
> > +	r = mtk_bdpsys_init(pdev);
> 
> Why not just put the contents of that function here? I don't see
> the point of this.

Because of some historical reasons, we keep mtk_bdpsys_init() for
changing init points between CLK_OF_DECLARE() and probe() more easily. I
can move all contents from mtk_bdpsys_init() here in next patch.

> > +	if (r) {
> > +		dev_err(&pdev->dev,
> > +			"could not register clock provider: %s: %d\n",
> > +			pdev->name, r);
> > +	}
> > +
> > +	return r;
> > +}
> > +
> > +static struct platform_driver clk_mt2701_bdp_drv = {
> > +	.probe = clk_mt2701_bdp_probe,
> > +	.driver = {
> > +		.name = "clk-mt2701-bdp",
> > +		.of_match_table = of_match_clk_mt2701_bdp,
> > +	},
> > +};
> > +
> > +builtin_platform_driver(clk_mt2701_bdp_drv);
> > diff --git a/drivers/clk/mediatek/clk-mt2701-eth.c b/drivers/clk/mediatek/clk-mt2701-eth.c
> > new file mode 100644
> > index 0000000..b2a71a4
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt2701-eth.c
> > @@ -0,0 +1,90 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: Shunli Wang <shunli.wang@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +#include <dt-bindings/clock/mt2701-clk.h>
> > +
> > +static const struct mtk_gate_regs eth_cg_regs = {
> > +	.sta_ofs = 0x0030,
> > +};
> > +
> > +#define GATE_ETH(_id, _name, _parent, _shift) {		\
> > +		.id = _id,				\
> > +		.name = _name,				\
> > +		.parent_name = _parent,			\
> > +		.regs = &eth_cg_regs,			\
> > +		.shift = _shift,			\
> > +		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
> > +	}
> > +
> > +static const struct mtk_gate eth_clks[] = {
> > +	GATE_ETH(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
> > +	GATE_ETH(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
> > +	GATE_ETH(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
> > +	GATE_ETH(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8),
> > +	GATE_ETH(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11),
> > +	GATE_ETH(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14),
> > +	GATE_ETH(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17),
> > +	GATE_ETH(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29),
> > +};
> > +
> > +static int mtk_ethsys_init(struct platform_device *pdev)
> > +{
> > +	struct clk_onecell_data *clk_data;
> > +	int r;
> > +	struct device_node *node = pdev->dev.of_node;
> > +
> > +	clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
> > +
> > +	mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
> > +						clk_data);
> > +
> > +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > +	return r;
> 
> Just return of_clk_add_provider() please.

I'll change it in next patch.

> > +}
> > +
> > +static const struct of_device_id of_match_clk_mt2701_eth[] = {
> > +	{ .compatible = "mediatek,mt2701-ethsys", },
> > +	{}
> > +};
> > +
> > +static int clk_mt2701_eth_probe(struct platform_device *pdev)
> > +{
> > +	int r;
> > +
> > +	r = mtk_ethsys_init(pdev);
> 
> Same comment.

Okay.

> > +	if (r) {
> > +		dev_err(&pdev->dev,
> > +			"could not register clock provider: %s: %d\n",
> > +			pdev->name, r);
> > +	}
> > +
> > +	return r;
> > +}
> > +
> > +static struct platform_driver clk_mt2701_eth_drv = {
> > +	.probe = clk_mt2701_eth_probe,
> > +	.driver = {
> > +		.name = "clk-mt2701-eth",
> > +		.of_match_table = of_match_clk_mt2701_eth,
> > +	},
> > +};
> > +
> > +builtin_platform_driver(clk_mt2701_eth_drv);
> > diff --git a/drivers/clk/mediatek/clk-mt2701-hif.c b/drivers/clk/mediatek/clk-mt2701-hif.c
> > new file mode 100644
> > index 0000000..e2b0039
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt2701-hif.c
> > @@ -0,0 +1,87 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: Shunli Wang <shunli.wang@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +#include <dt-bindings/clock/mt2701-clk.h>
> > +
> > +static const struct mtk_gate_regs hif_cg_regs = {
> > +	.sta_ofs = 0x0030,
> > +};
> > +
> > +#define GATE_HIF(_id, _name, _parent, _shift) {		\
> > +		.id = _id,				\
> > +		.name = _name,				\
> > +		.parent_name = _parent,			\
> > +		.regs = &hif_cg_regs,			\
> > +		.shift = _shift,			\
> > +		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
> > +	}
> > +
> > +static const struct mtk_gate hif_clks[] = {
> > +	GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
> > +	GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22),
> > +	GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24),
> > +	GATE_HIF(CLK_HIFSYS_PCIE1, "pcie1_clk", "ethpll_500m_ck", 25),
> > +	GATE_HIF(CLK_HIFSYS_PCIE2, "pcie2_clk", "ethpll_500m_ck", 26),
> > +};
> > +
> > +static int mtk_hifsys_init(struct platform_device *pdev)
> > +{
> > +	struct clk_onecell_data *clk_data;
> > +	int r;
> > +	struct device_node *node = pdev->dev.of_node;
> > +
> > +	clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
> > +
> > +	mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
> > +						clk_data);
> > +
> > +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > +	return r;
> 
> Just return of_clk_add_provider() please.

Okay.

> > +}
> > +
> > +static const struct of_device_id of_match_clk_mt2701_hif[] = {
> > +	{ .compatible = "mediatek,mt2701-hifsys", },
> > +	{}
> > +};
> > +
> > +static int clk_mt2701_hif_probe(struct platform_device *pdev)
> > +{
> > +	int r;
> > +
> > +	r = mtk_hifsys_init(pdev);
> 
> There's a pattern. Same comments apply for everything that uses
> this style.

I'll change them in next patch.

> > +	if (r) {
> > +		dev_err(&pdev->dev,
> > +			"could not register clock provider: %s: %d\n",
> > +			pdev->name, r);
> > +	}
> > +
> > +	return r;
> > +}
> > +
> > +static struct platform_driver clk_mt2701_hif_drv = {
> > +	.probe = clk_mt2701_hif_probe,
> > +	.driver = {
> > +		.name = "clk-mt2701-hif",
> > +		.of_match_table = of_match_clk_mt2701_hif,
> > +	},
> > +};
> > +
> > +builtin_platform_driver(clk_mt2701_hif_drv);
> [cut a bunch of same drivers]
> > diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
> > new file mode 100644
> > index 0000000..c225256
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt2701.c
> > @@ -0,0 +1,1046 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: Shunli Wang <shunli.wang@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +#include <dt-bindings/clock/mt2701-clk.h>
> > +
> > +/*
> > + * For some clocks, we don't care what their actual rates are. And these
> > + * clocks may change their rate on different products or different scenarios.
> > + * So we model these clocks' rate as 0, to denote it's not an actual rate.
> > + */
> > +#define DUMMY_RATE		0
> > +
> > +static DEFINE_SPINLOCK(lock);
> 
> Please name this something more mtk specific. mt2701_clk_lock?

Okay.

> > +
> > +static const struct mtk_fixed_clk top_fixed_clks[] = {
> > +	FIXED_CLK(CLK_TOP_DPI, "dpi_ck", "clk26m",
> > +		108 * MHZ),
> > +	FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", "clk26m",
> > +		400 * MHZ),
> > +	FIXED_CLK(CLK_TOP_VENCPLL, "vencpll_ck", "clk26m",
> > +		295750000),
> > +	FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, "hdmi_0_pix340m", "clk26m",
> > +		340 * MHZ),
> > +	FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, "hdmi_0_deep340m", "clk26m",
> > +		340 * MHZ),
> > +	FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, "hdmi_0_pll340m", "clk26m",
> > +		340 * MHZ),
> > +	FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_dig_cts", "clk26m",
> > +		300 * MHZ),
> > +	FIXED_CLK(CLK_TOP_HADDS2_FB, "hadds2_fbclk", "clk26m",
> > +		27 * MHZ),
> > +	FIXED_CLK(CLK_TOP_WBG_DIG_416M, "wbg_dig_ck_416m", "clk26m",
> > +		416 * MHZ),
> > +	FIXED_CLK(CLK_TOP_DSI0_LNTC_DSI, "dsi0_lntc_dsi", "clk26m",
> > +		143 * MHZ),
> > +	FIXED_CLK(CLK_TOP_HDMI_SCL_RX, "hdmi_scl_rx", "clk26m",
> > +		27 * MHZ),
> > +	FIXED_CLK(CLK_TOP_AUD_EXT1, "aud_ext1", "clk26m",
> > +		DUMMY_RATE),
> > +	FIXED_CLK(CLK_TOP_AUD_EXT2, "aud_ext2", "clk26m",
> > +		DUMMY_RATE),
> > +	FIXED_CLK(CLK_TOP_NFI1X_PAD, "nfi1x_pad", "clk26m",
> > +		DUMMY_RATE),
> > +};
> > +
> > +static const struct mtk_fixed_factor top_fixed_divs[] = {
> > +	FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1),
> > +	FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
> > +	FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
> > +	FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
> > +	FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
> > +	FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
> > +	FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
> > +	FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
> > +	FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
> > +	FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
> > +	FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
> > +	FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
> > +	FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
> > +	FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
> > +	FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
> > +	FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
> > +
> > +	FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, 1),
> > +	FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
> > +	FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
> > +	FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
> > +	FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
> > +	FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
> > +	FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll", 1, 52),
> > +	FACTOR(CLK_TOP_UNIVPLL_D108, "univpll_d108", "univpll", 1, 108),
> > +	FACTOR(CLK_TOP_USB_PHY48M, "usb_phy48m_ck", "univpll", 1, 26),
> > +	FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
> > +	FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
> > +	FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8),
> > +	FACTOR(CLK_TOP_8BDAC, "8bdac_ck", "univpll_d2", 1, 1),
> > +	FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2),
> > +	FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4),
> > +	FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8),
> > +	FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll_d3", 1, 16),
> > +	FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32),
> > +	FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
> > +	FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
> > +	FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8),
> > +
> > +	FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
> > +	FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
> > +	FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
> > +	FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8),
> > +
> > +	FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
> > +	FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
> > +
> > +	FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "dmpll_ck", 1, 2),
> > +	FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "dmpll_ck", 1, 4),
> > +	FACTOR(CLK_TOP_DMPLL_X2, "dmpll_x2", "dmpll_ck", 1, 1),
> > +
> > +	FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1),
> > +	FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2),
> > +	FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
> > +
> > +	FACTOR(CLK_TOP_VDECPLL, "vdecpll_ck", "vdecpll", 1, 1),
> > +	FACTOR(CLK_TOP_TVD2PLL, "tvd2pll_ck", "tvd2pll", 1, 1),
> > +	FACTOR(CLK_TOP_TVD2PLL_D2, "tvd2pll_d2", "tvd2pll", 1, 2),
> > +
> > +	FACTOR(CLK_TOP_MIPIPLL, "mipipll", "dpi_ck", 1, 1),
> > +	FACTOR(CLK_TOP_MIPIPLL_D2, "mipipll_d2", "dpi_ck", 1, 2),
> > +	FACTOR(CLK_TOP_MIPIPLL_D4, "mipipll_d4", "dpi_ck", 1, 4),
> > +
> > +	FACTOR(CLK_TOP_HDMIPLL, "hdmipll_ck", "hdmitx_dig_cts", 1, 1),
> > +	FACTOR(CLK_TOP_HDMIPLL_D2, "hdmipll_d2", "hdmitx_dig_cts", 1, 2),
> > +	FACTOR(CLK_TOP_HDMIPLL_D3, "hdmipll_d3", "hdmitx_dig_cts", 1, 3),
> > +
> > +	FACTOR(CLK_TOP_ARMPLL_1P3G, "armpll_1p3g_ck", "armpll", 1, 1),
> > +
> > +	FACTOR(CLK_TOP_AUDPLL, "audpll", "audpll_sel", 1, 1),
> > +	FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll_sel", 1, 4),
> > +	FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll_sel", 1, 8),
> > +	FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll_sel", 1, 16),
> > +	FACTOR(CLK_TOP_AUDPLL_D24, "audpll_d24", "audpll_sel", 1, 24),
> > +
> > +	FACTOR(CLK_TOP_AUD1PLL_98M, "aud1pll_98m_ck", "aud1pll", 1, 3),
> > +	FACTOR(CLK_TOP_AUD2PLL_90M, "aud2pll_90m_ck", "aud2pll", 1, 3),
> > +	FACTOR(CLK_TOP_HADDS2PLL_98M, "hadds2pll_98m", "hadds2pll", 1, 3),
> > +	FACTOR(CLK_TOP_HADDS2PLL_294M, "hadds2pll_294m", "hadds2pll", 1, 1),
> > +	FACTOR(CLK_TOP_ETHPLL_500M, "ethpll_500m_ck", "ethpll", 1, 1),
> > +	FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8),
> > +	FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793),
> > +	FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1),
> > +};
> > +
> > +static const char * const axi_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d2",
> > +	"syspll_d5",
> > +	"syspll1_d4",
> > +	"univpll_d5",
> > +	"univpll2_d2",
> > +	"mmpll_d2",
> > +	"dmpll_d2"
> > +};
> > +
> > +static const char * const mem_parents[] = {
> > +	"clk26m",
> > +	"dmpll_ck"
> > +};
> > +
> > +static const char * const ddrphycfg_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d8"
> > +};
> > +
> > +static const char * const mm_parents[] = {
> > +	"clk26m",
> > +	"vencpll_ck",
> > +	"syspll1_d2",
> > +	"syspll1_d4",
> > +	"univpll_d5",
> > +	"univpll1_d2",
> > +	"univpll2_d2",
> > +	"dmpll_ck"
> > +};
> > +
> > +static const char * const pwm_parents[] = {
> > +	"clk26m",
> > +	"univpll2_d4",
> > +	"univpll3_d2",
> > +	"univpll1_d4",
> > +};
> > +
> > +static const char * const vdec_parents[] = {
> > +	"clk26m",
> > +	"vdecpll_ck",
> > +	"syspll_d5",
> > +	"syspll1_d4",
> > +	"univpll_d5",
> > +	"univpll2_d2",
> > +	"vencpll_ck",
> > +	"msdcpll_d2",
> > +	"mmpll_d2"
> > +};
> > +
> > +static const char * const mfg_parents[] = {
> > +	"clk26m",
> > +	"mmpll_ck",
> > +	"dmpll_x2_ck",
> > +	"msdcpll_ck",
> > +	"clk26m",
> > +	"syspll_d3",
> > +	"univpll_d3",
> > +	"univpll1_d2"
> > +};
> > +
> > +static const char * const camtg_parents[] = {
> > +	"clk26m",
> > +	"univpll_d26",
> > +	"univpll2_d2",
> > +	"syspll3_d2",
> > +	"syspll3_d4",
> > +	"msdcpll_d2",
> > +	"mmpll_d2"
> > +};
> > +
> > +static const char * const uart_parents[] = {
> > +	"clk26m",
> > +	"univpll2_d8"
> > +};
> > +
> > +static const char * const spi_parents[] = {
> > +	"clk26m",
> > +	"syspll3_d2",
> > +	"syspll4_d2",
> > +	"univpll2_d4",
> > +	"univpll1_d8"
> > +};
> > +
> > +static const char * const usb20_parents[] = {
> > +	"clk26m",
> > +	"univpll1_d8",
> > +	"univpll3_d4"
> > +};
> > +
> > +static const char * const msdc30_parents[] = {
> > +	"clk26m",
> > +	"msdcpll_d2",
> > +	"syspll2_d2",
> > +	"syspll1_d4",
> > +	"univpll1_d4",
> > +	"univpll2_d4"
> > +};
> > +
> > +static const char * const audio_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d16"
> > +};
> > +
> > +static const char * const aud_intbus_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d4",
> > +	"syspll3_d2",
> > +	"syspll4_d2",
> > +	"univpll3_d2",
> > +	"univpll2_d4"
> > +};
> > +
> > +static const char * const pmicspi_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d8",
> > +	"syspll2_d4",
> > +	"syspll4_d2",
> > +	"syspll3_d4",
> > +	"syspll2_d8",
> > +	"syspll1_d16",
> > +	"univpll3_d4",
> > +	"univpll_d26",
> > +	"dmpll_d2",
> > +	"dmpll_d4"
> > +};
> > +
> > +static const char * const scp_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d8",
> > +	"dmpll_d2",
> > +	"dmpll_d4"
> > +};
> > +
> > +static const char * const dpi0_parents[] = {
> > +	"clk26m",
> > +	"mipipll",
> > +	"mipipll_d2",
> > +	"mipipll_d4",
> > +	"clk26m",
> > +	"tvdpll_ck",
> > +	"tvdpll_d2",
> > +	"tvdpll_d4"
> > +};
> > +
> > +static const char * const dpi1_parents[] = {
> > +	"clk26m",
> > +	"tvdpll_ck",
> > +	"tvdpll_d2",
> > +	"tvdpll_d4"
> > +};
> > +
> > +static const char * const tve_parents[] = {
> > +	"clk26m",
> > +	"mipipll",
> > +	"mipipll_d2",
> > +	"mipipll_d4",
> > +	"clk26m",
> > +	"tvdpll_ck",
> > +	"tvdpll_d2",
> > +	"tvdpll_d4"
> > +};
> > +
> > +static const char * const hdmi_parents[] = {
> > +	"clk26m",
> > +	"hdmipll_ck",
> > +	"hdmipll_d2",
> > +	"hdmipll_d3"
> > +};
> > +
> > +static const char * const apll_parents[] = {
> > +	"clk26m",
> > +	"audpll",
> > +	"audpll_d4",
> > +	"audpll_d8",
> > +	"audpll_d16",
> > +	"audpll_d24",
> > +	"clk26m",
> > +	"clk26m"
> > +};
> > +
> > +static const char * const rtc_parents[] = {
> > +	"32k_internal",
> > +	"32k_external",
> > +	"clk26m",
> > +	"univpll3_d8"
> > +};
> > +
> > +static const char * const nfi2x_parents[] = {
> > +	"clk26m",
> > +	"syspll2_d2",
> > +	"syspll_d7",
> > +	"univpll3_d2",
> > +	"syspll2_d4",
> > +	"univpll3_d4",
> > +	"syspll4_d4",
> > +	"clk26m"
> > +};
> > +
> > +static const char * const emmc_hclk_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d2",
> > +	"syspll1_d4",
> > +	"syspll2_d2"
> > +};
> > +
> > +static const char * const flash_parents[] = {
> > +	"clk26m_d8",
> > +	"clk26m",
> > +	"syspll2_d8",
> > +	"syspll3_d4",
> > +	"univpll3_d4",
> > +	"syspll4_d2",
> > +	"syspll2_d4",
> > +	"univpll2_d4"
> > +};
> > +
> > +static const char * const di_parents[] = {
> > +	"clk26m",
> > +	"tvd2pll_ck",
> > +	"tvd2pll_d2",
> > +	"clk26m"
> > +};
> > +
> > +static const char * const nr_osd_parents[] = {
> > +	"clk26m",
> > +	"vencpll_ck",
> > +	"syspll1_d2",
> > +	"syspll1_d4",
> > +	"univpll_d5",
> > +	"univpll1_d2",
> > +	"univpll2_d2",
> > +	"dmpll_ck"
> > +};
> > +
> > +static const char * const hdmirx_bist_parents[] = {
> > +	"clk26m",
> > +	"syspll_d3",
> > +	"clk26m",
> > +	"syspll1_d16",
> > +	"syspll4_d2",
> > +	"syspll1_d4",
> > +	"vencpll_ck",
> > +	"clk26m"
> > +};
> > +
> > +static const char * const intdir_parents[] = {
> > +	"clk26m",
> > +	"mmpll_ck",
> > +	"syspll_d2",
> > +	"univpll_d2"
> > +};
> > +
> > +static const char * const asm_parents[] = {
> > +	"clk26m",
> > +	"univpll2_d4",
> > +	"univpll2_d2",
> > +	"syspll_d5"
> > +};
> > +
> > +static const char * const ms_card_parents[] = {
> > +	"clk26m",
> > +	"univpll3_d8",
> > +	"syspll4_d4"
> > +};
> > +
> > +static const char * const ethif_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d2",
> > +	"syspll_d5",
> > +	"syspll1_d4",
> > +	"univpll_d5",
> > +	"univpll1_d2",
> > +	"dmpll_ck",
> > +	"dmpll_d2"
> > +};
> > +
> > +static const char * const hdmirx_parents[] = {
> > +	"clk26m",
> > +	"univpll_d52"
> > +};
> > +
> > +static const char * const cmsys_parents[] = {
> > +	"clk26m",
> > +	"syspll1_d2",
> > +	"univpll1_d2",
> > +	"univpll_d5",
> > +	"syspll_d5",
> > +	"syspll2_d2",
> > +	"syspll1_d4",
> > +	"syspll3_d2",
> > +	"syspll2_d4",
> > +	"syspll1_d8",
> > +	"clk26m",
> > +	"clk26m",
> > +	"clk26m",
> > +	"clk26m",
> > +	"clk26m"
> > +};
> > +
> > +static const char * const clk_8bdac_parents[] = {
> > +	"32k_internal",
> > +	"8bdac_ck",
> > +	"clk26m",
> > +	"clk26m"
> > +};
> > +
> > +static const char * const aud2dvd_parents[] = {
> > +	"a1sys_hp_ck",
> > +	"a2sys_hp_ck"
> > +};
> > +
> > +static const char * const padmclk_parents[] = {
> > +	"clk26m",
> > +	"univpll_d26",
> > +	"univpll_d52",
> > +	"univpll_d108",
> > +	"univpll2_d8",
> > +	"univpll2_d16",
> > +	"univpll2_d32"
> > +};
> > +
> > +static const char * const aud_mux_parents[] = {
> > +	"clk26m",
> > +	"aud1pll_98m_ck",
> > +	"aud2pll_90m_ck",
> > +	"hadds2pll_98m",
> > +	"audio_ext1_ck",
> > +	"audio_ext2_ck"
> > +};
> > +
> > +static const char * const aud_src_parents[] = {
> > +	"aud_mux1_sel",
> > +	"aud_mux2_sel"
> > +};
> > +
> > +static const char * const cpu_parents[] = {
> > +	"clk26m",
> > +	"armpll",
> > +	"mainpll",
> > +	"mmpll"
> > +};
> > +
> > +static const struct mtk_composite top_muxes[] = {
> > +	MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
> > +		0x0040, 0, 3, 7, CLK_IS_CRITICAL),
> > +	MUX_GATE_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
> > +		0x0040, 8, 1, 15, CLK_IS_CRITICAL),
> > +	MUX_GATE_FLAGS(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel",
> > +		ddrphycfg_parents, 0x0040, 16, 1, 23, CLK_IS_CRITICAL),
> > +	MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents,
> > +		0x0040, 24, 3, 31),
> > +
> > +	MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
> > +		0x0050, 0, 2, 7),
> > +	MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents,
> > +		0x0050, 8, 4, 15),
> > +	MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents,
> > +		0x0050, 16, 3, 23),
> > +	MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents,
> > +		0x0050, 24, 3, 31),
> > +	MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
> > +		0x0060, 0, 1, 7),
> > +
> > +	MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi_parents,
> > +		0x0060, 8, 3, 15),
> > +	MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents,
> > +		0x0060, 16, 2, 23),
> > +	MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents,
> > +		0x0060, 24, 3, 31),
> > +
> > +	MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents,
> > +		0x0070, 0, 3, 7),
> > +	MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents,
> > +		0x0070, 8, 3, 15),
> > +	MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", msdc30_parents,
> > +		0x0070, 16, 1, 23),
> > +	MUX_GATE(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
> > +		0x0070, 24, 3, 31),
> > +
> > +	MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents,
> > +		0x0080, 0, 4, 7),
> > +	MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents,
> > +		0x0080, 8, 2, 15),
> > +	MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents,
> > +		0x0080, 16, 3, 23),
> > +	MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents,
> > +		0x0080, 24, 2, 31),
> > +
> > +	MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents,
> > +		0x0090, 0, 3, 7),
> > +	MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents,
> > +		0x0090, 8, 2, 15),
> > +	MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents,
> > +		0x0090, 16, 3, 23),
> > +
> > +	MUX_GATE_FLAGS(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents,
> > +		0x00A0, 0, 2, 7, CLK_IS_CRITICAL),
> > +	MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents,
> > +		0x00A0, 8, 3, 15),
> > +	MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, "emmc_hclk_sel", emmc_hclk_parents,
> > +		0x00A0, 24, 2, 31),
> > +
> > +	MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents,
> > +		0x00B0, 0, 3, 7),
> > +	MUX_GATE(CLK_TOP_DI_SEL, "di_sel", di_parents,
> > +		0x00B0, 8, 2, 15),
> > +	MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", nr_osd_parents,
> > +		0x00B0, 16, 3, 23),
> > +	MUX_GATE(CLK_TOP_OSD_SEL, "osd_sel", nr_osd_parents,
> > +		0x00B0, 24, 3, 31),
> > +
> > +	MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, "hdmirx_bist_sel",
> > +		hdmirx_bist_parents, 0x00C0, 0, 3, 7),
> > +	MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents,
> > +		0x00C0, 8, 2, 15),
> > +	MUX_GATE(CLK_TOP_ASM_I_SEL, "asm_i_sel", asm_parents,
> > +		0x00C0, 16, 2, 23),
> > +	MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_parents,
> > +		0x00C0, 24, 3, 31),
> > +
> > +	MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_parents,
> > +		0x00D0, 0, 2, 7),
> > +	MUX_GATE(CLK_TOP_MS_CARD_SEL, "ms_card_sel", ms_card_parents,
> > +		0x00D0, 16, 2, 23),
> > +	MUX_GATE(CLK_TOP_ETHIF_SEL, "ethif_sel", ethif_parents,
> > +		0x00D0, 24, 3, 31),
> > +
> > +	MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, "hdmirx26_24_sel", hdmirx_parents,
> > +		0x00E0, 0, 1, 7),
> > +	MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents,
> > +		0x00E0, 8, 3, 15),
> > +	MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", cmsys_parents,
> > +		0x00E0, 16, 4, 23),
> > +
> > +	MUX_GATE(CLK_TOP_SPI1_SEL, "spi2_sel", spi_parents,
> > +		0x00E0, 24, 3, 31),
> > +	MUX_GATE(CLK_TOP_SPI2_SEL, "spi1_sel", spi_parents,
> > +		0x00F0, 0, 3, 7),
> > +	MUX_GATE(CLK_TOP_8BDAC_SEL, "8bdac_sel", clk_8bdac_parents,
> > +		0x00F0, 8, 2, 15),
> > +	MUX_GATE(CLK_TOP_AUD2DVD_SEL, "aud2dvd_sel", aud2dvd_parents,
> > +		0x00F0, 16, 1, 23),
> > +
> > +	MUX(CLK_TOP_PADMCLK_SEL, "padmclk_sel", padmclk_parents,
> > +		0x0100, 0, 3),
> > +
> > +	MUX(CLK_TOP_AUD_MUX1_SEL, "aud_mux1_sel", aud_mux_parents,
> > +		0x012c, 0, 3),
> > +	MUX(CLK_TOP_AUD_MUX2_SEL, "aud_mux2_sel", aud_mux_parents,
> > +		0x012c, 3, 3),
> > +	MUX(CLK_TOP_AUDPLL_MUX_SEL, "audpll_sel", aud_mux_parents,
> > +		0x012c, 6, 3),
> > +	MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, "aud_k1_src_sel", aud_src_parents,
> > +		0x012c, 15, 1, 23),
> > +	MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, "aud_k2_src_sel", aud_src_parents,
> > +		0x012c, 16, 1, 24),
> > +	MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, "aud_k3_src_sel", aud_src_parents,
> > +		0x012c, 17, 1, 25),
> > +	MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, "aud_k4_src_sel", aud_src_parents,
> > +		0x012c, 18, 1, 26),
> > +	MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, "aud_k5_src_sel", aud_src_parents,
> > +		0x012c, 19, 1, 27),
> > +	MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, "aud_k6_src_sel", aud_src_parents,
> > +		0x012c, 20, 1, 28),
> > +};
> > +
> > +static const struct mtk_clk_divider top_adj_divs[] = {
> > +	DIV_ADJ(CLK_TOP_AUD_EXTCK1_DIV, "audio_ext1_ck", "aud_ext1",
> > +		0x0120, 0, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_EXTCK2_DIV, "audio_ext2_ck", "aud_ext2",
> > +		0x0120, 8, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_MUX1_DIV, "aud_mux1_div", "aud_mux1_sel",
> > +		0x0120, 16, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_MUX2_DIV, "aud_mux2_div", "aud_mux2_sel",
> > +		0x0120, 24, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_K1_SRC_DIV, "aud_k1_src_div", "aud_k1_src_sel",
> > +		0x0124, 0, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_K2_SRC_DIV, "aud_k2_src_div", "aud_k2_src_sel",
> > +		0x0124, 8, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_K3_SRC_DIV, "aud_k3_src_div", "aud_k3_src_sel",
> > +		0x0124, 16, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_K4_SRC_DIV, "aud_k4_src_div", "aud_k4_src_sel",
> > +		0x0124, 24, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_K5_SRC_DIV, "aud_k5_src_div", "aud_k5_src_sel",
> > +		0x0128, 0, 8),
> > +	DIV_ADJ(CLK_TOP_AUD_K6_SRC_DIV, "aud_k6_src_div", "aud_k6_src_sel",
> > +		0x0128, 8, 8),
> > +};
> > +
> > +static const struct mtk_gate_regs top_aud_cg_regs = {
> > +	.sta_ofs = 0x012C,
> > +};
> > +
> > +#define GATE_TOP_AUD(_id, _name, _parent, _shift) {	\
> > +		.id = _id,				\
> > +		.name = _name,				\
> > +		.parent_name = _parent,			\
> > +		.regs = &top_aud_cg_regs,		\
> > +		.shift = _shift,			\
> > +		.ops = &mtk_clk_gate_ops_no_setclr,	\
> > +	}
> > +
> > +static const struct mtk_gate top_clks[] = {
> > +	GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div",
> > +		21),
> > +	GATE_TOP_AUD(CLK_TOP_AUD_44K_TIMING, "a2sys_hp_ck", "aud_mux2_div",
> > +		22),
> > +	GATE_TOP_AUD(CLK_TOP_AUD_I2S1_MCLK, "aud_i2s1_mclk", "aud_k1_src_div",
> > +		23),
> > +	GATE_TOP_AUD(CLK_TOP_AUD_I2S2_MCLK, "aud_i2s2_mclk", "aud_k2_src_div",
> > +		24),
> > +	GATE_TOP_AUD(CLK_TOP_AUD_I2S3_MCLK, "aud_i2s3_mclk", "aud_k3_src_div",
> > +		25),
> > +	GATE_TOP_AUD(CLK_TOP_AUD_I2S4_MCLK, "aud_i2s4_mclk", "aud_k4_src_div",
> > +		26),
> > +	GATE_TOP_AUD(CLK_TOP_AUD_I2S5_MCLK, "aud_i2s5_mclk", "aud_k5_src_div",
> > +		27),
> > +	GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div",
> > +		28),
> > +};
> > +
> > +void __iomem *devm_of_iomap(struct device *dev, int index)
> 
> Sorry what is this?

To reduce duplicated code of looking up base address.

> > +{
> > +	struct resource res;
> > +
> > +	if (!dev)
> > +		return NULL;
> > +
> > +	if (of_address_to_resource(dev->of_node, index, &res))
> > +		return NULL;
> > +
> > +	return devm_ioremap(dev, res.start, resource_size(&res));
> 
> Can't we just use platform_get_resouce() and
> devm_ioremap_resource() here? It looks like we always have a
> platform device.

I'll change it with these 2 functions.

> > +}
> > +
> > +static int mtk_topckgen_init(struct platform_device *pdev)
> > +{
> > +	struct clk_onecell_data *clk_data;
> > +	void __iomem *base;
> > +	int r;
> > +	struct device_node *node = pdev->dev.of_node;
> > +
> > +	base = devm_of_iomap(&pdev->dev, 0);
> > +	if (!base)
> > +		return -ENOMEM;
> > +
> > +	clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
> > +
> > +	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
> > +								clk_data);
> > +
> > +	mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
> > +								clk_data);
> > +
> > +	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
> > +				base, &lock, clk_data);
> > +
> > +	mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
> > +				base, &lock, clk_data);
> > +
> > +	mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
> > +						clk_data);
> > +
> > +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > +	return r;
> > +}
> > +
> > +static const struct mtk_gate_regs infra_cg_regs = {
> > +	.set_ofs = 0x0040,
> > +	.clr_ofs = 0x0044,
> > +	.sta_ofs = 0x0048,
> > +};
> > +
> > +#define GATE_ICG(_id, _name, _parent, _shift) {		\
> > +		.id = _id,				\
> > +		.name = _name,				\
> > +		.parent_name = _parent,			\
> > +		.regs = &infra_cg_regs,			\
> > +		.shift = _shift,			\
> > +		.ops = &mtk_clk_gate_ops_setclr,	\
> > +	}
> > +
> > +static const struct mtk_gate infra_clks[] = {
> > +	GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0),
> > +	GATE_ICG(CLK_INFRA_SMI, "smi_ck", "mm_sel", 1),
> > +	GATE_ICG(CLK_INFRA_QAXI_CM4, "cm4_ck", "axi_sel", 2),
> > +	GATE_ICG(CLK_INFRA_AUD_SPLIN_B, "audio_splin_bck", "hadds2pll_294m", 4),
> > +	GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "clk26m", 5),
> > +	GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "clk26m", 6),
> > +	GATE_ICG(CLK_INFRA_L2C_SRAM, "l2c_sram_ck", "mm_sel", 7),
> > +	GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
> > +	GATE_ICG(CLK_INFRA_CONNMCU, "connsys_bus", "wbg_dig_ck_416m", 12),
> > +	GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 13),
> > +	GATE_ICG(CLK_INFRA_RAMBUFIF, "rambufif_ck", "mem_sel", 14),
> > +	GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "mem_sel", 15),
> > +	GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
> > +	GATE_ICG(CLK_INFRA_CEC, "cec_ck", "rtc_sel", 18),
> > +	GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 19),
> > +	GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22),
> > +	GATE_ICG(CLK_INFRA_PMICWRAP, "pmicwrap_ck", "axi_sel", 23),
> > +	GATE_ICG(CLK_INFRA_DDCCI, "ddcci_ck", "axi_sel", 24),
> > +};
> > +
> > +static const struct mtk_fixed_factor infra_fixed_divs[] = {
> > +	FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
> > +};
> > +
> > +static struct clk_onecell_data *infra_clk_data;
> > +
> > +static void mtk_infrasys_init_early(struct device_node *node)
> > +{
> > +	int r, i;
> > +
> > +	if (!infra_clk_data) {
> > +		infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
> > +
> > +		for (i = 0; i < CLK_INFRA_NR; i++)
> > +			infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
> > +	}
> > +
> > +	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
> > +						infra_clk_data);
> > +
> > +	r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
> > +	if (r)
> > +		pr_err("%s(): could not register clock provider: %d\n",
> > +			__func__, r);
> > +}
> > +CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt2701-infracfg",
> > +			mtk_infrasys_init_early);
> > +
> > +static int mtk_infrasys_init(struct platform_device *pdev)
> > +{
> > +	int r, i;
> > +	struct device_node *node = pdev->dev.of_node;
> > +
> > +	if (!infra_clk_data) {
> > +		infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
> > +	} else {
> > +		for (i = 0; i < CLK_INFRA_NR; i++) {
> > +			if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
> > +				infra_clk_data->clks[i] = ERR_PTR(-ENOENT);
> > +		}
> > +	}
> > +
> > +	mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
> > +						infra_clk_data);
> > +	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
> > +						infra_clk_data);
> > +
> > +	r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
> > +
> > +	return r;
> > +}
> > +
> > +static const struct mtk_gate_regs peri0_cg_regs = {
> > +	.set_ofs = 0x0008,
> > +	.clr_ofs = 0x0010,
> > +	.sta_ofs = 0x0018,
> > +};
> > +
> > +static const struct mtk_gate_regs peri1_cg_regs = {
> > +	.set_ofs = 0x000c,
> > +	.clr_ofs = 0x0014,
> > +	.sta_ofs = 0x001c,
> > +};
> > +
> > +#define GATE_PERI0(_id, _name, _parent, _shift) {	\
> > +		.id = _id,				\
> > +		.name = _name,				\
> > +		.parent_name = _parent,			\
> > +		.regs = &peri0_cg_regs,			\
> > +		.shift = _shift,			\
> > +		.ops = &mtk_clk_gate_ops_setclr,	\
> > +	}
> > +
> > +#define GATE_PERI1(_id, _name, _parent, _shift) {	\
> > +		.id = _id,				\
> > +		.name = _name,				\
> > +		.parent_name = _parent,			\
> > +		.regs = &peri1_cg_regs,			\
> > +		.shift = _shift,			\
> > +		.ops = &mtk_clk_gate_ops_setclr,	\
> > +	}
> > +
> > +static const struct mtk_gate peri_clks[] = {
> > +	GATE_PERI0(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31),
> > +	GATE_PERI0(CLK_PERI_ETH, "eth_ck", "clk26m", 30),
> > +	GATE_PERI0(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 29),
> > +	GATE_PERI0(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 28),
> > +	GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "clk26m", 27),
> > +	GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 26),
> > +	GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 25),
> > +	GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 24),
> > +	GATE_PERI0(CLK_PERI_BTIF, "bitif_ck", "axi_sel", 23),
> > +	GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 22),
> > +	GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 21),
> > +	GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 20),
> > +	GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 19),
> > +	GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 18),
> > +	GATE_PERI0(CLK_PERI_MSDC50_3, "msdc50_3_ck", "emmc_hclk_sel", 17),
> > +	GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_3_sel", 16),
> > +	GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_2_sel", 15),
> > +	GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 14),
> > +	GATE_PERI0(CLK_PERI_MSDC30_0, "msdc30_0_ck", "msdc30_0_sel", 13),
> > +	GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12),
> > +	GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11),
> > +	GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10),
> > +	GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9),
> > +	GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8),
> > +	GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7),
> > +	GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6),
> > +	GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5),
> > +	GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4),
> > +	GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3),
> > +	GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2),
> > +	GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1),
> > +	GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0),
> > +
> > +	GATE_PERI1(CLK_PERI_FCI, "fci_ck", "ms_card_sel", 11),
> > +	GATE_PERI1(CLK_PERI_SPI2, "spi2_ck", "spi2_sel", 10),
> > +	GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi1_sel", 9),
> > +	GATE_PERI1(CLK_PERI_HOST89_DVD, "host89_dvd_ck", "aud2dvd_sel", 8),
> > +	GATE_PERI1(CLK_PERI_HOST89_SPI, "host89_spi_ck", "spi0_sel", 7),
> > +	GATE_PERI1(CLK_PERI_HOST89_INT, "host89_int_ck", "axi_sel", 6),
> > +	GATE_PERI1(CLK_PERI_FLASH, "flash_ck", "nfi2x_sel", 5),
> > +	GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "nfi1x_pad", 4),
> > +	GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "nfi1x_pad", 3),
> > +	GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 2),
> > +	GATE_PERI1(CLK_PERI_USB_SLV, "usbslv_ck", "axi_sel", 1),
> > +	GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 0),
> > +};
> > +
> > +static const char * const uart_ck_sel_parents[] = {
> > +	"clk26m",
> > +	"uart_sel",
> > +};
> > +
> > +static const struct mtk_composite peri_muxs[] = {
> > +	MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents,
> > +		0x40c, 0, 1),
> > +	MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents,
> > +		0x40c, 1, 1),
> > +	MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents,
> > +		0x40c, 2, 1),
> > +	MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents,
> > +		0x40c, 3, 1),
> > +};
> > +
> > +static int mtk_pericfg_init(struct platform_device *pdev)
> > +{
> > +	struct clk_onecell_data *clk_data;
> > +	void __iomem *base;
> > +	int r;
> > +	struct device_node *node = pdev->dev.of_node;
> > +
> > +	base = devm_of_iomap(&pdev->dev, 0);
> > +	if (!base)
> > +		return -ENOMEM;
> > +
> > +	clk_data = mtk_alloc_clk_data(CLK_PERI_NR);
> > +
> > +	mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
> > +						clk_data);
> > +
> > +	mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
> > +			&lock, clk_data);
> > +
> > +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > +	return r;
> 
> Just return of_clk_add_provider()?

Okay.

> > +}
> [...]
> > +
> > +static int clk_mt2701_probe(struct platform_device *pdev)
> > +{
> > +	int (*clk_init)(struct platform_device *);
> > +	int r;
> > +
> > +	clk_init = of_device_get_match_data(&pdev->dev);
> > +	if (!clk_init)
> > +		return -EINVAL;
> > +
> > +	r = clk_init(pdev);
> > +	if (r) {
> > +		dev_err(&pdev->dev,
> > +			"could not register clock provider: %s: %d\n",
> > +			pdev->name, r);
> > +	}
> 
> Braces are unnecessary.

I'll remove it.

> > +
> > +	return r;
> > +}
> > +
> > +static struct platform_driver clk_mt2701_drv = {
> > +	.probe = clk_mt2701_probe,
> > +	.driver = {
> > +		.name = "clk-mt2701",
> > +		.owner = THIS_MODULE,
> 
> This is unnecessary because platform_driver_register() already
> does it.

Okay, I'll remove it.

> > +		.of_match_table = of_match_clk_mt2701,
> > +	},
> > +};
> > +
> > +static int __init clk_mt2701_init(void)
> > +{
> > +	return platform_driver_register(&clk_mt2701_drv);
> > +}
> > +
> > +arch_initcall(clk_mt2701_init);
> > diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> > index bb30f70..0541df7 100644
> > --- a/drivers/clk/mediatek/clk-mtk.c
> > +++ b/drivers/clk/mediatek/clk-mtk.c
> > @@ -58,6 +58,9 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
> >  	for (i = 0; i < num; i++) {
> >  		const struct mtk_fixed_clk *rc = &clks[i];
> >  
> > +		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[rc->id]))
> > +			continue;
> > +
> >  		clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
> >  					      rc->rate);
> >  
> > @@ -81,6 +84,9 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
> >  	for (i = 0; i < num; i++) {
> >  		const struct mtk_fixed_factor *ff = &clks[i];
> >  
> > +		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[ff->id]))
> > +			continue;
> > +
> >  		clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
> >  				CLK_SET_RATE_PARENT, ff->mult, ff->div);
> >  
> > @@ -116,6 +122,9 @@ int mtk_clk_register_gates(struct device_node *node,
> >  	for (i = 0; i < num; i++) {
> >  		const struct mtk_gate *gate = &clks[i];
> >  
> > +		if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
> > +			continue;
> > +
> >  		clk = mtk_clk_register_gate(gate->name, gate->parent_name,
> >  				regmap,
> >  				gate->regs->set_ofs,
> > @@ -232,6 +241,9 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
> >  	for (i = 0; i < num; i++) {
> >  		const struct mtk_composite *mc = &mcs[i];
> >  
> > +		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mc->id]))
> > +			continue;
> > +
> >  		clk = mtk_clk_register_composite(mc, base, lock);
> >  
> >  		if (IS_ERR(clk)) {
> > @@ -244,3 +256,31 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
> >  			clk_data->clks[mc->id] = clk;
> >  	}
> >  }
> > +
> > +void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
> > +			int num, void __iomem *base, spinlock_t *lock,
> > +				struct clk_onecell_data *clk_data)
> > +{
> > +	struct clk *clk;
> > +	int i;
> > +
> > +	for (i = 0; i <  num; i++) {
> > +		const struct mtk_clk_divider *mcd = &mcds[i];
> > +
> > +		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
> 
> NULL is a valid clk. IS_ERR_OR_NULL is usually wrong.

Why NULL is a valid clk?

clk_data is designed for multiple initialization from different clock
types, such as infra_clk_data in clk-mt2701.c. So it will ignore valid
clocks to avoid duplicated clock registration. Here I assume a clock
pointer with error code or NULL to be an invalid (not initialized)
clock.

> > +			continue;
> > +
> > +		clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
> > +			mcd->flags, base +  mcd->div_reg, mcd->div_shift,
> > +			mcd->div_width, mcd->clk_divider_flags, lock);
> > +
> > +		if (IS_ERR(clk)) {
> > +			pr_err("Failed to register clk %s: %ld\n",
> > +				mcd->name, PTR_ERR(clk));
> > +			continue;
> > +		}
> > +
> > +		if (clk_data)
> > +			clk_data->clks[mcd->id] = clk;
> > +	}
> > +}
> > diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> > index 9f24fcf..f5d6b70 100644
> > --- a/drivers/clk/mediatek/clk-mtk.h
> > +++ b/drivers/clk/mediatek/clk-mtk.h
> > @@ -87,7 +87,8 @@ struct mtk_composite {
> >   * In case the rate change propagation to parent clocks is undesirable,
> >   * this macro allows to specify the clock flags manually.
> >   */
> > -#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, _gate, _flags) {	\
> > +#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\
> > +			_gate, _flags) {				\
> >  		.id = _id,						\
> >  		.name = _name,						\
> >  		.mux_reg = _reg,					\
> > @@ -106,7 +107,8 @@ struct mtk_composite {
> >   * parent clock by default.
> >   */
> >  #define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate)	\
> > -	MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, _gate, CLK_SET_RATE_PARENT)
> > +	MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\
> > +		_gate, CLK_SET_RATE_PARENT)
> >  
> >  #define MUX(_id, _name, _parents, _reg, _shift, _width) {		\
> >  		.id = _id,						\
> > @@ -121,7 +123,8 @@ struct mtk_composite {
> >  		.flags = CLK_SET_RATE_PARENT,				\
> >  	}
> >  
> > -#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) {	\
> > +#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg,	\
> > +					_div_width, _div_shift) {	\
> 
> Did anything actually change? Checkpatch fix?

Right. Just limit max line length to 80 chars.

> >  		.id = _id,						\
> >  		.parent = _parent,					\
> >  		.name = _name,						\

^ permalink raw reply

* [PATCHv2 3/4] mfd: altr-a10sr: Add Arria10 SR Monitor
From: Lee Jones @ 2016-10-31  8:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477598426-28125-4-git-send-email-tthayer@opensource.altera.com>

On Thu, 27 Oct 2016, tthayer at opensource.altera.com wrote:

> From: Thor Thayer <tthayer@opensource.altera.com>
> 
> Add the Altera Arria10 DevKit System Resource Monitor functionality
> to the MFD device.
> 
> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
> ---
> v2  Change from -mon to -monitor for clarity
> ---
>  drivers/mfd/altera-a10sr.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/mfd/altera-a10sr.c b/drivers/mfd/altera-a10sr.c
> index 06e1f7f..30de652 100644
> --- a/drivers/mfd/altera-a10sr.c
> +++ b/drivers/mfd/altera-a10sr.c
> @@ -33,6 +33,10 @@
>  		.name = "altr_a10sr_gpio",
>  		.of_compatible = "altr,a10sr-gpio",
>  	},
> +	{
> +		.name = "altr_a10sr_monitor",
> +		.of_compatible = "altr,a10sr-monitor",

So long as you use whichever compatible you agree on with Rob:

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

> +	},
>  };
>  
>  static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)

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

^ permalink raw reply

* [PATCH] staging: vc04_services: add vchiq_pagelist_info structure
From: Michael Zoran @ 2016-10-31  8:10 UTC (permalink / raw)
  To: linux-arm-kernel

The current dma_map_sg based implementation for bulk messages
computes many offsets into a single allocation multiple times in
both the create and free code paths.  This is inefficient,
error prone and in fact still has a few lingering issues
with arm64.

This change replaces a small portion of that inplementation with
new code that uses a new struct vchiq_pagelist_info to store the
needed information rather then complex offset calculations.

This improved implementation should be more efficient and easier
to understand and maintain.

Tests Run(Both Pass):
vchiq_test -p 1
vchiq_test -f 10

Signed-off-by: Michael Zoran <mzoran@crowfest.net>
---
 .../interface/vchiq_arm/vchiq_2835_arm.c           | 223 +++++++++++----------
 1 file changed, 113 insertions(+), 110 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
index 12938f2..a297d89 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -62,6 +62,18 @@ typedef struct vchiq_2835_state_struct {
    VCHIQ_ARM_STATE_T arm_state;
 } VCHIQ_2835_ARM_STATE_T;
 
+struct vchiq_pagelist_info {
+	PAGELIST_T *pagelist;
+	size_t pagelist_buffer_size;
+	dma_addr_t dma_addr;
+	enum dma_data_direction dma_dir;
+	unsigned int num_pages;
+	unsigned int pages_need_release;
+	struct page **pages;
+	struct scatterlist *scatterlist;
+	unsigned int scatterlist_mapped;
+};
+
 static void __iomem *g_regs;
 static unsigned int g_cache_line_size = sizeof(CACHE_LINE_SIZE);
 static unsigned int g_fragments_size;
@@ -77,13 +89,13 @@ static DEFINE_SEMAPHORE(g_free_fragments_mutex);
 static irqreturn_t
 vchiq_doorbell_irq(int irq, void *dev_id);
 
-static int
+static struct vchiq_pagelist_info *
 create_pagelist(char __user *buf, size_t count, unsigned short type,
-		struct task_struct *task, PAGELIST_T **ppagelist,
-		dma_addr_t *dma_addr);
+		struct task_struct *task);
 
 static void
-free_pagelist(dma_addr_t dma_addr, PAGELIST_T *pagelist, int actual);
+free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
+	      int actual);
 
 int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
 {
@@ -226,29 +238,27 @@ VCHIQ_STATUS_T
 vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk, VCHI_MEM_HANDLE_T memhandle,
 	void *offset, int size, int dir)
 {
-	PAGELIST_T *pagelist;
-	int ret;
-	dma_addr_t dma_addr;
+	struct vchiq_pagelist_info *pagelistinfo;
 
 	WARN_ON(memhandle != VCHI_MEM_HANDLE_INVALID);
 
-	ret = create_pagelist((char __user *)offset, size,
-			(dir == VCHIQ_BULK_RECEIVE)
-			? PAGELIST_READ
-			: PAGELIST_WRITE,
-			current,
-			&pagelist,
-			&dma_addr);
+	pagelistinfo = create_pagelist((char __user *)offset, size,
+				       (dir == VCHIQ_BULK_RECEIVE)
+				       ? PAGELIST_READ
+				       : PAGELIST_WRITE,
+				       current);
 
-	if (ret != 0)
+	if (!pagelistinfo)
 		return VCHIQ_ERROR;
 
 	bulk->handle = memhandle;
-	bulk->data = (void *)(unsigned long)dma_addr;
+	bulk->data = (void *)(unsigned long)pagelistinfo->dma_addr;
 
-	/* Store the pagelist address in remote_data, which isn't used by the
-	   slave. */
-	bulk->remote_data = pagelist;
+	/*
+	 * Store the pagelistinfo address in remote_data,
+	 * which isn't used by the slave.
+	 */
+	bulk->remote_data = pagelistinfo;
 
 	return VCHIQ_SUCCESS;
 }
@@ -257,8 +267,8 @@ void
 vchiq_complete_bulk(VCHIQ_BULK_T *bulk)
 {
 	if (bulk && bulk->remote_data && bulk->actual)
-		free_pagelist((dma_addr_t)(unsigned long)bulk->data,
-			      (PAGELIST_T *)bulk->remote_data, bulk->actual);
+		free_pagelist((struct vchiq_pagelist_info *)bulk->remote_data,
+			      bulk->actual);
 }
 
 void
@@ -346,6 +356,25 @@ vchiq_doorbell_irq(int irq, void *dev_id)
 	return ret;
 }
 
+static void
+cleaup_pagelistinfo(struct vchiq_pagelist_info *pagelistinfo)
+{
+	if (pagelistinfo->scatterlist_mapped) {
+		dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
+			     pagelistinfo->num_pages, pagelistinfo->dma_dir);
+	}
+
+	if (pagelistinfo->pages_need_release) {
+		unsigned int i;
+
+		for (i = 0; i < pagelistinfo->num_pages; i++)
+			put_page(pagelistinfo->pages[i]);
+	}
+
+	dma_free_coherent(g_dev, pagelistinfo->pagelist_buffer_size,
+			  pagelistinfo->pagelist, pagelistinfo->dma_addr);
+}
+
 /* There is a potential problem with partial cache lines (pages?)
 ** at the ends of the block when reading. If the CPU accessed anything in
 ** the same line (page?) then it may have pulled old data into the cache,
@@ -354,52 +383,64 @@ vchiq_doorbell_irq(int irq, void *dev_id)
 ** cached area.
 */
 
-static int
+static struct vchiq_pagelist_info *
 create_pagelist(char __user *buf, size_t count, unsigned short type,
-		struct task_struct *task, PAGELIST_T **ppagelist,
-		dma_addr_t *dma_addr)
+		struct task_struct *task)
 {
 	PAGELIST_T *pagelist;
+	struct vchiq_pagelist_info *pagelistinfo;
 	struct page **pages;
 	u32 *addrs;
 	unsigned int num_pages, offset, i, k;
 	int actual_pages;
-        unsigned long *need_release;
 	size_t pagelist_size;
 	struct scatterlist *scatterlist, *sg;
 	int dma_buffers;
-	int dir;
+	dma_addr_t dma_addr;
 
 	offset = ((unsigned int)(unsigned long)buf & (PAGE_SIZE - 1));
 	num_pages = (count + offset + PAGE_SIZE - 1) / PAGE_SIZE;
 
 	pagelist_size = sizeof(PAGELIST_T) +
-			(num_pages * sizeof(unsigned long)) +
-			sizeof(unsigned long) +
+			(num_pages * sizeof(u32)) +
 			(num_pages * sizeof(pages[0]) +
-			(num_pages * sizeof(struct scatterlist)));
-
-	*ppagelist = NULL;
-
-	dir = (type == PAGELIST_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+			(num_pages * sizeof(struct scatterlist))) +
+			sizeof(struct vchiq_pagelist_info);
 
 	/* Allocate enough storage to hold the page pointers and the page
 	** list
 	*/
 	pagelist = dma_zalloc_coherent(g_dev,
 				       pagelist_size,
-				       dma_addr,
+				       &dma_addr,
 				       GFP_KERNEL);
 
 	vchiq_log_trace(vchiq_arm_log_level, "create_pagelist - %pK",
 			pagelist);
 	if (!pagelist)
-		return -ENOMEM;
+		return NULL;
+
+	addrs		= pagelist->addrs;
+	pages		= (struct page **)(addrs + num_pages);
+	scatterlist	= (struct scatterlist *)(pages + num_pages);
+	pagelistinfo	= (struct vchiq_pagelist_info *)
+			  (scatterlist + num_pages);
 
-	addrs = pagelist->addrs;
-        need_release = (unsigned long *)(addrs + num_pages);
-	pages = (struct page **)(addrs + num_pages + 1);
-	scatterlist = (struct scatterlist *)(pages + num_pages);
+	pagelist->length = count;
+	pagelist->type = type;
+	pagelist->offset = offset;
+
+	/* Populate the fields of the pagelistinfo structure */
+	pagelistinfo->pagelist = pagelist;
+	pagelistinfo->pagelist_buffer_size = pagelist_size;
+	pagelistinfo->dma_addr = dma_addr;
+	pagelistinfo->dma_dir =  (type == PAGELIST_WRITE) ?
+				  DMA_TO_DEVICE : DMA_FROM_DEVICE;
+	pagelistinfo->num_pages = num_pages;
+	pagelistinfo->pages_need_release = 0;
+	pagelistinfo->pages = pages;
+	pagelistinfo->scatterlist = scatterlist;
+	pagelistinfo->scatterlist_mapped = 0;
 
 	if (is_vmalloc_addr(buf)) {
 		unsigned long length = count;
@@ -417,7 +458,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
 			length -= bytes;
 			off = 0;
 		}
-		*need_release = 0; /* do not try and release vmalloc pages */
+		/* do not try and release vmalloc pages */
 	} else {
 		down_read(&task->mm->mmap_sem);
 		actual_pages = get_user_pages(
@@ -440,34 +481,28 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
 				actual_pages--;
 				put_page(pages[actual_pages]);
 			}
-			dma_free_coherent(g_dev, pagelist_size,
-					  pagelist, *dma_addr);
-			if (actual_pages == 0)
-				actual_pages = -ENOMEM;
-			return actual_pages;
+			cleaup_pagelistinfo(pagelistinfo);
+			return NULL;
 		}
-		*need_release = 1; /* release user pages */
+		 /* release user pages */
+		pagelistinfo->pages_need_release = 1;
 	}
 
-	pagelist->length = count;
-	pagelist->type = type;
-	pagelist->offset = offset;
-
 	for (i = 0; i < num_pages; i++)
 		sg_set_page(scatterlist + i, pages[i], PAGE_SIZE, 0);
 
 	dma_buffers = dma_map_sg(g_dev,
 				 scatterlist,
 				 num_pages,
-				 dir);
+				 pagelistinfo->dma_dir);
 
 	if (dma_buffers == 0) {
-		dma_free_coherent(g_dev, pagelist_size,
-				  pagelist, *dma_addr);
-
-		return -EINTR;
+		cleaup_pagelistinfo(pagelistinfo);
+		return NULL;
 	}
 
+	pagelistinfo->scatterlist_mapped = 1;
+
 	/* Combine adjacent blocks for performance */
 	k = 0;
 	for_each_sg(scatterlist, sg, dma_buffers, i) {
@@ -499,11 +534,8 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
 		char *fragments;
 
 		if (down_interruptible(&g_free_fragments_sema) != 0) {
-			dma_unmap_sg(g_dev, scatterlist, num_pages,
-				     DMA_BIDIRECTIONAL);
-			dma_free_coherent(g_dev, pagelist_size,
-					  pagelist, *dma_addr);
-			return -EINTR;
+			cleaup_pagelistinfo(pagelistinfo);
+			return NULL;
 		}
 
 		WARN_ON(g_free_fragments == NULL);
@@ -517,42 +549,28 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
 			(fragments - g_fragments_base) / g_fragments_size;
 	}
 
-	*ppagelist = pagelist;
-
-	return 0;
+	return pagelistinfo;
 }
 
 static void
-free_pagelist(dma_addr_t dma_addr, PAGELIST_T *pagelist, int actual)
+free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
+	      int actual)
 {
-        unsigned long *need_release;
-	struct page **pages;
-	unsigned int num_pages, i;
-	size_t pagelist_size;
-	struct scatterlist *scatterlist;
-	int dir;
+	unsigned int i;
+	PAGELIST_T *pagelist   = pagelistinfo->pagelist;
+	struct page **pages    = pagelistinfo->pages;
+	unsigned int num_pages = pagelistinfo->num_pages;
 
 	vchiq_log_trace(vchiq_arm_log_level, "free_pagelist - %pK, %d",
-			pagelist, actual);
-
-	dir = (pagelist->type == PAGELIST_WRITE) ? DMA_TO_DEVICE :
-						   DMA_FROM_DEVICE;
-
-	num_pages =
-		(pagelist->length + pagelist->offset + PAGE_SIZE - 1) /
-		PAGE_SIZE;
+			pagelistinfo->pagelist, actual);
 
-	pagelist_size = sizeof(PAGELIST_T) +
-			(num_pages * sizeof(unsigned long)) +
-			sizeof(unsigned long) +
-			(num_pages * sizeof(pages[0]) +
-			(num_pages * sizeof(struct scatterlist)));
-
-        need_release = (unsigned long *)(pagelist->addrs + num_pages);
-	pages = (struct page **)(pagelist->addrs + num_pages + 1);
-	scatterlist = (struct scatterlist *)(pages + num_pages);
-
-	dma_unmap_sg(g_dev, scatterlist, num_pages, dir);
+	/*
+	 * NOTE: dma_unmap_sg must be called before the
+	 * cpu can touch any of the data/pages.
+	 */
+	dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
+		     pagelistinfo->num_pages, pagelistinfo->dma_dir);
+	pagelistinfo->scatterlist_mapped = 0;
 
 	/* Deal with any partial cache lines (fragments) */
 	if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) {
@@ -590,27 +608,12 @@ free_pagelist(dma_addr_t dma_addr, PAGELIST_T *pagelist, int actual)
 		up(&g_free_fragments_sema);
 	}
 
-	if (*need_release) {
-		unsigned int length = pagelist->length;
-		unsigned int offset = pagelist->offset;
-
-		for (i = 0; i < num_pages; i++) {
-			struct page *pg = pages[i];
-
-			if (pagelist->type != PAGELIST_WRITE) {
-				unsigned int bytes = PAGE_SIZE - offset;
-
-				if (bytes > length)
-					bytes = length;
-
-				length -= bytes;
-				offset = 0;
-				set_page_dirty(pg);
-			}
-			put_page(pg);
-		}
+	/* Need to mark all the pages dirty. */
+	if (pagelist->type != PAGELIST_WRITE &&
+	    pagelistinfo->pages_need_release) {
+		for (i = 0; i < num_pages; i++)
+			set_page_dirty(pages[i]);
 	}
 
-	dma_free_coherent(g_dev, pagelist_size,
-			  pagelist, dma_addr);
+	cleaup_pagelistinfo(pagelistinfo);
 }
-- 
2.10.1

^ permalink raw reply related

* [PATCH 1/4] mfd: ti_am335x_tscadc: store physical address
From: Lee Jones @ 2016-10-31  8:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <954adfa7-94d9-f785-aeab-6f20c8f4c3b9@kernel.org>

On Sun, 30 Oct 2016, Jonathan Cameron wrote:

> On 26/10/16 13:17, Lee Jones wrote:
> > On Fri, 30 Sep 2016, Mugunthan V N wrote:
> > 
> >> On Wednesday 28 September 2016 01:10 AM, Lee Jones wrote:
> >>> On Wed, 21 Sep 2016, Mugunthan V N wrote:
> >>>
> >>>> store the physical address of the device in its priv to use it
> >>>> for DMA addressing in the client drivers.
> >>>>
> >>>> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> >>>> ---
> >>>>  drivers/mfd/ti_am335x_tscadc.c       | 1 +
> >>>>  include/linux/mfd/ti_am335x_tscadc.h | 1 +
> >>>>  2 files changed, 2 insertions(+)
> >>>>
> >>>> diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
> >>>> index c8f027b..0f3fab4 100644
> >>>> --- a/drivers/mfd/ti_am335x_tscadc.c
> >>>> +++ b/drivers/mfd/ti_am335x_tscadc.c
> >>>> @@ -183,6 +183,7 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
> >>>>  		tscadc->irq = err;
> >>>>  
> >>>>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >>>> +	tscadc->tscadc_phys_base = res->start;
> >>>
> >>> This is unusual.  Can't you use a virt_to_phys() variant instead?
> >>>
> >>
> >> I tried using virt_to_phys(), but its not working for me.
> >> Also saw many drivers uses like this to get physical address
> >> ("git grep -n " res->start;" drivers/*").
> > 
> > Very well:
> > 
> > For my own reference:
> >   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> > 
> > Let me know how you wish this set to be handled.
> I'm happy to pick up the whole series.  There are some more mfd
> header changes in patch 2 but as they only add defines, I
> don't mind that much if I don't an Ack from you on those
> (btw this got to V3 but as patch 1 didn't change I'll carry
> your ack forwards).
> 
> Do you want an immutable branch?  Seems unlikely to cause
> much trouble even if there is a merge issue on all 10ish
> lines of mfd code in the next merge window.

Not at the moment, but if you could set things up so it's possible to
create one at a later date if things go Pete Tong, that would be
great.

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

^ permalink raw reply

* [PATCH] pinctrl: at91: add support for OUTPUT config
From: Linus Walleij @ 2016-10-31  8:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477641251-30468-1-git-send-email-wenyou.yang@atmel.com>

On Fri, Oct 28, 2016 at 9:54 AM, Wenyou Yang <wenyou.yang@atmel.com> wrote:

> From: Boris BREZILLON <b.brezillon@overkiz.com>
>
> Add support for pin output control through the pinctrl config:
>  - support enabling/disabling output on a given pin
>  - support output level setting (high or low)
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 1/2] ARM: oxnas: Add OX820 SMP support
From: Russell King - ARM Linux @ 2016-10-31  8:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9124cda0-d16b-0992-2552-8a617aeb5d40@baylibre.com>

On Mon, Oct 17, 2016 at 11:34:32AM +0200, Neil Armstrong wrote:
> On 10/17/2016 11:06 AM, Arnd Bergmann wrote:
> > On Monday, October 17, 2016 10:43:02 AM CEST Neil Armstrong wrote:
> > This seems to have been copied from plat-versatile, but is really
> > not needed here since you apparently have proper hardware support for
> > starting up the CPUs.
> Yes it seems.
> 
> > 
> > Any reason you can't just write to the cpu_ctrl register
> > once and keep going without that whole holding_pen loop
> > and spinlock?
> I suppose but I did not find any good examples except the plat-versatile code.
> I will try some simpler code.

There's plenty of examples - most ARM SMP platforms in the kernel now
do not blindly copy the versatile code.  You only have to go looking
for arch/arm/*/platsmp.c files to find them.

I'm not sure what you'd call a "good example" - maybe the imx code?
arch/arm/mach-imx/platsmp.c can't be simpler:

static int imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
        imx_set_cpu_jump(cpu, v7_secondary_startup);
        imx_enable_cpu(cpu, true);
        return 0;
}

I guess the difficult thing is to understand what each of those called
functions does... though the function names give a very accurate clue
there.

and because plat-versatile is almost entirely software-based, it's
easy to understand and follow, _despite_ being completely broken
for things like PM and kexec (which, the platform does not support.)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* [PATCH v4 00/23] soc: renesas: Add R-Car RST driver for obtaining mode pin state
From: Simon Horman @ 2016-10-31  8:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMuHMdVbpuv94x-ocTSDoEj+SbnESDbkuMXsXExQvoyZepp+Zg@mail.gmail.com>

On Wed, Oct 26, 2016 at 02:00:24PM +0200, Geert Uytterhoeven wrote:
> Hi Mike, Stephen,
> 
> On Fri, Oct 21, 2016 at 3:17 PM, Geert Uytterhoeven
> <geert+renesas@glider.be> wrote:
> > Currently the R-Car Clock Pulse Generator (CPG) drivers obtains the
> > state of the mode pins either by a call from the platform code, or
> > directly by using a hardcoded register access. This is a bit messy, and
> > creates a dependency between driver and platform code.
> >
> > This patch series converts the various Renesas R-Car clock drivers
> > and support code from reading the mode pin states using a hardcoded
> > register access to using a new minimalistic R-Car RST driver.
> >
> > All R-Car clock drivers will rely on the presence in DT of a device node
> > for the RST module.  Backwards compatibility with old DTBs is retained
> > only for R-Car Gen2, which has fallback code using its own private copy
> > of rcar_gen2_read_mode_pins().
> >
> > After this, there is still one remaining user of
> > rcar_gen2_read_mode_pins() left in platform code. A patch series to
> > remove that user has already been posted, though ("[PATCH/RFT 0/4] ARM:
> > shmobile: R-Car Gen2: Allow booting secondary CPU cores in debug mode").
> > Since v3, the other user has been removed in commit 9f5ce39ddb8f68b3
> > ("ARM: shmobile: rcar-gen2: Obtain extal frequency from DT").
> >
> > This series consists of 5 parts:
> >   A. Patches 1 and 2 add DT bindings and driver code for the R-Car RST
> >      driver,
> >   B. Patches 3-11 add device nodes for the RST modules to the R-Car DTS
> >      files,
> >   C. Patches 12-17 convert the clock drivers to call into the new R-Car
> >      RST driver,
> >   D. Patches 18-20 remove passing mode pin state to the clock drivers
> >      from the platform code,
> >   E. Patches 21-23 remove dead code from the clock drivers.
> >
> > As is usually the case with moving functionality from platform code to
> > DT, there are lots of hard dependencies:
> >   - The DT updates in Part B can be merged as soon as the DT bindings in
> >     Part A have been approved,
> >   - The clock driver updates in Part C depend functionally on the driver
> >     code in Part A, and on the DT updates in Part B,
> >   - The board code cleanups in Part D depend on the clock driver updates
> >     in Part C,
> >   - The block driver cleanups in part E depend on the board code
> >     cleanups in part D.
> >
> > Hence to maintain the required lockstep between SoC driver, clock
> > drivers, shmobile platform code, and shmobile DT, I propose to queue up
> > all patches in a single branch against v4.9-rc1, and send pull requests
> > to both Mike/Stephen (clock) and Simon (rest).
> >
> > ***
> 
> >   - Mike/Stephen/Simon/Magnus: Are you OK with the suggested merge
> >     approach above?
> 
> Is this OK for you?
> 
> I'd like to move forward with this, as this is a prerequisite for adding
> support for new SoCs (RZ/G) without adding more copies of
> rcar_gen2_read_mode_pins(), and removing that function from platform code
> for good.

This seems reasonable to me but likely the ARM SoC maintainers will want to
know about this plan before it is executed.

^ permalink raw reply

* [PATCH 0/6] mfd: audit and demodule drivers/mfd/ab* drivers
From: Linus Walleij @ 2016-10-31  8:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161030012440.10495-1-paul.gortmaker@windriver.com>

On Sun, Oct 30, 2016 at 2:24 AM, Paul Gortmaker
<paul.gortmaker@windriver.com> wrote:

> Nothing new here ; just another instance where we had modular remove
> and exit functions -- but the Makefile/Kconfig limited the use case to
> being always built-in; hence the code is useless and needs removing.
>
> So we remove the dead code and the misleading hints of modularity from
> these drivers, hoping that we manage to prevent some new drivers from
> copying these same old mistakes into pending new drivers.
(...)
> Paul Gortmaker (6):
>   mfd: ab3100-core: Make it explicitly non-modular
>   mfd: ab8500-core: Make it explicitly non-modular
>   mfd: ab8500-debugfs: Make it explicitly non-modular
>   mfd: ab8500-gpadc: Make it explicitly non-modular
>   mfd: ab8500: make sysctrl explicitly non-modular
>   mfd: abx500-core: drop unused MODULE_ tags from non-modular code

Acked-by: Linus Walleij <linus.walleij@linaro.org>

For the whole series.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v4 00/23] soc: renesas: Add R-Car RST driver for obtaining mode pin state
From: Geert Uytterhoeven @ 2016-10-31  8:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161031081923.GF18195@verge.net.au>

Hi Mike, Stephen, Arnd, Olof, Kevin,

Is the merge strategy [see ##### below] OK for you?
Thanks a lot!

On Mon, Oct 31, 2016 at 9:19 AM, Simon Horman <horms@verge.net.au> wrote:
> On Wed, Oct 26, 2016 at 02:00:24PM +0200, Geert Uytterhoeven wrote:
>> On Fri, Oct 21, 2016 at 3:17 PM, Geert Uytterhoeven
>> <geert+renesas@glider.be> wrote:
>> > Currently the R-Car Clock Pulse Generator (CPG) drivers obtains the
>> > state of the mode pins either by a call from the platform code, or
>> > directly by using a hardcoded register access. This is a bit messy, and
>> > creates a dependency between driver and platform code.
>> >
>> > This patch series converts the various Renesas R-Car clock drivers
>> > and support code from reading the mode pin states using a hardcoded
>> > register access to using a new minimalistic R-Car RST driver.
>> >
>> > All R-Car clock drivers will rely on the presence in DT of a device node
>> > for the RST module.  Backwards compatibility with old DTBs is retained
>> > only for R-Car Gen2, which has fallback code using its own private copy
>> > of rcar_gen2_read_mode_pins().
>> >
>> > After this, there is still one remaining user of
>> > rcar_gen2_read_mode_pins() left in platform code. A patch series to
>> > remove that user has already been posted, though ("[PATCH/RFT 0/4] ARM:
>> > shmobile: R-Car Gen2: Allow booting secondary CPU cores in debug mode").
>> > Since v3, the other user has been removed in commit 9f5ce39ddb8f68b3
>> > ("ARM: shmobile: rcar-gen2: Obtain extal frequency from DT").
>> >
>> > This series consists of 5 parts:
>> >   A. Patches 1 and 2 add DT bindings and driver code for the R-Car RST
>> >      driver,
>> >   B. Patches 3-11 add device nodes for the RST modules to the R-Car DTS
>> >      files,
>> >   C. Patches 12-17 convert the clock drivers to call into the new R-Car
>> >      RST driver,
>> >   D. Patches 18-20 remove passing mode pin state to the clock drivers
>> >      from the platform code,
>> >   E. Patches 21-23 remove dead code from the clock drivers.
>> >
>> > As is usually the case with moving functionality from platform code to
>> > DT, there are lots of hard dependencies:
>> >   - The DT updates in Part B can be merged as soon as the DT bindings in
>> >     Part A have been approved,
>> >   - The clock driver updates in Part C depend functionally on the driver
>> >     code in Part A, and on the DT updates in Part B,
>> >   - The board code cleanups in Part D depend on the clock driver updates
>> >     in Part C,
>> >   - The block driver cleanups in part E depend on the board code
>> >     cleanups in part D.
>> >
>> > Hence to maintain the required lockstep between SoC driver, clock
>> > drivers, shmobile platform code, and shmobile DT, I propose to queue up
>> > all patches in a single branch against v4.9-rc1, and send pull requests
>> > to both Mike/Stephen (clock) and Simon (rest).
>> >
>> > ***
>>
>> >   - Mike/Stephen/Simon/Magnus: Are you OK with the suggested merge
>> >     approach above?
>>
>> Is this OK for you?

#####

(link to the full series at
 https://groups.google.com/forum/#!topic/linux.kernel/fLSFsjOgPT8)

>>
>> I'd like to move forward with this, as this is a prerequisite for adding
>> support for new SoCs (RZ/G) without adding more copies of
>> rcar_gen2_read_mode_pins(), and removing that function from platform code
>> for good.
>
> This seems reasonable to me but likely the ARM SoC maintainers will want to
> know about this plan before it is executed.

OK, adding more people in the loop...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [PATCH 5/9] ASoC: pxa: switch to new ac97 bus support
From: Robert Jarzmik @ 2016-10-31  8:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477510907-23495-6-git-send-email-robert.jarzmik@free.fr>

Robert Jarzmik <robert.jarzmik@free.fr> writes:

> Switch to the new ac97 bus support in sound/ac97 instead of the legacy
> snd_ac97 one.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
I realized this one impacts sound/arm/pxa2xx-ac97.c.
This deserves a v2, with this patch being split into 2 pieces :
 - one for pxa2xx-ac97-lib.*
 - one which will be the true switch to the new ac97 bus.

Cheers.

--
Robert

^ permalink raw reply

* [PATCH V2 6/6] arm64: Add uprobe support
From: Pratyush Anand @ 2016-10-31  8:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161030140901.h6mdxbb4pgqpqs7j@localhost>

Hi Catalin,

On Sun, Oct 30, 2016 at 7:39 PM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Tue, Sep 27, 2016 at 01:18:00PM +0530, Pratyush Anand wrote:
>> --- /dev/null
>> +++ b/arch/arm64/kernel/probes/uprobes.c
>> @@ -0,0 +1,221 @@
>> +/*
>> + * Copyright (C) 2014-2016 Pratyush Anand <panand@redhat.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#include <linux/highmem.h>
>> +#include <linux/ptrace.h>
>> +#include <linux/uprobes.h>
>> +#include <asm/cacheflush.h>
>> +
>> +#include "decode-insn.h"
>> +
>> +#define UPROBE_INV_FAULT_CODE        UINT_MAX
>> +
>> +bool is_trap_insn(uprobe_opcode_t *insn)
>> +{
>> +     return false;
>> +}
>
> On the previous series, I had a comment left unanswered with regards to
> always returning false in is_trap_insn():
>
> Looking at handle_swbp(), if we hit a breakpoint for which we don't have
> a valid uprobe, this function currently sends a SIGTRAP. But if
> is_trap_insn() returns false always, is_trap_at_addr() would return 0 in
> this case so the SIGTRAP is never issued.

A agreed on this that the older implementation i.e. the default one of
is_trap_insn() is better for the time being.

probably 'strtle r0, [r0], #160' would have the closest matching
aarch32 instruction wrt BRK64_OPCODE_UPROBES(0xd42000A0). But that too
seems a bad instruction. So, there might not be any aarch32
instruction which will match to uprobe BRK instruction.


Therefore, if I send a V3 by removing aacrh64
Hi Catalin,

On Sun, Oct 30, 2016 at 7:39 PM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Tue, Sep 27, 2016 at 01:18:00PM +0530, Pratyush Anand wrote:
>> --- /dev/null
>> +++ b/arch/arm64/kernel/probes/uprobes.c
>> @@ -0,0 +1,221 @@
>> +/*
>> + * Copyright (C) 2014-2016 Pratyush Anand <panand@redhat.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#include <linux/highmem.h>
>> +#include <linux/ptrace.h>
>> +#include <linux/uprobes.h>
>> +#include <asm/cacheflush.h>
>> +
>> +#include "decode-insn.h"
>> +
>> +#define UPROBE_INV_FAULT_CODE        UINT_MAX
>> +
>> +bool is_trap_insn(uprobe_opcode_t *insn)
>> +{
>> +     return false;
>> +}
>
> On the previous series, I had a comment left unanswered with regards to
> always returning false in is_trap_insn():
>
> Looking at handle_swbp(), if we hit a breakpoint for which we don't have
> a valid uprobe, this function currently sends a SIGTRAP. But if
> is_trap_insn() returns false always, is_trap_at_addr() would return 0 in
> this case so the SIGTRAP is never issued.

A agreed on this that the older implementation i.e. the default one of
is_trap_insn() is better for the time being.

probably 'strtle r0, [r0], #160' would have the closest matching
aarch32 instruction wrt BRK64_OPCODE_UPROBES(0xd42000A0). But that too
seems a bad instruction. So, there might not be any aarch32
instruction which will match to uprobe BRK instruction.


Therefore, if I send a V3 by removing aacrh64
Hi Catalin,

On Sun, Oct 30, 2016 at 7:39 PM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Tue, Sep 27, 2016 at 01:18:00PM +0530, Pratyush Anand wrote:
>> --- /dev/null
>> +++ b/arch/arm64/kernel/probes/uprobes.c
>> @@ -0,0 +1,221 @@
>> +/*
>> + * Copyright (C) 2014-2016 Pratyush Anand <panand@redhat.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#include <linux/highmem.h>
>> +#include <linux/ptrace.h>
>> +#include <linux/uprobes.h>
>> +#include <asm/cacheflush.h>
>> +
>> +#include "decode-insn.h"
>> +
>> +#define UPROBE_INV_FAULT_CODE        UINT_MAX
>> +
>> +bool is_trap_insn(uprobe_opcode_t *insn)
>> +{
>> +     return false;
>> +}
>
> On the previous series, I had a comment left unanswered with regards to
> always returning false in is_trap_insn():
>
> Looking at handle_swbp(), if we hit a breakpoint for which we don't have
> a valid uprobe, this function currently sends a SIGTRAP. But if
> is_trap_insn() returns false always, is_trap_at_addr() would return 0 in
> this case so the SIGTRAP is never issued.

A agreed on this that the older implementation i.e. the default one of
is_trap_insn() is better for the time being. I sent out V2 before your
last comment on it in V1 :(.

probably 'strtle r0, [r0], #160' would have the closest matching
aarch32 instruction wrt BRK64_OPCODE_UPROBES(0xd42000A0). But that too
seems a bad aarch32 instruction. So, there might not be any aarch32
instruction which will match to uprobe BRK instruction.


Therefore, if I send a V3 by removing aacrh64 is_trap_insn(), would
that be acceptable, or do you see any other issue with this patch
series? If there is anything else, I would address that in V3 as well.

Thanks for your review.

~Pratyush

^ permalink raw reply

* [PATCH 0/5] drm/sun4i: Handle TV overscan
From: Russell King - ARM Linux @ 2016-10-31  8:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018100349.qm2f554oiwyjwrsi@lukather>

On Tue, Oct 18, 2016 at 12:03:49PM +0200, Maxime Ripard wrote:
> The first one is that this overscanning should be reported by the
> connector I guess? but this is really TV specific, so we need one way
> to let the user tell how the image is displayed on its side, and we
> cannot really autodetect it, and this needs to be done at runtime so
> that we can present some shiny interface to let it select which
> overscan ratio works for him/her.

See xbmc... they go through a nice shiny setup which includes adjusting
the visible area.  From what I remember, it has pointers on each corner
which you can adjust to be just visible on the screen, so xbmc knows
how much overscan there is, and xbmc itself reduces down to the user
set size.

> The second one is that we still need to expose the reduced modes to
> userspace, and not only the displayed size, so that the applications
> know what they must draw on. But I guess this could be adjusted by the
> core too.
> 
> In order to work consistently, I think all planes should be adjusted
> that way, so that relative coordinates are from the primary plane
> origin, and not the display origin. But that could be adjusted too by
> the core I guess.

I'm not sure about that - we want the graphics to be visible, but that
may not be appropriate for an video overlay frame.  It's quite common
for (eg) broadcast video to contain dead pixels or other artifacts on
the right hand side, and the broadcast video expects overscan to be
present.

I know this because I have run my TV with overscan disabled, even for
broadcast TV.

> The fourth one being the major one. Every time I raised the issue on
> IRC, the answer basically was "we don't care about analog", so I'm a
> bit pessimistic about whether dealing with this in the core would be
> accepted, hence why I chose to deal with this at the driver level.

Yea, that's quite sad, "analog" has become a dirty word, but really
this has nothing to do with "analog" at all - there are LCD TVs (and
some monitors) out there which take HDMI signals but refuse to
disable overscan no matter what you do to them if you provide them
with a "broadcast"  mode - so the analog excuse is very poor.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* Memory range end be inclusive or exclusive? Re: [PATCH v1 1/4] kexec: (bugfix) calc correct end address of memory ranges in device tree
From: AKASHI Takahiro @ 2016-10-31  8:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160906002958.GB16712@linaro.org>

Simon,

On Tue, Sep 06, 2016 at 09:29:59AM +0900, AKASHI Takahiro wrote:
> Simon,
> 
> What is your opinion on this issue?

Pinged you several times so far.

Can you please give me your comment?
(attached below is the original patch.)

-Takahiro AKASHI

> 
> On Mon, Aug 01, 2016 at 01:52:40PM +0900, AKASHI Takahiro wrote:
> > On Fri, Jul 29, 2016 at 06:23:56PM +0100, Russell King - ARM Linux wrote:
> > > On Fri, Jul 29, 2016 at 10:12:26AM -0700, Geoff Levand wrote:
> > > > On Fri, 2016-07-29 at 09:27 +0100, Russell King - ARM Linux wrote:
> > > > 
> > > > > So, these functions are a mess and need fixing.
> > > > 
> > > > Since this change isn't really related to arm64 support, I'll
> > > > drop this patch from my series.
> > > 
> > > Do you have a case which triggers bugs in this code?
> > 
> > Actually, this patch was necessary when my kdump used "usable-memory"
> > properties in "memory" nodes, as on ppc64, to limit the usable memory
> > regions that can be used by crash dump kernel.
> > Since then, I've moved to the approach of using "mem=" kernel parameter,
> > then introducing a new property, "linux,usable-memory-range," under /chosen
> > and now we don't need this patch any more.
> > 
> > So, we can drop it but I still believe that it is buggy.
> 
> Due to the discussions[1], I may want to re-enable "usable-memory"
> property on arm64. In addition, I would like to add a function,
> dtb_add_usable_memory_properties(), a variant of
> add_usable_memory_properties(), to kexec/dt-ops.c.
> So this issue is quite crucial now.
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/452685.html
> 
> -Takahiro AKASHI
> 
> > Thanks,
> > -Takahiro AKASHI
> > 
> > > -- 
> > > RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
> > > FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> > > according to speedtest.net.
===8<===
From: AKASHI Takahiro <takahiro.akashi@linaro.org>

The end address of "reg" attribute in device tree's memory should be
inclusive.
---
 kexec/fs2dt.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/kexec/fs2dt.c b/kexec/fs2dt.c
index 79aa0f3..953f78a 100644
--- a/kexec/fs2dt.c
+++ b/kexec/fs2dt.c
@@ -236,7 +236,8 @@ static void add_dyn_reconf_usable_mem_property__(int fd)
 						    ranges_size*8);
 				}
 				ranges[rlen++] = cpu_to_be64(loc_base);
-				ranges[rlen++] = cpu_to_be64(loc_end - loc_base);
+				ranges[rlen++] = cpu_to_be64(loc_end
+								- loc_base + 1);
 				rngs_cnt++;
 			}
 		}
@@ -350,7 +351,7 @@ static void add_usable_mem_property(int fd, size_t len)
 					    ranges_size*sizeof(*ranges));
 			}
 			ranges[rlen++] = cpu_to_be64(loc_base);
-			ranges[rlen++] = cpu_to_be64(loc_end - loc_base);
+			ranges[rlen++] = cpu_to_be64(loc_end - loc_base + 1);
 		}
 	}
 
-- 
2.10.0

^ permalink raw reply related

* [PATCH] [ARM] Fix stack alignment when processing backtraces
From: Russell King - ARM Linux @ 2016-10-31  8:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018170510.GA12248@obsidianresearch.com>

On Tue, Oct 18, 2016 at 11:05:10AM -0600, Jason Gunthorpe wrote:
> The dumpstm helper within c_backtrace pushed 5 dwords onto the stack
> causing the stack to become unaligned and then calls printk. This
> causes memory corruption in the kernel which assumes AAPCS calling
> convention.
> 
> Since this bit of asm doesn't use the standard prologue just add
> another register to restore alignment.
> 
> Fixes: 7ab3f8d595a1b ("[ARM] Add ability to dump exception stacks to kernel backtraces")
> Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
> ---
>  arch/arm/lib/backtrace.S | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> In my case the kernel was hitting a WARN_ON during boot and then
> reliably failed to start the compiled-in initramfs.
> 
> I'm inferring that the stack misalignment caused some kind of memory
> corruption which wiped out the unpacked initramfs.
> 
> Saw with gcc 5.4.0 on a kirkwood armv5te
> 
> diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
> index fab5a50503ae..25e1cce19991 100644
> --- a/arch/arm/lib/backtrace.S
> +++ b/arch/arm/lib/backtrace.S
> @@ -116,7 +116,8 @@ ENDPROC(c_backtrace)
>  #define reg   r5
>  #define stack r6
>  
> -.Ldumpstm:	stmfd	sp!, {instr, reg, stack, r7, lr}
> +	        /* Must maintain 8 byte stack alignment */
> +.Ldumpstm:	stmfd	sp!, {r3, instr, reg, stack, r7, lr}
>  		mov	stack, r0
>  		mov	instr, r1
>  		mov	reg, #10
> @@ -140,7 +141,7 @@ ENDPROC(c_backtrace)
>  		teq	r7, #0
>  		adrne	r0, .Lcr
>  		blne	printk
> -		ldmfd	sp!, {instr, reg, stack, r7, pc}
> +		ldmfd	sp!, {r3, instr, reg, stack, r7, pc}

I'd prefer r8 to get used rather than r3, as it makes it look like
r3 is somehow required to be preserved when that's not the case.
Makes the code slightly more difficult to understand.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply


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