Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v3 15/24] media: Add userspace header file for i.MX
From: Steve Longerbeam @ 2017-01-13 23:13 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: robh+dt, mark.rutland, shawnguo, kernel, fabio.estevam, linux,
	mchehab, hverkuil, nick, markus.heiser, laurent.pinchart+renesas,
	bparrot, geert, arnd, sudipm.mukherjee, minghsiu.tsai,
	tiffany.lin, jean-christophe.trotin, horms+renesas,
	niklas.soderlund+renesas, robert.jarzmik, songjun.wu,
	andrew-ct.chen, gregkh, devicetree, linux-kernel,
	linux-arm-kernel, linux-media, devel, Steve Longerbeam
In-Reply-To: <1484309143.31475.31.camel@pengutronix.de>



On 01/13/2017 04:05 AM, Philipp Zabel wrote:
> Am Freitag, den 06.01.2017, 18:11 -0800 schrieb Steve Longerbeam:
>> This adds a header file for use by userspace programs wanting to interact
>> with the i.MX media driver. It defines custom v4l2 controls and events
>> generated by the i.MX v4l2 subdevices.
>>
>> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
>> ---
>>   include/uapi/media/Kbuild |  1 +
>>   include/uapi/media/imx.h  | 30 ++++++++++++++++++++++++++++++
>>   2 files changed, 31 insertions(+)
>>   create mode 100644 include/uapi/media/imx.h
>>
>> diff --git a/include/uapi/media/Kbuild b/include/uapi/media/Kbuild
>> index aafaa5a..fa78958 100644
>> --- a/include/uapi/media/Kbuild
>> +++ b/include/uapi/media/Kbuild
>> @@ -1 +1,2 @@
>>   # UAPI Header export list
>> +header-y += imx.h
>> diff --git a/include/uapi/media/imx.h b/include/uapi/media/imx.h
>> new file mode 100644
>> index 0000000..2421d9c
>> --- /dev/null
>> +++ b/include/uapi/media/imx.h
>> @@ -0,0 +1,30 @@
>> +/*
>> + * Copyright (c) 2014-2015 Mentor Graphics Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by the
>> + * Free Software Foundation; either version 2 of the
>> + * License, or (at your option) any later version
>> + */
>> +
>> +#ifndef __UAPI_MEDIA_IMX_H__
>> +#define __UAPI_MEDIA_IMX_H__
>> +
>> +/*
>> + * events from the subdevs
>> + */
>> +#define V4L2_EVENT_IMX_CLASS          V4L2_EVENT_PRIVATE_START
>> +#define V4L2_EVENT_IMX_NFB4EOF        (V4L2_EVENT_IMX_CLASS + 1)
>> +#define V4L2_EVENT_IMX_EOF_TIMEOUT    (V4L2_EVENT_IMX_CLASS + 2)
>> +#define V4L2_EVENT_IMX_FRAME_INTERVAL (V4L2_EVENT_IMX_CLASS + 3)
> Aren't these generic enough to warrant common events? I would think
> there have to be other capture IP cores that can signal aborted frames
> or frame timeouts.

Yes, agreed. A frame capture timeout, or frame interval error, are
both generic concepts. At some point it would be great to make the
Frame Interval Monitor generally available under v4l2-core. As for the
EOF timeout event, I'll look into moving that into a generic V4L2 event.

Steve

^ permalink raw reply

* [PATCH] ARM: BCM5301X: Set 5 GHz wireless frequency limits on Netgear R8000
From: Rafał Miłecki @ 2017-01-13 23:58 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Arnd Bergmann, Rob Herring, Mark Rutland, Russell King,
	Hauke Mehrtens, Hante Meuleman,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Rafał Miłecki

From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>

Netgear R8000 is a tri-band home router. It has three BCM43602 chipsets
two of them for 5 GHz band. Both seem the same and their firmwares
report the same set of channels. The problem is due to hardware / board
design there are extra limitations that should be respected.

First PHY should be used for U-NII-2 and U-NII-3. Third PHY should be
used for U-NII-1. Using them in a different way may result in wireless
not working or in noticeably reduced performance. Basic version of this
info was provided by Broadcom employee, then it has been verified by me
using original vendor firmware (which has limitations hardcoded in UI).

This patch uses recently introduced ieee80211-freq-limit property to
describe these limitations at DT level.

Referencing PCIe devices in DT required specifying all related bridges.
Below you can see (a bit complex) PCI tree from R8000 that explains all
entries that I needed to put in DT.

0000:00:00.0		14e4:8012	Bridge Device
└─ 0000:01:00.0		14e4:aa52	Network Controller

0001:00:00.0		14e4:8012	Bridge Device
└─ 0001:01:00.0		10b5:8603	Bridge Device
   ├─ 0001:02:01.0	10b5:8603	Bridge Device
   │  └─ 0001:03:00.0	14e4:aa52	Network Controller
   ├─ 0001:02:02.0	10b5:8603	Bridge Device
   │  └─ 0001:04:00.0	14e4:aa52	Network Controller
   ├─ 0001:02:03.0	000d:0000	0x000000
   ├─ 0001:02:04.0	000d:0000	0x000000
   ├─ 0001:02:05.0	000d:0000	0x000000
   ├─ 0001:02:06.0	000d:0000	0x000000
   ├─ (...)
   ├─ 0001:02:1d.0	000d:0000	0x000000
   ├─ 0001:02:1e.0	000d:0000	0x000000
   └─ 0001:02:1f.0	000d:0000	0x000000

Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
---
 arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 48 +++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm5301x.dtsi             |  8 +++++
 2 files changed, 56 insertions(+)

diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
index cd13534..8e39a84 100644
--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
@@ -108,6 +108,54 @@
 	};
 };
 
+&pcie0 {
+	#address-cells = <3>;
+	#size-cells = <2>;
+
+	bridge@0,0,0 {
+		reg = <0x0000 0 0 0 0>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		wifi@0,1,0 {
+			reg = <0x0000 0 0 0 0>;
+			ieee80211-freq-limit = <5735000 5835000>;
+		};
+	};
+};
+
+&pcie1 {
+	#address-cells = <3>;
+	#size-cells = <2>;
+
+	bridge@1,0,0 {
+		reg = <0x0000 0 0 0 0>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		bridge@1,1,0 {
+			reg = <0x0000 0 0 0 0>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			bridge@1,2,2 {
+				reg = <0x1000 0 0 0 0>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				wifi@1,4,0 {
+					reg = <0x0000 0 0 0 0>;
+					ieee80211-freq-limit = <5170000 5730000>;
+				};
+			};
+		};
+	};
+};
+
 &usb2 {
 	vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi
index a4614c9..4fbb089 100644
--- a/arch/arm/boot/dts/bcm5301x.dtsi
+++ b/arch/arm/boot/dts/bcm5301x.dtsi
@@ -243,6 +243,14 @@
 			#gpio-cells = <2>;
 		};
 
+		pcie0: pcie@12000 {
+			reg = <0x00012000 0x1000>;
+		};
+
+		pcie1: pcie@13000 {
+			reg = <0x00013000 0x1000>;
+		};
+
 		usb2: usb2@21000 {
 			reg = <0x00021000 0x1000>;
 
-- 
2.10.1

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

^ permalink raw reply related

* Re: [PATCH v3 2/4] dt-bindings: Add TI SCI PM Domains
From: Rob Herring @ 2017-01-14  2:40 UTC (permalink / raw)
  To: Dave Gerlach
  Cc: Ulf Hansson, Rafael J . Wysocki, Kevin Hilman,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Nishanth Menon, Keerthy, Russell King, Tero Kristo, Sudeep Holla,
	Santosh Shilimkar, Lokesh Vutla
In-Reply-To: <84d7d49b-933b-8b26-f18a-3a5054738cb1-l0cyMroinI0@public.gmane.org>

On Fri, Jan 13, 2017 at 2:28 PM, Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org> wrote:
> On 01/13/2017 01:25 PM, Rob Herring wrote:
>>
>> On Thu, Jan 12, 2017 at 9:27 AM, Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org> wrote:
>>>
>>> Rob,
>>>
>>> On 01/11/2017 03:34 PM, Rob Herring wrote:
>>>>
>>>>
>>>> On Mon, Jan 9, 2017 at 11:57 AM, Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org> wrote:
>>>>>
>>>>>
>>>>> Rob,
>>>>>
>>>>> On 01/09/2017 11:50 AM, Rob Herring wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Wed, Jan 04, 2017 at 02:55:34PM -0600, Dave Gerlach wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Add a generic power domain implementation, TI SCI PM Domains, that
>>>>>>> will hook into the genpd framework and allow the TI SCI protocol to
>>>>>>> control device power states.
>>>>>>>
>>>>>>> Also, provide macros representing each device index as understood
>>>>>>> by TI SCI to be used in the device node power-domain references.
>>>>>>> These are identifiers for the K2G devices managed by the PMMC.
>>>>>>>
>>>>>>> Signed-off-by: Nishanth Menon <nm-l0cyMroinI0@public.gmane.org>
>>>>>>> Signed-off-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
>>>>>>> ---
>>>>>>> v2->v3:
>>>>>>>         Update k2g_pds node docs to show it should be a child of pmmc
>>>>>>> node.
>>>>>>>         In early versions a phandle was used to point to pmmc and
>>>>>>> docs
>>>>>>> still
>>>>>>>         incorrectly showed this.
>>>>>>>
>>>>>>>  .../devicetree/bindings/soc/ti/sci-pm-domain.txt   | 59
>>>>>>> ++++++++++++++
>>>>>>>  MAINTAINERS                                        |  2 +
>>>>>>>  include/dt-bindings/genpd/k2g.h                    | 90
>>>>>>> ++++++++++++++++++++++
>>>>>>>  3 files changed, 151 insertions(+)
>>>>>>>  create mode 100644
>>>>>>> Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>  create mode 100644 include/dt-bindings/genpd/k2g.h
>>>>>>>
>>>>>>> diff --git
>>>>>>> a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>> b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>> new file mode 100644
>>>>>>> index 000000000000..4c9064e512cb
>>>>>>> --- /dev/null
>>>>>>> +++ b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>> @@ -0,0 +1,59 @@
>>>>>>> +Texas Instruments TI-SCI Generic Power Domain
>>>>>>> +---------------------------------------------
>>>>>>> +
>>>>>>> +Some TI SoCs contain a system controller (like the PMMC, etc...)
>>>>>>> that
>>>>>>> is
>>>>>>> +responsible for controlling the state of the IPs that are present.
>>>>>>> +Communication between the host processor running an OS and the
>>>>>>> system
>>>>>>> +controller happens through a protocol known as TI-SCI [1]. This pm
>>>>>>> domain
>>>>>>> +implementation plugs into the generic pm domain framework and makes
>>>>>>> use
>>>>>>> of
>>>>>>> +the TI SCI protocol power on and off each device when needed.
>>>>>>> +
>>>>>>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>>>>>>> +
>>>>>>> +PM Domain Node
>>>>>>> +==============
>>>>>>> +The PM domain node represents the global PM domain managed by the
>>>>>>> PMMC,
>>>>>>> +which in this case is the single implementation as documented by the
>>>>>>> generic
>>>>>>> +PM domain bindings in
>>>>>>> Documentation/devicetree/bindings/power/power_domain.txt.
>>>>>>> +Because this relies on the TI SCI protocol to communicate with the
>>>>>>> PMMC
>>>>>>> it
>>>>>>> +must be a child of the pmmc node.
>>>>>>> +
>>>>>>> +Required Properties:
>>>>>>> +--------------------
>>>>>>> +- compatible: should be "ti,sci-pm-domain"
>>>>>>> +- #power-domain-cells: Must be 0.
>>>>>>> +
>>>>>>> +Example (K2G):
>>>>>>> +-------------
>>>>>>> +       pmmc: pmmc {
>>>>>>> +               compatible = "ti,k2g-sci";
>>>>>>> +               ...
>>>>>>> +
>>>>>>> +               k2g_pds: k2g_pds {
>>>>>>> +                       compatible = "ti,sci-pm-domain";
>>>>>>> +                       #power-domain-cells = <0>;
>>>>>>> +               };
>>>>>>> +       };
>>>>>>> +
>>>>>>> +PM Domain Consumers
>>>>>>> +===================
>>>>>>> +Hardware blocks that require SCI control over their state must
>>>>>>> provide
>>>>>>> +a reference to the sci-pm-domain they are part of and a unique
>>>>>>> device
>>>>>>> +specific ID that identifies the device.
>>>>>>> +
>>>>>>> +Required Properties:
>>>>>>> +--------------------
>>>>>>> +- power-domains: phandle pointing to the corresponding PM domain
>>>>>>> node.
>>>>>>> +- ti,sci-id: index representing the device id to be passed oevr SCI
>>>>>>> to
>>>>>>> +            be used for device control.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> As I've already stated before, this goes in power-domain cells. When
>>>>>> you
>>>>>> have a single thing (i.e. node) that controls multiple things, then
>>>>>> you
>>>>>> you need to specify the ID for each of them in phandle args. This is
>>>>>> how
>>>>>> irqs, gpio, clocks, *everything* in DT works.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> You think the reasoning for doing it this way provided by both Ulf and
>>>>> myself on v2 [1] is not valid then?
>>>>>
>>>>> From Ulf:
>>>>>
>>>>> To me, the TI SCI ID, is similar to a "conid" for any another "device
>>>>> resource" (like clock, pinctrl, regulator etc) which we can describe
>>>>> in DT and assign to a device node. The only difference here, is that
>>>>> we don't have common API to fetch the resource (like clk_get(),
>>>>> regulator_get()), but instead we fetches the device's resource from
>>>>> SoC specific code, via genpd's device ->attach() callback.
>>>>
>>>>
>>>>
>>>> Sorry, but that sounds like a kernel problem to me and has nothing to
>>>> do with DT bindings.
>>>>
>>>>> From me:
>>>>>
>>>>> Yes, you've pretty much hit it on the head. It is not an index into a
>>>>> list
>>>>> of genpds but rather identifies the device *within* a single genpd. It
>>>>> is
>>>>> a
>>>>> property specific to each device that resides in a ti-sci-genpd, not a
>>>>> mapping describing which genpd the device belongs to. The generic power
>>>>> domain binding is concerned with mapping the device to a specific
>>>>> genpd,
>>>>> which is does fine for us, but we have a sub mapping for devices that
>>>>> exist
>>>>> inside a genpd which, we must describe as well, hence the ti,sci-id.
>>>>>
>>>>>
>>>>> So to summarize, the genpd framework does interpret the phandle arg as
>>>>> an
>>>>> index into multiple genpds, just as you've said other frameworks do,
>>>>> but
>>>>> this is not what I am trying to do, we have multiple devices within
>>>>> this
>>>>> *single* genpd, hence the need for the ti,sci-id property.
>>>>
>>>>
>>>>
>>>> Fix the genpd framework rather than work around it in DT.
>>>
>>>
>>>
>>> I still disagree that this has nothing to do with DT bindings, as the
>>> current DT binding represents something different already. I am trying to
>>> extend it to give me additional information needed for our platforms. Are
>>> you saying that we should break what the current DT binding already
>>> represents to mean something else?
>>
>>
>> No idea because what's the current binding? From the patch, looks like
>> a new binding to me.
>
>
> Yes, ti,sci-id is a new binding. I am referring to the current meaning of
> the "power-domains" binding, which is where you are asking this property to
> be added, in "power-domains" cells. This is documented here [1] in the
> kernel, although looking at it I must admit it is not very clear.
>
> The power-domains cell represents an offset into an array of power domains,
> if you choose to use it. That's what the genpd framework is hard coded to
> interpret it as. This is correct, as it is an index into a static list of
> power domains, used to identify which power domain a device belongs to,
> which is exactly what the genpd framework itself is concerned with. This is
> already how it is used in the kernel today.

Strictly speaking, the cells are purely for the interpretation of the
phandle they are associated with. If some controller wants to have 20
cells, then it could assuming a good reason. The reality is we tend to
align the meaning of the cells. If genpd is interpreting the cells and
not letting the driver for the power domain controller interpret them,
then still, genpd needs to be fixed.

IIRC, initially it was said genpd required 0 cells, hence my confusion.

> My ti,sci-id is not an index into a list of power domains, so it should not
> go in the power-domains cells and go against what the power-domains binding
> says that the cell expects. We have one single power domain, and the new
> ti,sci-id binding is not something the genpd framework itself is concerned
> with as it's our property to identify a device inside a power domain, not to
> identify which power domain it is associated with.

What is the id used for? I can understand why you need to know what
power domain a device is in (as power-domains identifies), but not
what devices are in a power domain.

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

^ permalink raw reply

* Re: [PATCH v2 1/2] of: base: add support to find the level of the last cache
From: Rob Herring @ 2017-01-14  2:45 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Catalin Marinas, Will Deacon,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Tan Xiaojun,
	Mark Rutland
In-Reply-To: <1484245772-31511-1-git-send-email-sudeep.holla-5wv7dgnIgG8@public.gmane.org>

On Thu, Jan 12, 2017 at 12:29 PM, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
> It is useful to have helper function just to get the number of cache
> levels for a given logical cpu. We can obtain the same by just checking
> the level at which the last cache is present. This patch adds support
> to find the level of the last cache for a given cpu.
>
> It will be used on ARM64 platform where the device tree provides the
> information for the additional non-architected/transparent/external
> last level caches that are not integrated with the processors.
>
> Suggested-by: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
> Signed-off-by: Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org>
> ---
>  drivers/of/base.c  | 27 +++++++++++++++++++++++++++
>  include/linux/of.h |  1 +
>  2 files changed, 28 insertions(+)
>
> v1->v2:
>         - Moved to using "cache-level" in the last level cache instead
>           of counting through all the nodes as suggested by Rob
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d4bea3c797d6..c1128a077aea 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -25,6 +25,7 @@
>  #include <linux/cpu.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/of_graph.h>
>  #include <linux/spinlock.h>
>  #include <linux/slab.h>
> @@ -2268,6 +2269,32 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)
>  }
>
>  /**
> + * of_find_last_cache_level - Find the level at which the last cache is
> + *             present for the given logical cpu
> + *
> + * @cpu: cpu number(logical index) for which the last cache level is needed
> + *
> + * Returns the the level at which the last cache is present. It is exactly
> + * same as  the total number of cache levels for the given logical cpu.
> + */
> +int of_find_last_cache_level(unsigned int cpu)
> +{
> +       int cache_level = 0;
> +       struct device_node *prev = NULL, *np = of_cpu_device_node_get(cpu);
> +
> +       while (np) {
> +               prev = np;
> +               of_node_put(np);
> +               np = of_find_next_cache_node(np);
> +       }
> +
> +       if (prev)

Probably don't need this check. Otherwise,

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

> +               of_property_read_u32(prev, "cache-level", &cache_level);
> +
> +       return cache_level;
> +}
> +
> +/**
>   * of_graph_parse_endpoint() - parse common endpoint node properties
>   * @node: pointer to endpoint device_node
>   * @endpoint: pointer to the OF endpoint data structure
> diff --git a/include/linux/of.h b/include/linux/of.h
> index d72f01009297..21e6323de0f3 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -280,6 +280,7 @@ extern struct device_node *of_get_child_by_name(const struct device_node *node,
>
>  /* cache lookup */
>  extern struct device_node *of_find_next_cache_node(const struct device_node *);
> +extern int of_find_last_cache_level(unsigned int cpu);
>  extern struct device_node *of_find_node_with_property(
>         struct device_node *from, const char *prop_name);
>
> --
> 2.7.4
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH 1/2] dt-bindings: document renesas-ostm timer
From: Chris Brandt @ 2017-01-14  3:30 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Rob Herring, Mark Rutland, Simon Horman, Magnus Damm,
	Russell King, Daniel Lezcano, Thomas Gleixner, Geert Uytterhoeven,
	devicetree@vger.kernel.org, Linux-Renesas
In-Reply-To: <CAMuHMdX_hx2M8Q4y7gptJvad4cbb+M54DZVCmbhunKuk4esbGA@mail.gmail.com>

Hi Geert,

Thank you for your review.


On Friday, January 13, 2017, Geert Uytterhoeven wrote:
> > +The OSTM comes with 2 independent channels.
> > +We will use the first channel (OSTM0) as a free running clocksource
> > +and the second channel (OSTM1) as a interrupt driven clock event.
> > +
> > +Additionally we will use the clocksource channel (OTSM0) for the
> > +system schedule timer sched_clock().
> 
> The above two sentences are software policy, not hardware description.
> Hence they do not belong in the DT bindings document.
> You can move them to the commit description, though.

OK.


> > +Required Properties:
> > +
> > +  - compatible: must be one or more of the following:
> > +    - "renesas,ostm-r7s72100" for the r7s72100 OSTM
> 
> Please use "renesas,r7s72100-ostm" instead, to match current practices.

If I look at the current r7s72100.dtsi:

compatible = "renesas,r7s72100-cpg-clocks", "renesas,rz-cpg-clocks";
compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks";
compatible = "renesas,scif-r7s72100", "renesas,scif";
compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
compatible = "renesas,mtu2-r7s72100", "renesas,mtu2";
compatible = "renesas,mmcif-r7s72100", "renesas,sh-mmcif";
compatible = "renesas,sdhi-r7s72100";

Is "renesas,xxx-r7s7210" the old way, and "renesas,r7s72100-xxx" is the new way??



> > +  - reg: base address and length of the registers block for each timer
> channel.
> > +    There should be 2 sets of addresses, one for each channel.
> > +
> > +  - interrupts: interrupt specifiers for the timers. There should be 2
> > +    interupts, one for each channel.
> > +
> > +  - clocks: a list of phandle + clock-specifier pairs, one for each
> entry
> > +    channel. There should be 2 sets, one for each channel.
> 
> Are the channels truly independent? If yes, I think it's better to have
> two separate device nodes, one for each channel.
> Each channel has its own module clock, so using separate devices means
> Runtime PM can manage both channels through their module clocks as soon as
> you add a "power-domains" property pointing to the clock domain controller.


Yes, technically they are independent channels.
The way the driver is currently written, 1 instance of the driver uses 2 channels
for different things. Ch0 will be set up as a 'clocksource', and ch1 will be set up
as a 'clock event'.

As in:

static int __init ostm_timer_init(struct ostm_device *ostm)
{
	int ret = 0;

	/* ostm0 will be clock source */
	ret = ostm_init_clksrc(ostm);
	if (ret)
		goto err;

	/* use ostm0 as system scheduling clock */
	ret = ostm_init_sched_clock(&ostm->clksrc);
	if (ret)
		goto err;

	/* ostm1 will be clock event */
	ret = ostm_init_clkevt(ostm);
err:
	return ret;
}



Do you think it would be better if a driver instance only does 1 thing: Either
'clocksource' or 'clock event'??
Then, I would make 2 ostm nodes and pass in the mode I would like it operate in?

For example:

&ostm0 {
	mode = "clocksource";
	status = "okay";
};

&ostm1 {
	mode = "clock-event";
	status = "okay";
};



Thank you,
Chris

^ permalink raw reply

* [PATCH v6 0/3] dmaengine: xilinx_dma: Bug fixes
From: Kedareswara rao Appana @ 2017-01-14  5:35 UTC (permalink / raw)
  To: robh+dt, mark.rutland, dan.j.williams, vinod.koul, michal.simek,
	soren.brinkmann, appanad, moritz.fischer, laurent.pinchart, luis,
	Jose.Abreu
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree

This patch series fixes below bugs in DMA and VDMA IP's
---> Do not start VDMA until frame buffer is processed by the h/w
---> Fix bug in Multi frame sotres handling in VDMA
---> Fix issues w.r.to multi frame descriptors submit with AXI DMA S2MM(recv) Side.

Kedareswara rao Appana (3):
  dmaengine: xilinx_dma: Check for channel idle state before submitting
    dma descriptor
  dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in
    vdma
  dmaengine: xilinx_dma: Fix race condition in the driver for multiple
    descriptor scenario

 .../devicetree/bindings/dma/xilinx/xilinx_dma.txt  |   2 +
 drivers/dma/xilinx/xilinx_dma.c                    | 270 ++++++++++++---------
 2 files changed, 161 insertions(+), 111 deletions(-)

-- 
2.1.2

^ permalink raw reply

* [PATCH v6 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor
From: Kedareswara rao Appana @ 2017-01-14  5:35 UTC (permalink / raw)
  To: robh+dt, mark.rutland, dan.j.williams, vinod.koul, michal.simek,
	soren.brinkmann, appanad, moritz.fischer, laurent.pinchart, luis,
	Jose.Abreu
  Cc: dmaengine, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <1484372155-19423-1-git-send-email-appanad@xilinx.com>

Add variable for checking channel idle state to ensure that dma descriptor is not
Submitted when DMA engine is in progress.

This will avoids the pollling for a bit in the status register to know
Dma state in the driver hot path.

Reviewed-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v6:
---> Updated commit message as suggested by Vinod.
---> Added Channel idle variable description in the driver
     as suggested by Vinod.
Changes for v5:
---> None.
Changes for v4:
---> None.
Changes for v3:
---> None.
Changes for v2:
---> Add idle check in the reset as suggested by Jose Abreu
---> Removed xilinx_dma_is_running/xilinx_dma_is_idle checks
    in the driver and used common idle checks across the driver
    as suggested by Laurent Pinchart.

 drivers/dma/xilinx/xilinx_dma.c | 61 +++++++++++++++--------------------------
 1 file changed, 22 insertions(+), 39 deletions(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 8288fe4..5eeea57 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -321,6 +321,7 @@ struct xilinx_dma_tx_descriptor {
  * @cyclic: Check for cyclic transfers.
  * @genlock: Support genlock mode
  * @err: Channel has errors
+ * @idle: Check for channel idle
  * @tasklet: Cleanup work after irq
  * @config: Device configuration info
  * @flush_on_fsync: Flush on Frame sync
@@ -351,6 +352,7 @@ struct xilinx_dma_chan {
 	bool cyclic;
 	bool genlock;
 	bool err;
+	bool idle;
 	struct tasklet_struct tasklet;
 	struct xilinx_vdma_config config;
 	bool flush_on_fsync;
@@ -920,32 +922,6 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
 }
 
 /**
- * xilinx_dma_is_running - Check if DMA channel is running
- * @chan: Driver specific DMA channel
- *
- * Return: '1' if running, '0' if not.
- */
-static bool xilinx_dma_is_running(struct xilinx_dma_chan *chan)
-{
-	return !(dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) &
-		 XILINX_DMA_DMASR_HALTED) &&
-		(dma_ctrl_read(chan, XILINX_DMA_REG_DMACR) &
-		 XILINX_DMA_DMACR_RUNSTOP);
-}
-
-/**
- * xilinx_dma_is_idle - Check if DMA channel is idle
- * @chan: Driver specific DMA channel
- *
- * Return: '1' if idle, '0' if not.
- */
-static bool xilinx_dma_is_idle(struct xilinx_dma_chan *chan)
-{
-	return dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) &
-		XILINX_DMA_DMASR_IDLE;
-}
-
-/**
  * xilinx_dma_halt - Halt DMA channel
  * @chan: Driver specific DMA channel
  */
@@ -966,6 +942,7 @@ static void xilinx_dma_halt(struct xilinx_dma_chan *chan)
 			chan, dma_ctrl_read(chan, XILINX_DMA_REG_DMASR));
 		chan->err = true;
 	}
+	chan->idle = true;
 }
 
 /**
@@ -1007,6 +984,9 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 	if (chan->err)
 		return;
 
+	if (!chan->idle)
+		return;
+
 	if (list_empty(&chan->pending_list))
 		return;
 
@@ -1018,13 +998,6 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 	tail_segment = list_last_entry(&tail_desc->segments,
 				       struct xilinx_vdma_tx_segment, node);
 
-	/* If it is SG mode and hardware is busy, cannot submit */
-	if (chan->has_sg && xilinx_dma_is_running(chan) &&
-	    !xilinx_dma_is_idle(chan)) {
-		dev_dbg(chan->dev, "DMA controller still busy\n");
-		return;
-	}
-
 	/*
 	 * If hardware is idle, then all descriptors on the running lists are
 	 * done, start new transfers
@@ -1110,6 +1083,7 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 		vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize);
 	}
 
+	chan->idle = false;
 	if (!chan->has_sg) {
 		list_del(&desc->node);
 		list_add_tail(&desc->node, &chan->active_list);
@@ -1136,6 +1110,9 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)
 	if (chan->err)
 		return;
 
+	if (!chan->idle)
+		return;
+
 	if (list_empty(&chan->pending_list))
 		return;
 
@@ -1181,6 +1158,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)
 
 	list_splice_tail_init(&chan->pending_list, &chan->active_list);
 	chan->desc_pendingcount = 0;
+	chan->idle = false;
 }
 
 /**
@@ -1196,15 +1174,11 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
 	if (chan->err)
 		return;
 
-	if (list_empty(&chan->pending_list))
+	if (!chan->idle)
 		return;
 
-	/* If it is SG mode and hardware is busy, cannot submit */
-	if (chan->has_sg && xilinx_dma_is_running(chan) &&
-	    !xilinx_dma_is_idle(chan)) {
-		dev_dbg(chan->dev, "DMA controller still busy\n");
+	if (list_empty(&chan->pending_list))
 		return;
-	}
 
 	head_desc = list_first_entry(&chan->pending_list,
 				     struct xilinx_dma_tx_descriptor, node);
@@ -1302,6 +1276,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
 
 	list_splice_tail_init(&chan->pending_list, &chan->active_list);
 	chan->desc_pendingcount = 0;
+	chan->idle = false;
 }
 
 /**
@@ -1366,6 +1341,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
 	}
 
 	chan->err = false;
+	chan->idle = true;
 
 	return err;
 }
@@ -1447,6 +1423,7 @@ static irqreturn_t xilinx_dma_irq_handler(int irq, void *data)
 	if (status & XILINX_DMA_DMASR_FRM_CNT_IRQ) {
 		spin_lock(&chan->lock);
 		xilinx_dma_complete_descriptor(chan);
+		chan->idle = true;
 		chan->start_transfer(chan);
 		spin_unlock(&chan->lock);
 	}
@@ -2327,6 +2304,12 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
 	chan->has_sg = xdev->has_sg;
 	chan->desc_pendingcount = 0x0;
 	chan->ext_addr = xdev->ext_addr;
+	/* This variable enusres that descripotrs are not
+	 * Submited when dma engine is in progress. This variable is
+	 * Added to avoid pollling for a bit in the status register to
+	 * Know dma state in the driver hot path.
+	 */
+	chan->idle = true;
 
 	spin_lock_init(&chan->lock);
 	INIT_LIST_HEAD(&chan->pending_list);
-- 
2.1.2

^ permalink raw reply related

* [PATCH v6 2/3] dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in vdma
From: Kedareswara rao Appana @ 2017-01-14  5:35 UTC (permalink / raw)
  To: robh+dt, mark.rutland, dan.j.williams, vinod.koul, michal.simek,
	soren.brinkmann, appanad, moritz.fischer, laurent.pinchart, luis,
	Jose.Abreu
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree
In-Reply-To: <1484372155-19423-1-git-send-email-appanad@xilinx.com>

When VDMA is configured for more than one frame in the h/w.
For example h/w is configured for n number of frames, user
Submits n number of frames and triggered the DMA using issue_pending API.

In the current driver flow we are submitting one frame at a time,
But we should submit all the n number of frames at one time
As the h/w is configured for n number of frames.

This patch fixes this issue.

Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v6:
---> Added Rob Acked-by
---> Updated commit message as suggested by Vinod.
Changes for v5:
---> Updated xlnx,fstore-config property to xlnx,fstore-enable
     and updated description as suggested by Rob.
Changes for v4:
---> Add Check for framestore configuration on Transmit case as well
     as suggested by Jose Abreu.
---> Modified the dev_dbg checks to dev_warn checks as suggested
     by Jose Abreu.
Changes for v3:
---> Added Checks for frame store configuration. If frame store
     Configuration is not present at the h/w level and user
     Submits less frames added debug prints in the driver as relevant.
Changes for v2:
---> Fixed race conditions in the driver as suggested by Jose Abreu
---> Fixed unnecessray if else checks in the vdma_start_transfer
     as suggested by Laurent Pinchart.

 .../devicetree/bindings/dma/xilinx/xilinx_dma.txt  |  2 +
 drivers/dma/xilinx/xilinx_dma.c                    | 78 +++++++++++++++-------
 2 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
index a2b8bfa..e951c09 100644
--- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
+++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
@@ -66,6 +66,8 @@ Optional child node properties:
 Optional child node properties for VDMA:
 - xlnx,genlock-mode: Tells Genlock synchronization is
 	enabled/disabled in hardware.
+- xlnx,fstore-enable: boolean; if defined, it indicates that controller
+	supports frame store configuration.
 Optional child node properties for AXI DMA:
 -dma-channels: Number of dma channels in child node.
 
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 5eeea57..edb5b71 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -322,6 +322,7 @@ struct xilinx_dma_tx_descriptor {
  * @genlock: Support genlock mode
  * @err: Channel has errors
  * @idle: Check for channel idle
+ * @has_fstoreen: Check for frame store configuration
  * @tasklet: Cleanup work after irq
  * @config: Device configuration info
  * @flush_on_fsync: Flush on Frame sync
@@ -353,6 +354,7 @@ struct xilinx_dma_chan {
 	bool genlock;
 	bool err;
 	bool idle;
+	bool has_fstoreen;
 	struct tasklet_struct tasklet;
 	struct xilinx_vdma_config config;
 	bool flush_on_fsync;
@@ -990,6 +992,27 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 	if (list_empty(&chan->pending_list))
 		return;
 
+	/*
+	 * Note: When VDMA is built with default h/w configuration
+	 * User should submit frames upto H/W configured.
+	 * If users submits less than h/w configured
+	 * VDMA engine tries to write to a invalid location
+	 * Results undefined behaviour/memory corruption.
+	 *
+	 * If user would like to submit frames less than h/w capable
+	 * On S2MM side please enable debug info 13 at the h/w level
+	 * On MM2S side please enable debug info 6 at the h/w level
+	 * It will allows the frame buffers numbers to be modified at runtime.
+	 */
+	if (!chan->has_fstoreen &&
+	     chan->desc_pendingcount < chan->num_frms) {
+		dev_warn(chan->dev, "Frame Store Configuration is not enabled at the\n");
+		dev_warn(chan->dev, "H/w level enable Debug info 13 or 6 at the h/w level\n");
+		dev_warn(chan->dev, "OR Submit the frames upto h/w Capable\n\r");
+
+		return;
+	}
+
 	desc = list_first_entry(&chan->pending_list,
 				struct xilinx_dma_tx_descriptor, node);
 	tail_desc = list_last_entry(&chan->pending_list,
@@ -1052,25 +1075,38 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 	if (chan->has_sg) {
 		dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
 				tail_segment->phys);
+		list_splice_tail_init(&chan->pending_list, &chan->active_list);
+		chan->desc_pendingcount = 0;
 	} else {
 		struct xilinx_vdma_tx_segment *segment, *last = NULL;
-		int i = 0;
+		int i = 0, j = 0;
 
 		if (chan->desc_submitcount < chan->num_frms)
 			i = chan->desc_submitcount;
 
-		list_for_each_entry(segment, &desc->segments, node) {
-			if (chan->ext_addr)
-				vdma_desc_write_64(chan,
-					XILINX_VDMA_REG_START_ADDRESS_64(i++),
-					segment->hw.buf_addr,
-					segment->hw.buf_addr_msb);
-			else
-				vdma_desc_write(chan,
-					XILINX_VDMA_REG_START_ADDRESS(i++),
-					segment->hw.buf_addr);
-
-			last = segment;
+		for (j = 0; j < chan->num_frms; ) {
+			list_for_each_entry(segment, &desc->segments, node) {
+				if (chan->ext_addr)
+					vdma_desc_write_64(chan,
+					  XILINX_VDMA_REG_START_ADDRESS_64(i++),
+					  segment->hw.buf_addr,
+					  segment->hw.buf_addr_msb);
+				else
+					vdma_desc_write(chan,
+					    XILINX_VDMA_REG_START_ADDRESS(i++),
+					    segment->hw.buf_addr);
+
+				last = segment;
+			}
+			list_del(&desc->node);
+			list_add_tail(&desc->node, &chan->active_list);
+			j++;
+			if (list_empty(&chan->pending_list) ||
+			    (i == chan->num_frms))
+				break;
+			desc = list_first_entry(&chan->pending_list,
+						struct xilinx_dma_tx_descriptor,
+						node);
 		}
 
 		if (!last)
@@ -1081,20 +1117,14 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 		vdma_desc_write(chan, XILINX_DMA_REG_FRMDLY_STRIDE,
 				last->hw.stride);
 		vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize);
-	}
 
-	chan->idle = false;
-	if (!chan->has_sg) {
-		list_del(&desc->node);
-		list_add_tail(&desc->node, &chan->active_list);
-		chan->desc_submitcount++;
-		chan->desc_pendingcount--;
+		chan->desc_submitcount += j;
+		chan->desc_pendingcount -= j;
 		if (chan->desc_submitcount == chan->num_frms)
 			chan->desc_submitcount = 0;
-	} else {
-		list_splice_tail_init(&chan->pending_list, &chan->active_list);
-		chan->desc_pendingcount = 0;
 	}
+
+	chan->idle = false;
 }
 
 /**
@@ -1342,6 +1372,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
 
 	chan->err = false;
 	chan->idle = true;
+	chan->desc_submitcount = 0;
 
 	return err;
 }
@@ -2320,6 +2351,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
 	has_dre = of_property_read_bool(node, "xlnx,include-dre");
 
 	chan->genlock = of_property_read_bool(node, "xlnx,genlock-mode");
+	chan->has_fstoreen = of_property_read_bool(node, "xlnx,fstore-enable");
 
 	err = of_property_read_u32(node, "xlnx,datawidth", &value);
 	if (err) {
-- 
2.1.2

^ permalink raw reply related

* [PATCH v6 3/3] dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario
From: Kedareswara rao Appana @ 2017-01-14  5:35 UTC (permalink / raw)
  To: robh+dt, mark.rutland, dan.j.williams, vinod.koul, michal.simek,
	soren.brinkmann, appanad, moritz.fischer, laurent.pinchart, luis,
	Jose.Abreu
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree
In-Reply-To: <1484372155-19423-1-git-send-email-appanad@xilinx.com>

As per AXI DMA spec the software must not move the tail pointer to a location
That has not been updated (next descriptor field of the h/w descriptor
Should always point to a valid address).

When user submits multiple descriptors on the recv side, with the
Current driver flow the last buffer descriptor next descriptor field
Points to a invalid location, resulting the invalid data or errors in the
DMA engine.

This patch fixes this issue by creating a Buffer Descritpor Chain during
Channel allocation itself and use those Buffer Descriptors.

Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v6:
---> Updated Commit message as suggested by Vinod.
Changes for v5:
---> None.
Changes for v4:
---> None.
Changes for v3:
---> None.
Changes for v2:
---> None.

 drivers/dma/xilinx/xilinx_dma.c | 133 +++++++++++++++++++++++++---------------
 1 file changed, 83 insertions(+), 50 deletions(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index edb5b71..c5cd935 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -163,6 +163,7 @@
 #define XILINX_DMA_BD_SOP		BIT(27)
 #define XILINX_DMA_BD_EOP		BIT(26)
 #define XILINX_DMA_COALESCE_MAX		255
+#define XILINX_DMA_NUM_DESCS		255
 #define XILINX_DMA_NUM_APP_WORDS	5
 
 /* Multi-Channel DMA Descriptor offsets*/
@@ -310,6 +311,7 @@ struct xilinx_dma_tx_descriptor {
  * @pending_list: Descriptors waiting
  * @active_list: Descriptors ready to submit
  * @done_list: Complete descriptors
+ * @free_seg_list: Free descriptors
  * @common: DMA common channel
  * @desc_pool: Descriptors pool
  * @dev: The dma device
@@ -331,7 +333,9 @@ struct xilinx_dma_tx_descriptor {
  * @desc_submitcount: Descriptor h/w submitted count
  * @residue: Residue for AXI DMA
  * @seg_v: Statically allocated segments base
+ * @seg_p: Physical allocated segments base
  * @cyclic_seg_v: Statically allocated segment base for cyclic transfers
+ * @cyclic_seg_p: Physical allocated segments base for cyclic dma
  * @start_transfer: Differentiate b/w DMA IP's transfer
  */
 struct xilinx_dma_chan {
@@ -342,6 +346,7 @@ struct xilinx_dma_chan {
 	struct list_head pending_list;
 	struct list_head active_list;
 	struct list_head done_list;
+	struct list_head free_seg_list;
 	struct dma_chan common;
 	struct dma_pool *desc_pool;
 	struct device *dev;
@@ -363,7 +368,9 @@ struct xilinx_dma_chan {
 	u32 desc_submitcount;
 	u32 residue;
 	struct xilinx_axidma_tx_segment *seg_v;
+	dma_addr_t seg_p;
 	struct xilinx_axidma_tx_segment *cyclic_seg_v;
+	dma_addr_t cyclic_seg_p;
 	void (*start_transfer)(struct xilinx_dma_chan *chan);
 	u16 tdest;
 };
@@ -569,17 +576,31 @@ static struct xilinx_axidma_tx_segment *
 xilinx_axidma_alloc_tx_segment(struct xilinx_dma_chan *chan)
 {
 	struct xilinx_axidma_tx_segment *segment;
-	dma_addr_t phys;
-
-	segment = dma_pool_zalloc(chan->desc_pool, GFP_ATOMIC, &phys);
-	if (!segment)
-		return NULL;
+	unsigned long flags;
 
-	segment->phys = phys;
+	spin_lock_irqsave(&chan->lock, flags);
+	if (!list_empty(&chan->free_seg_list)) {
+		segment = list_first_entry(&chan->free_seg_list,
+					   struct xilinx_axidma_tx_segment,
+					   node);
+		list_del(&segment->node);
+	}
+	spin_unlock_irqrestore(&chan->lock, flags);
 
 	return segment;
 }
 
+static void xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw)
+{
+	u32 next_desc = hw->next_desc;
+	u32 next_desc_msb = hw->next_desc_msb;
+
+	memset(hw, 0, sizeof(struct xilinx_axidma_desc_hw));
+
+	hw->next_desc = next_desc;
+	hw->next_desc_msb = next_desc_msb;
+}
+
 /**
  * xilinx_dma_free_tx_segment - Free transaction segment
  * @chan: Driver specific DMA channel
@@ -588,7 +609,9 @@ xilinx_axidma_alloc_tx_segment(struct xilinx_dma_chan *chan)
 static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
 				struct xilinx_axidma_tx_segment *segment)
 {
-	dma_pool_free(chan->desc_pool, segment, segment->phys);
+	xilinx_dma_clean_hw_desc(&segment->hw);
+
+	list_add_tail(&segment->node, &chan->free_seg_list);
 }
 
 /**
@@ -713,16 +736,26 @@ static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
 static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
 {
 	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	unsigned long flags;
 
 	dev_dbg(chan->dev, "Free all channel resources.\n");
 
 	xilinx_dma_free_descriptors(chan);
+
 	if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
-		xilinx_dma_free_tx_segment(chan, chan->cyclic_seg_v);
-		xilinx_dma_free_tx_segment(chan, chan->seg_v);
+		spin_lock_irqsave(&chan->lock, flags);
+		INIT_LIST_HEAD(&chan->free_seg_list);
+		spin_unlock_irqrestore(&chan->lock, flags);
+
+		/* Free Memory that is allocated for cyclic DMA Mode */
+		dma_free_coherent(chan->dev, sizeof(*chan->cyclic_seg_v),
+				  chan->cyclic_seg_v, chan->cyclic_seg_p);
+	}
+
+	if (chan->xdev->dma_config->dmatype != XDMA_TYPE_AXIDMA) {
+		dma_pool_destroy(chan->desc_pool);
+		chan->desc_pool = NULL;
 	}
-	dma_pool_destroy(chan->desc_pool);
-	chan->desc_pool = NULL;
 }
 
 /**
@@ -805,6 +838,7 @@ static void xilinx_dma_do_tasklet(unsigned long data)
 static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
 {
 	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	int i;
 
 	/* Has this channel already been allocated? */
 	if (chan->desc_pool)
@@ -815,11 +849,30 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
 	 * for meeting Xilinx VDMA specification requirement.
 	 */
 	if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
-		chan->desc_pool = dma_pool_create("xilinx_dma_desc_pool",
-				   chan->dev,
-				   sizeof(struct xilinx_axidma_tx_segment),
-				   __alignof__(struct xilinx_axidma_tx_segment),
-				   0);
+		/* Allocate the buffer descriptors. */
+		chan->seg_v = dma_zalloc_coherent(chan->dev,
+						  sizeof(*chan->seg_v) *
+						  XILINX_DMA_NUM_DESCS,
+						  &chan->seg_p, GFP_KERNEL);
+		if (!chan->seg_v) {
+			dev_err(chan->dev,
+				"unable to allocate channel %d descriptors\n",
+				chan->id);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
+			chan->seg_v[i].hw.next_desc =
+			lower_32_bits(chan->seg_p + sizeof(*chan->seg_v) *
+				((i + 1) % XILINX_DMA_NUM_DESCS));
+			chan->seg_v[i].hw.next_desc_msb =
+			upper_32_bits(chan->seg_p + sizeof(*chan->seg_v) *
+				((i + 1) % XILINX_DMA_NUM_DESCS));
+			chan->seg_v[i].phys = chan->seg_p +
+				sizeof(*chan->seg_v) * i;
+			list_add_tail(&chan->seg_v[i].node,
+				      &chan->free_seg_list);
+		}
 	} else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
 		chan->desc_pool = dma_pool_create("xilinx_cdma_desc_pool",
 				   chan->dev,
@@ -834,7 +887,8 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
 				     0);
 	}
 
-	if (!chan->desc_pool) {
+	if (!chan->desc_pool &&
+	    (chan->xdev->dma_config->dmatype != XDMA_TYPE_AXIDMA)) {
 		dev_err(chan->dev,
 			"unable to allocate channel %d descriptor pool\n",
 			chan->id);
@@ -843,22 +897,20 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
 
 	if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
 		/*
-		 * For AXI DMA case after submitting a pending_list, keep
-		 * an extra segment allocated so that the "next descriptor"
-		 * pointer on the tail descriptor always points to a
-		 * valid descriptor, even when paused after reaching taildesc.
-		 * This way, it is possible to issue additional
-		 * transfers without halting and restarting the channel.
-		 */
-		chan->seg_v = xilinx_axidma_alloc_tx_segment(chan);
-
-		/*
 		 * For cyclic DMA mode we need to program the tail Descriptor
 		 * register with a value which is not a part of the BD chain
 		 * so allocating a desc segment during channel allocation for
 		 * programming tail descriptor.
 		 */
-		chan->cyclic_seg_v = xilinx_axidma_alloc_tx_segment(chan);
+		chan->cyclic_seg_v = dma_zalloc_coherent(chan->dev,
+					sizeof(*chan->cyclic_seg_v),
+					&chan->cyclic_seg_p, GFP_KERNEL);
+		if (!chan->cyclic_seg_v) {
+			dev_err(chan->dev,
+				"unable to allocate desc segment for cyclic DMA\n");
+			return -ENOMEM;
+		}
+		chan->cyclic_seg_v->phys = chan->cyclic_seg_p;
 	}
 
 	dma_cookie_init(dchan);
@@ -1198,7 +1250,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)
 static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
 {
 	struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
-	struct xilinx_axidma_tx_segment *tail_segment, *old_head, *new_head;
+	struct xilinx_axidma_tx_segment *tail_segment;
 	u32 reg;
 
 	if (chan->err)
@@ -1217,21 +1269,6 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
 	tail_segment = list_last_entry(&tail_desc->segments,
 				       struct xilinx_axidma_tx_segment, node);
 
-	if (chan->has_sg && !chan->xdev->mcdma) {
-		old_head = list_first_entry(&head_desc->segments,
-					struct xilinx_axidma_tx_segment, node);
-		new_head = chan->seg_v;
-		/* Copy Buffer Descriptor fields. */
-		new_head->hw = old_head->hw;
-
-		/* Swap and save new reserve */
-		list_replace_init(&old_head->node, &new_head->node);
-		chan->seg_v = old_head;
-
-		tail_segment->hw.next_desc = chan->seg_v->phys;
-		head_desc->async_tx.phys = new_head->phys;
-	}
-
 	reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR);
 
 	if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
@@ -1729,7 +1766,7 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
 {
 	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
 	struct xilinx_dma_tx_descriptor *desc;
-	struct xilinx_axidma_tx_segment *segment = NULL, *prev = NULL;
+	struct xilinx_axidma_tx_segment *segment = NULL;
 	u32 *app_w = (u32 *)context;
 	struct scatterlist *sg;
 	size_t copy;
@@ -1780,10 +1817,6 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
 					       XILINX_DMA_NUM_APP_WORDS);
 			}
 
-			if (prev)
-				prev->hw.next_desc = segment->phys;
-
-			prev = segment;
 			sg_used += copy;
 
 			/*
@@ -1797,7 +1830,6 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
 	segment = list_first_entry(&desc->segments,
 				   struct xilinx_axidma_tx_segment, node);
 	desc->async_tx.phys = segment->phys;
-	prev->hw.next_desc = segment->phys;
 
 	/* For the last DMA_MEM_TO_DEV transfer, set EOP */
 	if (chan->direction == DMA_MEM_TO_DEV) {
@@ -2346,6 +2378,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
 	INIT_LIST_HEAD(&chan->pending_list);
 	INIT_LIST_HEAD(&chan->done_list);
 	INIT_LIST_HEAD(&chan->active_list);
+	INIT_LIST_HEAD(&chan->free_seg_list);
 
 	/* Retrieve the channel properties from the device tree */
 	has_dre = of_property_read_bool(node, "xlnx,include-dre");
-- 
2.1.2

^ permalink raw reply related

* Re: [PATCH v3 6/7] devicetree: power: bq27xxx: add monitored battery documentation
From: Matt Ranostay @ 2017-01-14  6:07 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Sebastian Reichel,
	Tony Lindgren
In-Reply-To: <20170113172821.noogiax7bqwhkoev@rob-hp-laptop>

On Fri, Jan 13, 2017 at 9:28 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Tue, Jan 10, 2017 at 10:20:02PM -0800, Matt Ranostay wrote:
>> Depends-On: http://marc.info/?l=linux-pm&m=148392292830015&w=2
>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>> ---
>>  Documentation/devicetree/bindings/power/supply/bq27xxx.txt | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/power/supply/bq27xxx.txt b/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
>> index b0c95ef63e68..0472a2db0f13 100644
>> --- a/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
>> +++ b/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
>> @@ -28,9 +28,17 @@ Required properties:
>>   * "ti,bq27621" - BQ27621
>>  - reg: integer, i2c address of the device.
>>
>> +Optional properties:
>> +- monitored-battery: phandle of battery information devicetree node
>
> We need a common way to describe charger/monitor to battery connections,
> not yet another way. The battery and power supply related bindings are a
> bit of a mess from what I've looked at.

Sebastian, your thoughts here?

Thanks,

Matt

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

^ permalink raw reply

* [PATCH v1 1/3] dt: bindings: add documentation for zx2967 family reset controller
From: Baoyou Xie @ 2017-01-14  7:05 UTC (permalink / raw)
  To: jun.nie, p.zabel, robh+dt, mark.rutland
  Cc: devicetree, xie.baoyou, linux-kernel, chen.chaokai, wang.qiang01,
	baoyou.xie, shawnguo, linux-arm-kernel

This patch adds dt-binding documentation for zx2967 family
reset controller.

Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
 .../devicetree/bindings/reset/zte,zx2967-reset.txt   | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt

diff --git a/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
new file mode 100644
index 0000000..22d590e
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
@@ -0,0 +1,20 @@
+ZTE zx2967 SoCs Reset Controller
+=======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: should be one of the following.
+	* zte,zx296718-reset
+- reg: physical base address of the controller and length of memory mapped
+	region.
+- #reset-cells: must be 1.
+
+example:
+
+	toprst: reset@1461060 {
+		compatible = "zte,zx296718-reset";
+		reg = <0x01461060 0x8>;
+		#reset-cells = <1>;
+	};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v1 2/3] MAINTAINERS: add zx2967 reset controller driver to ARM ZTE architecture
From: Baoyou Xie @ 2017-01-14  7:05 UTC (permalink / raw)
  To: jun.nie, p.zabel, robh+dt, mark.rutland
  Cc: devicetree, xie.baoyou, linux-kernel, chen.chaokai, wang.qiang01,
	baoyou.xie, shawnguo, linux-arm-kernel
In-Reply-To: <1484377530-30635-1-git-send-email-baoyou.xie@linaro.org>

Add the zx2967 reset controller driver as maintained by ARM ZTE
architecture maintainers, as they're parts of the core IP.

Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2793808..08f8155 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1980,10 +1980,12 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	arch/arm/mach-zx/
 F:	drivers/clk/zte/
+F:	drivers/reset/reset-zx2967.c
 F:	drivers/soc/zte/
 F:	drivers/thermal/zx*
 F:	Documentation/devicetree/bindings/arm/zte.txt
 F:	Documentation/devicetree/bindings/clock/zx296702-clk.txt
+F:	Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
 F:	Documentation/devicetree/bindings/soc/zte/
 F:	Documentation/devicetree/bindings/thermal/zx*
 F:	include/dt-bindings/soc/zx*.h
-- 
2.7.4

^ permalink raw reply related

* [PATCH v1 3/3] reset: zx2967: add reset controller driver for ZTE's zx2967 family
From: Baoyou Xie @ 2017-01-14  7:05 UTC (permalink / raw)
  To: jun.nie, p.zabel, robh+dt, mark.rutland
  Cc: devicetree, xie.baoyou, linux-kernel, chen.chaokai, wang.qiang01,
	baoyou.xie, shawnguo, linux-arm-kernel
In-Reply-To: <1484377530-30635-1-git-send-email-baoyou.xie@linaro.org>

This patch adds reset controller driver for ZTE's zx2967 family.

Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
 drivers/reset/Kconfig        |   6 ++
 drivers/reset/Makefile       |   1 +
 drivers/reset/reset-zx2967.c | 136 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+)
 create mode 100644 drivers/reset/reset-zx2967.c

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 172dc96..972d077 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -92,6 +92,12 @@ config RESET_ZYNQ
 	help
 	  This enables the reset controller driver for Xilinx Zynq SoCs.
 
+config RESET_ZX2967
+	bool "ZX2967 Reset Driver"
+	depends on ARCH_ZX || COMPILE_TEST
+	help
+	  This enables the reset controller driver for ZTE zx2967 family.
+
 source "drivers/reset/sti/Kconfig"
 source "drivers/reset/hisilicon/Kconfig"
 source "drivers/reset/tegra/Kconfig"
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 13b346e..807b77b 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o
 obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
 obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
+obj-$(CONFIG_RESET_ZX2967) += reset-zx2967.o
diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c
new file mode 100644
index 0000000..63f9c41
--- /dev/null
+++ b/drivers/reset/reset-zx2967.c
@@ -0,0 +1,136 @@
+/*
+ * ZTE's zx2967 family thermal sensor driver
+ *
+ * Copyright (C) 2017 ZTE Ltd.
+ *
+ * Author: Baoyou Xie <baoyou.xie@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+struct zx2967_reset {
+	void __iomem			*reg_base;
+	spinlock_t			lock;
+	struct reset_controller_dev	rcdev;
+};
+
+static int zx2967_reset_assert(struct reset_controller_dev *rcdev,
+			   unsigned long id)
+{
+	struct zx2967_reset *reset = NULL;
+	int bank = id / 32;
+	int offset = id % 32;
+	unsigned int reg;
+	unsigned long flags;
+
+	reset = container_of(rcdev, struct zx2967_reset, rcdev);
+
+	spin_lock_irqsave(&reset->lock, flags);
+
+	reg = readl(reset->reg_base + (bank * 4));
+	writel(reg & ~BIT(offset), reset->reg_base + (bank * 4));
+	reg = readl(reset->reg_base + (bank * 4));
+
+	spin_unlock_irqrestore(&reset->lock, flags);
+
+	return 0;
+}
+
+static int zx2967_reset_deassert(struct reset_controller_dev *rcdev,
+			     unsigned long id)
+{
+	struct zx2967_reset *reset = NULL;
+	int bank = id / 32;
+	int offset = id % 32;
+	unsigned int reg;
+	unsigned long flags;
+
+	reset = container_of(rcdev, struct zx2967_reset, rcdev);
+
+	spin_lock_irqsave(&reset->lock, flags);
+
+	reg = readl(reset->reg_base + (bank * 4));
+	writel(reg | BIT(offset), reset->reg_base + (bank * 4));
+	reg = readl(reset->reg_base + (bank * 4));
+
+	spin_unlock_irqrestore(&reset->lock, flags);
+
+	return 0;
+}
+
+static struct reset_control_ops zx2967_reset_ops = {
+	.assert		= zx2967_reset_assert,
+	.deassert	= zx2967_reset_deassert,
+};
+
+static int zx2967_reset_probe(struct platform_device *pdev)
+{
+	struct zx2967_reset *reset;
+	struct resource *res;
+
+	reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
+	if (!reset)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	reset->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(reset->reg_base))
+		return PTR_ERR(reset->reg_base);
+
+	spin_lock_init(&reset->lock);
+
+	reset->rcdev.owner = THIS_MODULE;
+	reset->rcdev.nr_resets = resource_size(res) * 8;
+	reset->rcdev.ops = &zx2967_reset_ops;
+	reset->rcdev.of_node = pdev->dev.of_node;
+
+	dev_info(&pdev->dev, "reset controller cnt:%d",
+		  reset->rcdev.nr_resets);
+
+	return reset_controller_register(&reset->rcdev);
+}
+
+static int zx2967_reset_remove(struct platform_device *pdev)
+{
+	struct zx2967_reset *reset = platform_get_drvdata(pdev);
+
+	reset_controller_unregister(&reset->rcdev);
+
+	return 0;
+}
+
+static const struct of_device_id zx2967_reset_dt_ids[] = {
+	 { .compatible = "zte,zx296718-reset", },
+	 {},
+};
+MODULE_DEVICE_TABLE(of, zx2967_reset_dt_ids);
+
+static struct platform_driver zx2967_reset_driver = {
+	.probe	= zx2967_reset_probe,
+	.remove	= zx2967_reset_remove,
+	.driver = {
+		.name		= "zx2967-reset",
+		.of_match_table	= zx2967_reset_dt_ids,
+	},
+};
+
+static int __init zx2967_reset_init(void)
+{
+	return platform_driver_register(&zx2967_reset_driver);
+}
+arch_initcall(zx2967_reset_init);
+
+static void __exit zx2967_reset_exit(void)
+{
+	platform_driver_unregister(&zx2967_reset_driver);
+}
+module_exit(zx2967_reset_exit);
+
+MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
+MODULE_DESCRIPTION("ZTE zx2967 Reset Controller Driver");
+MODULE_LICENSE("GPL");
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCHv4 3/5] pinctrl: mvebu: pinctrl driver for 98DX3236 SoC
From: Chris Packham @ 2017-01-14  7:50 UTC (permalink / raw)
  To: Sebastian Hesselbarth, linux-arm-kernel@lists.infradead.org
  Cc: Kalyan Kinthada, Linus Walleij, Rob Herring, Mark Rutland,
	Thomas Petazzoni, Laxman Dewangan, linux-gpio@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <2fca7ac2-9a88-19b1-28c5-5192b9c4a2bc@gmail.com>

On 13/01/17 22:54, Sebastian Hesselbarth wrote:
> On 13.01.2017 10:12, Chris Packham wrote:
>> From: Kalyan Kinthada <kalyan.kinthada@alliedtelesis.co.nz>
>>
>> This pinctrl driver supports the 98DX3236, 98DX3336 and 98DX4251 SoCs
>> from Marvell.
>>
>> Signed-off-by: Kalyan Kinthada <kalyan.kinthada@alliedtelesis.co.nz>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>> Acked-by: Rob Herring <robh@kernel.org>
>> Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
>> ---
>>
>> Notes:
>>     Changes in v2:
>>     - include sdio support for the 98DX4251
>>     Changes in v3:
>>     - None
>>     Changes in v4:
>>     - Correct some discrepencies between binding and driver.
>
> Well, unfortunately I still see differences between the "gpio" in
> the binding and "gpo" in the driver.
>
> Please go back to that list I sent you yesterday and fix them all.
>

I think you may have missed my initial reply [1]. Or I have missed your 
response to it. Long story short "gpo" is intentional because some of 
those pins can't be used as inputs. But if you still want me to change 
it I will.

[1] - https://lkml.org/lkml/2017/1/12/117


^ permalink raw reply

* Re: [PATCH v1 2/2] arm: dts: mt2701: add nor flash node
From: Boris Brezillon @ 2017-01-14  8:29 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Matthias Brugger, Guochun Mao, David Woodhouse, Brian Norris,
	Richard Weinberger, Cyrille Pitchen, Rob Herring, Mark Rutland,
	Russell King, linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <0fafcd8d-cf99-de6b-728f-5e3637810b68-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Fri, 13 Jan 2017 18:33:40 +0100
Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> On 01/13/2017 05:56 PM, Boris Brezillon wrote:
> > On Fri, 13 Jan 2017 17:44:12 +0100
> > Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> >   
> >> On 01/13/2017 05:28 PM, Boris Brezillon wrote:  
> >>> On Fri, 13 Jan 2017 17:13:55 +0100
> >>> Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> >>>     
> >>>> On 01/13/2017 04:12 PM, Matthias Brugger wrote:    
> >>>>>
> >>>>>
> >>>>> On 13/01/17 15:17, Boris Brezillon wrote:      
> >>>>>> On Fri, 13 Jan 2017 15:13:29 +0800
> >>>>>> Guochun Mao <guochun.mao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org> wrote:
> >>>>>>      
> >>>>>>> Add Mediatek nor flash node.
> >>>>>>>
> >>>>>>> Signed-off-by: Guochun Mao <guochun.mao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> >>>>>>> ---
> >>>>>>>  arch/arm/boot/dts/mt2701-evb.dts |   25 +++++++++++++++++++++++++
> >>>>>>>  arch/arm/boot/dts/mt2701.dtsi    |   12 ++++++++++++
> >>>>>>>  2 files changed, 37 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/arch/arm/boot/dts/mt2701-evb.dts
> >>>>>>> b/arch/arm/boot/dts/mt2701-evb.dts
> >>>>>>> index 082ca88..85e5ae8 100644
> >>>>>>> --- a/arch/arm/boot/dts/mt2701-evb.dts
> >>>>>>> +++ b/arch/arm/boot/dts/mt2701-evb.dts
> >>>>>>> @@ -24,6 +24,31 @@
> >>>>>>>      };
> >>>>>>>  };
> >>>>>>>
> >>>>>>> +&nor_flash {
> >>>>>>> +    pinctrl-names = "default";
> >>>>>>> +    pinctrl-0 = <&nor_pins_default>;
> >>>>>>> +    status = "okay";
> >>>>>>> +    flash@0 {
> >>>>>>> +        compatible = "jedec,spi-nor";
> >>>>>>> +        reg = <0>;
> >>>>>>> +    };
> >>>>>>> +};
> >>>>>>> +
> >>>>>>> +&pio {
> >>>>>>> +    nor_pins_default: nor {
> >>>>>>> +        pins1 {
> >>>>>>> +            pinmux = <MT2701_PIN_240_EXT_XCS__FUNC_EXT_XCS>,
> >>>>>>> +                 <MT2701_PIN_241_EXT_SCK__FUNC_EXT_SCK>,
> >>>>>>> +                 <MT2701_PIN_239_EXT_SDIO0__FUNC_EXT_SDIO0>,
> >>>>>>> +                 <MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1>,
> >>>>>>> +                 <MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2>,
> >>>>>>> +                 <MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3>;
> >>>>>>> +            drive-strength = <MTK_DRIVE_4mA>;
> >>>>>>> +            bias-pull-up;
> >>>>>>> +        };
> >>>>>>> +    };
> >>>>>>> +};
> >>>>>>> +
> >>>>>>>  &uart0 {
> >>>>>>>      status = "okay";
> >>>>>>>  };
> >>>>>>> diff --git a/arch/arm/boot/dts/mt2701.dtsi
> >>>>>>> b/arch/arm/boot/dts/mt2701.dtsi
> >>>>>>> index bdf8954..1eefce4 100644
> >>>>>>> --- a/arch/arm/boot/dts/mt2701.dtsi
> >>>>>>> +++ b/arch/arm/boot/dts/mt2701.dtsi
> >>>>>>> @@ -227,6 +227,18 @@
> >>>>>>>          status = "disabled";
> >>>>>>>      };
> >>>>>>>
> >>>>>>> +    nor_flash: spi@11014000 {
> >>>>>>> +        compatible = "mediatek,mt2701-nor",
> >>>>>>> +                 "mediatek,mt8173-nor";      
> >>>>>>
> >>>>>> Why define both here? Is "mediatek,mt8173-nor" really providing a
> >>>>>> subset of the features supported by "mediatek,mt2701-nor"?
> >>>>>>      
> >>>>>
> >>>>> I think even if the ip block is the same, we should provide both
> >>>>> bindings, just in case in the future we find out that mt2701 has some
> >>>>> hidden bug, feature or bug-feature. This way even if we update the
> >>>>> driver, we stay compatible with older device tree blobs in the wild.
> >>>>>
> >>>>> We can drop the mt2701-nor in the bindings definition if you want.     
> >>>
> >>> Oh, sorry, I misunderstood. What I meant is that if you want to
> >>> list/support all possible compatibles, maybe you should just put one
> >>> compatible in your DT and patch your driver (+ binding doc) to define
> >>> all of them.    
> >>
> >> Uh, what ? I lost you here :-)

I mean adding a new entry in the mtk_nor_of_ids table (in
mtk-quadspi.c) so that the mediatek,mt2701-nor compatible string can be
matched directly, and you won't need to define 2 compatible strings in
your device tree.

> >>  
> >>>> This exactly. We should have a DT compat in the form:
> >>>> compatible = "vendor,<soc>-block", "vendor,<oldest-compat-soc>-block";
> >>>> Then if we find a problem in the future, we can match on the
> >>>> "vendor,<soc>-block" and still support the old DTs.    
> >>>
> >>> Not sure it's only in term of whose IP appeared first. My understanding
> >>> is that it's a way to provide inheritance. For example:
> >>>
> >>> 	"<soc-vendor>,<ip-version>", "<ip-vendor>,<ip-version>";
> >>>
> >>> or
> >>>
> >>> 	"<soc-vendor>,<full-featured-ip-version>","<soc-vendor>,<basic-feature-ip-version>";
> >>>
> >>> BTW, which one is the oldest between mt8173 and mt2701? :-)    
> >>
> >> And that's another thing and I agree with you, but I don't think that's
> >> what we're discussing in this thread. But (!), OT, I think we should
> >> codify the rules in Documentation/ . This discussion came up multiple
> >> times recently.
> >>
> >> And my question still stands, what do we put into the DT here, IMO
> >> compatible = "mediatek,mt2701-nor", "mediatek,mt8173-nor";  
> > 
> > I'd say
> > 
> > 	compatible = "mediatek,mt8173-nor";
> > 
> > because both compatible are referring to very specific IP version. It's
> > not the same as  
> 
> But then you don't have the ability to handle a block in this particular
> SoC in case there's a bug found in it in the future,
> so IMO it should be:
> 
> compatible = "mediatek,mt2701-nor", "mediatek,mt8173-nor";

Sorry again, I meant

	compatible = "mediatek,mt2701-nor";

> 
> > 	compatible = "mediatek,mt8173-nor", "mediatek,mt81xx-nor";  
> 
> This doesn't look right, since here we add two new compatibles ...

That was just an example to describe how compatible inheritance works
(at least that's my understanding of it), it does not apply to this
particular use case.

> 
> > where you clearly have a generic compatible which is overloaded by a
> > specific one.
> > 
> > But anyway, I'm not the one taking the decision here, let's wait for DT
> > maintainers reviews.
> >   
> >> and what goes into the binding document ? I guess both too ?  
> > 
> > If both exist, they should be both documented.
> >   
> 
> 

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

^ permalink raw reply

* Re: [PATCH v4 1/2] iio: adc: Add Maxim MAX11100 driver
From: Jonathan Cameron @ 2017-01-14 10:22 UTC (permalink / raw)
  To: Jacopo Mondi, wsa+renesas-jBu1N2QxHDJrcw3mvpCnnVaTQe2KTcn/,
	magnus.damm-Re5JQEeQqe8AvxtiuMwx3w, knaack.h-Mmb7MZpHnFY,
	lars-Qo5EllUWu/uELgA04lAiVw, pmeerw-jW+XmwGofnusTnJN9+BGXg,
	marek.vasut-Re5JQEeQqe8AvxtiuMwx3w, geert-Td1EMuHUCqxL1ZNQvxDV9g,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484301038-16386-2-git-send-email-jacopo+renesas-AW8dsiIh9cEdnm+yROfE0A@public.gmane.org>

On 13/01/17 09:50, Jacopo Mondi wrote:
> From: Jacopo Mondi <jacopo-AW8dsiIh9cEdnm+yROfE0A@public.gmane.org>
> 
> Add iio driver for Maxim MAX11100 single-channel ADC.
> 
> Signed-off-by: Jacopo Mondi <jacopo+renesas-AW8dsiIh9cEdnm+yROfE0A@public.gmane.org>
> Tested-by: Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
Small issue with DMA using SPI controllers and the location of buffer
in your read.

Otherwise looks good to me.

Jonathan
> ---
>  drivers/iio/adc/Kconfig    |   9 +++
>  drivers/iio/adc/Makefile   |   1 +
>  drivers/iio/adc/max11100.c | 187 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 197 insertions(+)
>  create mode 100644 drivers/iio/adc/max11100.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 38bc319..c32bc7a 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -307,6 +307,15 @@ config MAX1027
>  	  To compile this driver as a module, choose M here: the module will be
>  	  called max1027.
>  
> +config MAX11100
> +	tristate "Maxim max11100 ADC driver"
> +	depends on SPI_MASTER
> +	help
> +	  Say yes here to build support for Maxim max11100 SPI ADC
> +
> +	  To compile this driver as a module, choose M here: the module will be
> +	  called max11100.
> +
>  config MAX1363
>  	tristate "Maxim max1363 ADC driver"
>  	depends on I2C
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index d36c4be..5684369 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -31,6 +31,7 @@ obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
>  obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
>  obj-$(CONFIG_LTC2485) += ltc2485.o
>  obj-$(CONFIG_MAX1027) += max1027.o
> +obj-$(CONFIG_MAX11100) += max11100.o
>  obj-$(CONFIG_MAX1363) += max1363.o
>  obj-$(CONFIG_MCP320X) += mcp320x.o
>  obj-$(CONFIG_MCP3422) += mcp3422.o
> diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c
> new file mode 100644
> index 0000000..78e2a45
> --- /dev/null
> +++ b/drivers/iio/adc/max11100.c
> @@ -0,0 +1,187 @@
> +/*
> + * iio/adc/max11100.c
> + * Maxim max11100 ADC Driver with IIO interface
> + *
> + * Copyright (C) 2016 Renesas Electronics Corporation
> + * Copyright (C) 2016 Jacopo Mondi
> + *
> + * 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/delay.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/spi/spi.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/driver.h>
> +
> +/*
> + * LSB is the ADC single digital step
> + * 1 LSB = (vref_mv / 2 ^ 16)
> + *
> + * LSB is used to calculate analog voltage value
> + * from the number of ADC steps count
> + *
> + * Ain = (count * LSB)
> + */
> +#define MAX11100_LSB_DIV		(1 << 16)
> +
> +struct max11100_state {
> +	const struct max11100_chip_desc *desc;
> +	struct regulator *vref_reg;
> +	struct spi_device *spi;
> +};
> +
> +static struct iio_chan_spec max11100_channels[] = {
> +	{ /* [0] */
> +		.type = IIO_VOLTAGE,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +	},
> +};
> +
> +static struct max11100_chip_desc {
> +	unsigned int num_chan;
> +	const struct iio_chan_spec *channels;
> +} max11100_desc = {
> +	.num_chan = ARRAY_SIZE(max11100_channels),
> +	.channels = max11100_channels,
> +};
> +
> +static int max11100_read_single(struct iio_dev *indio_dev, int *val)
> +{
> +	int ret;
> +	struct max11100_state *state = iio_priv(indio_dev);
> +	uint8_t buffer[3];
> +
> +	ret = spi_read(state->spi, buffer, sizeof(buffer));
Buffer needs to be __cacheline_aligned to safely use spi_read on spi
controllers that use DMA.

Two easy ways of doing this, either allocate buffer using kmalloc or
take advantage of the fact that spi_priv() is cache line aligned and
stick you buffer at the end of your private structure and mark it
__cacheline_aligned to ensure it also appropriately aligned in it's own
cacheline.

> +	if (ret) {
> +		dev_err(&indio_dev->dev, "SPI transfer failed\n");
> +		return ret;
> +	}
> +
> +	/* the first 8 bits sent out from ADC must be 0s */
> +	if (buffer[0]) {
> +		dev_err(&indio_dev->dev, "Invalid value: buffer[0] != 0\n");
> +		return -EINVAL;
> +	}
> +
> +	*val = (buffer[1] << 8) | buffer[2];
> +
> +	return 0;
> +}
> +
> +static int max11100_read_raw(struct iio_dev *indio_dev,
> +			     struct iio_chan_spec const *chan,
> +			     int *val, int *val2, long info)
> +{
> +	int ret, vref_uv;
> +	struct max11100_state *state = iio_priv(indio_dev);
> +
> +	switch (info) {
> +	case IIO_CHAN_INFO_RAW:
> +		ret = max11100_read_single(indio_dev, val);
> +		if (ret)
> +			return ret;
> +
> +		return IIO_VAL_INT;
> +
> +	case IIO_CHAN_INFO_SCALE:
> +		vref_uv = regulator_get_voltage(state->vref_reg);
> +		if (vref_uv < 0)
> +			/* dummy regulator "get_voltage" returns -EINVAL */
> +			return -EINVAL;
> +
> +		*val =  vref_uv / 1000;
> +		*val2 = MAX11100_LSB_DIV;
> +		return IIO_VAL_FRACTIONAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct iio_info max11100_info = {
> +	.driver_module = THIS_MODULE,
> +	.read_raw = max11100_read_raw,
> +};
> +
> +static int max11100_probe(struct spi_device *spi)
> +{
> +	int ret;
> +	struct iio_dev *indio_dev;
> +	struct max11100_state *state;
> +
> +	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	spi_set_drvdata(spi, indio_dev);
> +
> +	state = iio_priv(indio_dev);
> +	state->spi = spi;
> +	state->desc = &max11100_desc;
> +
> +	indio_dev->dev.parent = &spi->dev;
> +	indio_dev->dev.of_node = spi->dev.of_node;
> +	indio_dev->info = &max11100_info;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +	indio_dev->channels = state->desc->channels;
> +	indio_dev->num_channels = state->desc->num_chan;
> +
> +	state->vref_reg = devm_regulator_get(&spi->dev, "vref");
> +	if (IS_ERR(state->vref_reg))
> +		return PTR_ERR(state->vref_reg);
> +
> +	ret = regulator_enable(state->vref_reg);
> +	if (ret)
> +		return ret;
> +
> +	ret = iio_device_register(indio_dev);
> +	if (ret)
> +		goto disable_regulator;
> +
> +	return 0;
> +
> +disable_regulator:
> +	regulator_disable(state->vref_reg);
> +
> +	return ret;
> +}
> +
> +static int max11100_remove(struct spi_device *spi)
> +{
> +	struct iio_dev *indio_dev = spi_get_drvdata(spi);
> +	struct max11100_state *state = iio_priv(indio_dev);
> +
> +	regulator_disable(state->vref_reg);
> +
> +	iio_device_unregister(indio_dev);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id max11100_ids[] = {
> +	{.compatible = "maxim,max11100"},
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, max11100_ids);
> +
> +static struct spi_driver max11100_driver = {
> +	.driver = {
> +		.name	= "max11100",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = of_match_ptr(max11100_ids),
> +	},
> +	.probe		= max11100_probe,
> +	.remove		= max11100_remove,
> +};
> +
> +module_spi_driver(max11100_driver);
> +
> +MODULE_AUTHOR("Jacopo Mondi <jacopo-AW8dsiIh9cEdnm+yROfE0A@public.gmane.org>");
> +MODULE_DESCRIPTION("Maxim max11100 ADC Driver");
> +MODULE_LICENSE("GPL v2");
> 

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

^ permalink raw reply

* Re: [PATCH v2 5/6] arm: dts: mt2701: Add ethernet device node.
From: John Crispin @ 2017-01-14 10:32 UTC (permalink / raw)
  To: Erin Lo, Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Sean Wang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1484296978-18572-6-git-send-email-erin.lo-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

Hi Erin,

small comment inline

On 13/01/2017 09:42, Erin Lo wrote:
> From: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> 
> Add ethernet device node for MT2701.
> 
> Signed-off-by: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Erin Lo <erin.lo-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
>  arch/arm/boot/dts/mt2701-evb.dts | 40 ++++++++++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/mt2701.dtsi    | 22 ++++++++++++++++++++++
>  2 files changed, 62 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
> index a483798..40abd3b 100644
> --- a/arch/arm/boot/dts/mt2701-evb.dts
> +++ b/arch/arm/boot/dts/mt2701-evb.dts
> @@ -28,7 +28,47 @@
>  	status = "okay";
>  };
>  
> +&eth {
> +	mac-address = [00 00 00 00 00 00];
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac1_pins>;
> +	gmac1: mac@1 {
> +		compatible = "mediatek,eth-mac";
> +		reg = <1>;
> +		phy-handle = <&phy5>;
> +	};
> +
> +	mdio-bus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		phy5: ethernet-phy@5 {
> +			reg = <5>;
> +			phy-mode = "rgmii-rxid";
> +		};
> +	};
> +};
> +
>  &pio {
> +	gmac1_pins: eth@0 {
> +		pins_eth {
> +			pinmux = <MT2701_PIN_275_MDC__FUNC_MDC>,
> +				 <MT2701_PIN_276_MDIO__FUNC_MDIO>,
> +				 <MT2701_PIN_262_G2_TXEN__FUNC_G2_TXEN>,
> +				 <MT2701_PIN_263_G2_TXD3__FUNC_G2_TXD3>,
> +				 <MT2701_PIN_264_G2_TXD2__FUNC_G2_TXD2>,
> +				 <MT2701_PIN_265_G2_TXD1__FUNC_G2_TXD1>,
> +				 <MT2701_PIN_266_G2_TXD0__FUNC_G2_TXD0>,
> +				 <MT2701_PIN_267_G2_TXC__FUNC_G2_TXC>,
> +				 <MT2701_PIN_268_G2_RXC__FUNC_G2_RXC>,
> +				 <MT2701_PIN_269_G2_RXD0__FUNC_G2_RXD0>,
> +				 <MT2701_PIN_270_G2_RXD1__FUNC_G2_RXD1>,
> +				 <MT2701_PIN_271_G2_RXD2__FUNC_G2_RXD2>,
> +				 <MT2701_PIN_272_G2_RXD3__FUNC_G2_RXD3>,
> +				 <MT2701_PIN_274_G2_RXDV__FUNC_G2_RXDV>;
> +		};
> +	};
> +
>  	spi_pins_a: spi0@0 {
>  		pins_spi {
>  			pinmux = <MT2701_PIN_53_SPI0_CSN__FUNC_SPI0_CS>,
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index 4f52019..3847f70 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -381,6 +381,28 @@
>  		#clock-cells = <1>;
>  	};
>  
> +	eth: ethernet@1b100000 {
> +		compatible = "mediatek,mt7623-eth";
> +		reg = <0 0x1b100000 0 0x20000>;
> +		interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_SPI 199 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
> +		clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
> +			 <&apmixedsys CLK_APMIXED_TRGPLL>,
> +			 <&ethsys CLK_ETHSYS_ESW>,
> +			 <&ethsys CLK_ETHSYS_GP2>,
> +			 <&ethsys CLK_ETHSYS_GP1>;
> +		clock-names = "ethif", "trgpll", "esw", "gp2", "gp1";
> +		power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
> +		resets = <&watchdog MT2701_TOPRGU_ETHDMA_RST>;

are you sure this is correct ? on mt7623 we point the reset at ethsys
and not the watchdog.

	John

> +		reset-names = "eth";
> +		mediatek,ethsys = <&ethsys>;
> +		mediatek,pctl = <&syscfg_pctl_a>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +	};
> +
>  	bdpsys: syscon@1c000000 {
>  		compatible = "mediatek,mt2701-bdpsys", "syscon";
>  		reg = <0 0x1c000000 0 0x1000>;
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2] iio: max5481: Add support for Maxim digital potentiometers
From: Jonathan Cameron @ 2017-01-14 10:38 UTC (permalink / raw)
  To: Slawomir Stepien, linux-iio-u79uwXL29TY76Z2rM5mHXA
  Cc: cristina.moraru09-Re5JQEeQqe8AvxtiuMwx3w,
	matthew.weber-lFk7bPDcGtkY5TsXZYaR1UEOCMrvLtNR,
	maury.anderson-lFk7bPDcGtkY5TsXZYaR1UEOCMrvLtNR,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mark Rutland,
	Rob Herring
In-Reply-To: <20170108185733.GA8511-SwUeJysX96B82hYKe6nXyg@public.gmane.org>

On 08/01/17 18:57, Slawomir Stepien wrote:
> From: Matt Weber <matthew.weber-lFk7bPDcGtkY5TsXZYaR1UEOCMrvLtNR@public.gmane.org>
> 
> Add implementation for Maxim Integrated 5481, 5482, 5483,
> and 5484 digital potentiometer devices.
> 
> Datasheet:
> http://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf
> 
> Signed-off-by: Maury Anderson <maury.anderson-lFk7bPDcGtkY5TsXZYaR1UEOCMrvLtNR@public.gmane.org>
> Signed-off-by: Matthew Weber <matthew.weber-lFk7bPDcGtkY5TsXZYaR1UEOCMrvLtNR@public.gmane.org>
> Signed-off-by: Slawomir Stepien <sst-IjDXvh/HVVUAvxtiuMwx3w@public.gmane.org>
As this has device tree bindings it should have gone to linux-devicetree,
Rob and Mark (maintainers of bindings).

Spi buffers for spi_write need to be cacheline aligned.  See below
for roughly why.

Jonathan
> ---
> 
> This is my resubmission of this patch after original authors decided not to
> pursuit it inclusion into kernel.
> 
> Tested using signal analyzer.
> 
> Changes since v1:
> * removed not needed '``' and 'c' chars
> * includes are now sorted
> * added coma to last item in enum max5481_variant
> * removed maxpos from struct max5481_cfg
> * max5481_CHANNEL is no MAX5481_CHANNEL and it does not have 'ch' argument
> * max5481_write_cmd is now based around switch
> * removed not needed cast in max5481_write_cmd
> * wpier state is saved after iio_device_unregister
> * changed names in spi_device_id and acpi_device_id to be equal to names in of_device_id
> 
> ---
>  .../bindings/iio/potentiometer/max5481.txt         |  23 +++
>  drivers/iio/potentiometer/Kconfig                  |  11 ++
>  drivers/iio/potentiometer/Makefile                 |   1 +
>  drivers/iio/potentiometer/max5481.c                | 215 +++++++++++++++++++++
>  4 files changed, 250 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/potentiometer/max5481.txt
>  create mode 100644 drivers/iio/potentiometer/max5481.c
> 
> diff --git a/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt b/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt
> new file mode 100644
> index 000000000000..6a91b106e076
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt
> @@ -0,0 +1,23 @@
> +* Maxim Linear-Taper Digital Potentiometer MAX5481-MAX5484
> +
> +The node for this driver must be a child node of a SPI controller, hence
> +all mandatory properties described in
> +
> +        Documentation/devicetree/bindings/spi/spi-bus.txt
> +
> +must be specified.
> +
> +Required properties:
> +	- compatible:  	Must be one of the following, depending on the
> +			model:
> +			"maxim,max5481"
> +			"maxim,max5482"
> +			"maxim,max5483"
> +			"maxim,max5484"
> +
> +Example:
> +max548x: max548x@0 {
> +	compatible = "maxim,max5482";
> +	spi-max-frequency = <7000000>;
> +	reg = <0>; /* chip-select */
> +};
> diff --git a/drivers/iio/potentiometer/Kconfig b/drivers/iio/potentiometer/Kconfig
> index 2e9da1cf3297..8bf282510be6 100644
> --- a/drivers/iio/potentiometer/Kconfig
> +++ b/drivers/iio/potentiometer/Kconfig
> @@ -15,6 +15,17 @@ config DS1803
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called ds1803.
>  
> +config MAX5481
> +        tristate "Maxim MAX5481-MAX5484 Digital Potentiometer driver"
> +        depends on SPI
> +        help
> +          Say yes here to build support for the Maxim
> +          MAX5481, MAX5482, MAX5483, MAX5484 digital potentiometer
> +          chips.
> +
> +          To compile this driver as a module, choose M here: the
> +          module will be called max5481.
> +
>  config MAX5487
>          tristate "Maxim MAX5487/MAX5488/MAX5489 Digital Potentiometer driver"
>          depends on SPI
> diff --git a/drivers/iio/potentiometer/Makefile b/drivers/iio/potentiometer/Makefile
> index 8adb58f38c0b..2260d40e0936 100644
> --- a/drivers/iio/potentiometer/Makefile
> +++ b/drivers/iio/potentiometer/Makefile
> @@ -4,6 +4,7 @@
>  
>  # When adding new entries keep the list in alphabetical order
>  obj-$(CONFIG_DS1803) += ds1803.o
> +obj-$(CONFIG_MAX5481) += max5481.o
>  obj-$(CONFIG_MAX5487) += max5487.o
>  obj-$(CONFIG_MCP4131) += mcp4131.o
>  obj-$(CONFIG_MCP4531) += mcp4531.o
> diff --git a/drivers/iio/potentiometer/max5481.c b/drivers/iio/potentiometer/max5481.c
> new file mode 100644
> index 000000000000..59ced74b0252
> --- /dev/null
> +++ b/drivers/iio/potentiometer/max5481.c
> @@ -0,0 +1,215 @@
> +/*
> + * Maxim Integrated MAX5481-MAX5484 digital potentiometer driver
> + * Copyright 2016 Rockwell Collins
> + *
> + * Datasheet:
> + * http://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf
> + *
> + * 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/acpi.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/spi/spi.h>
> +
> +/* write wiper reg */
> +#define MAX5481_WRITE_WIPER (0 << 4)
> +/* copy wiper reg to NV reg */
> +#define MAX5481_COPY_AB_TO_NV (2 << 4)
> +/* copy NV reg to wiper reg */
> +#define MAX5481_COPY_NV_TO_AB (3 << 4)
> +
> +#define MAX5481_MAX_POS    1023
> +
> +enum max5481_variant {
> +	max5481,
> +	max5482,
> +	max5483,
> +	max5484,
> +};
> +
> +struct max5481_cfg {
> +	int kohms;
> +};
> +
> +static const struct max5481_cfg max5481_cfg[] = {
> +	[max5481] = { .kohms =  10, },
> +	[max5482] = { .kohms =  50, },
> +	[max5483] = { .kohms =  10, },
> +	[max5484] = { .kohms =  50, },
> +};
> +
> +struct max5481_data {
> +	struct spi_device *spi;
> +	const struct max5481_cfg *cfg;
> +};
> +
> +#define MAX5481_CHANNEL {					\
> +	.type = IIO_RESISTANCE,					\
> +	.indexed = 1,						\
> +	.output = 1,						\
> +	.channel = 0,						\
> +	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
> +	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
> +}
> +
> +static const struct iio_chan_spec max5481_channels[] = {
> +	MAX5481_CHANNEL,
> +};
> +
> +static int max5481_write_cmd(struct spi_device *spi, u8 cmd, u16 val)
> +{
> +	/* SPI Format from MAX5481-MAX5484 (19-3708; Rev 5; 4/10) pg 15 */
> +	u8 msg[3];
It's clearly one of those days - same issue in two drivers in a row. :(
Still I can refine me response ;)

There are requirements for buffers passed directly to spi_read / spi_write.
They get passed to spi_sync which calls into the spi master drivers.
SPI master drivers are explicitly allowed to directly use this buffer
in dma. On most modern platforms it is fine to do DMA from any location...

However, cacheline corruption comes in here. There is no guarantee that
the SPI controller won't write back to this address, as it it will be
bypassing the processor whilst doing this, that can result in a difference
in other parts of the cacheline between what is in the cache and what is
in main memory.  At the end of the dma transfer any changes elsewhere in
the cacheline can be wiped out as result. (or something like that ;)

Anyhow, two solutions.  Either allocate the memory in it's own cacheline
which will naturally happen if you allocate on the heap using kmalloc
or use the fact we carefully align the iio_priv memory to be cacheline
aligned. This means that if you stick a __cacheline_aligned buffer at the
end of your iio_priv structure it was also be in it's own cacheline.

Not doing this is the source of really hard to track down bugs!
> +
> +	msg[0] = cmd;
> +
> +	switch (cmd) {
> +	case MAX5481_WRITE_WIPER:
> +		msg[1] = val >> 2;
> +		msg[2] = (val & 0x3) << 6;
> +		return spi_write(spi, msg, ARRAY_SIZE(msg));
> +
> +	case MAX5481_COPY_AB_TO_NV:
> +	case MAX5481_COPY_NV_TO_AB:
> +		return spi_write(spi, msg, sizeof(u8));
> +
> +	default:
> +		return -EIO;
> +	}
> +}
> +
> +static int max5481_read_raw(struct iio_dev *indio_dev,
> +		struct iio_chan_spec const *chan,
> +		int *val, int *val2, long mask)
> +{
> +	struct max5481_data *data = iio_priv(indio_dev);
> +
> +	if (mask != IIO_CHAN_INFO_SCALE)
> +		return -EINVAL;
> +
> +	*val = 1000 * data->cfg->kohms;
> +	*val2 = MAX5481_MAX_POS;
> +
> +	return IIO_VAL_FRACTIONAL;
> +}
> +
> +static int max5481_write_raw(struct iio_dev *indio_dev,
> +		struct iio_chan_spec const *chan,
> +		int val, int val2, long mask)
> +{
> +	struct max5481_data *data = iio_priv(indio_dev);
> +
> +	if (mask != IIO_CHAN_INFO_RAW)
> +		return -EINVAL;
> +
> +	if (val < 0 || val > MAX5481_MAX_POS)
> +		return -EINVAL;
> +
> +	return max5481_write_cmd(data->spi, MAX5481_WRITE_WIPER, val);
> +}
> +
> +static const struct iio_info max5481_info = {
> +	.read_raw = max5481_read_raw,
> +	.write_raw = max5481_write_raw,
> +	.driver_module = THIS_MODULE,
> +};
> +
> +static int max5481_probe(struct spi_device *spi)
> +{
> +	struct iio_dev *indio_dev;
> +	struct max5481_data *data;
> +	const struct spi_device_id *id = spi_get_device_id(spi);
> +	int ret;
> +
> +	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(&spi->dev, indio_dev);
> +	data = iio_priv(indio_dev);
> +
> +	data->spi = spi;
> +	data->cfg = &max5481_cfg[id->driver_data];
> +
> +	indio_dev->name = id->name;
> +	indio_dev->dev.parent = &spi->dev;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +	/* variant specific configuration */
> +	indio_dev->info = &max5481_info;
> +	indio_dev->channels = max5481_channels;
> +	indio_dev->num_channels = ARRAY_SIZE(max5481_channels);
> +
> +	/* restore wiper from NV */
> +	ret = max5481_write_cmd(data->spi, MAX5481_COPY_NV_TO_AB, 0);
> +	if (ret < 0)
> +		return ret;
> +
> +	return iio_device_register(indio_dev);
> +}
> +
> +static int max5481_remove(struct spi_device *spi)
> +{
> +	struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
> +
> +	iio_device_unregister(indio_dev);
> +
> +	/* save wiper reg to NV reg */
> +	return max5481_write_cmd(spi, MAX5481_COPY_AB_TO_NV, 0);
> +}
> +
> +static const struct spi_device_id max5481_id_table[] = {
> +	{ "max5481", max5481 },
> +	{ "max5482", max5482 },
> +	{ "max5483", max5483 },
> +	{ "max5484", max5484 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(spi, max5481_id_table);
> +
> +#if defined(CONFIG_OF)
> +static const struct of_device_id max5481_match[] = {
> +	{ .compatible = "maxim,max5481", .data = &max5481_cfg[max5481] },
> +	{ .compatible = "maxim,max5482", .data = &max5481_cfg[max5482] },
> +	{ .compatible = "maxim,max5483", .data = &max5481_cfg[max5483] },
> +	{ .compatible = "maxim,max5484", .data = &max5481_cfg[max5484] },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, max5481_match);
> +#endif
> +
> +#if defined(CONFIG_ACPI)
> +static const struct acpi_device_id max5481_acpi_match[] = {
> +	{ "max5481", max5481 },
> +	{ "max5482", max5482 },
> +	{ "max5483", max5483 },
> +	{ "max5484", max5484 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(acpi, max5481_acpi_match);
> +#endif
> +
> +static struct spi_driver max5481_driver = {
> +	.driver = {
> +		.name  = "max5481",
> +		.owner = THIS_MODULE,
> +		.of_match_table = of_match_ptr(max5481_match),
> +		.acpi_match_table = ACPI_PTR(max5481_acpi_match),
> +	},
> +	.probe = max5481_probe,
> +	.remove = max5481_remove,
> +	.id_table = max5481_id_table,
> +};
> +
> +module_spi_driver(max5481_driver);
> +
> +MODULE_AUTHOR("Maury Anderson <maury.anderson-lFk7bPDcGtkY5TsXZYaR1UEOCMrvLtNR@public.gmane.org>");
> +MODULE_DESCRIPTION("max5481 SPI driver");
> +MODULE_LICENSE("GPL v2");
> 

^ permalink raw reply

* Re: [PATCH v4] iio:temperature: Add support for TI TMP007 sensor
From: Jonathan Cameron @ 2017-01-14 10:48 UTC (permalink / raw)
  To: Rob Herring, Manivannan Sadhasivam
  Cc: pmeerw-jW+XmwGofnusTnJN9+BGXg, linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170110053603.n6ihrg3r6z4244g5@rob-hp-laptop>

On 10/01/17 05:36, Rob Herring wrote:
> On Mon, Jan 09, 2017 at 08:25:26AM +0530, Manivannan Sadhasivam wrote:
>> This patch adds support for TI TMP007 - 16 bit IR thermopile sensor with integrated Math engine.
>> Sensor takes care of calculating the object temperature with the help of calibrated constants stored in non-volatile memory,
>> thereby reducing the calculation overhead.
>>
>> Signed-off-by: Manivannan Sadhasivam <manivannanece23-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> ---
>>
>> Changes since v3:
>>
>> 1. Removed caching of status register
>> 2. Modified comments for data validity
>> 3. Added possible address combinations in dTree bindings file
>>
>>  .../devicetree/bindings/iio/temperature/tmp007.txt |  27 ++
> 
> This could be documented under trivial-devices.txt, but doesn't hurt to 
> have it here.
> 
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Thanks as ever Rob - I don't say that often enough!

Anyhow, nice little driver. Applied to the togreg branch of iio.git and
pushed out as testing for the autobuilders to see if they can find anything
we missed.

Was a bit messy going in with some fuzz, but superficially looks fine.

Thanks,

Jonathan
> 
>>  drivers/iio/temperature/Kconfig                    |  10 +
>>  drivers/iio/temperature/Makefile                   |   1 +
>>  drivers/iio/temperature/tmp007.c                   | 345 +++++++++++++++++++++
>>  4 files changed, 383 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/iio/temperature/tmp007.txt
>>  create mode 100644 drivers/iio/temperature/tmp007.c
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: [PATCH v2] iio: max5481: Add support for Maxim digital potentiometers
From: Slawomir Stepien @ 2017-01-14 11:42 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	cristina.moraru09-Re5JQEeQqe8AvxtiuMwx3w,
	matthew.weber-lFk7bPDcGtkY5TsXZYaR1UEOCMrvLtNR,
	maury.anderson-lFk7bPDcGtkY5TsXZYaR1UEOCMrvLtNR,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mark Rutland,
	Rob Herring
In-Reply-To: <ee973aa1-c881-6bc8-c61a-9f36b8598f5f-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

On Jan 14, 2017 10:38, Jonathan Cameron wrote:
> As this has device tree bindings it should have gone to linux-devicetree,
> Rob and Mark (maintainers of bindings).

I will add them to CC on the new version.

> Spi buffers for spi_write need to be cacheline aligned.  See below
> for roughly why.

I can recall that from my previous submissions... I made the same mistake.
Thank you once again for explaining that. I hope this will imprint in my mind
from now on.

Thank you!

> Jonathan
> > ---
> > +static int max5481_write_cmd(struct spi_device *spi, u8 cmd, u16 val)
> > +{
> > +	/* SPI Format from MAX5481-MAX5484 (19-3708; Rev 5; 4/10) pg 15 */
> > +	u8 msg[3];
> It's clearly one of those days - same issue in two drivers in a row. :(
> Still I can refine me response ;)
> 
> There are requirements for buffers passed directly to spi_read / spi_write.
> They get passed to spi_sync which calls into the spi master drivers.
> SPI master drivers are explicitly allowed to directly use this buffer
> in dma. On most modern platforms it is fine to do DMA from any location...
> 
> However, cacheline corruption comes in here. There is no guarantee that
> the SPI controller won't write back to this address, as it it will be
> bypassing the processor whilst doing this, that can result in a difference
> in other parts of the cacheline between what is in the cache and what is
> in main memory.  At the end of the dma transfer any changes elsewhere in
> the cacheline can be wiped out as result. (or something like that ;)
> 
> Anyhow, two solutions.  Either allocate the memory in it's own cacheline
> which will naturally happen if you allocate on the heap using kmalloc
> or use the fact we carefully align the iio_priv memory to be cacheline
> aligned. This means that if you stick a __cacheline_aligned buffer at the
> end of your iio_priv structure it was also be in it's own cacheline.
> 
> Not doing this is the source of really hard to track down bugs!
> > +
> > +	msg[0] = cmd;
> > +
> > +	switch (cmd) {
> > +	case MAX5481_WRITE_WIPER:
> > +		msg[1] = val >> 2;
> > +		msg[2] = (val & 0x3) << 6;
> > +		return spi_write(spi, msg, ARRAY_SIZE(msg));
> > +
> > +	case MAX5481_COPY_AB_TO_NV:
> > +	case MAX5481_COPY_NV_TO_AB:
> > +		return spi_write(spi, msg, sizeof(u8));
> > +
> > +	default:
> > +		return -EIO;
> > +	}
> > +}

-- 
Slawomir Stepien

^ permalink raw reply

* Re: [PATCH v2 2/2] iio: distance: srf08: add IIO driver for us ranger
From: Jonathan Cameron @ 2017-01-14 12:17 UTC (permalink / raw)
  To: Andreas Klinger, knaack.h-Mmb7MZpHnFY,
	lars-Qo5EllUWu/uELgA04lAiVw, pmeerw-jW+XmwGofnusTnJN9+BGXg,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, ktsai-GubuWUlQtMwciDkP5Hr2oA,
	wsa-z923LK4zBo2bacvFa/9K2g, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, trivial-DgEjT+Ai2ygdnm+yROfE0A,
	mranostay-Re5JQEeQqe8AvxtiuMwx3w,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170110184815.GA15532@andreas>

On 10/01/17 18:48, Andreas Klinger wrote:
> This is the IIO driver for devantech srf08 ultrasonic ranger which can be
> used to measure the distances to an object.
> 
> The sensor supports I2C with some registers.
> 
> Supported Features include:
> - read the distance in ranging mode in centimeters
> - output of the driver is directly the read value
> - together with the scale the driver delivers the distance in meters
> - only the first echo of the nearest object is delivered
> - set max gain register; userspace enters analogue value
> - set range registers; userspace enters range in millimeters in 43 mm steps
> 
> Features not supported by this driver:
> - ranging mode in inches or in microseconds
> - ANN mode
> - change I2C address through this driver
> - light sensor
> 
> The driver was added in the directory "proximity" of the iio subsystem
> in absence of another directory named "distance".
> There is also a new submenu "distance"
Hi Andreas,

Sorry it took me a while to get to this!

I'd not bother with the new submenu.  Perhaps we should rename the
proximity menu to proximity/distance.

We already the lightening detector in there which is definitely not
measuring proximity in the convetional sense!

Anyhow, the actual code is fine, but we need to think about how the
userspace ABI fits within the wider IIO ABI.  Naming and approaches
that make sense in a single class of drivers can end up meaining
very different things for other drivers.  Various suggestions inline.

Jonathan
> 
> Signed-off-by: Andreas Klinger <ak-n176/SwNRljddJNmlsFzeA@public.gmane.org>
> ---
>  drivers/iio/proximity/Kconfig  |  15 ++
>  drivers/iio/proximity/Makefile |   1 +
>  drivers/iio/proximity/srf08.c  | 362 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 378 insertions(+)
>  create mode 100644 drivers/iio/proximity/srf08.c
> 
> diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
> index ef4c73db5b53..7b10a137702b 100644
> --- a/drivers/iio/proximity/Kconfig
> +++ b/drivers/iio/proximity/Kconfig
> @@ -46,3 +46,18 @@ config SX9500
>  	  module will be called sx9500.
>  
>  endmenu
> +
> +menu "Distance sensors"
> +
> +config SRF08
> +	tristate "Devantech SRF08 ultrasonic ranger sensor"
> +	depends on I2C
> +	help
> +	  Say Y here to build a driver for Devantech SRF08 ultrasonic
> +	  ranger sensor. This driver can be used to measure the distance
> +	  of objects.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called srf08.
> +
> +endmenu
> diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile
> index 9aadd9a8ee99..e914c2a5dd49 100644
> --- a/drivers/iio/proximity/Makefile
> +++ b/drivers/iio/proximity/Makefile
> @@ -5,4 +5,5 @@
>  # When adding new entries keep the list in alphabetical order
>  obj-$(CONFIG_AS3935)		+= as3935.o
>  obj-$(CONFIG_LIDAR_LITE_V2)	+= pulsedlight-lidar-lite-v2.o
> +obj-$(CONFIG_SRF08)		+= srf08.o
>  obj-$(CONFIG_SX9500)		+= sx9500.o
> diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c
> new file mode 100644
> index 000000000000..f38c74ed0933
> --- /dev/null
> +++ b/drivers/iio/proximity/srf08.c
> @@ -0,0 +1,362 @@
> +/*
> + * srf08.c - Support for Devantech SRF08 ultrasonic ranger
> + *
> + * Copyright (c) 2016 Andreas Klinger <ak-n176/SwNRljddJNmlsFzeA@public.gmane.org>
> + *
> + * This file is subject to the terms and conditions of version 2 of
> + * the GNU General Public License.  See the file COPYING in the main
> + * directory of this archive for more details.
> + *
> + * For details about the device see:
> + * http://www.robot-electronics.co.uk/htm/srf08tech.html
> + */
> +
> +#include <linux/err.h>
> +#include <linux/i2c.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/bitops.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +
> +/* registers of SRF08 device */
> +#define SRF08_WRITE_COMMAND	0x00	/* Command Register */
> +#define SRF08_WRITE_MAX_GAIN	0x01	/* Max Gain Register: 0 .. 31 */
> +#define SRF08_WRITE_RANGE	0x02	/* Range Register: 0 .. 255 */
> +#define SRF08_READ_SW_REVISION	0x00	/* Software Revision */
> +#define SRF08_READ_LIGHT	0x01	/* Light Sensor during last echo */
> +#define SRF08_READ_ECHO_1_HIGH	0x02	/* Range of first echo received */
> +#define SRF08_READ_ECHO_1_LOW	0x03	/* Range of first echo received */
> +
> +#define SRF08_CMD_RANGING_CM	0x51	/* Ranging Mode - Result in cm */
> +
> +#define SRF08_DEFAULT_GAIN	1025	/* max. analogue value of Gain */
> +#define SRF08_DEFAULT_RANGE	11008	/* max. value of Range in mm */
> +
> +struct srf08_data {
> +	struct i2c_client	*client;
> +	int			gain;			/* Max Gain */
> +	int			range_mm;		/* Range in mm */
> +	struct mutex		lock;
> +};
> +
> +static const int srf08_gain[] = {
> +	 94,  97, 100, 103, 107, 110, 114, 118,
> +	123, 128, 133, 139, 145, 152, 159, 168,
> +	177, 187, 199, 212, 227, 245, 265, 288,
> +	317, 352, 395, 450, 524, 626, 777, 1025 };
> +
> +static int srf08_read_ranging(struct srf08_data *data)
> +{
> +	struct i2c_client *client = data->client;
> +	int ret, i;
> +
> +	mutex_lock(&data->lock);
> +
> +	ret = i2c_smbus_write_byte_data(data->client,
> +			SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "write command - err: %d\n", ret);
> +		mutex_unlock(&data->lock);
> +		return ret;
> +	}
> +
> +	/*
> +	 * normally after 65 ms the device should have the read value
> +	 * we round it up to 100 ms
I'd suggest this should be adapted so that it takes advantage of knowing
roughly how long it is going to take as the 'range' maximum is changed.
So perhaps in the basic case, sleep for 65 msecs, then poll at 5msec
intervals.  If we know it's going to be a lot faster, then poll it from
an earlier time.
> +	 *
> +	 * we read here until a correct version number shows up as
> +	 * suggested by the documentation
> +	 */
> +	for (i = 0; i < 5; i++) {
> +		ret = i2c_smbus_read_byte_data(data->client,
> +						SRF08_READ_SW_REVISION);
> +
> +		/* check if a valid version number is read */
> +		if (ret < 255 && ret > 0)
> +			break;
> +		msleep(20);
> +	}
> +
> +	if (ret >= 255 || ret <= 0) {
> +		dev_err(&client->dev, "device not ready\n");
> +		mutex_unlock(&data->lock);
> +		return -EIO;
> +	}
> +
> +	ret = i2c_smbus_read_word_swapped(data->client,
> +						SRF08_READ_ECHO_1_HIGH);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "cannot read distance: ret=%d\n", ret);
> +		mutex_unlock(&data->lock);
> +		return ret;
> +	}
> +
> +	mutex_unlock(&data->lock);
> +
> +	return ret;
> +}
> +
> +static int srf08_read_raw(struct iio_dev *indio_dev,
> +			    struct iio_chan_spec const *channel, int *val,
> +			    int *val2, long mask)
> +{
> +	struct srf08_data *data = iio_priv(indio_dev);
> +	int ret;
> +
> +	if (channel->type != IIO_DISTANCE)
> +		return -EINVAL;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		ret = srf08_read_ranging(data);
> +		if (ret < 0)
> +			return ret;
> +		*val = ret;
> +		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_SCALE:
> +		/* 1 LSB is 1 cm */
> +		*val = 0;
> +		*val2 = 10000;
> +		return IIO_VAL_INT_PLUS_MICRO;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static ssize_t srf08_show_range_mm_available(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	int i, len = 0;
> +
> +	for (i = 0; i < 256; i++)
> +		len += scnprintf(buf + len, PAGE_SIZE - len,
> +							"%d ", (i + 1) * 43);
> +
> +	buf[len - 1] = '\n';
> +
> +	return len;
> +}
> +
> +static IIO_DEVICE_ATTR(range_mm_available, S_IRUGO,
> +				srf08_show_range_mm_available, NULL, 0);
> +
> +static ssize_t srf08_show_range_mm(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct srf08_data *data = iio_priv(indio_dev);
> +
> +	return sprintf(buf, "%d\n", data->range_mm);
> +}
> +
> +/*
> + * set the range of the sensor to an even multiple of 43 mm
> + * which corresponds to 1 LSB in the register
> + *
> + * register value    corresponding range
> + *         0x00             43 mm
> + *         0x01             86 mm
> + *         0x02            129 mm
> + *         ...
> + *         0xFF          11008 mm
> + */
> +static ssize_t srf08_write_range_mm(struct device *dev,
> +					struct device_attribute *attr,
> +					const char *buf, size_t len)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct srf08_data *data = iio_priv(indio_dev);
> +	struct i2c_client *client = data->client;
> +	int ret;
> +	unsigned int val, mod;
> +	u8 regval;
> +
> +	ret = kstrtouint(buf, 10, &val);
> +	if (ret)
> +		return ret;
> +
> +	ret = val / 43 - 1;
> +	mod = val % 43;
> +
> +	if (mod || (ret < 0) || (ret > 255))
> +		return -EINVAL;
> +
> +	regval = ret;
> +
> +	mutex_lock(&data->lock);
> +
> +	ret = i2c_smbus_write_byte_data(data->client,
> +						SRF08_WRITE_RANGE, regval);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "write_range - err: %d\n", ret);
> +		mutex_unlock(&data->lock);
> +		return ret;
> +	}
> +
> +	data->range_mm = val;
> +
> +	mutex_unlock(&data->lock);
> +
> +	return len;
> +}
> +
> +static IIO_DEVICE_ATTR(range_mm, S_IRUGO | S_IWUSR,
> +			srf08_show_range_mm, srf08_write_range_mm, 0);
> +
> +static ssize_t srf08_show_gain_available(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	int i, len = 0;
> +
> +	for (i = 0; i < ARRAY_SIZE(srf08_gain); i++)
> +		len += sprintf(buf + len, "%d ", srf08_gain[i]);
> +
> +	len += sprintf(buf + len, "\n");
> +
> +	return len;
> +}
> +
> +static IIO_DEVICE_ATTR(gain_available, S_IRUGO,
> +				srf08_show_gain_available, NULL, 0);
> +
> +static ssize_t srf08_show_gain(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct srf08_data *data = iio_priv(indio_dev);
> +	int len;
> +
> +	len = sprintf(buf, "%d\n", data->gain);
> +
> +	return len;
> +}
> +
> +static ssize_t srf08_write_gain(struct device *dev,
> +						struct device_attribute *attr,
> +						const char *buf, size_t len)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct srf08_data *data = iio_priv(indio_dev);
> +	struct i2c_client *client = data->client;
> +	int ret, i;
> +	unsigned int val;
> +	u8 regval;
> +
> +	ret = kstrtouint(buf, 10, &val);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i < ARRAY_SIZE(srf08_gain); i++)
> +		if (val == srf08_gain[i]) {
> +			regval = i;
> +			break;
> +		}
> +
> +	if (i >= ARRAY_SIZE(srf08_gain))
> +		return -EINVAL;
> +
> +	mutex_lock(&data->lock);
> +
> +	ret = i2c_smbus_write_byte_data(data->client,
> +						SRF08_WRITE_MAX_GAIN, regval);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "write_gain - err: %d\n", ret);
> +		mutex_unlock(&data->lock);
> +		return ret;
> +	}
> +
> +	data->gain = val;
> +
> +	mutex_unlock(&data->lock);
> +
> +	return len;
> +}
> +
> +static IIO_DEVICE_ATTR(gain, S_IRUGO | S_IWUSR,
> +					srf08_show_gain, srf08_write_gain, 0);
> +
> +static struct attribute *srf08_attributes[] = {
> +	&iio_dev_attr_range_mm.dev_attr.attr,
> +	&iio_dev_attr_range_mm_available.dev_attr.attr,
> +	&iio_dev_attr_gain.dev_attr.attr,
> +	&iio_dev_attr_gain_available.dev_attr.attr,
Hmm. Custom attributes always give us issues. The primary point of IIO
is to enforce (more or less) standard interfaces.

If you do need to add something new then that is fine (and I do think
you need to here!).

They need to be formally proposed as an addition to the ABI with
docs in /Documentation/ABI/testing/sysfs-bus-iio*

Once we take one driver using it it becomes part of our ABI that
userspace will need to handle, hence we consider these very
carefully.

My gut feeling would be that gain needs to be more specific as it's
a term that can mean very different things.. Here we are talking
about an amplifier on a signal that we are then looking at the timing
of.   It might otherwise be interpretted as another term for what
we term 'scale' in IIO.

So what to call it... Perhaps afegain for Analog front end gain?
We might want to add this to the core supported attrs, but lets
not do so until we see if we have this on a number of devices.

The description would need to make it explicit that this gain is
for cases where we aren't measuring the magnitude of what is
being amplified.

For the range, it's an interesting one.  Again the term range could
mean too many things within the wider ABI. We need to make it more
specific.

Actually reading the datasheet, I think this is fundamentally about the
maximum sampling frequency rather than directly about the range.
The only reason you'd reduce the range is to speed that up. It doesn't
improve the resolution, the device simply answers quicker.

So I'd support this as sampling_frequency.  You could then use
the the iio_info_mask_*_available and relevant callback to provide
info on what it then restricts the possible output values to
(rather than controlling it directly).

> +	NULL,
> +};
> +
> +static const struct attribute_group srf08_attribute_group = {
> +	.attrs = srf08_attributes,
> +};
> +
> +static const struct iio_chan_spec srf08_channels[] = {
> +	{
> +		.type = IIO_DISTANCE,
> +		.info_mask_separate =
> +				BIT(IIO_CHAN_INFO_RAW) |
> +				BIT(IIO_CHAN_INFO_SCALE),
> +	},
> +};
> +
> +static const struct iio_info srf08_info = {
> +	.read_raw = srf08_read_raw,
> +	.attrs = &srf08_attribute_group,
> +	.driver_module = THIS_MODULE,
> +};
> +
> +static int srf08_probe(struct i2c_client *client,
> +					 const struct i2c_device_id *id)
> +{
> +	struct iio_dev *indio_dev;
> +	struct srf08_data *data;
> +
> +	if (!i2c_check_functionality(client->adapter,
> +					I2C_FUNC_SMBUS_READ_BYTE_DATA |
> +					I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
> +					I2C_FUNC_SMBUS_READ_WORD_DATA))
> +		return -ENODEV;
> +
> +	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	data = iio_priv(indio_dev);
> +	i2c_set_clientdata(client, indio_dev);
> +	data->client = client;
> +
> +	/*
> +	 * set default values of device here
> +	 * these values are already set on the hardware after power on
> +	 */
> +	data->gain = SRF08_DEFAULT_GAIN;
> +	data->range_mm = SRF08_DEFAULT_RANGE;
We should be a little careful with assumptions about the device having
just been powered on.  The driver might simply have been removed and
reprobed.  So I'd sugest rewriting them whatever to be sure we have
what we expect.  Either that or if they can be read back, then just
always retrieve them from the device.
> +
> +	indio_dev->name = dev_name(&client->dev);
> +	indio_dev->dev.parent = &client->dev;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +	indio_dev->info = &srf08_info;
> +	indio_dev->channels = srf08_channels;
> +	indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
> +
> +	mutex_init(&data->lock);
> +
> +	return devm_iio_device_register(&client->dev, indio_dev);
> +}
> +
> +static const struct i2c_device_id srf08_id[] = {
> +	{ "srf08", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, srf08_id);
> +
> +static struct i2c_driver srf08_driver = {
> +	.driver = {
> +		.name	= "srf08",
> +	},
> +	.probe = srf08_probe,
> +	.id_table = srf08_id,
> +};
> +module_i2c_driver(srf08_driver);
> +
> +MODULE_AUTHOR("Andreas Klinger <ak-n176/SwNRljddJNmlsFzeA@public.gmane.org>");
> +MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver");
> +MODULE_LICENSE("GPL");
> 

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

^ permalink raw reply

* [PATCH 0/4] Drop drivers for Exynos4415
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
  To: Sylwester Nawrocki, Tomasz Figa, Chanwoo Choi, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Kukjin Kim,
	Krzysztof Kozlowski, Javier Martinez Canillas, Inki Dae,
	Joonyoung Shim, Seung-Woo Kim, Kyungmin Park, Linus Walleij,
	linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, dri-deve

Hi,

Support for Exynos4415 is being removed because:
1. There are no upstream users,
2. There are no known downstream users,
3. Except compile testing, you cannot build working kernel
   for Exynos4415 anymore.

Patches are rebased on current next and are independent.
Please pick up as you wish.

Best regards,
Krzysztof

Krzysztof Kozlowski (4):
  ARM: EXYNOS: Remove Exynos4415 driver (SoC not supported anymore)
  clk: samsung: Remove Exynos4415 driver (SoC not supported anymore)
  pinctrl: samsung: Remove support for Exynos4415 (SoC not supported
    anymore)
  drm: exynos: Remove support for Exynos4415 (SoC not supported anymore)

 .../devicetree/bindings/clock/exynos4415-clock.txt |   38 -
 .../bindings/display/exynos/exynos_dsim.txt        |    1 -
 .../bindings/display/exynos/samsung-fimd.txt       |    1 -
 arch/arm/mach-exynos/Kconfig                       |    5 -
 arch/arm/mach-exynos/exynos.c                      |    1 -
 arch/arm/mach-exynos/suspend.c                     |    1 -
 drivers/clk/samsung/Makefile                       |    1 -
 drivers/clk/samsung/clk-exynos4415.c               | 1022 --------------------
 drivers/gpu/drm/exynos/exynos_drm_dsi.c            |   15 +-
 drivers/gpu/drm/exynos/exynos_drm_fimd.c           |   18 +-
 drivers/pinctrl/samsung/pinctrl-exynos.c           |   75 --
 drivers/pinctrl/samsung/pinctrl-samsung.c          |    2 -
 drivers/pinctrl/samsung/pinctrl-samsung.h          |    1 -
 include/dt-bindings/clock/exynos4415.h             |  360 -------
 14 files changed, 3 insertions(+), 1538 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos4415-clock.txt
 delete mode 100644 drivers/clk/samsung/clk-exynos4415.c
 delete mode 100644 include/dt-bindings/clock/exynos4415.h

-- 
2.9.3


^ permalink raw reply

* [PATCH 1/4] ARM: EXYNOS: Remove Exynos4415 driver (SoC not supported anymore)
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
  To: Sylwester Nawrocki, Tomasz Figa, Chanwoo Choi, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Kukjin Kim,
	Krzysztof Kozlowski, Javier Martinez Canillas, Inki Dae,
	Joonyoung Shim, Seung-Woo Kim, Kyungmin Park, Linus Walleij,
	linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, dri-deve
In-Reply-To: <20170114123642.15581-1-krzk@kernel.org>

Support for Exynos4415 is going away because there are no internal nor
external users.

Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
the platform cannot be instantiated so remove also the mach code.

Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
 arch/arm/mach-exynos/Kconfig   | 5 -----
 arch/arm/mach-exynos/exynos.c  | 1 -
 arch/arm/mach-exynos/suspend.c | 1 -
 3 files changed, 7 deletions(-)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 0bb63b8d21e7..0a99140b6ba2 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -95,11 +95,6 @@ config SOC_EXYNOS4412
 	default y
 	depends on ARCH_EXYNOS4
 
-config SOC_EXYNOS4415
-	bool "SAMSUNG EXYNOS4415"
-	default y
-	depends on ARCH_EXYNOS4
-
 config SOC_EXYNOS5250
 	bool "SAMSUNG EXYNOS5250"
 	default y
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 35b832f4bc7e..c404c15ad07f 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -210,7 +210,6 @@ static char const *const exynos_dt_compat[] __initconst = {
 	"samsung,exynos4210",
 	"samsung,exynos4212",
 	"samsung,exynos4412",
-	"samsung,exynos4415",
 	"samsung,exynos5",
 	"samsung,exynos5250",
 	"samsung,exynos5260",
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index 518420241062..25e7c5326259 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -270,7 +270,6 @@ EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu");
 EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
 EXYNOS_PMU_IRQ(exynos4212_pmu_irq, "samsung,exynos4212-pmu");
 EXYNOS_PMU_IRQ(exynos4412_pmu_irq, "samsung,exynos4412-pmu");
-EXYNOS_PMU_IRQ(exynos4415_pmu_irq, "samsung,exynos4415-pmu");
 EXYNOS_PMU_IRQ(exynos5250_pmu_irq, "samsung,exynos5250-pmu");
 EXYNOS_PMU_IRQ(exynos5420_pmu_irq, "samsung,exynos5420-pmu");
 
-- 
2.9.3

^ permalink raw reply related

* [PATCH 2/4] clk: samsung: Remove Exynos4415 driver (SoC not supported anymore)
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
  To: Sylwester Nawrocki, Tomasz Figa, Chanwoo Choi, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Kukjin Kim,
	Krzysztof Kozlowski, Javier Martinez Canillas, Inki Dae,
	Joonyoung Shim, Seung-Woo Kim, Kyungmin Park, Linus Walleij,
	linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, dri-deve
In-Reply-To: <20170114123642.15581-1-krzk@kernel.org>

Support for Exynos4415 is going away because there are no internal nor
external users.

Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
the platform cannot be instantiated so remove also the drivers.

Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
 .../devicetree/bindings/clock/exynos4415-clock.txt |   38 -
 drivers/clk/samsung/Makefile                       |    1 -
 drivers/clk/samsung/clk-exynos4415.c               | 1022 --------------------
 include/dt-bindings/clock/exynos4415.h             |  360 -------
 4 files changed, 1421 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos4415-clock.txt
 delete mode 100644 drivers/clk/samsung/clk-exynos4415.c
 delete mode 100644 include/dt-bindings/clock/exynos4415.h

diff --git a/Documentation/devicetree/bindings/clock/exynos4415-clock.txt b/Documentation/devicetree/bindings/clock/exynos4415-clock.txt
deleted file mode 100644
index 847d98bae8cf..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos4415-clock.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-* Samsung Exynos4415 Clock Controller
-
-The Exynos4415 clock controller generates and supplies clock to various
-consumer devices within the Exynos4415 SoC.
-
-Required properties:
-
-- compatible: should be one of the following:
-  - "samsung,exynos4415-cmu" - for the main system clocks controller
-    (CMU_LEFTBUS, CMU_RIGHTBUS, CMU_TOP, CMU_CPU clock domains).
-  - "samsung,exynos4415-cmu-dmc" - for the Exynos4415 SoC DRAM Memory
-    Controller (DMC) domain clock controller.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos4415.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	cmu: clock-controller@10030000 {
-		compatible = "samsung,exynos4415-cmu";
-		reg = <0x10030000 0x18000>;
-		#clock-cells = <1>;
-	};
-
-	cmu-dmc: clock-controller@105C0000 {
-		compatible = "samsung,exynos4415-cmu-dmc";
-		reg = <0x105C0000 0x3000>;
-		#clock-cells = <1>;
-	};
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 57f4dc6dc447..7afc21dc374e 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -5,7 +5,6 @@
 obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-pll.o clk-cpu.o
 obj-$(CONFIG_SOC_EXYNOS3250)	+= clk-exynos3250.o
 obj-$(CONFIG_ARCH_EXYNOS4)	+= clk-exynos4.o
-obj-$(CONFIG_SOC_EXYNOS4415)	+= clk-exynos4415.o
 obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5260)	+= clk-exynos5260.o
 obj-$(CONFIG_SOC_EXYNOS5410)	+= clk-exynos5410.o
diff --git a/drivers/clk/samsung/clk-exynos4415.c b/drivers/clk/samsung/clk-exynos4415.c
deleted file mode 100644
index 6c9063159717..000000000000
--- a/drivers/clk/samsung/clk-exynos4415.c
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- * Author: Chanwoo Choi <cw00.choi@samsung.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.
- *
- * Common Clock Framework support for Exynos4415 SoC.
- */
-
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/syscore_ops.h>
-
-#include <dt-bindings/clock/exynos4415.h>
-
-#include "clk.h"
-#include "clk-pll.h"
-
-#define SRC_LEFTBUS		0x4200
-#define DIV_LEFTBUS		0x4500
-#define GATE_IP_LEFTBUS		0x4800
-#define GATE_IP_IMAGE		0x4930
-#define SRC_RIGHTBUS		0x8200
-#define DIV_RIGHTBUS		0x8500
-#define GATE_IP_RIGHTBUS	0x8800
-#define GATE_IP_PERIR		0x8960
-#define EPLL_LOCK		0xc010
-#define G3D_PLL_LOCK		0xc020
-#define DISP_PLL_LOCK		0xc030
-#define ISP_PLL_LOCK		0xc040
-#define EPLL_CON0		0xc110
-#define EPLL_CON1		0xc114
-#define EPLL_CON2		0xc118
-#define G3D_PLL_CON0		0xc120
-#define G3D_PLL_CON1		0xc124
-#define G3D_PLL_CON2		0xc128
-#define ISP_PLL_CON0		0xc130
-#define ISP_PLL_CON1		0xc134
-#define ISP_PLL_CON2		0xc138
-#define DISP_PLL_CON0		0xc140
-#define DISP_PLL_CON1		0xc144
-#define DISP_PLL_CON2		0xc148
-#define SRC_TOP0		0xc210
-#define SRC_TOP1		0xc214
-#define SRC_CAM			0xc220
-#define SRC_TV			0xc224
-#define SRC_MFC			0xc228
-#define SRC_G3D			0xc22c
-#define SRC_LCD			0xc234
-#define SRC_ISP			0xc238
-#define SRC_MAUDIO		0xc23c
-#define SRC_FSYS		0xc240
-#define SRC_PERIL0		0xc250
-#define SRC_PERIL1		0xc254
-#define SRC_CAM1		0xc258
-#define SRC_TOP_ISP0		0xc25c
-#define SRC_TOP_ISP1		0xc260
-#define SRC_MASK_TOP		0xc310
-#define SRC_MASK_CAM		0xc320
-#define SRC_MASK_TV		0xc324
-#define SRC_MASK_LCD		0xc334
-#define SRC_MASK_ISP		0xc338
-#define SRC_MASK_MAUDIO		0xc33c
-#define SRC_MASK_FSYS		0xc340
-#define SRC_MASK_PERIL0		0xc350
-#define SRC_MASK_PERIL1		0xc354
-#define DIV_TOP			0xc510
-#define DIV_CAM			0xc520
-#define DIV_TV			0xc524
-#define DIV_MFC			0xc528
-#define DIV_G3D			0xc52c
-#define DIV_LCD			0xc534
-#define DIV_ISP			0xc538
-#define DIV_MAUDIO		0xc53c
-#define DIV_FSYS0		0xc540
-#define DIV_FSYS1		0xc544
-#define DIV_FSYS2		0xc548
-#define DIV_PERIL0		0xc550
-#define DIV_PERIL1		0xc554
-#define DIV_PERIL2		0xc558
-#define DIV_PERIL3		0xc55c
-#define DIV_PERIL4		0xc560
-#define DIV_PERIL5		0xc564
-#define DIV_CAM1		0xc568
-#define DIV_TOP_ISP1		0xc56c
-#define DIV_TOP_ISP0		0xc570
-#define CLKDIV2_RATIO		0xc580
-#define GATE_SCLK_CAM		0xc820
-#define GATE_SCLK_TV		0xc824
-#define GATE_SCLK_MFC		0xc828
-#define GATE_SCLK_G3D		0xc82c
-#define GATE_SCLK_LCD		0xc834
-#define GATE_SCLK_MAUDIO	0xc83c
-#define GATE_SCLK_FSYS		0xc840
-#define GATE_SCLK_PERIL		0xc850
-#define GATE_IP_CAM		0xc920
-#define GATE_IP_TV		0xc924
-#define GATE_IP_MFC		0xc928
-#define GATE_IP_G3D		0xc92c
-#define GATE_IP_LCD		0xc934
-#define GATE_IP_FSYS		0xc940
-#define GATE_IP_PERIL		0xc950
-#define GATE_BLOCK		0xc970
-#define APLL_LOCK		0x14000
-#define APLL_CON0		0x14100
-#define SRC_CPU			0x14200
-#define DIV_CPU0		0x14500
-#define DIV_CPU1		0x14504
-
-static const unsigned long exynos4415_cmu_clk_regs[] __initconst = {
-	SRC_LEFTBUS,
-	DIV_LEFTBUS,
-	GATE_IP_LEFTBUS,
-	GATE_IP_IMAGE,
-	SRC_RIGHTBUS,
-	DIV_RIGHTBUS,
-	GATE_IP_RIGHTBUS,
-	GATE_IP_PERIR,
-	EPLL_LOCK,
-	G3D_PLL_LOCK,
-	DISP_PLL_LOCK,
-	ISP_PLL_LOCK,
-	EPLL_CON0,
-	EPLL_CON1,
-	EPLL_CON2,
-	G3D_PLL_CON0,
-	G3D_PLL_CON1,
-	G3D_PLL_CON2,
-	ISP_PLL_CON0,
-	ISP_PLL_CON1,
-	ISP_PLL_CON2,
-	DISP_PLL_CON0,
-	DISP_PLL_CON1,
-	DISP_PLL_CON2,
-	SRC_TOP0,
-	SRC_TOP1,
-	SRC_CAM,
-	SRC_TV,
-	SRC_MFC,
-	SRC_G3D,
-	SRC_LCD,
-	SRC_ISP,
-	SRC_MAUDIO,
-	SRC_FSYS,
-	SRC_PERIL0,
-	SRC_PERIL1,
-	SRC_CAM1,
-	SRC_TOP_ISP0,
-	SRC_TOP_ISP1,
-	SRC_MASK_TOP,
-	SRC_MASK_CAM,
-	SRC_MASK_TV,
-	SRC_MASK_LCD,
-	SRC_MASK_ISP,
-	SRC_MASK_MAUDIO,
-	SRC_MASK_FSYS,
-	SRC_MASK_PERIL0,
-	SRC_MASK_PERIL1,
-	DIV_TOP,
-	DIV_CAM,
-	DIV_TV,
-	DIV_MFC,
-	DIV_G3D,
-	DIV_LCD,
-	DIV_ISP,
-	DIV_MAUDIO,
-	DIV_FSYS0,
-	DIV_FSYS1,
-	DIV_FSYS2,
-	DIV_PERIL0,
-	DIV_PERIL1,
-	DIV_PERIL2,
-	DIV_PERIL3,
-	DIV_PERIL4,
-	DIV_PERIL5,
-	DIV_CAM1,
-	DIV_TOP_ISP1,
-	DIV_TOP_ISP0,
-	CLKDIV2_RATIO,
-	GATE_SCLK_CAM,
-	GATE_SCLK_TV,
-	GATE_SCLK_MFC,
-	GATE_SCLK_G3D,
-	GATE_SCLK_LCD,
-	GATE_SCLK_MAUDIO,
-	GATE_SCLK_FSYS,
-	GATE_SCLK_PERIL,
-	GATE_IP_CAM,
-	GATE_IP_TV,
-	GATE_IP_MFC,
-	GATE_IP_G3D,
-	GATE_IP_LCD,
-	GATE_IP_FSYS,
-	GATE_IP_PERIL,
-	GATE_BLOCK,
-	APLL_LOCK,
-	APLL_CON0,
-	SRC_CPU,
-	DIV_CPU0,
-	DIV_CPU1,
-};
-
-/* list of all parent clock list */
-PNAME(mout_g3d_pllsrc_p)	= { "fin_pll", };
-
-PNAME(mout_apll_p)		= { "fin_pll", "fout_apll", };
-PNAME(mout_g3d_pll_p)		= { "fin_pll", "fout_g3d_pll", };
-PNAME(mout_isp_pll_p)		= { "fin_pll", "fout_isp_pll", };
-PNAME(mout_disp_pll_p)		= { "fin_pll", "fout_disp_pll", };
-
-PNAME(mout_mpll_user_p)		= { "fin_pll", "div_mpll_pre", };
-PNAME(mout_epll_p)		= { "fin_pll", "fout_epll", };
-PNAME(mout_core_p)		= { "mout_apll", "mout_mpll_user_c", };
-PNAME(mout_hpm_p)		= { "mout_apll", "mout_mpll_user_c", };
-
-PNAME(mout_ebi_p)		= { "div_aclk_200", "div_aclk_160", };
-PNAME(mout_ebi_1_p)		= { "mout_ebi", "mout_g3d_pll", };
-
-PNAME(mout_gdl_p)		= { "mout_mpll_user_l", };
-PNAME(mout_gdr_p)		= { "mout_mpll_user_r", };
-
-PNAME(mout_aclk_266_p)		= { "mout_mpll_user_t", "mout_g3d_pll", };
-
-PNAME(group_epll_g3dpll_p)	= { "mout_epll", "mout_g3d_pll" };
-PNAME(group_sclk_p)		= { "xxti", "xusbxti",
-				    "none", "mout_isp_pll",
-				    "none", "none", "div_mpll_pre",
-				    "mout_epll", "mout_g3d_pll", };
-PNAME(group_spdif_p)		= { "mout_audio0", "mout_audio1",
-				    "mout_audio2", "spdif_extclk", };
-PNAME(group_sclk_audio2_p)	= { "audiocdclk2", "none",
-				    "none", "mout_isp_pll",
-				    "mout_disp_pll", "xusbxti",
-				    "div_mpll_pre", "mout_epll",
-				    "mout_g3d_pll", };
-PNAME(group_sclk_audio1_p)	= { "audiocdclk1", "none",
-				    "none", "mout_isp_pll",
-				    "mout_disp_pll", "xusbxti",
-				    "div_mpll_pre", "mout_epll",
-				    "mout_g3d_pll", };
-PNAME(group_sclk_audio0_p)	= { "audiocdclk0", "none",
-				    "none", "mout_isp_pll",
-				    "mout_disp_pll", "xusbxti",
-				    "div_mpll_pre", "mout_epll",
-				    "mout_g3d_pll", };
-PNAME(group_fimc_lclk_p)	= { "xxti", "xusbxti",
-				    "none", "mout_isp_pll",
-				    "none", "mout_disp_pll",
-				    "mout_mpll_user_t", "mout_epll",
-				    "mout_g3d_pll", };
-PNAME(group_sclk_fimd0_p)	= { "xxti", "xusbxti",
-				    "m_bitclkhsdiv4_4l", "mout_isp_pll",
-				    "mout_disp_pll", "sclk_hdmiphy",
-				    "div_mpll_pre", "mout_epll",
-				    "mout_g3d_pll", };
-PNAME(mout_hdmi_p)		= { "sclk_pixel", "sclk_hdmiphy" };
-PNAME(mout_mfc_p)		= { "mout_mfc_0", "mout_mfc_1" };
-PNAME(mout_g3d_p)		= { "mout_g3d_0", "mout_g3d_1" };
-PNAME(mout_jpeg_p)		= { "mout_jpeg_0", "mout_jpeg_1" };
-PNAME(mout_jpeg1_p)		= { "mout_epll", "mout_g3d_pll" };
-PNAME(group_aclk_isp0_300_p)	= { "mout_isp_pll", "div_mpll_pre" };
-PNAME(group_aclk_isp0_400_user_p) = { "fin_pll", "div_aclk_400_mcuisp" };
-PNAME(group_aclk_isp0_300_user_p) = { "fin_pll", "mout_aclk_isp0_300" };
-PNAME(group_aclk_isp1_300_user_p) = { "fin_pll", "mout_aclk_isp1_300" };
-PNAME(group_mout_mpll_user_t_p)	= { "mout_mpll_user_t" };
-
-static const struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initconst = {
-	/* HACK: fin_pll hardcoded to xusbxti until detection is implemented. */
-	FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0),
-};
-
-static const struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initconst = {
-	FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 27000000),
-};
-
-static const struct samsung_mux_clock exynos4415_mux_clks[] __initconst = {
-	/*
-	 * NOTE: Following table is sorted by register address in ascending
-	 * order and then bitfield shift in descending order, as it is done
-	 * in the User's Manual. When adding new entries, please make sure
-	 * that the order is preserved, to avoid merge conflicts and make
-	 * further work with defined data easier.
-	 */
-
-	/* SRC_LEFTBUS */
-	MUX(CLK_MOUT_MPLL_USER_L, "mout_mpll_user_l", mout_mpll_user_p,
-		SRC_LEFTBUS, 4, 1),
-	MUX(CLK_MOUT_GDL, "mout_gdl", mout_gdl_p, SRC_LEFTBUS, 0, 1),
-
-	/* SRC_RIGHTBUS */
-	MUX(CLK_MOUT_MPLL_USER_R, "mout_mpll_user_r", mout_mpll_user_p,
-		SRC_RIGHTBUS, 4, 1),
-	MUX(CLK_MOUT_GDR, "mout_gdr", mout_gdr_p, SRC_RIGHTBUS, 0, 1),
-
-	/* SRC_TOP0 */
-	MUX(CLK_MOUT_EBI, "mout_ebi", mout_ebi_p, SRC_TOP0, 28, 1),
-	MUX(CLK_MOUT_ACLK_200, "mout_aclk_200", group_mout_mpll_user_t_p,
-		SRC_TOP0, 24, 1),
-	MUX(CLK_MOUT_ACLK_160, "mout_aclk_160", group_mout_mpll_user_t_p,
-		SRC_TOP0, 20, 1),
-	MUX(CLK_MOUT_ACLK_100, "mout_aclk_100", group_mout_mpll_user_t_p,
-		SRC_TOP0, 16, 1),
-	MUX(CLK_MOUT_ACLK_266, "mout_aclk_266", mout_aclk_266_p,
-		SRC_TOP0, 12, 1),
-	MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p,
-		SRC_TOP0, 8, 1),
-	MUX(CLK_MOUT_EPLL, "mout_epll", mout_epll_p, SRC_TOP0, 4, 1),
-	MUX(CLK_MOUT_EBI_1, "mout_ebi_1", mout_ebi_1_p, SRC_TOP0, 0, 1),
-
-	/* SRC_TOP1 */
-	MUX(CLK_MOUT_ISP_PLL, "mout_isp_pll", mout_isp_pll_p,
-		SRC_TOP1, 28, 1),
-	MUX(CLK_MOUT_DISP_PLL, "mout_disp_pll", mout_disp_pll_p,
-		SRC_TOP1, 16, 1),
-	MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p,
-		SRC_TOP1, 12, 1),
-	MUX(CLK_MOUT_ACLK_400_MCUISP, "mout_aclk_400_mcuisp",
-		group_mout_mpll_user_t_p, SRC_TOP1, 8, 1),
-	MUX(CLK_MOUT_G3D_PLLSRC, "mout_g3d_pllsrc", mout_g3d_pllsrc_p,
-		SRC_TOP1, 0, 1),
-
-	/* SRC_CAM */
-	MUX(CLK_MOUT_CSIS1, "mout_csis1", group_fimc_lclk_p, SRC_CAM, 28, 4),
-	MUX(CLK_MOUT_CSIS0, "mout_csis0", group_fimc_lclk_p, SRC_CAM, 24, 4),
-	MUX(CLK_MOUT_CAM1, "mout_cam1", group_fimc_lclk_p, SRC_CAM, 20, 4),
-	MUX(CLK_MOUT_FIMC3_LCLK, "mout_fimc3_lclk", group_fimc_lclk_p, SRC_CAM,
-		12, 4),
-	MUX(CLK_MOUT_FIMC2_LCLK, "mout_fimc2_lclk", group_fimc_lclk_p, SRC_CAM,
-		8, 4),
-	MUX(CLK_MOUT_FIMC1_LCLK, "mout_fimc1_lclk", group_fimc_lclk_p, SRC_CAM,
-		4, 4),
-	MUX(CLK_MOUT_FIMC0_LCLK, "mout_fimc0_lclk", group_fimc_lclk_p, SRC_CAM,
-		0, 4),
-
-	/* SRC_TV */
-	MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
-
-	/* SRC_MFC */
-	MUX(CLK_MOUT_MFC, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1),
-	MUX(CLK_MOUT_MFC_1, "mout_mfc_1", group_epll_g3dpll_p, SRC_MFC, 4, 1),
-	MUX(CLK_MOUT_MFC_0, "mout_mfc_0", group_mout_mpll_user_t_p, SRC_MFC, 0,
-		1),
-
-	/* SRC_G3D */
-	MUX(CLK_MOUT_G3D, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1),
-	MUX(CLK_MOUT_G3D_1, "mout_g3d_1", group_epll_g3dpll_p, SRC_G3D, 4, 1),
-	MUX(CLK_MOUT_G3D_0, "mout_g3d_0", group_mout_mpll_user_t_p, SRC_G3D, 0,
-		1),
-
-	/* SRC_LCD */
-	MUX(CLK_MOUT_MIPI0, "mout_mipi0", group_fimc_lclk_p, SRC_LCD, 12, 4),
-	MUX(CLK_MOUT_FIMD0, "mout_fimd0", group_sclk_fimd0_p, SRC_LCD, 0, 4),
-
-	/* SRC_ISP */
-	MUX(CLK_MOUT_TSADC_ISP, "mout_tsadc_isp", group_fimc_lclk_p, SRC_ISP,
-		16, 4),
-	MUX(CLK_MOUT_UART_ISP, "mout_uart_isp", group_fimc_lclk_p, SRC_ISP,
-		12, 4),
-	MUX(CLK_MOUT_SPI1_ISP, "mout_spi1_isp", group_fimc_lclk_p, SRC_ISP,
-		8, 4),
-	MUX(CLK_MOUT_SPI0_ISP, "mout_spi0_isp", group_fimc_lclk_p, SRC_ISP,
-		4, 4),
-	MUX(CLK_MOUT_PWM_ISP, "mout_pwm_isp", group_fimc_lclk_p, SRC_ISP,
-		0, 4),
-
-	/* SRC_MAUDIO */
-	MUX(CLK_MOUT_AUDIO0, "mout_audio0", group_sclk_audio0_p, SRC_MAUDIO,
-		0, 4),
-
-	/* SRC_FSYS */
-	MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4),
-	MUX(CLK_MOUT_MMC2, "mout_mmc2", group_sclk_p, SRC_FSYS, 8, 4),
-	MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4),
-	MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4),
-
-	/* SRC_PERIL0 */
-	MUX(CLK_MOUT_UART3, "mout_uart3", group_sclk_p, SRC_PERIL0, 12, 4),
-	MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4),
-	MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4),
-	MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4),
-
-	/* SRC_PERIL1 */
-	MUX(CLK_MOUT_SPI2, "mout_spi2", group_sclk_p, SRC_PERIL1, 24, 4),
-	MUX(CLK_MOUT_SPI1, "mout_spi1", group_sclk_p, SRC_PERIL1, 20, 4),
-	MUX(CLK_MOUT_SPI0, "mout_spi0", group_sclk_p, SRC_PERIL1, 16, 4),
-	MUX(CLK_MOUT_SPDIF, "mout_spdif", group_spdif_p, SRC_PERIL1, 8, 4),
-	MUX(CLK_MOUT_AUDIO2, "mout_audio2", group_sclk_audio2_p, SRC_PERIL1,
-		4, 4),
-	MUX(CLK_MOUT_AUDIO1, "mout_audio1", group_sclk_audio1_p, SRC_PERIL1,
-		0, 4),
-
-	/* SRC_CPU */
-	MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p,
-		SRC_CPU, 24, 1),
-	MUX(CLK_MOUT_HPM, "mout_hpm", mout_hpm_p, SRC_CPU, 20, 1),
-	MUX_F(CLK_MOUT_CORE, "mout_core", mout_core_p, SRC_CPU, 16, 1, 0,
-		CLK_MUX_READ_ONLY),
-	MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
-		CLK_SET_RATE_PARENT, 0),
-
-	/* SRC_CAM1 */
-	MUX(CLK_MOUT_PXLASYNC_CSIS1_FIMC, "mout_pxlasync_csis1",
-		group_fimc_lclk_p, SRC_CAM1, 20, 1),
-	MUX(CLK_MOUT_PXLASYNC_CSIS0_FIMC, "mout_pxlasync_csis0",
-		group_fimc_lclk_p, SRC_CAM1, 16, 1),
-	MUX(CLK_MOUT_JPEG, "mout_jpeg", mout_jpeg_p, SRC_CAM1, 8, 1),
-	MUX(CLK_MOUT_JPEG1, "mout_jpeg_1", mout_jpeg1_p, SRC_CAM1, 4, 1),
-	MUX(CLK_MOUT_JPEG0, "mout_jpeg_0", group_mout_mpll_user_t_p, SRC_CAM1,
-		0, 1),
-
-	/* SRC_TOP_ISP0 */
-	MUX(CLK_MOUT_ACLK_ISP0_300, "mout_aclk_isp0_300",
-		group_aclk_isp0_300_p, SRC_TOP_ISP0, 8, 1),
-	MUX(CLK_MOUT_ACLK_ISP0_400, "mout_aclk_isp0_400_user",
-		group_aclk_isp0_400_user_p, SRC_TOP_ISP0, 4, 1),
-	MUX(CLK_MOUT_ACLK_ISP0_300_USER, "mout_aclk_isp0_300_user",
-		group_aclk_isp0_300_user_p, SRC_TOP_ISP0, 0, 1),
-
-	/* SRC_TOP_ISP1 */
-	MUX(CLK_MOUT_ACLK_ISP1_300, "mout_aclk_isp1_300",
-		group_aclk_isp0_300_p, SRC_TOP_ISP1, 4, 1),
-	MUX(CLK_MOUT_ACLK_ISP1_300_USER, "mout_aclk_isp1_300_user",
-		group_aclk_isp1_300_user_p, SRC_TOP_ISP1, 0, 1),
-};
-
-static const struct samsung_div_clock exynos4415_div_clks[] __initconst = {
-	/*
-	 * NOTE: Following table is sorted by register address in ascending
-	 * order and then bitfield shift in descending order, as it is done
-	 * in the User's Manual. When adding new entries, please make sure
-	 * that the order is preserved, to avoid merge conflicts and make
-	 * further work with defined data easier.
-	 */
-
-	/* DIV_LEFTBUS */
-	DIV(CLK_DIV_GPL, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
-	DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 4),
-
-	/* DIV_RIGHTBUS */
-	DIV(CLK_DIV_GPR, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
-	DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 4),
-
-	/* DIV_TOP */
-	DIV(CLK_DIV_ACLK_400_MCUISP, "div_aclk_400_mcuisp",
-		"mout_aclk_400_mcuisp", DIV_TOP, 24, 3),
-	DIV(CLK_DIV_EBI, "div_ebi", "mout_ebi_1", DIV_TOP, 16, 3),
-	DIV(CLK_DIV_ACLK_200, "div_aclk_200", "mout_aclk_200", DIV_TOP, 12, 3),
-	DIV(CLK_DIV_ACLK_160, "div_aclk_160", "mout_aclk_160", DIV_TOP, 8, 3),
-	DIV(CLK_DIV_ACLK_100, "div_aclk_100", "mout_aclk_100", DIV_TOP, 4, 4),
-	DIV(CLK_DIV_ACLK_266, "div_aclk_266", "mout_aclk_266", DIV_TOP, 0, 3),
-
-	/* DIV_CAM */
-	DIV(CLK_DIV_CSIS1, "div_csis1", "mout_csis1", DIV_CAM, 28, 4),
-	DIV(CLK_DIV_CSIS0, "div_csis0", "mout_csis0", DIV_CAM, 24, 4),
-	DIV(CLK_DIV_CAM1, "div_cam1", "mout_cam1", DIV_CAM, 20, 4),
-	DIV(CLK_DIV_FIMC3_LCLK, "div_fimc3_lclk", "mout_fimc3_lclk", DIV_CAM,
-		12, 4),
-	DIV(CLK_DIV_FIMC2_LCLK, "div_fimc2_lclk", "mout_fimc2_lclk", DIV_CAM,
-		8, 4),
-	DIV(CLK_DIV_FIMC1_LCLK, "div_fimc1_lclk", "mout_fimc1_lclk", DIV_CAM,
-		4, 4),
-	DIV(CLK_DIV_FIMC0_LCLK, "div_fimc0_lclk", "mout_fimc0_lclk", DIV_CAM,
-		0, 4),
-
-	/* DIV_TV */
-	DIV(CLK_DIV_TV_BLK, "div_tv_blk", "mout_g3d_pll", DIV_TV, 0, 4),
-
-	/* DIV_MFC */
-	DIV(CLK_DIV_MFC, "div_mfc", "mout_mfc", DIV_MFC, 0, 4),
-
-	/* DIV_G3D */
-	DIV(CLK_DIV_G3D, "div_g3d", "mout_g3d", DIV_G3D, 0, 4),
-
-	/* DIV_LCD */
-	DIV_F(CLK_DIV_MIPI0_PRE, "div_mipi0_pre", "div_mipi0", DIV_LCD, 20, 4,
-		CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_MIPI0, "div_mipi0", "mout_mipi0", DIV_LCD, 16, 4),
-	DIV(CLK_DIV_FIMD0, "div_fimd0", "mout_fimd0", DIV_LCD, 0, 4),
-
-	/* DIV_ISP */
-	DIV(CLK_DIV_UART_ISP, "div_uart_isp", "mout_uart_isp", DIV_ISP, 28, 4),
-	DIV_F(CLK_DIV_SPI1_ISP_PRE, "div_spi1_isp_pre", "div_spi1_isp",
-		DIV_ISP, 20, 8, CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_SPI1_ISP, "div_spi1_isp", "mout_spi1_isp", DIV_ISP, 16, 4),
-	DIV_F(CLK_DIV_SPI0_ISP_PRE, "div_spi0_isp_pre", "div_spi0_isp",
-		DIV_ISP, 8, 8, CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 4, 4),
-	DIV(CLK_DIV_PWM_ISP, "div_pwm_isp", "mout_pwm_isp", DIV_ISP, 0, 4),
-
-	/* DIV_MAUDIO */
-	DIV(CLK_DIV_PCM0, "div_pcm0", "div_audio0", DIV_MAUDIO, 4, 8),
-	DIV(CLK_DIV_AUDIO0, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4),
-
-	/* DIV_FSYS0 */
-	DIV_F(CLK_DIV_TSADC_PRE, "div_tsadc_pre", "div_tsadc", DIV_FSYS0, 8, 8,
-		CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_TSADC, "div_tsadc", "mout_tsadc", DIV_FSYS0, 0, 4),
-
-	/* DIV_FSYS1 */
-	DIV_F(CLK_DIV_MMC1_PRE, "div_mmc1_pre", "div_mmc1", DIV_FSYS1, 24, 8,
-		CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_MMC1, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
-	DIV_F(CLK_DIV_MMC0_PRE, "div_mmc0_pre", "div_mmc0", DIV_FSYS1, 8, 8,
-		CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
-
-	/* DIV_FSYS2 */
-	DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2_pre", "div_mmc2", DIV_FSYS2, 8, 8,
-		CLK_SET_RATE_PARENT, 0),
-	DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4,
-		CLK_SET_RATE_PARENT, 0),
-
-	/* DIV_PERIL0 */
-	DIV(CLK_DIV_UART3, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4),
-	DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
-	DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
-	DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
-
-	/* DIV_PERIL1 */
-	DIV_F(CLK_DIV_SPI1_PRE, "div_spi1_pre", "div_spi1", DIV_PERIL1, 24, 8,
-		CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_SPI1, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4),
-	DIV_F(CLK_DIV_SPI0_PRE, "div_spi0_pre", "div_spi0", DIV_PERIL1, 8, 8,
-		CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_SPI0, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4),
-
-	/* DIV_PERIL2 */
-	DIV_F(CLK_DIV_SPI2_PRE, "div_spi2_pre", "div_spi2", DIV_PERIL2, 8, 8,
-		CLK_SET_RATE_PARENT, 0),
-	DIV(CLK_DIV_SPI2, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4),
-
-	/* DIV_PERIL4 */
-	DIV(CLK_DIV_PCM2, "div_pcm2", "div_audio2", DIV_PERIL4, 20, 8),
-	DIV(CLK_DIV_AUDIO2, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
-	DIV(CLK_DIV_PCM1, "div_pcm1", "div_audio1", DIV_PERIL4, 20, 8),
-	DIV(CLK_DIV_AUDIO1, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
-
-	/* DIV_PERIL5 */
-	DIV(CLK_DIV_I2S1, "div_i2s1", "div_audio1", DIV_PERIL5, 0, 6),
-
-	/* DIV_CAM1 */
-	DIV(CLK_DIV_PXLASYNC_CSIS1_FIMC, "div_pxlasync_csis1_fimc",
-		"mout_pxlasync_csis1", DIV_CAM1, 24, 4),
-	DIV(CLK_DIV_PXLASYNC_CSIS0_FIMC, "div_pxlasync_csis0_fimc",
-		"mout_pxlasync_csis0", DIV_CAM1, 20, 4),
-	DIV(CLK_DIV_JPEG, "div_jpeg", "mout_jpeg", DIV_CAM1, 0, 4),
-
-	/* DIV_CPU0 */
-	DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3),
-	DIV_F(CLK_DIV_APLL, "div_apll", "mout_apll", DIV_CPU0, 24, 3,
-			CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
-	DIV(CLK_DIV_PCLK_DBG, "div_pclk_dbg", "div_core2", DIV_CPU0, 20, 3),
-	DIV(CLK_DIV_ATB, "div_atb", "div_core2", DIV_CPU0, 16, 3),
-	DIV(CLK_DIV_PERIPH, "div_periph", "div_core2", DIV_CPU0, 12, 3),
-	DIV(CLK_DIV_COREM1, "div_corem1", "div_core2", DIV_CPU0, 8, 3),
-	DIV(CLK_DIV_COREM0, "div_corem0", "div_core2", DIV_CPU0, 4, 3),
-	DIV_F(CLK_DIV_CORE, "div_core", "mout_core", DIV_CPU0, 0, 3,
-		CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
-
-	/* DIV_CPU1 */
-	DIV(CLK_DIV_HPM, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
-	DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
-};
-
-static const struct samsung_gate_clock exynos4415_gate_clks[] __initconst = {
-	/*
-	 * NOTE: Following table is sorted by register address in ascending
-	 * order and then bitfield shift in descending order, as it is done
-	 * in the User's Manual. When adding new entries, please make sure
-	 * that the order is preserved, to avoid merge conflicts and make
-	 * further work with defined data easier.
-	 */
-
-	/* GATE_IP_LEFTBUS */
-	GATE(CLK_ASYNC_G3D, "async_g3d", "div_aclk_100", GATE_IP_LEFTBUS, 6,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_ASYNC_MFCL, "async_mfcl", "div_aclk_100", GATE_IP_LEFTBUS, 4,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_ASYNC_TVX, "async_tvx", "div_aclk_100", GATE_IP_LEFTBUS, 3,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PPMULEFT, "ppmuleft", "div_aclk_100", GATE_IP_LEFTBUS, 1,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_GPIO_LEFT, "gpio_left", "div_aclk_100", GATE_IP_LEFTBUS, 0,
-		CLK_IGNORE_UNUSED, 0),
-
-	/* GATE_IP_IMAGE */
-	GATE(CLK_PPMUIMAGE, "ppmuimage", "div_aclk_100", GATE_IP_IMAGE,
-		9, 0, 0),
-	GATE(CLK_QEMDMA2, "qe_mdma2", "div_aclk_100", GATE_IP_IMAGE,
-		8, 0, 0),
-	GATE(CLK_QEROTATOR, "qe_rotator", "div_aclk_100", GATE_IP_IMAGE,
-		7, 0, 0),
-	GATE(CLK_SMMUMDMA2, "smmu_mdam2", "div_aclk_100", GATE_IP_IMAGE,
-		5, 0, 0),
-	GATE(CLK_SMMUROTATOR, "smmu_rotator", "div_aclk_100", GATE_IP_IMAGE,
-		4, 0, 0),
-	GATE(CLK_MDMA2, "mdma2", "div_aclk_100", GATE_IP_IMAGE, 2, 0, 0),
-	GATE(CLK_ROTATOR, "rotator", "div_aclk_100", GATE_IP_IMAGE, 1, 0, 0),
-
-	/* GATE_IP_RIGHTBUS */
-	GATE(CLK_ASYNC_ISPMX, "async_ispmx", "div_aclk_100",
-		GATE_IP_RIGHTBUS, 9, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_ASYNC_MAUDIOX, "async_maudiox", "div_aclk_100",
-		GATE_IP_RIGHTBUS, 7, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_ASYNC_MFCR, "async_mfcr", "div_aclk_100",
-		GATE_IP_RIGHTBUS, 6, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_ASYNC_FSYSD, "async_fsysd", "div_aclk_100",
-		GATE_IP_RIGHTBUS, 5, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_ASYNC_LCD0X, "async_lcd0x", "div_aclk_100",
-		GATE_IP_RIGHTBUS, 3, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_ASYNC_CAMX, "async_camx", "div_aclk_100",
-		GATE_IP_RIGHTBUS, 2, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PPMURIGHT, "ppmuright", "div_aclk_100",
-		GATE_IP_RIGHTBUS, 1, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_GPIO_RIGHT, "gpio_right", "div_aclk_100",
-		GATE_IP_RIGHTBUS, 0, CLK_IGNORE_UNUSED, 0),
-
-	/* GATE_IP_PERIR */
-	GATE(CLK_ANTIRBK_APBIF, "antirbk_apbif", "div_aclk_100",
-		GATE_IP_PERIR, 24, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_EFUSE_WRITER_APBIF, "efuse_writer_apbif", "div_aclk_100",
-		GATE_IP_PERIR, 23, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_MONOCNT, "monocnt", "div_aclk_100", GATE_IP_PERIR, 22,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_TZPC6, "tzpc6", "div_aclk_100", GATE_IP_PERIR, 21,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PROVISIONKEY1, "provisionkey1", "div_aclk_100",
-		GATE_IP_PERIR, 20, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PROVISIONKEY0, "provisionkey0", "div_aclk_100",
-		GATE_IP_PERIR, 19, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_CMU_ISPPART, "cmu_isppart", "div_aclk_100", GATE_IP_PERIR, 18,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_TMU_APBIF, "tmu_apbif", "div_aclk_100",
-		GATE_IP_PERIR, 17, 0, 0),
-	GATE(CLK_KEYIF, "keyif", "div_aclk_100", GATE_IP_PERIR, 16, 0, 0),
-	GATE(CLK_RTC, "rtc", "div_aclk_100", GATE_IP_PERIR, 15, 0, 0),
-	GATE(CLK_WDT, "wdt", "div_aclk_100", GATE_IP_PERIR, 14, 0, 0),
-	GATE(CLK_MCT, "mct", "div_aclk_100", GATE_IP_PERIR, 13, 0, 0),
-	GATE(CLK_SECKEY, "seckey", "div_aclk_100", GATE_IP_PERIR, 12,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_HDMI_CEC, "hdmi_cec", "div_aclk_100", GATE_IP_PERIR, 11,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_TZPC5, "tzpc5", "div_aclk_100", GATE_IP_PERIR, 10,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_TZPC4, "tzpc4", "div_aclk_100", GATE_IP_PERIR, 9,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_TZPC3, "tzpc3", "div_aclk_100", GATE_IP_PERIR, 8,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_TZPC2, "tzpc2", "div_aclk_100", GATE_IP_PERIR, 7,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_TZPC1, "tzpc1", "div_aclk_100", GATE_IP_PERIR, 6,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_TZPC0, "tzpc0", "div_aclk_100", GATE_IP_PERIR, 5,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_CMU_COREPART, "cmu_corepart", "div_aclk_100", GATE_IP_PERIR, 4,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_CMU_TOPPART, "cmu_toppart", "div_aclk_100", GATE_IP_PERIR, 3,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PMU_APBIF, "pmu_apbif", "div_aclk_100", GATE_IP_PERIR, 2,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_SYSREG, "sysreg", "div_aclk_100", GATE_IP_PERIR, 1,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_CHIP_ID, "chip_id", "div_aclk_100", GATE_IP_PERIR, 0,
-		CLK_IGNORE_UNUSED, 0),
-
-	/* GATE_SCLK_CAM - non-completed */
-	GATE(CLK_SCLK_PXLAYSNC_CSIS1_FIMC, "sclk_pxlasync_csis1_fimc",
-		"div_pxlasync_csis1_fimc", GATE_SCLK_CAM, 11,
-		CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_PXLAYSNC_CSIS0_FIMC, "sclk_pxlasync_csis0_fimc",
-		"div_pxlasync_csis0_fimc", GATE_SCLK_CAM,
-		10, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_jpeg",
-		GATE_SCLK_CAM, 8, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_CSIS1, "sclk_csis1", "div_csis1",
-		GATE_SCLK_CAM, 7, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_CSIS0, "sclk_csis0", "div_csis0",
-		GATE_SCLK_CAM, 6, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1",
-		GATE_SCLK_CAM, 5, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_FIMC3_LCLK, "sclk_fimc3_lclk", "div_fimc3_lclk",
-		GATE_SCLK_CAM, 3, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_FIMC2_LCLK, "sclk_fimc2_lclk", "div_fimc2_lclk",
-		GATE_SCLK_CAM, 2, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_FIMC1_LCLK, "sclk_fimc1_lclk", "div_fimc1_lclk",
-		GATE_SCLK_CAM, 1, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_FIMC0_LCLK, "sclk_fimc0_lclk", "div_fimc0_lclk",
-		GATE_SCLK_CAM, 0, CLK_SET_RATE_PARENT, 0),
-
-	/* GATE_SCLK_TV */
-	GATE(CLK_SCLK_PIXEL, "sclk_pixel", "div_tv_blk",
-		GATE_SCLK_TV, 3, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi",
-		GATE_SCLK_TV, 2, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_MIXER, "sclk_mixer", "div_tv_blk",
-		GATE_SCLK_TV, 0, CLK_SET_RATE_PARENT, 0),
-
-	/* GATE_SCLK_MFC */
-	GATE(CLK_SCLK_MFC, "sclk_mfc", "div_mfc",
-		GATE_SCLK_MFC, 0, CLK_SET_RATE_PARENT, 0),
-
-	/* GATE_SCLK_G3D */
-	GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d",
-		GATE_SCLK_G3D, 0, CLK_SET_RATE_PARENT, 0),
-
-	/* GATE_SCLK_LCD */
-	GATE(CLK_SCLK_MIPIDPHY4L, "sclk_mipidphy4l", "div_mipi0",
-		GATE_SCLK_LCD, 4, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_MIPI0, "sclk_mipi0", "div_mipi0_pre",
-		GATE_SCLK_LCD, 3, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_MDNIE0, "sclk_mdnie0", "div_fimd0",
-		GATE_SCLK_LCD, 1, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_FIMD0, "sclk_fimd0", "div_fimd0",
-		GATE_SCLK_LCD, 0, CLK_SET_RATE_PARENT, 0),
-
-	/* GATE_SCLK_MAUDIO */
-	GATE(CLK_SCLK_PCM0, "sclk_pcm0", "div_pcm0",
-		GATE_SCLK_MAUDIO, 1, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0",
-		GATE_SCLK_MAUDIO, 0, CLK_SET_RATE_PARENT, 0),
-
-	/* GATE_SCLK_FSYS */
-	GATE(CLK_SCLK_TSADC, "sclk_tsadc", "div_tsadc_pre",
-		GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi",
-		GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc2_pre",
-		GATE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre",
-		GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre",
-		GATE_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
-
-	/* GATE_SCLK_PERIL */
-	GATE(CLK_SCLK_I2S, "sclk_i2s1", "div_i2s1",
-		GATE_SCLK_PERIL, 18, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_PCM2, "sclk_pcm2", "div_pcm2",
-		GATE_SCLK_PERIL, 16, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_PCM1, "sclk_pcm1", "div_pcm1",
-		GATE_SCLK_PERIL, 15, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2",
-		GATE_SCLK_PERIL, 14, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1",
-		GATE_SCLK_PERIL, 13, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif",
-		GATE_SCLK_PERIL, 10, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi2_pre",
-		GATE_SCLK_PERIL, 8, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi1_pre",
-		GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre",
-		GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3",
-		GATE_SCLK_PERIL, 3, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
-		GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1",
-		GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0),
-	GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
-		GATE_SCLK_PERIL, 0, CLK_SET_RATE_PARENT, 0),
-
-	/* GATE_IP_CAM */
-	GATE(CLK_SMMUFIMC_LITE2, "smmufimc_lite2", "div_aclk_160", GATE_IP_CAM,
-		22, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_FIMC_LITE2, "fimc_lite2", "div_aclk_160", GATE_IP_CAM,
-		20, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PIXELASYNCM1, "pixelasyncm1", "div_aclk_160", GATE_IP_CAM,
-		18, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PIXELASYNCM0, "pixelasyncm0", "div_aclk_160", GATE_IP_CAM,
-		17, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PPMUCAMIF, "ppmucamif", "div_aclk_160", GATE_IP_CAM,
-		16, CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_SMMUJPEG, "smmujpeg", "div_aclk_160", GATE_IP_CAM, 11, 0, 0),
-	GATE(CLK_SMMUFIMC3, "smmufimc3", "div_aclk_160", GATE_IP_CAM, 10, 0, 0),
-	GATE(CLK_SMMUFIMC2, "smmufimc2", "div_aclk_160", GATE_IP_CAM, 9, 0, 0),
-	GATE(CLK_SMMUFIMC1, "smmufimc1", "div_aclk_160", GATE_IP_CAM, 8, 0, 0),
-	GATE(CLK_SMMUFIMC0, "smmufimc0", "div_aclk_160", GATE_IP_CAM, 7, 0, 0),
-	GATE(CLK_JPEG, "jpeg", "div_aclk_160", GATE_IP_CAM, 6, 0, 0),
-	GATE(CLK_CSIS1, "csis1", "div_aclk_160", GATE_IP_CAM, 5, 0, 0),
-	GATE(CLK_CSIS0, "csis0", "div_aclk_160", GATE_IP_CAM, 4, 0, 0),
-	GATE(CLK_FIMC3, "fimc3", "div_aclk_160", GATE_IP_CAM, 3, 0, 0),
-	GATE(CLK_FIMC2, "fimc2", "div_aclk_160", GATE_IP_CAM, 2, 0, 0),
-	GATE(CLK_FIMC1, "fimc1", "div_aclk_160", GATE_IP_CAM, 1, 0, 0),
-	GATE(CLK_FIMC0, "fimc0", "div_aclk_160", GATE_IP_CAM, 0, 0, 0),
-
-	/* GATE_IP_TV */
-	GATE(CLK_PPMUTV, "ppmutv", "div_aclk_100", GATE_IP_TV, 5, 0, 0),
-	GATE(CLK_SMMUTV, "smmutv", "div_aclk_100", GATE_IP_TV, 4, 0, 0),
-	GATE(CLK_HDMI, "hdmi", "div_aclk_100", GATE_IP_TV, 3, 0, 0),
-	GATE(CLK_MIXER, "mixer", "div_aclk_100", GATE_IP_TV, 1, 0, 0),
-	GATE(CLK_VP, "vp", "div_aclk_100", GATE_IP_TV, 0, 0, 0),
-
-	/* GATE_IP_MFC */
-	GATE(CLK_PPMUMFC_R, "ppmumfc_r", "div_aclk_200", GATE_IP_MFC, 4,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_PPMUMFC_L, "ppmumfc_l", "div_aclk_200", GATE_IP_MFC, 3,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_SMMUMFC_R, "smmumfc_r", "div_aclk_200", GATE_IP_MFC, 2, 0, 0),
-	GATE(CLK_SMMUMFC_L, "smmumfc_l", "div_aclk_200", GATE_IP_MFC, 1, 0, 0),
-	GATE(CLK_MFC, "mfc", "div_aclk_200", GATE_IP_MFC, 0, 0, 0),
-
-	/* GATE_IP_G3D */
-	GATE(CLK_PPMUG3D, "ppmug3d", "div_aclk_200", GATE_IP_G3D, 1,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_G3D, "g3d", "div_aclk_200", GATE_IP_G3D, 0, 0, 0),
-
-	/* GATE_IP_LCD */
-	GATE(CLK_PPMULCD0, "ppmulcd0", "div_aclk_160", GATE_IP_LCD, 5,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_SMMUFIMD0, "smmufimd0", "div_aclk_160", GATE_IP_LCD, 4, 0, 0),
-	GATE(CLK_DSIM0, "dsim0", "div_aclk_160", GATE_IP_LCD, 3, 0, 0),
-	GATE(CLK_SMIES, "smies", "div_aclk_160", GATE_IP_LCD, 2, 0, 0),
-	GATE(CLK_MIE0, "mie0", "div_aclk_160", GATE_IP_LCD, 1, 0, 0),
-	GATE(CLK_FIMD0, "fimd0", "div_aclk_160", GATE_IP_LCD, 0, 0, 0),
-
-	/* GATE_IP_FSYS */
-	GATE(CLK_TSADC, "tsadc", "div_aclk_200", GATE_IP_FSYS, 20, 0, 0),
-	GATE(CLK_PPMUFILE, "ppmufile", "div_aclk_200", GATE_IP_FSYS, 17,
-		CLK_IGNORE_UNUSED, 0),
-	GATE(CLK_NFCON, "nfcon", "div_aclk_200", GATE_IP_FSYS, 16, 0, 0),
-	GATE(CLK_USBDEVICE, "usbdevice", "div_aclk_200", GATE_IP_FSYS, 13,
-		0, 0),
-	GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0),
-	GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0),
-	GATE(CLK_SDMMC2, "sdmmc2", "div_aclk_200", GATE_IP_FSYS, 7, 0, 0),
-	GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0),
-	GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0),
-	GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0),
-	GATE(CLK_PDMA0, "pdma0", "div_aclk_200", GATE_IP_FSYS, 0, 0, 0),
-
-	/* GATE_IP_PERIL */
-	GATE(CLK_SPDIF, "spdif", "div_aclk_100", GATE_IP_PERIL, 26, 0, 0),
-	GATE(CLK_PWM, "pwm", "div_aclk_100", GATE_IP_PERIL, 24, 0, 0),
-	GATE(CLK_PCM2, "pcm2", "div_aclk_100", GATE_IP_PERIL, 23, 0, 0),
-	GATE(CLK_PCM1, "pcm1", "div_aclk_100", GATE_IP_PERIL, 22, 0, 0),
-	GATE(CLK_I2S1, "i2s1", "div_aclk_100", GATE_IP_PERIL, 20, 0, 0),
-	GATE(CLK_SPI2, "spi2", "div_aclk_100", GATE_IP_PERIL, 18, 0, 0),
-	GATE(CLK_SPI1, "spi1", "div_aclk_100", GATE_IP_PERIL, 17, 0, 0),
-	GATE(CLK_SPI0, "spi0", "div_aclk_100", GATE_IP_PERIL, 16, 0, 0),
-	GATE(CLK_I2CHDMI, "i2chdmi", "div_aclk_100", GATE_IP_PERIL, 14, 0, 0),
-	GATE(CLK_I2C7, "i2c7", "div_aclk_100", GATE_IP_PERIL, 13, 0, 0),
-	GATE(CLK_I2C6, "i2c6", "div_aclk_100", GATE_IP_PERIL, 12, 0, 0),
-	GATE(CLK_I2C5, "i2c5", "div_aclk_100", GATE_IP_PERIL, 11, 0, 0),
-	GATE(CLK_I2C4, "i2c4", "div_aclk_100", GATE_IP_PERIL, 10, 0, 0),
-	GATE(CLK_I2C3, "i2c3", "div_aclk_100", GATE_IP_PERIL, 9, 0, 0),
-	GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0),
-	GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0),
-	GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0),
-	GATE(CLK_UART3, "uart3", "div_aclk_100", GATE_IP_PERIL, 3, 0, 0),
-	GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0),
-	GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0),
-	GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0),
-};
-
-/*
- * APLL & MPLL & BPLL & ISP_PLL & DISP_PLL & G3D_PLL
- */
-static const struct samsung_pll_rate_table exynos4415_pll_rates[] __initconst = {
-	PLL_35XX_RATE(1600000000, 400, 3,  1),
-	PLL_35XX_RATE(1500000000, 250, 2,  1),
-	PLL_35XX_RATE(1400000000, 175, 3,  0),
-	PLL_35XX_RATE(1300000000, 325, 3,  1),
-	PLL_35XX_RATE(1200000000, 400, 4,  1),
-	PLL_35XX_RATE(1100000000, 275, 3,  1),
-	PLL_35XX_RATE(1066000000, 533, 6,  1),
-	PLL_35XX_RATE(1000000000, 250, 3,  1),
-	PLL_35XX_RATE(960000000,  320, 4,  1),
-	PLL_35XX_RATE(900000000,  300, 4,  1),
-	PLL_35XX_RATE(850000000,  425, 6,  1),
-	PLL_35XX_RATE(800000000,  200, 3,  1),
-	PLL_35XX_RATE(700000000,  175, 3,  1),
-	PLL_35XX_RATE(667000000,  667, 12, 1),
-	PLL_35XX_RATE(600000000,  400, 4,  2),
-	PLL_35XX_RATE(550000000,  275, 3,  2),
-	PLL_35XX_RATE(533000000,  533, 6,  2),
-	PLL_35XX_RATE(520000000,  260, 3,  2),
-	PLL_35XX_RATE(500000000,  250, 3,  2),
-	PLL_35XX_RATE(440000000,  220, 3,  2),
-	PLL_35XX_RATE(400000000,  200, 3,  2),
-	PLL_35XX_RATE(350000000,  175, 3,  2),
-	PLL_35XX_RATE(300000000,  300, 3,  3),
-	PLL_35XX_RATE(266000000,  266, 3,  3),
-	PLL_35XX_RATE(200000000,  200, 3,  3),
-	PLL_35XX_RATE(160000000,  160, 3,  3),
-	PLL_35XX_RATE(100000000,  200, 3,  4),
-	{ /* sentinel */ }
-};
-
-/* EPLL */
-static const struct samsung_pll_rate_table exynos4415_epll_rates[] __initconst = {
-	PLL_36XX_RATE(800000000, 200, 3, 1,     0),
-	PLL_36XX_RATE(288000000,  96, 2, 2,     0),
-	PLL_36XX_RATE(192000000, 128, 2, 3,     0),
-	PLL_36XX_RATE(144000000,  96, 2, 3,     0),
-	PLL_36XX_RATE(96000000,  128, 2, 4,     0),
-	PLL_36XX_RATE(84000000,  112, 2, 4,     0),
-	PLL_36XX_RATE(80750011,  107, 2, 4, 43691),
-	PLL_36XX_RATE(73728004,   98, 2, 4, 19923),
-	PLL_36XX_RATE(67987602,  271, 3, 5, 62285),
-	PLL_36XX_RATE(65911004,  175, 2, 5, 49982),
-	PLL_36XX_RATE(50000000,  200, 3, 5,     0),
-	PLL_36XX_RATE(49152003,  131, 2, 5,  4719),
-	PLL_36XX_RATE(48000000,  128, 2, 5,     0),
-	PLL_36XX_RATE(45250000,  181, 3, 5,     0),
-	{ /* sentinel */ }
-};
-
-static const struct samsung_pll_clock exynos4415_plls[] __initconst = {
-	PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
-		APLL_LOCK, APLL_CON0, exynos4415_pll_rates),
-	PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
-		EPLL_LOCK, EPLL_CON0, exynos4415_epll_rates),
-	PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "mout_g3d_pllsrc",
-		G3D_PLL_LOCK, G3D_PLL_CON0, exynos4415_pll_rates),
-	PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "fin_pll",
-		ISP_PLL_LOCK, ISP_PLL_CON0, exynos4415_pll_rates),
-	PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll",
-		"fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, exynos4415_pll_rates),
-};
-
-static const struct samsung_cmu_info cmu_info __initconst = {
-	.pll_clks		= exynos4415_plls,
-	.nr_pll_clks		= ARRAY_SIZE(exynos4415_plls),
-	.mux_clks		= exynos4415_mux_clks,
-	.nr_mux_clks		= ARRAY_SIZE(exynos4415_mux_clks),
-	.div_clks		= exynos4415_div_clks,
-	.nr_div_clks		= ARRAY_SIZE(exynos4415_div_clks),
-	.gate_clks		= exynos4415_gate_clks,
-	.nr_gate_clks		= ARRAY_SIZE(exynos4415_gate_clks),
-	.fixed_clks		= exynos4415_fixed_rate_clks,
-	.nr_fixed_clks		= ARRAY_SIZE(exynos4415_fixed_rate_clks),
-	.fixed_factor_clks	= exynos4415_fixed_factor_clks,
-	.nr_fixed_factor_clks	= ARRAY_SIZE(exynos4415_fixed_factor_clks),
-	.nr_clk_ids		= CLK_NR_CLKS,
-	.clk_regs		= exynos4415_cmu_clk_regs,
-	.nr_clk_regs		= ARRAY_SIZE(exynos4415_cmu_clk_regs),
-};
-
-static void __init exynos4415_cmu_init(struct device_node *np)
-{
-	samsung_cmu_register_one(np, &cmu_info);
-}
-CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init);
-
-/*
- * CMU DMC
- */
-
-#define MPLL_LOCK		0x008
-#define MPLL_CON0		0x108
-#define MPLL_CON1		0x10c
-#define MPLL_CON2		0x110
-#define BPLL_LOCK		0x118
-#define BPLL_CON0		0x218
-#define BPLL_CON1		0x21c
-#define BPLL_CON2		0x220
-#define SRC_DMC			0x300
-#define DIV_DMC1		0x504
-
-static const unsigned long exynos4415_cmu_dmc_clk_regs[] __initconst = {
-	MPLL_LOCK,
-	MPLL_CON0,
-	MPLL_CON1,
-	MPLL_CON2,
-	BPLL_LOCK,
-	BPLL_CON0,
-	BPLL_CON1,
-	BPLL_CON2,
-	SRC_DMC,
-	DIV_DMC1,
-};
-
-PNAME(mout_mpll_p)		= { "fin_pll", "fout_mpll", };
-PNAME(mout_bpll_p)		= { "fin_pll", "fout_bpll", };
-PNAME(mbpll_p)			= { "mout_mpll", "mout_bpll", };
-
-static const struct samsung_mux_clock exynos4415_dmc_mux_clks[] __initconst = {
-	MUX(CLK_DMC_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_DMC, 12, 1),
-	MUX(CLK_DMC_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_DMC, 10, 1),
-	MUX(CLK_DMC_MOUT_DPHY, "mout_dphy", mbpll_p, SRC_DMC, 8, 1),
-	MUX(CLK_DMC_MOUT_DMC_BUS, "mout_dmc_bus", mbpll_p, SRC_DMC, 4, 1),
-};
-
-static const struct samsung_div_clock exynos4415_dmc_div_clks[] __initconst = {
-	DIV(CLK_DMC_DIV_DMC, "div_dmc", "div_dmc_pre", DIV_DMC1, 27, 3),
-	DIV(CLK_DMC_DIV_DPHY, "div_dphy", "mout_dphy", DIV_DMC1, 23, 3),
-	DIV(CLK_DMC_DIV_DMC_PRE, "div_dmc_pre", "mout_dmc_bus",
-		DIV_DMC1, 19, 2),
-	DIV(CLK_DMC_DIV_DMCP, "div_dmcp", "div_dmcd", DIV_DMC1, 15, 3),
-	DIV(CLK_DMC_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3),
-	DIV(CLK_DMC_DIV_MPLL_PRE, "div_mpll_pre", "mout_mpll", DIV_DMC1, 8, 2),
-};
-
-static const struct samsung_pll_clock exynos4415_dmc_plls[] __initconst = {
-	PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll",
-		MPLL_LOCK, MPLL_CON0, exynos4415_pll_rates),
-	PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll",
-		BPLL_LOCK, BPLL_CON0, exynos4415_pll_rates),
-};
-
-static const struct samsung_cmu_info cmu_dmc_info __initconst = {
-	.pll_clks		= exynos4415_dmc_plls,
-	.nr_pll_clks		= ARRAY_SIZE(exynos4415_dmc_plls),
-	.mux_clks		= exynos4415_dmc_mux_clks,
-	.nr_mux_clks		= ARRAY_SIZE(exynos4415_dmc_mux_clks),
-	.div_clks		= exynos4415_dmc_div_clks,
-	.nr_div_clks		= ARRAY_SIZE(exynos4415_dmc_div_clks),
-	.nr_clk_ids		= NR_CLKS_DMC,
-	.clk_regs		= exynos4415_cmu_dmc_clk_regs,
-	.nr_clk_regs		= ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs),
-};
-
-static void __init exynos4415_cmu_dmc_init(struct device_node *np)
-{
-	samsung_cmu_register_one(np, &cmu_dmc_info);
-}
-CLK_OF_DECLARE(exynos4415_cmu_dmc, "samsung,exynos4415-cmu-dmc",
-		exynos4415_cmu_dmc_init);
diff --git a/include/dt-bindings/clock/exynos4415.h b/include/dt-bindings/clock/exynos4415.h
deleted file mode 100644
index 7eed55100721..000000000000
--- a/include/dt-bindings/clock/exynos4415.h
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- * Author: Chanwoo Choi <cw00.choi@samsung.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.
- *
- * Device Tree binding constants for Samsung Exynos4415 clock controllers.
- */
-
-#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H
-#define _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H
-
-/*
- * Let each exported clock get a unique index, which is used on DT-enabled
- * platforms to lookup the clock from a clock specifier. These indices are
- * therefore considered an ABI and so must not be changed. This implies
- * that new clocks should be added either in free spaces between clock groups
- * or at the end.
- */
-
-/*
- * Main CMU
- */
-
-#define CLK_OSCSEL			1
-#define CLK_FIN_PLL			2
-#define CLK_FOUT_APLL			3
-#define CLK_FOUT_MPLL			4
-#define CLK_FOUT_EPLL			5
-#define CLK_FOUT_G3D_PLL		6
-#define CLK_FOUT_ISP_PLL		7
-#define CLK_FOUT_DISP_PLL		8
-
-/* Muxes */
-#define CLK_MOUT_MPLL_USER_L		16
-#define CLK_MOUT_GDL			17
-#define CLK_MOUT_MPLL_USER_R		18
-#define CLK_MOUT_GDR			19
-#define CLK_MOUT_EBI			20
-#define CLK_MOUT_ACLK_200		21
-#define CLK_MOUT_ACLK_160		22
-#define CLK_MOUT_ACLK_100		23
-#define CLK_MOUT_ACLK_266		24
-#define CLK_MOUT_G3D_PLL		25
-#define CLK_MOUT_EPLL			26
-#define CLK_MOUT_EBI_1			27
-#define CLK_MOUT_ISP_PLL		28
-#define CLK_MOUT_DISP_PLL		29
-#define CLK_MOUT_MPLL_USER_T		30
-#define CLK_MOUT_ACLK_400_MCUISP	31
-#define CLK_MOUT_G3D_PLLSRC		32
-#define CLK_MOUT_CSIS1			33
-#define CLK_MOUT_CSIS0			34
-#define CLK_MOUT_CAM1			35
-#define CLK_MOUT_FIMC3_LCLK		36
-#define CLK_MOUT_FIMC2_LCLK		37
-#define CLK_MOUT_FIMC1_LCLK		38
-#define CLK_MOUT_FIMC0_LCLK		39
-#define CLK_MOUT_MFC			40
-#define CLK_MOUT_MFC_1			41
-#define CLK_MOUT_MFC_0			42
-#define CLK_MOUT_G3D			43
-#define CLK_MOUT_G3D_1			44
-#define CLK_MOUT_G3D_0			45
-#define CLK_MOUT_MIPI0			46
-#define CLK_MOUT_FIMD0			47
-#define CLK_MOUT_TSADC_ISP		48
-#define CLK_MOUT_UART_ISP		49
-#define CLK_MOUT_SPI1_ISP		50
-#define CLK_MOUT_SPI0_ISP		51
-#define CLK_MOUT_PWM_ISP		52
-#define CLK_MOUT_AUDIO0			53
-#define CLK_MOUT_TSADC			54
-#define CLK_MOUT_MMC2			55
-#define CLK_MOUT_MMC1			56
-#define CLK_MOUT_MMC0			57
-#define CLK_MOUT_UART3			58
-#define CLK_MOUT_UART2			59
-#define CLK_MOUT_UART1			60
-#define CLK_MOUT_UART0			61
-#define CLK_MOUT_SPI2			62
-#define CLK_MOUT_SPI1			63
-#define CLK_MOUT_SPI0			64
-#define CLK_MOUT_SPDIF			65
-#define CLK_MOUT_AUDIO2			66
-#define CLK_MOUT_AUDIO1			67
-#define CLK_MOUT_MPLL_USER_C		68
-#define CLK_MOUT_HPM			69
-#define CLK_MOUT_CORE			70
-#define CLK_MOUT_APLL			71
-#define CLK_MOUT_PXLASYNC_CSIS1_FIMC	72
-#define CLK_MOUT_PXLASYNC_CSIS0_FIMC	73
-#define CLK_MOUT_JPEG			74
-#define CLK_MOUT_JPEG1			75
-#define CLK_MOUT_JPEG0			76
-#define CLK_MOUT_ACLK_ISP0_300		77
-#define CLK_MOUT_ACLK_ISP0_400		78
-#define CLK_MOUT_ACLK_ISP0_300_USER	79
-#define CLK_MOUT_ACLK_ISP1_300		80
-#define CLK_MOUT_ACLK_ISP1_300_USER	81
-#define CLK_MOUT_HDMI			82
-
-/* Dividers */
-#define CLK_DIV_GPL			90
-#define CLK_DIV_GDL			91
-#define CLK_DIV_GPR			92
-#define CLK_DIV_GDR			93
-#define CLK_DIV_ACLK_400_MCUISP		94
-#define CLK_DIV_EBI			95
-#define CLK_DIV_ACLK_200		96
-#define CLK_DIV_ACLK_160		97
-#define CLK_DIV_ACLK_100		98
-#define CLK_DIV_ACLK_266		99
-#define CLK_DIV_CSIS1			100
-#define CLK_DIV_CSIS0			101
-#define CLK_DIV_CAM1			102
-#define CLK_DIV_FIMC3_LCLK		103
-#define CLK_DIV_FIMC2_LCLK		104
-#define CLK_DIV_FIMC1_LCLK		105
-#define CLK_DIV_FIMC0_LCLK		106
-#define CLK_DIV_TV_BLK			107
-#define CLK_DIV_MFC			108
-#define CLK_DIV_G3D			109
-#define CLK_DIV_MIPI0_PRE		110
-#define CLK_DIV_MIPI0			111
-#define CLK_DIV_FIMD0			112
-#define CLK_DIV_UART_ISP		113
-#define CLK_DIV_SPI1_ISP_PRE		114
-#define CLK_DIV_SPI1_ISP		115
-#define CLK_DIV_SPI0_ISP_PRE		116
-#define CLK_DIV_SPI0_ISP		117
-#define CLK_DIV_PWM_ISP			118
-#define CLK_DIV_PCM0			119
-#define CLK_DIV_AUDIO0			120
-#define CLK_DIV_TSADC_PRE		121
-#define CLK_DIV_TSADC			122
-#define CLK_DIV_MMC1_PRE		123
-#define CLK_DIV_MMC1			124
-#define CLK_DIV_MMC0_PRE		125
-#define CLK_DIV_MMC0			126
-#define CLK_DIV_MMC2_PRE		127
-#define CLK_DIV_MMC2			128
-#define CLK_DIV_UART3			129
-#define CLK_DIV_UART2			130
-#define CLK_DIV_UART1			131
-#define CLK_DIV_UART0			132
-#define CLK_DIV_SPI1_PRE		133
-#define CLK_DIV_SPI1			134
-#define CLK_DIV_SPI0_PRE		135
-#define CLK_DIV_SPI0			136
-#define CLK_DIV_SPI2_PRE		137
-#define CLK_DIV_SPI2			138
-#define CLK_DIV_PCM2			139
-#define CLK_DIV_AUDIO2			140
-#define CLK_DIV_PCM1			141
-#define CLK_DIV_AUDIO1			142
-#define CLK_DIV_I2S1			143
-#define CLK_DIV_PXLASYNC_CSIS1_FIMC	144
-#define CLK_DIV_PXLASYNC_CSIS0_FIMC	145
-#define CLK_DIV_JPEG			146
-#define CLK_DIV_CORE2			147
-#define CLK_DIV_APLL			148
-#define CLK_DIV_PCLK_DBG		149
-#define CLK_DIV_ATB			150
-#define CLK_DIV_PERIPH			151
-#define CLK_DIV_COREM1			152
-#define CLK_DIV_COREM0			153
-#define CLK_DIV_CORE			154
-#define CLK_DIV_HPM			155
-#define CLK_DIV_COPY			156
-
-/* Gates */
-#define CLK_ASYNC_G3D			180
-#define CLK_ASYNC_MFCL			181
-#define CLK_ASYNC_TVX			182
-#define CLK_PPMULEFT			183
-#define CLK_GPIO_LEFT			184
-#define CLK_PPMUIMAGE			185
-#define CLK_QEMDMA2			186
-#define CLK_QEROTATOR			187
-#define CLK_SMMUMDMA2			188
-#define CLK_SMMUROTATOR			189
-#define CLK_MDMA2			190
-#define CLK_ROTATOR			191
-#define CLK_ASYNC_ISPMX			192
-#define CLK_ASYNC_MAUDIOX		193
-#define CLK_ASYNC_MFCR			194
-#define CLK_ASYNC_FSYSD			195
-#define CLK_ASYNC_LCD0X			196
-#define CLK_ASYNC_CAMX			197
-#define CLK_PPMURIGHT			198
-#define CLK_GPIO_RIGHT			199
-#define CLK_ANTIRBK_APBIF		200
-#define CLK_EFUSE_WRITER_APBIF		201
-#define CLK_MONOCNT			202
-#define CLK_TZPC6			203
-#define CLK_PROVISIONKEY1		204
-#define CLK_PROVISIONKEY0		205
-#define CLK_CMU_ISPPART			206
-#define CLK_TMU_APBIF			207
-#define CLK_KEYIF			208
-#define CLK_RTC				209
-#define CLK_WDT				210
-#define CLK_MCT				211
-#define CLK_SECKEY			212
-#define CLK_HDMI_CEC			213
-#define CLK_TZPC5			214
-#define CLK_TZPC4			215
-#define CLK_TZPC3			216
-#define CLK_TZPC2			217
-#define CLK_TZPC1			218
-#define CLK_TZPC0			219
-#define CLK_CMU_COREPART		220
-#define CLK_CMU_TOPPART			221
-#define CLK_PMU_APBIF			222
-#define CLK_SYSREG			223
-#define CLK_CHIP_ID			224
-#define CLK_SMMUFIMC_LITE2		225
-#define CLK_FIMC_LITE2			226
-#define CLK_PIXELASYNCM1		227
-#define CLK_PIXELASYNCM0		228
-#define CLK_PPMUCAMIF			229
-#define CLK_SMMUJPEG			230
-#define CLK_SMMUFIMC3			231
-#define CLK_SMMUFIMC2			232
-#define CLK_SMMUFIMC1			233
-#define CLK_SMMUFIMC0			234
-#define CLK_JPEG			235
-#define CLK_CSIS1			236
-#define CLK_CSIS0			237
-#define CLK_FIMC3			238
-#define CLK_FIMC2			239
-#define CLK_FIMC1			240
-#define CLK_FIMC0			241
-#define CLK_PPMUTV			242
-#define CLK_SMMUTV			243
-#define CLK_HDMI			244
-#define CLK_MIXER			245
-#define CLK_VP				246
-#define CLK_PPMUMFC_R			247
-#define CLK_PPMUMFC_L			248
-#define CLK_SMMUMFC_R			249
-#define CLK_SMMUMFC_L			250
-#define CLK_MFC				251
-#define CLK_PPMUG3D			252
-#define CLK_G3D				253
-#define CLK_PPMULCD0			254
-#define CLK_SMMUFIMD0			255
-#define CLK_DSIM0			256
-#define CLK_SMIES			257
-#define CLK_MIE0			258
-#define CLK_FIMD0			259
-#define CLK_TSADC			260
-#define CLK_PPMUFILE			261
-#define CLK_NFCON			262
-#define CLK_USBDEVICE			263
-#define CLK_USBHOST			264
-#define CLK_SROMC			265
-#define CLK_SDMMC2			266
-#define CLK_SDMMC1			267
-#define CLK_SDMMC0			268
-#define CLK_PDMA1			269
-#define CLK_PDMA0			270
-#define CLK_SPDIF			271
-#define CLK_PWM				272
-#define CLK_PCM2			273
-#define CLK_PCM1			274
-#define CLK_I2S1			275
-#define CLK_SPI2			276
-#define CLK_SPI1			277
-#define CLK_SPI0			278
-#define CLK_I2CHDMI			279
-#define CLK_I2C7			280
-#define CLK_I2C6			281
-#define CLK_I2C5			282
-#define CLK_I2C4			283
-#define CLK_I2C3			284
-#define CLK_I2C2			285
-#define CLK_I2C1			286
-#define CLK_I2C0			287
-#define CLK_UART3			288
-#define CLK_UART2			289
-#define CLK_UART1			290
-#define CLK_UART0			291
-
-/* Special clocks */
-#define CLK_SCLK_PXLAYSNC_CSIS1_FIMC	330
-#define CLK_SCLK_PXLAYSNC_CSIS0_FIMC	331
-#define CLK_SCLK_JPEG			332
-#define CLK_SCLK_CSIS1			333
-#define CLK_SCLK_CSIS0			334
-#define CLK_SCLK_CAM1			335
-#define CLK_SCLK_FIMC3_LCLK		336
-#define CLK_SCLK_FIMC2_LCLK		337
-#define CLK_SCLK_FIMC1_LCLK		338
-#define CLK_SCLK_FIMC0_LCLK		339
-#define CLK_SCLK_PIXEL			340
-#define CLK_SCLK_HDMI			341
-#define CLK_SCLK_MIXER			342
-#define CLK_SCLK_MFC			343
-#define CLK_SCLK_G3D			344
-#define CLK_SCLK_MIPIDPHY4L		345
-#define CLK_SCLK_MIPI0			346
-#define CLK_SCLK_MDNIE0			347
-#define CLK_SCLK_FIMD0			348
-#define CLK_SCLK_PCM0			349
-#define CLK_SCLK_AUDIO0			350
-#define CLK_SCLK_TSADC			351
-#define CLK_SCLK_EBI			352
-#define CLK_SCLK_MMC2			353
-#define CLK_SCLK_MMC1			354
-#define CLK_SCLK_MMC0			355
-#define CLK_SCLK_I2S			356
-#define CLK_SCLK_PCM2			357
-#define CLK_SCLK_PCM1			358
-#define CLK_SCLK_AUDIO2			359
-#define CLK_SCLK_AUDIO1			360
-#define CLK_SCLK_SPDIF			361
-#define CLK_SCLK_SPI2			362
-#define CLK_SCLK_SPI1			363
-#define CLK_SCLK_SPI0			364
-#define CLK_SCLK_UART3			365
-#define CLK_SCLK_UART2			366
-#define CLK_SCLK_UART1			367
-#define CLK_SCLK_UART0			368
-#define CLK_SCLK_HDMIPHY		369
-
-/*
- * Total number of clocks of main CMU.
- * NOTE: Must be equal to last clock ID increased by one.
- */
-#define CLK_NR_CLKS			370
-
-/*
- * CMU DMC
- */
-#define CLK_DMC_FOUT_MPLL		1
-#define CLK_DMC_FOUT_BPLL		2
-
-#define CLK_DMC_MOUT_MPLL		3
-#define CLK_DMC_MOUT_BPLL		4
-#define CLK_DMC_MOUT_DPHY		5
-#define CLK_DMC_MOUT_DMC_BUS		6
-
-#define CLK_DMC_DIV_DMC			7
-#define CLK_DMC_DIV_DPHY		8
-#define CLK_DMC_DIV_DMC_PRE		9
-#define CLK_DMC_DIV_DMCP		10
-#define CLK_DMC_DIV_DMCD		11
-#define CLK_DMC_DIV_MPLL_PRE		12
-
-/*
- * Total number of clocks of CMU_DMC.
- * NOTE: Must be equal to highest clock ID increased by one.
- */
-#define NR_CLKS_DMC			13
-
-#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H */
-- 
2.9.3


^ permalink raw reply related

* [PATCH 3/4] pinctrl: samsung: Remove support for Exynos4415 (SoC not supported anymore)
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
  To: Sylwester Nawrocki, Tomasz Figa, Chanwoo Choi, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Kukjin Kim,
	Krzysztof Kozlowski, Javier Martinez Canillas, Inki Dae,
	Joonyoung Shim, Seung-Woo Kim, Kyungmin Park, Linus Walleij,
	linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, dri-deve
In-Reply-To: <20170114123642.15581-1-krzk@kernel.org>

Support for Exynos4415 is going away because there are no internal nor
external users.

Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
the platform cannot be instantiated so remove also the drivers.

Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
 drivers/pinctrl/samsung/pinctrl-exynos.c  | 75 -------------------------------
 drivers/pinctrl/samsung/pinctrl-samsung.c |  2 -
 drivers/pinctrl/samsung/pinctrl-samsung.h |  1 -
 3 files changed, 78 deletions(-)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 07409fde02b2..24814db251a7 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -919,81 +919,6 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
 	},
 };
 
-/* pin banks of exynos4415 pin-controller 0 */
-static const struct samsung_pin_bank_data exynos4415_pin_banks0[] = {
-	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
-	EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
-	EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
-	EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
-	EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
-	EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
-	EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
-	EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
-	EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
-	EXYNOS_PIN_BANK_EINTG(1, 0x1C0, "gpf2", 0x38),
-};
-
-/* pin banks of exynos4415 pin-controller 1 */
-static const struct samsung_pin_bank_data exynos4415_pin_banks1[] = {
-	EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpk0", 0x08),
-	EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
-	EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
-	EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
-	EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpl0", 0x18),
-	EXYNOS_PIN_BANK_EINTN(6, 0x120, "mp00"),
-	EXYNOS_PIN_BANK_EINTN(4, 0x140, "mp01"),
-	EXYNOS_PIN_BANK_EINTN(6, 0x160, "mp02"),
-	EXYNOS_PIN_BANK_EINTN(8, 0x180, "mp03"),
-	EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "mp04"),
-	EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "mp05"),
-	EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "mp06"),
-	EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
-	EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
-	EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c),
-	EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30),
-	EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34),
-	EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
-	EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
-	EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
-	EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
-};
-
-/* pin banks of exynos4415 pin-controller 2 */
-static const struct samsung_pin_bank_data exynos4415_pin_banks2[] = {
-	EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
-	EXYNOS_PIN_BANK_EINTN(2, 0x000, "etc1"),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos4415 SoC. Exynos4415 SoC includes
- * three gpio/pin-mux/pinconfig controllers.
- */
-const struct samsung_pin_ctrl exynos4415_pin_ctrl[] = {
-	{
-		/* pin-controller instance 0 data */
-		.pin_banks	= exynos4415_pin_banks0,
-		.nr_banks	= ARRAY_SIZE(exynos4415_pin_banks0),
-		.eint_gpio_init = exynos_eint_gpio_init,
-		.suspend	= exynos_pinctrl_suspend,
-		.resume		= exynos_pinctrl_resume,
-	}, {
-		/* pin-controller instance 1 data */
-		.pin_banks	= exynos4415_pin_banks1,
-		.nr_banks	= ARRAY_SIZE(exynos4415_pin_banks1),
-		.eint_gpio_init = exynos_eint_gpio_init,
-		.eint_wkup_init = exynos_eint_wkup_init,
-		.suspend	= exynos_pinctrl_suspend,
-		.resume		= exynos_pinctrl_resume,
-	}, {
-		/* pin-controller instance 2 data */
-		.pin_banks	= exynos4415_pin_banks2,
-		.nr_banks	= ARRAY_SIZE(exynos4415_pin_banks2),
-		.eint_gpio_init = exynos_eint_gpio_init,
-		.suspend	= exynos_pinctrl_suspend,
-		.resume		= exynos_pinctrl_resume,
-	},
-};
-
 /* pin banks of exynos5250 pin-controller 0 */
 static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = {
 	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 41e62391c33c..3bc925f61b71 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1238,8 +1238,6 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = (void *)exynos4210_pin_ctrl },
 	{ .compatible = "samsung,exynos4x12-pinctrl",
 		.data = (void *)exynos4x12_pin_ctrl },
-	{ .compatible = "samsung,exynos4415-pinctrl",
-		.data = (void *)exynos4415_pin_ctrl },
 	{ .compatible = "samsung,exynos5250-pinctrl",
 		.data = (void *)exynos5250_pin_ctrl },
 	{ .compatible = "samsung,exynos5260-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 043cb6c11180..6f7ce7539a00 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -273,7 +273,6 @@ struct samsung_pmx_func {
 extern const struct samsung_pin_ctrl exynos3250_pin_ctrl[];
 extern const struct samsung_pin_ctrl exynos4210_pin_ctrl[];
 extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos4415_pin_ctrl[];
 extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[];
 extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[];
 extern const struct samsung_pin_ctrl exynos5410_pin_ctrl[];
-- 
2.9.3

^ permalink raw reply related


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