Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/5] drivers: mmc: sunxi: limit A64 MMC2 to 8K DMA buffer
From: André Przywara @ 2017-01-05 23:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170105175746.fq6crpc3krz7tzxi@lukather>

On 05/01/17 17:57, Maxime Ripard wrote:
> Hi Rob,
> 
> On Wed, Jan 04, 2017 at 08:07:50AM -0600, Rob Herring wrote:
>> On Mon, Jan 02, 2017 at 11:03:43PM +0000, Andre Przywara wrote:
>>> From: Maxime Ripard <maxime.ripard@free-electrons.com>
>>>
>>> Unlike the A64 user manual reports, the third MMC controller on the
>>> A64 (and the only one capable of 8-bit HS400 eMMC transfers) has a
>>> DMA buffer size limit of 8KB (much like the very old Allwinner SoCs).
>>> This does not affect the other two controllers, so introduce a new
>>> DT compatible string to let the driver use different settings for that
>>> particular device. This will also help to enable the high-speed transfer
>>> modes of that controller later.
>>>
>>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>>> ---
>>>  Documentation/devicetree/bindings/mmc/sunxi-mmc.txt | 1 +
>>>  drivers/mmc/host/sunxi-mmc.c                        | 7 +++++++
>>>  2 files changed, 8 insertions(+)
>>
>> Acked-by: Rob Herring <robh@kernel.org>
> 
> Some kind of a digression on this: we have three MMC controllers on
> this SoC. Like this patch shows, the third one is clearly different,
> and supports both more modes, a wider bus, and specific quirks. We
> need a new compatible for this one, everything's perfect.
> 
> However, the other two are mostly the same, but seems to need
> different tuning parameters to get more performances out of the
> controller (but this is unclear yet). How do we usually deal with
> that?

I guess you wanted to hear Rob's opinion ;-), but "get more performance"
sounds like we add one (or more) properties to tune those values.
If I get this right, it works with default values, but is sub-optimal?

Cheers,
Andre.

^ permalink raw reply

* [PATCH v2 3/8] ARM: dts: armada-388-clearfog: Utilize new DSA binding
From: Russell King - ARM Linux @ 2017-01-06  0:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170105192957.14304-4-f.fainelli@gmail.com>

On Thu, Jan 05, 2017 at 11:29:52AM -0800, Florian Fainelli wrote:
> Utilize the new DSA binding, introduced with commit 8c5ad1d6179d ("net:
> dsa: Document new binding"). The legacy binding node is kept included, but is
> marked disabled.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

Booted here on clearfog, and tested traffic passes between two lan
ports, and a lan port and the cpu port... and generally still seems
to work as a switch.  All seems well on the face of it.

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>

Thanks.

> ---
>  arch/arm/boot/dts/armada-388-clearfog.dts | 65 +++++++++++++++++++++++++++++++
>  1 file changed, 65 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts
> index 71ce201c903e..40ec6d768669 100644
> --- a/arch/arm/boot/dts/armada-388-clearfog.dts
> +++ b/arch/arm/boot/dts/armada-388-clearfog.dts
> @@ -351,6 +351,8 @@
>  	};
>  
>  	dsa at 0 {
> +		status = "disabled";
> +
>  		compatible = "marvell,dsa";
>  		dsa,ethernet = <&eth1>;
>  		dsa,mii-bus = <&mdio>;
> @@ -444,3 +446,66 @@
>  		status = "disabled";
>  	};
>  };
> +
> +&mdio {
> +	status = "okay";
> +
> +	switch at 4 {
> +		compatible = "marvell,mv88e6085";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = <4>;
> +		pinctrl-0 = <&clearfog_dsa0_clk_pins &clearfog_dsa0_pins>;
> +		pinctrl-names = "default";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port at 0 {
> +				reg = <0>;
> +				label = "lan5";
> +			};
> +
> +			port at 1 {
> +				reg = <1>;
> +				label = "lan4";
> +			};
> +
> +			port at 2 {
> +				reg = <2>;
> +				label = "lan3";
> +			};
> +
> +			port at 3 {
> +				reg = <3>;
> +				label = "lan2";
> +			};
> +
> +			port at 4 {
> +				reg = <4>;
> +				label = "lan1";
> +			};
> +
> +			port at 5 {
> +				reg = <5>;
> +				label = "cpu";
> +				ethernet = <&eth1>;
> +				fixed-link {
> +					speed = <1000>;
> +					full-duplex;
> +				};
> +			};
> +
> +			port at 6 {
> +				/* 88E1512 external phy */
> +				reg = <6>;
> +				label = "lan6";
> +				fixed-link {
> +					speed = <1000>;
> +					full-duplex;
> +				};
> +			};
> +		};
> +	};
> +};
> -- 
> 2.9.3
> 

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

^ permalink raw reply

* [PATCHv2 2/2] arm: Adjust memory boundaries after reservations
From: Russell King - ARM Linux @ 2017-01-06  0:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483657274-11346-3-git-send-email-labbott@redhat.com>

Only comments are to do with the comments...

On Thu, Jan 05, 2017 at 03:01:14PM -0800, Laura Abbott wrote:
> 
> adjust_lowmem_bounds is responsible for setting up the boundary for
> lowmem/hihgmme. This needs to be setup before memblock reservations can

highmem

> occur. At the time memblock reservations can occur, memory can also be
> removed from the system. The lowmem/highmem boundary and end of memory
> may be affected by this but it is currently not recalculated. On some
> systems this may be harmless, on o thers this may result in incorrect

others

> ranges being passed to the main memory allocator. Correct this by
> recalculating the lowmem/highmem boundary after all reservations have
> been made.
> 
> Signed-off-by: Laura Abbott <labbott@redhat.com>
> ---
> v2: Rebased for changes in sanity_check_meminfo cleanup
> ---
>  arch/arm/kernel/setup.c | 8 ++++++++
>  arch/arm/mm/mmu.c       | 9 ++++++---
>  2 files changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index 8a8051c..4625115 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -1093,8 +1093,16 @@ void __init setup_arch(char **cmdline_p)
>  	setup_dma_zone(mdesc);
>  	xen_early_init();
>  	efi_init();
> +	/*
> +	 * Make sure the calcualtion for lowmem/highmem is set appropriately

calculation

> +	 * before reserving/allocating any mmeory
> +	 */
>  	adjust_lowmem_bounds();
>  	arm_memblock_init(mdesc);
> +	/*
> +	 * Memory may have been removed so recalculate the bounds.
> +	 */

Single line comments should be... /* blah */

> +	adjust_lowmem_bounds();
>  
>  	early_ioremap_reset();
>  
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index ce5123b..7ca6910 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -1157,6 +1157,7 @@ void __init adjust_lowmem_bounds(void)
>  	phys_addr_t memblock_limit = 0;
>  	u64 vmalloc_limit;
>  	struct memblock_region *reg;
> +	phys_addr_t lowmem_limit = 0;
>  
>  	/*
>  	 * Let's use our own (unoptimized) equivalent of __pa() that is
> @@ -1173,14 +1174,14 @@ void __init adjust_lowmem_bounds(void)
>  
>  
>  		if (reg->base < vmalloc_limit) {
> -			if (block_end > arm_lowmem_limit)
> +			if (block_end > lowmem_limit)
>  				/*
>  				 * Compare as u64 to ensure vmalloc_limit does
>  				 * not get truncated. block_end should always
>  				 * fit in phys_addr_t so there should be no
>  				 * issue with assignment.
>  				 */
> -				arm_lowmem_limit = min_t(u64,
> +				lowmem_limit = min_t(u64,
>  							 vmalloc_limit,
>  							 block_end);
>  
> @@ -1201,12 +1202,14 @@ void __init adjust_lowmem_bounds(void)
>  				if (!IS_ALIGNED(block_start, PMD_SIZE))
>  					memblock_limit = block_start;
>  				else if (!IS_ALIGNED(block_end, PMD_SIZE))
> -					memblock_limit = arm_lowmem_limit;
> +					memblock_limit = lowmem_limit;
>  			}
>  
>  		}
>  	}
>  
> +	arm_lowmem_limit = lowmem_limit;
> +
>  	high_memory = __va(arm_lowmem_limit - 1) + 1;
>  
>  	/*
> -- 
> 2.7.4
> 

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

^ permalink raw reply

* [nomadik:lis3lv02 5/6] warning: (IIO_ST_ACCEL_3AXIS) selects IIO_ST_ACCEL_SPI_3AXIS which has unmet direct dependencies (IIO && ..)
From: kbuild test robot @ 2017-01-06  0:43 UTC (permalink / raw)
  To: linux-arm-kernel

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git lis3lv02
head:   e343deae8006a1fc109534497c943eab51a1c2a8
commit: 0a9710dd480b06b6fefefdedc732020f2297e247 [5/6] iio: accel: st_accel: handle deprecated bindings
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git checkout 0a9710dd480b06b6fefefdedc732020f2297e247
        # save the attached .config to linux build tree
        make.cross ARCH=powerpc 

All warnings (new ones prefixed by >>):

warning: (IIO_ST_ACCEL_3AXIS) selects IIO_ST_ACCEL_SPI_3AXIS which has unmet direct dependencies (IIO && !SENSORS_LIS3_SPI && IIO_ST_ACCEL_3AXIS && IIO_ST_SENSORS_SPI)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 51856 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170106/9cb0f0b3/attachment-0001.gz>

^ permalink raw reply

* [RESEND 2/2] arm64: dts: Add dts files for Hisilicon Hi3660 SoC
From: Chen Feng @ 2017-01-06  0:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170105141456.GA5710@hector.attlocal.net>



On 2017/1/5 22:14, Andy Gross wrote:
> On Mon, Dec 26, 2016 at 05:36:12PM +0800, Chen Feng wrote:
>> Add initial dtsi file to support Hisilicon Hi3660 SoC with
>> support of Octal core CPUs in two clusters(4 * A53 & 4 * A73).
>>
>> Also add dts file to support HiKey960 development board which
>> based on Hi3660 SoC.
>> The output console is earlycon "earlycon=pl011,0xfdf05000".
>> And the con_init uart5 with a fixed clock, which already
>> configured at bootloader.
>>
>> When clock is available, the uart5 will be modified.
>>
>> Tested on HiKey960 Board.
>>
>> Signed-off-by: Chen Feng <puck.chen@hisilicon.com>
>> ---
>>  arch/arm64/boot/dts/hisilicon/Makefile            |   1 +
>>  arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts |  34 +++++
>>  arch/arm64/boot/dts/hisilicon/hi3660.dtsi         | 156 ++++++++++++++++++++++
>>  3 files changed, 191 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
>>  create mode 100644 arch/arm64/boot/dts/hisilicon/hi3660.dtsi
>>
>> diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
>> index d5f43a0..b633b5d 100644
>> --- a/arch/arm64/boot/dts/hisilicon/Makefile
>> +++ b/arch/arm64/boot/dts/hisilicon/Makefile
>> @@ -1,4 +1,5 @@
>>  dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
>> +dtb-$(CONFIG_ARCH_HISI) += hi3660-hikey960.dtb
>>  dtb-$(CONFIG_ARCH_HISI) += hip05-d02.dtb
>>  dtb-$(CONFIG_ARCH_HISI) += hip06-d03.dtb
>>  
>> diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
>> new file mode 100644
>> index 0000000..3d7aead
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
>> @@ -0,0 +1,34 @@
>> +/*
>> + * dts file for Hisilicon HiKey960 Development Board
>> + *
>> + * Copyright (C) 2016, Hisilicon Ltd.
>> + *
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "hi3660.dtsi"
>> +
>> +/ {
>> +	model = "HiKey960";
>> +	compatible = "hisilicon,hi3660";
>> +
>> +	aliases {
>> +		serial5 = &uart5;       /* console UART */
>> +	};
>> +
>> +	chosen {
>> +		stdout-path = "serial5:115200n8";
>> +	};
>> +
>> +	memory at 0 {
>> +		device_type = "memory";
>> +		reg = <0x0 0x00400000 0x0 0xBFE00000>;
> 
> Use lower case letters for hex numbers.  0xbfe00000.
> 


ok, thanks!
>> +	};
>> +
>> +	soc {
>> +		uart5: uart at fdf05000 {
>> +			status = "ok";
>> +		};
>> +	};
>> +};
> 
> <snip>
> 
> Regards,
> 
> Andy
> 
> .
> 

^ permalink raw reply

* [PATCH v3] arm64: mm: Fix NOMAP page initialization
From: Hanjun Guo @ 2017-01-06  1:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c74d6ec6-16ba-dccc-3b0d-a8bedcb46dc5@linaro.org>

On 2017/1/5 10:03, Hanjun Guo wrote:
> On 2017/1/4 21:56, Ard Biesheuvel wrote:
>> On 16 December 2016 at 16:54, Robert Richter <rrichter@cavium.com> wrote:
>>> On ThunderX systems with certain memory configurations we see the
>>> following BUG_ON():
>>>
>>>  kernel BUG at mm/page_alloc.c:1848!
>>>
>>> This happens for some configs with 64k page size enabled. The BUG_ON()
>>> checks if start and end page of a memmap range belongs to the same
>>> zone.
>>>
>>> The BUG_ON() check fails if a memory zone contains NOMAP regions. In
>>> this case the node information of those pages is not initialized. This
>>> causes an inconsistency of the page links with wrong zone and node
>>> information for that pages. NOMAP pages from node 1 still point to the
>>> mem zone from node 0 and have the wrong nid assigned.
>>>
>>> The reason for the mis-configuration is a change in pfn_valid() which
>>> reports pages marked NOMAP as invalid:
>>>
>>>  68709f45385a arm64: only consider memblocks with NOMAP cleared for
>>> linear mapping
>>>
>>> This causes pages marked as nomap being no longer reassigned to the
>>> new zone in memmap_init_zone() by calling __init_single_pfn().
>>>
>>> Fixing this by implementing an arm64 specific early_pfn_valid(). This
>>> causes all pages of sections with memory including NOMAP ranges to be
>>> initialized by __init_single_page() and ensures consistency of page
>>> links to zone, node and section.
>>>
>>
>> I like this solution a lot better than the first one, but I am still
>> somewhat uneasy about having the kernel reason about attributes of
>> pages it should not touch in the first place. But the fact that
>> early_pfn_valid() is only used a single time in the whole kernel does
>> give some confidence that we are not simply moving the problem
>> elsewhere.
>>
>> Given that you are touching arch/arm/ as well as arch/arm64, could you
>> explain why only arm64 needs this treatment? Is it simply because we
>> don't have NUMA support there?
>>
>> Considering that Hisilicon D05 suffered from the same issue, I would
>> like to get some coverage there as well. Hanjun, is this something you
>> can arrange? Thanks
>
> Sure, we will test this patch with LTP MM stress test (which triggers
> the bug on D05), and give the feedback.

a update here, tested on 4.9,

  - Applied Ard's two patches only
  - Applied Robert's patch only

Both of them can work fine on D05 with NUMA enabled, which means
boot ok and LTP MM stress test is passed.

I'm not familiar with memory management, it's up to you guys to make
a decision :)

Thanks
Hanjun

^ permalink raw reply

* [PATCH v2 9/9] ARM: sunxi: Convert pinctrl nodes to generic bindings
From: André Przywara @ 2017-01-06  1:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170105153556.pzec5jjuz7pmvsmn@lukather>

On 05/01/17 15:35, Maxime Ripard wrote:

Hi Maxime,

> On Wed, Jan 04, 2017 at 02:16:23AM +0000, Andr? Przywara wrote:
>> So can I ask that we start taking this seriously and stop doing things
>> which prevent Allwinner boards from being supported properly?
>> Which would first involve dropping this very patch?
> 
> The driver still supports the old binding.

Yes, a _current_ version of the driver supports both bindings, but older
versions *require* the older binding and bail out if various
allwinner,xxx properties are missing - as in those proposed new DTs:

4.9 kernel with sunxi/for-next .dtb:
sun8i-h3-pinctrl 1c20800.pinctrl: missing allwinner,function property in
node uart0
sun8i-h3-pinctrl 1c20800.pinctrl: missing allwinner,function property in
node mmc0
sunxi-mmc: probe of 1c0f000.mmc failed with error -22

>> Having done breakage in the past (with "allwinner,sun7i-a20-mmc", for
>> instance) is no excuse for doing it again.
> 
> I'm not sure which breakage we introduced with a new compatible: the
> old compatible is working just like it used to, and the new one is
> working like we need it to.

But the new compatible is not recognized with older kernels, preventing
people from using the newest DT with older kernels as well.
I proposed to simply work around this by using the old compatible as a
fallback: compatible="sun7i-a20-mmc", "sun5i-a13-mmc";
Unfortunately this suggestion was not followed.
So now we can't boot a 4.8 (or earlier) kernel with a .dtb from a 4.9 or
later tree. Adding the extra string would fix this.

Actually the recommended approach to avoid this situation in the first
place is to always use compatible strings with the SoC-specific name as
the first string, followed by the compatible string the driver works
with. And this should be done upon introducing a new DT to the tree -
even if at this point the driver doesn't deal with the new string.
Unknown strings will just be skipped.
So for instance the H5 DT should read: "sun50i-h5-mmc",
"sun50i-a64-mmc", "sun5i-a13-mmc"; (with the last string possibly being
optional). The current kernel driver will not match the h5 string, so it
falls back to the a64 string and works. If we learn about a neat eMMC
5.1 feature (or any quirk the H5 can benefit from) somewhere in the
future, we can add the code together with this h5 string to the driver
and don't need to change the DT at all.

>> And especially I want to avoid this habit creeping into the arm64
>> world (thinking about the H5 here, which may be impacted by this
>> very patch, for instance).
> 
> And again, if you looked at the entire serie, you would have seen that
> I took this into account.

I saw that and I appreciate that very much, but that post was not about
keeping compatibility with older DTs, but allowing older kernels to run
with the latest DT as well.
Newer DTs from your -next branch do not work with older kernels - that
is what my whole post was about. _Why_ we should care is explained there.

And please don't get me wrong: I am not asking for rewriting and bending
the whole kernel source to make this possible, it's just that we drop
this patch here, for instance, or simply not _change_ compatible names,
but instead add new strings.

Cheers,
Andre.

^ permalink raw reply

* [PATCH v2 10/19] media: Add i.MX media core driver
From: Steve Longerbeam @ 2017-01-06  1:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c04a85dc-4f62-798f-2e37-d7848657730a@mentor.com>


On 01/04/2017 05:33 AM, Vladimir Zapolskiy wrote:
> Hi Steve,
>
> On 01/03/2017 10:57 PM, Steve Longerbeam wrote:
>> Add the core media driver for i.MX SOC.
>>
>> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
>> ---
>>   Documentation/devicetree/bindings/media/imx.txt   | 205 +++++
> v2 was sent before getting Rob's review comments, but still they
> should be addressed in v3.

yes, those changes will be part of v3 as well.

>
> Also I would suggest to separate device tree binding documentation
> change and place it as the first patch in the series, this should
> make the following DTS changes valid.

done.

>
>>   Documentation/media/v4l-drivers/imx.rst           | 430 ++++++++++
>>   drivers/staging/media/Kconfig                     |   2 +
>>   drivers/staging/media/Makefile                    |   1 +
>>   drivers/staging/media/imx/Kconfig                 |   8 +
>>   drivers/staging/media/imx/Makefile                |   6 +
>>   drivers/staging/media/imx/TODO                    |  18 +
>>   drivers/staging/media/imx/imx-media-common.c      | 985 ++++++++++++++++++++++
>>   drivers/staging/media/imx/imx-media-dev.c         | 479 +++++++++++
>>   drivers/staging/media/imx/imx-media-fim.c         | 509 +++++++++++
>>   drivers/staging/media/imx/imx-media-internal-sd.c | 457 ++++++++++
>>   drivers/staging/media/imx/imx-media-of.c          | 291 +++++++
>>   drivers/staging/media/imx/imx-media-of.h          |  25 +
>>   drivers/staging/media/imx/imx-media.h             | 299 +++++++
>>   include/media/imx.h                               |  15 +
>>   include/uapi/Kbuild                               |   1 +
>>   include/uapi/linux/v4l2-controls.h                |   4 +
>>   include/uapi/media/Kbuild                         |   2 +
>>   include/uapi/media/imx.h                          |  30 +
> Probably Greg should ack the UAPI changes, you may consider
> to split them into a separate patch.

I split out the one-line addition to include/uapi/Kbuild with an empty
include/uapi/media/Kbuild into a new patch "UAPI: Add media UAPI Kbuild 
file".
Also added a patch "media: Add userspace header file for i.MX".


>
>
>> +
>> +struct imx_media_subdev *
>> +imx_media_find_subdev_by_sd(struct imx_media_dev *imxmd,
>> +			    struct v4l2_subdev *sd)
>> +{
>> +	struct imx_media_subdev *imxsd;
>> +	int i, ret = -ENODEV;
>> +
>> +	for (i = 0; i < imxmd->num_subdevs; i++) {
>> +		imxsd = &imxmd->subdev[i];
>> +		if (sd == imxsd->sd) {
> This can be simplifed:
>
> ...
>
> 	if (sd == imxsd->sd)
> 		return imxsd;
> }
>
> return ERR_PTR(-ENODEV);

yep, done.

>
>> +struct imx_media_subdev *
>> +imx_media_find_subdev_by_id(struct imx_media_dev *imxmd, u32 grp_id)
>> +{
>> +	struct imx_media_subdev *imxsd;
>> +	int i, ret = -ENODEV;
>> +
>> +	for (i = 0; i < imxmd->num_subdevs; i++) {
>> +		imxsd = &imxmd->subdev[i];
>> +		if (imxsd->sd && imxsd->sd->grp_id == grp_id) {
>> +			ret = 0;
>> +			break;
> This can be simplifed:
>
> ...
>
> 	if (imxsd->sd && imxsd->sd->grp_id == grp_i)
> 		return imxsd;
> }
>
> return ERR_PTR(-ENODEV);

done.

>
>
>> diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
>> new file mode 100644
>> index 0000000..8d22730
>> --- /dev/null
>> +++ b/drivers/staging/media/imx/imx-media-dev.c
>> @@ -0,0 +1,479 @@
>> +/*
>> + * V4L2 Media Controller Driver for Freescale i.MX5/6 SOC
>> + *
>> + * Copyright (c) 2016 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.
>> + */
>> +#include <linux/module.h>
>> +#include <linux/delay.h>
>> +#include <linux/fs.h>
>> +#include <linux/timer.h>
>> +#include <linux/sched.h>
>> +#include <linux/slab.h>
>> +#include <linux/spinlock.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pinctrl/consumer.h>
>> +#include <linux/of_platform.h>
>> +#include <media/v4l2-ioctl.h>
>> +#include <media/v4l2-ctrls.h>
>> +#include <media/v4l2-event.h>
>> +#include <media/v4l2-mc.h>
> Please sort out the list of headers alphabetically.

done.

>> +#include <video/imx-ipu-v3.h>
>> +#include <media/imx.h>
>> +#include "imx-media.h"
>> +#include "imx-media-of.h"
>> +
>> +#define DEVICE_NAME "imx-media"
> I suppose you don't need this macro.

sure why not, removed.

>
> [snip]
>
>> + */
>> +static int imx_media_create_links(struct imx_media_dev *imxmd)
>> +{
>> +	struct imx_media_subdev *local_sd;
>> +	struct imx_media_subdev *remote_sd;
>> +	struct v4l2_subdev *source, *sink;
>> +	struct imx_media_link *link;
>> +	struct imx_media_pad *pad;
>> +	u16 source_pad, sink_pad;
>> +	int num_pads, i, j, k;
>> +	int ret = 0;
>> +
>> +	for (i = 0; i < imxmd->num_subdevs; i++) {
>> +		local_sd = &imxmd->subdev[i];
>> +		num_pads = local_sd->num_sink_pads + local_sd->num_src_pads;
>> +
>> +		for (j = 0; j < num_pads; j++) {
>> +			pad = &local_sd->pad[j];
>> +
>> +			for (k = 0; k < pad->num_links; k++) {
>> +				link = &pad->link[k];
>> +
>>   <snip>
> Indentation depth is quite terrific.

yes, it needs to iterate by subdev, pads in the subdev, then links
in the pad. But I moved the code under the innermost loop into a
function imx_media_create_link(), which creates a single media
link. So it's not so much an eye-sore now.

>
>
>> +static struct platform_driver imx_media_pdrv = {
>> +	.probe		= imx_media_probe,
>> +	.remove		= imx_media_remove,
>> +	.driver		= {
>> +		.name	= DEVICE_NAME,
>> +		.owner	= THIS_MODULE,
> Setting of .owner is not needed nowadays IIRC.

a quick look at struct device_driver definition didn't mention that
.owner member is deprecated or not needed, so for now I'll leave
it in place. We can revisit that later.

>
>> +		.of_match_table	= imx_media_dt_ids,
>> +	},
>> +};
>> +
>> +module_platform_driver(imx_media_pdrv);
>> +
>> +MODULE_DESCRIPTION("i.MX5/6 v4l2 media controller driver");
>> +MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/staging/media/imx/imx-media-fim.c b/drivers/staging/media/imx/imx-media-fim.c
>> new file mode 100644
>> index 0000000..52bfa8d
>> --- /dev/null
>> +++ b/drivers/staging/media/imx/imx-media-fim.c
>> @@ -0,0 +1,509 @@
>> +/*
>> + * Frame Interval Monitor.
>> + *
>> + * Copyright (c) 2016 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.
>> + */
>> +#include <linux/module.h>
>> +#include <linux/delay.h>
>> +#include <linux/slab.h>
>> +#include <linux/platform_device.h>
>> +#ifdef CONFIG_IMX_GPT_ICAP
>> +#include <linux/mxc_icap.h>
>> +#endif
> This looks clumsy. Include it unconditionally, if needed
> do #ifdef's inside the header file.

The i.MX input capture patch will come later. These are just
placeholders until then, the config name could even change.
For now I just removed the above conditional include.

>
>> +#include <media/v4l2-subdev.h>
>> +#include <media/v4l2-of.h>
>> +#include <media/v4l2-ctrls.h>
> Please sort out the list alphabetically.

done.

>> +	if (IS_ENABLED(CONFIG_IMX_GPT_ICAP)) {
>> +		ret = of_property_read_u32_array(fim_np,
>> +						 "input-capture-channel",
>> +						 icap, 2);
>> +		if (!ret) {
>> +			fim->icap_channel = icap[0];
>> +			fim->icap_flags = icap[1];
>> +		}
> Should you return error otherwise?

nope, it's an optional property.

>
>> diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
>> new file mode 100644
>> index 0000000..018d05a
>> --- /dev/null
>> +++ b/drivers/staging/media/imx/imx-media-of.c
>> @@ -0,0 +1,291 @@
>> +/*
>> + * Media driver for Freescale i.MX5/6 SOC
>> + *
>> + * Open Firmware parsing.
>> + *
>> + * Copyright (c) 2016 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.
>> + */
>> +#include <linux/of_platform.h>
>> +#include <media/v4l2-device.h>
>> +#include <media/videobuf2-dma-contig.h>
>> +#include <media/v4l2-subdev.h>
>> +#include <media/v4l2-of.h>
>> +#include <media/v4l2-ctrls.h>
> Please sort out the list alphabetically.

done.

>>
>> +static int of_get_port_count(const struct device_node *np)
>> +{
>> +	struct device_node *child;
>> +	int num = 0;
>> +
>> +	/* if this node is itself a port, return 1 */
>> +	if (of_node_cmp(np->name, "port") == 0)
>> +		return 1;
>> +
>> +	for_each_child_of_node(np, child) {
>> +		if (of_node_cmp(child->name, "port") == 0)
>> +			num++;
>> +	}
> Unneeded bracers.

fixed.

>
>> +static struct imx_media_subdev *
>> +of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
>> +		bool is_csi_port)
>> +{
>> +	struct imx_media_subdev *imxsd;
>> +	int i, num_pads, ret;
>> +
>> +	if (!of_device_is_available(sd_np)) {
>> +		dev_dbg(imxmd->dev, "%s: %s not enabled\n", __func__,
>> +			sd_np->name);
>> +		return NULL;
>> +	}
>> +
>> +	/* register this subdev with async notifier */
>> +	imxsd = imx_media_add_async_subdev(imxmd, sd_np, NULL);
>> +	if (!imxsd)
>> +		return NULL;
>> +	if (IS_ERR(imxsd))
>> +		return imxsd;
> if (IS_ERR_OR_NULL(imxsd))
> 	return imxsd;

yep, done.

>> +
>> +	if (imxsd->num_sink_pads == 0) {
>> +		/* this might be a sensor */
>> +		of_parse_sensor(imxmd, imxsd, sd_np);
>> +	}
> Unneeded bracers.

ok removed.

>
>> +
>> +	for (i = 0; i < num_pads; i++) {
>> +		struct device_node *epnode = NULL, *port, *remote_np;
>> +		struct imx_media_subdev *remote_imxsd;
>> +		struct imx_media_pad *pad;
>> +		int remote_pad;
> Too deep indentation, may be move the cycle body into a separate function?

in this case I prefer not to, of_parse_subdev() is called recursively, and I
think it's bad form to hide that fact by moving the recursive call into a
separate function. The indentation is not that deep, only two loops deep.


>
>> +
>> +		/* init this pad */
>> +		pad = &imxsd->pad[i];
>> +		pad->pad.flags = (i < imxsd->num_sink_pads) ?
>> +			MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
>> +
>> +		if (is_csi_port)
>> +			port = (i < imxsd->num_sink_pads) ? sd_np : NULL;
>> +		else
>> +			port = of_graph_get_port_by_id(sd_np, i);
>> +		if (!port)
>> +			continue;
>> +
>> +		while ((epnode = of_get_next_child(port, epnode))) {
> Please reuse for_each_child_of_node() here.

done.

>
>> +			of_get_remote_pad(epnode, &remote_np, &remote_pad);
>> +			if (!remote_np) {
>> +				of_node_put(epnode);
> Please remove of_node_put() here, of_get_next_child() does it.

oops, good catch, fixed.

>
>> +				continue;
>> +			}
>> +
>> +			ret = of_add_pad_link(imxmd, pad, sd_np, remote_np,
>> +					      i, remote_pad);
>> +			if (ret) {
>> +				imxsd = ERR_PTR(ret);
>> +				break;
>> +			}
>> +
>> +			if (i < imxsd->num_sink_pads) {
>> +				/* follow sink endpoints upstream */
>> +				remote_imxsd = of_parse_subdev(imxmd,
>> +							       remote_np,
>> +							       false);
>> +				if (IS_ERR(remote_imxsd)) {
>> +					imxsd = remote_imxsd;
>> +					break;
>> +				}
>> +			}
>> +
>> +			of_node_put(remote_np);
>> +			of_node_put(epnode);

also removed this put of epnode.

>>
>> +
>> +int imx_media_of_parse(struct imx_media_dev *imxmd,
>> +		       struct imx_media_subdev *(*csi)[4],
>> +		       struct device_node *np)
>> +{
>> +	struct device_node *csi_np;
>> +	struct imx_media_subdev *lcsi;
> Please swap two lines above to get the reverse christmas tree ordering.

done.

>
>> +	u32 ipu_id, csi_id;
>> +	int i, ret;
>> +
>> +	for (i = 0; ; i++) {
>> +		csi_np = of_parse_phandle(np, "ports", i);
>> +		if (!csi_np)
>> +			break;
>> +
>> +		lcsi = of_parse_subdev(imxmd, csi_np, true);
>> +		if (IS_ERR(lcsi)) {
>> +			ret = PTR_ERR(lcsi);
>> +			goto err_put;
>> +		}
>> +
>> +		of_property_read_u32(csi_np, "reg", &csi_id);
> Not sure if it is safe enough to ignore return value and potentially
> left csi_id uninitialized.

The CSI nodes are port nodes, and the reg property is required,
so I added a check and error return here.

>
>> +		ipu_id = of_alias_get_id(csi_np->parent, "ipu");
>> +
>> +		if (ipu_id > 1 || csi_id > 1) {
>> +			dev_err(imxmd->dev, "%s: invalid ipu/csi id (%u/%u)\n",
>> +				__func__, ipu_id, csi_id);
>> +			ret = -EINVAL;
>> +			goto err_put;
>> +		}
>> +
>> +		of_node_put(csi_np);
> You can put the node right after of_alias_get_id() call, then in case
> of error return right from the if block and remove the goto label.

done.

>
>> +
>> +		(*csi)[ipu_id * 2 + csi_id] = lcsi;
>> +	}
>> +
>> +	return 0;
>> +err_put:
>> +	of_node_put(csi_np);
>> +	return ret;
>> +}
>> diff --git a/drivers/staging/media/imx/imx-media-of.h b/drivers/staging/media/imx/imx-media-of.h
>> new file mode 100644
>> index 0000000..0c61b05
>> --- /dev/null
>> +++ b/drivers/staging/media/imx/imx-media-of.h
>> @@ -0,0 +1,25 @@
>> +/*
>> + * V4L2 Media Controller Driver for Freescale i.MX5/6 SOC
>> + *
>> + * Open Firmware parsing.
>> + *
>> + * Copyright (c) 2016 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 _IMX_MEDIA_OF_H
>> +#define _IMX_MEDIA_OF_H
>> +
> I do believe you should include some headers or add declarations
> of "struct imx_media_dev", "struct imx_media_subdev", "struct device_node".

actually imx-media-of.h isn't really needed, I just moved those prototypes
into imx-media.h and removed imx-media-of.h.

>> diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
>> new file mode 100644
>> index 0000000..6a018a9
>> --- /dev/null
>> +++ b/drivers/staging/media/imx/imx-media.h
>> @@ -0,0 +1,299 @@
>> +/*
>> + * V4L2 Media Controller Driver for Freescale i.MX5/6 SOC
>> + *
>> + * Copyright (c) 2016 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 _IMX_MEDIA_H
>> +#define _IMX_MEDIA_H
> Please insert here an empty line to improve readability.

done.

>
>> +#include <media/v4l2-device.h>
>> +#include <media/v4l2-subdev.h>
>> +#include <media/v4l2-ctrls.h>
>> +#include <media/v4l2-of.h>
> Please sort out the list alphabetically.

done.

Steve

^ permalink raw reply

* [PATCH v2,7/9] irqchip/ls-scfg-msi: add LS1046a MSI support
From: M.H. Lian @ 2017-01-06  1:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7cd3cc33-741a-6ab1-6444-17a626991d33@arm.com>

Hi Marc,

Thanks for your review.
Please see my comments inline.

Thanks,
Minghuan

> -----Original Message-----
> From: Marc Zyngier [mailto:marc.zyngier at arm.com]
> Sent: Thursday, January 05, 2017 11:19 PM
> To: M.H. Lian <minghuan.lian@nxp.com>; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> devicetree at vger.kernel.org
> Cc: Rob Herring <robh@kernel.org>; Jason Cooper
> <jason@lakedaemon.net>; Roy Zang <roy.zang@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; Stuart Yoder <stuart.yoder@nxp.com>; Leo Li
> <leoyang.li@nxp.com>; Scott Wood <scott.wood@nxp.com>
> Subject: Re: [PATCH v2,7/9] irqchip/ls-scfg-msi: add LS1046a MSI support
> 
> On 05/01/17 08:10, Minghuan Lian wrote:
> > LS1046a includes 4 MSIRs, each MSIR is assigned a dedicate GIC SPI
> > interrupt and provides 32 MSI interrupts. Compared to previous MSI,
> > LS1046a's IBS(interrupt bit select) shift is changed to 2 and total
> > MSI interrupt number is changed to 128.
> >
> > The patch adds structure 'ls_scfg_msir' to describe MSIR setting and
> > 'ibs_shift' to store the different value between the SoCs.
> >
> > Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
> > ---
> > v2-v1:
> > - MSI dts node change has been merged into the patch 6/9
> >
> >  drivers/irqchip/irq-ls-scfg-msi.c | 161
> > +++++++++++++++++++++++++++++---------
> >  1 file changed, 126 insertions(+), 35 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-ls-scfg-msi.c
> > b/drivers/irqchip/irq-ls-scfg-msi.c
> > index cef67cc..67547bd 100644
> > --- a/drivers/irqchip/irq-ls-scfg-msi.c
> > +++ b/drivers/irqchip/irq-ls-scfg-msi.c
> > @@ -17,13 +17,24 @@
> >  #include <linux/irq.h>
> >  #include <linux/irqchip/chained_irq.h>  #include <linux/irqdomain.h>
> > +#include <linux/of_irq.h>
> >  #include <linux/of_pci.h>
> >  #include <linux/of_platform.h>
> >  #include <linux/spinlock.h>
> >
> > -#define MSI_MAX_IRQS	32
> > -#define MSI_IBS_SHIFT	3
> > -#define MSIR		4
> > +#define MSI_IRQS_PER_MSIR	32
> > +#define MSI_MSIR_OFFSET		4
> > +
> > +struct ls_scfg_msi_cfg {
> > +	u32 ibs_shift; /* Shift of interrupt bit select */ };
> > +
> > +struct ls_scfg_msir {
> > +	struct ls_scfg_msi *msi_data;
> > +	unsigned int index;
> > +	unsigned int gic_irq;
> > +	void __iomem *reg;
> > +};
> >
> >  struct ls_scfg_msi {
> >  	spinlock_t		lock;
> > @@ -32,8 +43,11 @@ struct ls_scfg_msi {
> >  	struct irq_domain	*msi_domain;
> >  	void __iomem		*regs;
> >  	phys_addr_t		msiir_addr;
> > -	int			irq;
> > -	DECLARE_BITMAP(used, MSI_MAX_IRQS);
> > +	struct ls_scfg_msi_cfg	*cfg;
> > +	u32			msir_num;
> > +	struct ls_scfg_msir	*msir;
> > +	u32			irqs_num;
> > +	unsigned long		*used;
> >  };
> >
> >  static struct irq_chip ls_scfg_msi_irq_chip = { @@ -55,7 +69,7 @@
> > static void ls_scfg_msi_compose_msg(struct irq_data *data, struct
> > msi_msg *msg)
> >
> >  	msg->address_hi = upper_32_bits(msi_data->msiir_addr);
> >  	msg->address_lo = lower_32_bits(msi_data->msiir_addr);
> > -	msg->data = data->hwirq << MSI_IBS_SHIFT;
> > +	msg->data = data->hwirq;
> >  }
> >
> >  static int ls_scfg_msi_set_affinity(struct irq_data *irq_data, @@
> > -81,8 +95,8 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain
> *domain,
> >  	WARN_ON(nr_irqs != 1);
> >
> >  	spin_lock(&msi_data->lock);
> > -	pos = find_first_zero_bit(msi_data->used, MSI_MAX_IRQS);
> > -	if (pos < MSI_MAX_IRQS)
> > +	pos = find_first_zero_bit(msi_data->used, msi_data->irqs_num);
> > +	if (pos < msi_data->irqs_num)
> >  		__set_bit(pos, msi_data->used);
> >  	else
> >  		err = -ENOSPC;
> > @@ -106,7 +120,7 @@ static void ls_scfg_msi_domain_irq_free(struct
> irq_domain *domain,
> >  	int pos;
> >
> >  	pos = d->hwirq;
> > -	if (pos < 0 || pos >= MSI_MAX_IRQS) {
> > +	if (pos < 0 || pos >= msi_data->irqs_num) {
> >  		pr_err("failed to teardown msi. Invalid hwirq %d\n", pos);
> >  		return;
> >  	}
> > @@ -123,15 +137,17 @@ static void ls_scfg_msi_domain_irq_free(struct
> > irq_domain *domain,
> >
> >  static void ls_scfg_msi_irq_handler(struct irq_desc *desc)  {
> > -	struct ls_scfg_msi *msi_data = irq_desc_get_handler_data(desc);
> > +	struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc);
> > +	struct ls_scfg_msi *msi_data = msir->msi_data;
> >  	unsigned long val;
> > -	int pos, virq;
> > +	int pos, virq, hwirq;
> >
> >  	chained_irq_enter(irq_desc_get_chip(desc), desc);
> >
> > -	val = ioread32be(msi_data->regs + MSIR);
> > -	for_each_set_bit(pos, &val, MSI_MAX_IRQS) {
> > -		virq = irq_find_mapping(msi_data->parent, (31 - pos));
> > +	val = ioread32be(msir->reg);
> > +	for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) {
> > +		hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir-
> >index;
> > +		virq = irq_find_mapping(msi_data->parent, hwirq);
> >  		if (virq)
> >  			generic_handle_irq(virq);
> >  	}
> > @@ -143,7 +159,7 @@ static int ls_scfg_msi_domains_init(struct
> > ls_scfg_msi *msi_data)  {
> >  	/* Initialize MSI domain parent */
> >  	msi_data->parent = irq_domain_add_linear(NULL,
> > -						 MSI_MAX_IRQS,
> > +						 msi_data->irqs_num,
> >  						 &ls_scfg_msi_domain_ops,
> >  						 msi_data);
> >  	if (!msi_data->parent) {
> > @@ -164,16 +180,83 @@ static int ls_scfg_msi_domains_init(struct
> ls_scfg_msi *msi_data)
> >  	return 0;
> >  }
> >
> > +static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int
> > +index) {
> > +	struct ls_scfg_msir *msir;
> > +	int virq, i, hwirq;
> > +
> > +	virq = platform_get_irq(msi_data->pdev, index);
> > +	if (virq <= 0)
> > +		return -ENODEV;
> > +
> > +	msir = &msi_data->msir[index];
> > +	msir->index = index;
> > +	msir->msi_data = msi_data;
> > +	msir->gic_irq = virq;
> > +	msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index;
> > +
> > +	irq_set_chained_handler_and_data(msir->gic_irq,
> > +					 ls_scfg_msi_irq_handler,
> > +					 msir);
> > +
> > +	/* Release the hwirqs corresponding to this MSIR */
> > +	for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
> > +		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
> > +		bitmap_clear(msi_data->used, hwirq, 1);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir) {
> > +	struct ls_scfg_msi *msi_data = msir->msi_data;
> > +	int i, hwirq;
> > +
> > +	if (msir->gic_irq > 0)
> > +		irq_set_chained_handler_and_data(msir->gic_irq, NULL,
> NULL);
> > +
> > +	for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
> > +		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
> > +		bitmap_set(msi_data->used, hwirq, 1);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static struct ls_scfg_msi_cfg ls1021_msi_cfg = {
> > +	.ibs_shift = 3,
> > +};
> > +
> > +static struct ls_scfg_msi_cfg ls1046_msi_cfg = {
> > +	.ibs_shift = 2,
> > +};
> > +
> > +static const struct of_device_id ls_scfg_msi_id[] = {
> > +	{ .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg },
> > +	{ .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg },
> > +	{ .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg },
> 
> So after 3 patches adding compatibility between the fsl,1s10 and
> fsl,ls10 names, you discard them? How does it work again with the old DTs?
> 
[Minghuan Lian]  ok, I will store the old compatible.
This typo makes me very uncomfortable  :(

> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, ls_scfg_msi_id);
> > +
> >  static int ls_scfg_msi_probe(struct platform_device *pdev)  {
> > +	const struct of_device_id *match;
> >  	struct ls_scfg_msi *msi_data;
> >  	struct resource *res;
> > -	int ret;
> > +	int i, ret;
> > +
> > +	match = of_match_device(ls_scfg_msi_id, &pdev->dev);
> > +	if (!match)
> > +		return -ENODEV;
> >
> >  	msi_data = devm_kzalloc(&pdev->dev, sizeof(*msi_data),
> GFP_KERNEL);
> >  	if (!msi_data)
> >  		return -ENOMEM;
> >
> > +	msi_data->cfg = (struct ls_scfg_msi_cfg *) match->data;
> > +
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >  	msi_data->regs = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(msi_data->regs)) {
> > @@ -182,23 +265,37 @@ static int ls_scfg_msi_probe(struct
> platform_device *pdev)
> >  	}
> >  	msi_data->msiir_addr = res->start;
> >
> > -	msi_data->irq = platform_get_irq(pdev, 0);
> > -	if (msi_data->irq <= 0) {
> > -		dev_err(&pdev->dev, "failed to get MSI irq\n");
> > -		return -ENODEV;
> > -	}
> > -
> >  	msi_data->pdev = pdev;
> >  	spin_lock_init(&msi_data->lock);
> >
> > +	msi_data->irqs_num = MSI_IRQS_PER_MSIR *
> > +			     (1 << msi_data->cfg->ibs_shift);
> > +	msi_data->used = devm_kcalloc(&pdev->dev,
> > +				    BITS_TO_LONGS(msi_data->irqs_num),
> > +				    sizeof(*msi_data->used),
> > +				    GFP_KERNEL);
> > +	if (!msi_data->used)
> > +		return -ENOMEM;
> > +	/*
> > +	 * Reserve all the hwirqs
> > +	 * The available hwirqs will be released in ls1_msi_setup_hwirq()
> > +	 */
> > +	bitmap_set(msi_data->used, 0, msi_data->irqs_num);
> > +
> > +	msi_data->msir_num = of_irq_count(pdev->dev.of_node);
> > +	msi_data->msir = devm_kcalloc(&pdev->dev, msi_data->msir_num,
> > +				      sizeof(*msi_data->msir),
> > +				      GFP_KERNEL);
> > +	if (!msi_data->msir)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < msi_data->msir_num; i++)
> > +		ls_scfg_msi_setup_hwirq(msi_data, i);
> > +
> >  	ret = ls_scfg_msi_domains_init(msi_data);
> >  	if (ret)
> >  		return ret;
> >
> > -	irq_set_chained_handler_and_data(msi_data->irq,
> > -					 ls_scfg_msi_irq_handler,
> > -					 msi_data);
> > -
> >  	platform_set_drvdata(pdev, msi_data);
> >
> >  	return 0;
> > @@ -207,8 +304,10 @@ static int ls_scfg_msi_probe(struct
> > platform_device *pdev)  static int ls_scfg_msi_remove(struct
> > platform_device *pdev)  {
> >  	struct ls_scfg_msi *msi_data = platform_get_drvdata(pdev);
> > +	int i;
> >
> > -	irq_set_chained_handler_and_data(msi_data->irq, NULL, NULL);
> > +	for (i = 0; i < msi_data->msir_num; i++)
> > +		ls_scfg_msi_teardown_hwirq(&msi_data->msir[i]);
> >
> >  	irq_domain_remove(msi_data->msi_domain);
> >  	irq_domain_remove(msi_data->parent);
> > @@ -218,14 +317,6 @@ static int ls_scfg_msi_remove(struct
> platform_device *pdev)
> >  	return 0;
> >  }
> >
> > -static const struct of_device_id ls_scfg_msi_id[] = {
> > -	{ .compatible = "fsl,1s1021a-msi", }, /* a typo */
> > -	{ .compatible = "fsl,1s1043a-msi", }, /* a typo */
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ^
> these entries definitely need to be restored.
> 
> Also, please make sure you have a cover letter at the beginning of the series.
> I flag series to review by flagging the cover letter, and I suspect many of us
> are doing something similar. Not doing so is likely to leave your series
> unreviewed...
[Minghuan Lian]  I see. I will add cover letter for this series. And I will
do this for all series of patches.

> 
> Thanks,
> 
> 	M.
> --
> Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH v2 3/4] ARM64: dts: exynos5433: use macros for pinctrl configuration on Exynos5433
From: Andi Shyti @ 2017-01-06  2:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170105200807.54j2ebve6kqd5bob@kozik-lap>

Hi Krzysztof,

> Andi,
> Please fix missing Signed-off-by and resend with Linus' tags for #1 and
> #2 and with other accumulated tags.

patch #1 has already been merged in mainline:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=1259feddd0f83649d5c48d730c140b4f7f3fa288

and patch #2 is in LinusW's -next branch.

does it still make sense to send them again? If you want I can
send again patch 3 and 4 as independent patches with Chanwoo's
review (the only tags).

Thanks,
Andi

^ permalink raw reply

* [PATCH v6 3/3] arm: dts: mt2701: Add node for Mediatek JPEG Decoder
From: Rick Chang @ 2017-01-06  2:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479894203.8964.29.camel@mtksdaap41>

Hi Hans,

The dependence on [1] has been merged in 4.10, but [2] has not.Do you have 
any idea about this patch series? Should we wait for [2] or we could merge
the source code and dt-binding first?

Best Regards,
Rick

On Wed, 2016-11-23 at 17:43 +0800, Rick Chang wrote:
> On Wed, 2016-11-23 at 09:54 +0800, Rick Chang wrote:
> > Hi Hans,
> > 
> > On Tue, 2016-11-22 at 13:43 +0100, Hans Verkuil wrote:
> > > On 22/11/16 04:21, Rick Chang wrote:
> > > > Hi Hans,
> > > >
> > > > On Mon, 2016-11-21 at 15:51 +0100, Hans Verkuil wrote:
> > > >> On 17/11/16 04:38, Rick Chang wrote:
> > > >>> Signed-off-by: Rick Chang <rick.chang@mediatek.com>
> > > >>> Signed-off-by: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
> > > >>> ---
> > > >>> This patch depends on:
> > > >>>   CCF "Add clock support for Mediatek MT2701"[1]
> > > >>>   iommu and smi "Add the dtsi node of iommu and smi for mt2701"[2]
> > > >>>
> > > >>> [1] http://lists.infradead.org/pipermail/linux-mediatek/2016-October/007271.html
> > > >>> [2] https://patchwork.kernel.org/patch/9164013/
> > > >>
> > > >> I assume that 1 & 2 will appear in 4.10? So this patch needs to go in
> > > >> after the
> > > >> other two are merged in 4.10?
> > > >>
> > > >> Regards,
> > > >>
> > > >> 	Hans
> > > >
> > > > [1] will appear in 4.10, but [2] will appear latter than 4.10.So this
> > > > patch needs to go in after [1] & [2] will be merged in 4.11.
> > > 
> > > So what should I do? Merge the driver for 4.11 and wait with this patch
> > > until [2] is merged in 4.11? Does that sound reasonable?
> > > 
> > > Regards,
> > > 
> > > 	Hans
> > 
> > What do you think about this? You merge the driver first and I send this
> > patch again after [1] & [2] is merged.
> 
> BTW, to prevent merging conflict, the dtsi should be merged by mediatek
> SoC maintainer, Matthias.I think we can only take care on the driver
> part at this moment.
> 

^ permalink raw reply

* [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
From: Sebastian Reichel @ 2017-01-06  2:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAAEAJfBeu7Z_JeM55Tyj4a2ZOxNWhq7qoPDwFyftoO8sCumVQw@mail.gmail.com>

Hi,

On Thu, Jan 05, 2017 at 02:34:48PM -0300, Ezequiel Garcia wrote:
> > +static int axp20x_power_probe(struct platform_device *pdev)
> > +{
> > +       struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> > +       struct axp20x_batt_ps *axp20x_batt;
> > +       struct power_supply_config psy_cfg = {};
> > +
> 
> To be consistent with the AC power supply and USB power supply,
> you might want to call of_device_is_available() here.
> Otherwise, the device probes even if "disabled" in the DTS.

I would expect that check in the mfd code. Probe should not be
called at all if the sub-device is disabled.

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170106/306245c1/attachment.sig>

^ permalink raw reply

* [RESEND] spi: davinci: Allow device tree devices to use DMA
From: David Lechner @ 2017-01-06  3:26 UTC (permalink / raw)
  To: linux-arm-kernel

This allows SPI devices specified in a device tree to use DMA when the
master controller.

Since device tree is supposed to only describe the hardware, adding such
a configuration option to device tree would not be acceptable. So, this
is the best we can do for now to get SPI devices working with DMA.

Unfortunately, this excludes the possibility of using one SPI device with
DMA and one without on the same master.

Signed-off-by: David Lechner <david@lechnology.com>
---

When I originally submitted this patch, there was some discussion as to whether
dspi->dma_rx should be changed to return an error rather than being null.

However, I prefer it the way it is and don't see a compelling reason to change
it.

 drivers/spi/spi-davinci.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index d36c11b..c6cf73a 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -388,6 +388,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
 static int davinci_spi_of_setup(struct spi_device *spi)
 {
 	struct davinci_spi_config *spicfg = spi->controller_data;
+	struct davinci_spi *dspi = spi_master_get_devdata(spi->master);
 	struct device_node *np = spi->dev.of_node;
 	u32 prop;
 
@@ -400,6 +401,9 @@ static int davinci_spi_of_setup(struct spi_device *spi)
 		if (!of_property_read_u32(np, "ti,spi-wdelay", &prop))
 			spicfg->wdelay = (u8)prop;
 		spi->controller_data = spicfg;
+		/* Use DMA for device if master supports it */
+		if (dspi->dma_rx)
+			spicfg->io_type = SPI_IO_TYPE_DMA;
 	}
 
 	return 0;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v29 0/9] arm64: add kdump support
From: Pratyush Anand @ 2017-01-06  3:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161228043347.27358-1-takahiro.akashi@linaro.org>



On Wednesday 28 December 2016 10:03 AM, AKASHI Takahiro wrote:
> This patch series adds kdump support on arm64.
>
> To load a crash-dump kernel to the systems, a series of patches to
> kexec-tools[1] are also needed. Please use the latest one, v4 [2].
> For your convinience, you can pick them up from:
>    https://git.linaro.org/people/takahiro.akashi/linux-aarch64.git arm64/kdump
>    https://git.linaro.org/people/takahiro.akashi/kexec-tools.git arm64/kdump
>
> To examine vmcore (/proc/vmcore) on a crash-dump kernel, you can use
>   - crash utility (v7.1.7 or later) [3]
>     (As of today, the very latest tree cannot handle a core image correctly
>      due to the commit 7fd8329ba502 ("taint/module: Clean up global and module
>      taint flags handling")
>
>
> The previous version, v27, was also:
> Tested-by: Pratyush Anand <panand@redhat.com> (mustang and seattle)

You have my "Tested-by" for this version as well :-). Patches works 
great after applying them over v4.10-rc2.

I used crash-utility from below where there are few patches queued for 
crash-7.1.8
https://github.com/crash-utility/crash

~Pratyush

^ permalink raw reply

* [PATCH V2 0/2] kexec-tools: arm64: Enable D-cache in purgatory
From: Pratyush Anand @ 2017-01-06  3:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1482129830.git.panand@redhat.com>

Hi James and All,

Any feedback/review comment on it?

~Pratyush

On Monday 19 December 2016 12:43 PM, Pratyush Anand wrote:
> It takes more that 2 minutes to verify SHA in purgatory when vmlinuz image
> is around 13MB and initramfs is around 30MB. It takes more than 20 second
> even when we have -O2 optimization enabled. However, if dcache is enabled
> during purgatory execution then, it takes just a second in SHA
> verification.
>
> Therefore, these patches adds support for dcache enabling facility during
> purgatory execution.
>
> Although I have simplified the logic a bit now, however I understand that
> there are reservations for introducing this complexity for gaining few
> seconding of execution time during kexec or crash reboot.  But, I believe
> if d-cache enabling code is stable enough then there should not be any
> hindrances to accept it. So, please give it a try with your platform and
> let me know if you see any issue or it does not work. I am still open to
> improve it further if needed.
>
> Changes since V1:
> 	- Moved page table creation logic from purgatory to kexec code.
> 	- Only 4K page table is supported, with 48 bit VA and 2M block size
> 	- if platform supports a 4K page size, then D-cache is always
> 	  enabled now.
>
> Pratyush Anand (2):
>   kexec: arm64: create identity page table to be used in purgatory
>   arm64: enable d-cache support during purgatory sha verification
>
>  kexec/arch/arm64/kexec-arm64.c         | 152 ++++++++++++++++++
>  purgatory/arch/arm64/Makefile          |   1 +
>  purgatory/arch/arm64/cache.S           | 281 +++++++++++++++++++++++++++++++++
>  purgatory/arch/arm64/purgatory-arm64.c |   5 +
>  4 files changed, 439 insertions(+)
>  create mode 100644 purgatory/arch/arm64/cache.S
>

^ permalink raw reply

* [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
From: Chen-Yu Tsai @ 2017-01-06  3:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170102163723.7939-18-quentin.schulz@free-electrons.com>

 Hi,

On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> The X-Powers AXP20X and AXP22X PMICs can have a battery as power supply.
>
> This patch adds the battery power supply driver to get various data from
> the PMIC, such as the battery status (charging, discharging, full,
> dead), current max limit, current current, battery capacity (in
> percentage), voltage max and min limits, current voltage and battery
> capacity (in Ah).
>
> This battery driver uses the AXP20X/AXP22X ADC driver as PMIC data
> provider.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
>  drivers/power/supply/Kconfig          |  12 +
>  drivers/power/supply/Makefile         |   1 +
>  drivers/power/supply/axp20x_battery.c | 458 ++++++++++++++++++++++++++++++++++
>  3 files changed, 471 insertions(+)
>  create mode 100644 drivers/power/supply/axp20x_battery.c
>
> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> index c552b4b..48619de 100644
> --- a/drivers/power/supply/Kconfig
> +++ b/drivers/power/supply/Kconfig
> @@ -226,6 +226,18 @@ config CHARGER_AXP20X
>           This driver can also be built as a module. If so, the module will be
>           called axp20x_ac_power.
>
> +config BATTERY_AXP20X
> +       tristate "X-Powers AXP20X battery driver"
> +       depends on MFD_AXP20X
> +       depends on AXP20X_ADC
> +       depends on IIO
> +       help
> +         Say Y here to enable support for X-Powers AXP20X PMICs' battery power
> +         supply.
> +
> +         This driver can also be built as a module. If so, the module will be
> +         called axp20x_battery.
> +
>  config AXP288_CHARGER
>         tristate "X-Powers AXP288 Charger"
>         depends on MFD_AXP20X && EXTCON_AXP288
> diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
> index 7d22417..5a217b2 100644
> --- a/drivers/power/supply/Makefile
> +++ b/drivers/power/supply/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_TEST_POWER)      += test_power.o
>
>  obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
>  obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o
> +obj-$(CONFIG_BATTERY_AXP20X)   += axp20x_battery.o
>  obj-$(CONFIG_CHARGER_AXP20X)   += axp20x_ac_power.o
>  obj-$(CONFIG_BATTERY_DS2760)   += ds2760_battery.o
>  obj-$(CONFIG_BATTERY_DS2780)   += ds2780_battery.o
> diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
> new file mode 100644
> index 0000000..e1d7b5f
> --- /dev/null
> +++ b/drivers/power/supply/axp20x_battery.c
> @@ -0,0 +1,458 @@
> +/*
> + * Battery power supply driver for X-Powers AXP20X and AXP22X PMICs
> + *
> + * Copyright 2016 Free Electrons NextThing Co.
> + *     Quentin Schulz <quentin.schulz@free-electrons.com>
> + *
> + * This driver is based on a previous upstreaming attempt by:
> + *     Bruno Pr?mont <bonbons@linux-vserver.org>
> + *
> + * This file is subject to the terms and conditions of the GNU General
> + * Public License. See the file "COPYING" in the main directory of this
> + * archive for more details.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/power_supply.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/time.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/consumer.h>
> +#include <linux/mfd/axp20x.h>
> +
> +#define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2)
> +
> +#define AXP20X_PWR_OP_BATT_PRESENT     BIT(5)
> +#define AXP20X_PWR_OP_BATT_ACTIVATED   BIT(3)
> +
> +#define AXP209_FG_PERCENT              GENMASK(6, 0)
> +#define AXP22X_FG_VALID                        BIT(7)
> +
> +#define AXP20X_CHRG_CTRL1_TGT_VOLT     GENMASK(6, 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_1V     (0 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_15V    BIT(5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_2V     (2 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_36V    (3 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_CURR     GENMASK(3, 0)
> +
> +#define AXP22X_CHRG_CTRL1_TGT_4_22V    BIT(5)
> +#define AXP22X_CHRG_CTRL1_TGT_4_24V    (3 << 5)
> +
> +#define AXP20X_V_OFF_MASK              GENMASK(2, 0)
> +
> +struct axp20x_batt_ps {
> +       struct regmap *regmap;
> +       struct power_supply *batt;
> +       struct axp20x_dev *axp20x;
> +       struct iio_channel *batt_chrg_i;
> +       struct iio_channel *batt_dischrg_i;
> +       struct iio_channel *batt_v;
> +       u8 axp_id;
> +};
> +
> +static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +                                         int *val)
> +{
> +       int ret, reg;
> +
> +       ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
> +       if (ret)
> +               return ret;
> +
> +       switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
> +       case AXP20X_CHRG_CTRL1_TGT_4_1V:
> +               *val = 4100000;
> +               break;
> +       case AXP20X_CHRG_CTRL1_TGT_4_15V:
> +               *val = 4150000;
> +               break;
> +       case AXP20X_CHRG_CTRL1_TGT_4_2V:
> +               *val = 4200000;
> +               break;
> +       case AXP20X_CHRG_CTRL1_TGT_4_36V:
> +               *val = 4360000;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +                                         int *val)
> +{
> +       int ret, reg;
> +
> +       ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
> +       if (ret)
> +               return ret;
> +
> +       switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
> +       case AXP20X_CHRG_CTRL1_TGT_4_1V:
> +               *val = 4100000;
> +               break;
> +       case AXP20X_CHRG_CTRL1_TGT_4_2V:
> +               *val = 4200000;
> +               break;
> +       case AXP22X_CHRG_CTRL1_TGT_4_22V:
> +               *val = 4220000;
> +               break;
> +       case AXP22X_CHRG_CTRL1_TGT_4_24V:
> +               *val = 4240000;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_battery_get_prop(struct power_supply *psy,
> +                                  enum power_supply_property psp,
> +                                  union power_supply_propval *val)
> +{
> +       struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
> +       struct iio_channel *chan;
> +       int ret = 0, reg, val1;
> +
> +       switch (psp) {
> +       case POWER_SUPPLY_PROP_PRESENT:
> +       case POWER_SUPPLY_PROP_ONLINE:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
> +                                 &reg);
> +               if (ret)
> +                       return ret;
> +
> +               val->intval = !!(reg & AXP20X_PWR_OP_BATT_PRESENT);
> +               break;
> +
> +       case POWER_SUPPLY_PROP_STATUS:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
> +                                 &reg);
> +               if (ret)
> +                       return ret;
> +
> +               if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
> +                       val->intval = POWER_SUPPLY_STATUS_CHARGING;
> +                       return 0;
> +               }
> +
> +               ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i,
> +                                                &val1);
> +               if (ret)
> +                       return ret;
> +
> +               if (val1) {
> +                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> +                       return 0;
> +               }
> +
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &val1);
> +               if (ret)
> +                       return ret;
> +
> +               /*
> +                * Fuel Gauge data takes 7 bits but the stored value seems to be
> +                * directly the raw percentage without any scaling to 7 bits.
> +                */
> +               if ((val1 & AXP209_FG_PERCENT) == 100)
> +                       val->intval = POWER_SUPPLY_STATUS_FULL;
> +               else
> +                       val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
> +               break;
> +
> +       case POWER_SUPPLY_PROP_HEALTH:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
> +                                 &val1);
> +               if (ret)
> +                       return ret;
> +
> +               if (val1 & AXP20X_PWR_OP_BATT_ACTIVATED) {
> +                       val->intval = POWER_SUPPLY_HEALTH_DEAD;
> +                       return 0;
> +               }
> +
> +               val->intval = POWER_SUPPLY_HEALTH_GOOD;
> +               break;
> +
> +       case POWER_SUPPLY_PROP_CURRENT_MAX:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
> +               if (ret)
> +                       return ret;
> +
> +               reg &= AXP20X_CHRG_CTRL1_TGT_CURR;
> +               val->intval = reg * 100000 + 300000;
> +               break;


This controls the charge current. I believe the correct property to use
is CONSTANT_CHARGE_CURRENT. And you should add CONSTANT_CHARGE_CURRENT_MAX
which returns the highest possible setting.

Also letting the user control this might not always be a good idea.
IIUC, LiPo batteries can only be charged at 1C, where C is the
rated capacity (X mAh).

> +
> +       case POWER_SUPPLY_PROP_CURRENT_NOW:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
> +                                 &reg);
> +               if (ret)
> +                       return ret;
> +
> +               if (reg & AXP20X_PWR_STATUS_BAT_CHARGING)
> +                       chan = axp20x_batt->batt_chrg_i;
> +               else
> +                       chan = axp20x_batt->batt_dischrg_i;
> +
> +               ret = iio_read_channel_processed(chan, &val->intval);
> +               if (ret)
> +                       return ret;
> +
> +               /*
> +                * IIO framework gives mV but Power Supply framework gives ?V.
> +                */
> +               val->intval *= 1000;
> +               break;
> +
> +       case POWER_SUPPLY_PROP_CAPACITY:
> +               /* When no battery is present, return capacity is 100% */
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
> +                                 &reg);
> +               if (ret)
> +                       return ret;
> +
> +               if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) {
> +                       val->intval = 100;
> +                       return 0;
> +               }
> +
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &reg);
> +               if (ret)
> +                       return ret;
> +
> +               if (axp20x_batt->axp_id == AXP221_ID &&
> +                   !(reg & AXP22X_FG_VALID))
> +                       return -EINVAL;
> +
> +               /*
> +                * Fuel Gauge data takes 7 bits but the stored value seems to be
> +                * directly the raw percentage without any scaling to 7 bits.
> +                */
> +               val->intval = reg & AXP209_FG_PERCENT;
> +               break;
> +
> +       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
> +               if (axp20x_batt->axp_id == AXP209_ID)
> +                       return axp20x_battery_get_max_voltage(axp20x_batt,
> +                                                             &val->intval);
> +               return axp22x_battery_get_max_voltage(axp20x_batt,
> +                                                     &val->intval);
> +
> +       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, &reg);
> +               if (ret)
> +                       return ret;
> +
> +               val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK);
> +               break;
> +
> +       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> +               ret = iio_read_channel_processed(axp20x_batt->batt_v,
> +                                                &val->intval);
> +               if (ret)
> +                       return ret;
> +
> +               /*
> +                * IIO framework gives mV but Power Supply framework gives ?V.
> +                */
> +               val->intval *= 1000;
> +               break;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +                                         int val)
> +{
> +       switch (val) {
> +       case 4100000:
> +               return regmap_update_bits(axp20x_batt->regmap,
> +                                         AXP20X_CHRG_CTRL1,
> +                                         AXP20X_CHRG_CTRL1_TGT_VOLT,
> +                                         AXP20X_CHRG_CTRL1_TGT_4_1V);
> +       case 4150000:
> +               if (axp20x_batt->axp_id == AXP221_ID)
> +                       return -EINVAL;
> +
> +               return regmap_update_bits(axp20x_batt->regmap,
> +                                         AXP20X_CHRG_CTRL1,
> +                                         AXP20X_CHRG_CTRL1_TGT_VOLT,
> +                                         AXP20X_CHRG_CTRL1_TGT_4_15V);
> +       case 4200000:
> +               return regmap_update_bits(axp20x_batt->regmap,
> +                                         AXP20X_CHRG_CTRL1,
> +                                         AXP20X_CHRG_CTRL1_TGT_VOLT,
> +                                         AXP20X_CHRG_CTRL1_TGT_4_2V);
> +       default:
> +               /*
> +                * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
> +                * can be set to 4.22V and 4.24V, but these voltages are too
> +                * high for Lithium based batteries (AXP PMICs are supposed to
> +                * be used with these kinds of battery).
> +                */
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_battery_set_prop(struct power_supply *psy,
> +                                  enum power_supply_property psp,
> +                                  const union power_supply_propval *val)
> +{
> +       struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
> +       int ret = 0, val1;
> +
> +       switch (psp) {
> +       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> +               val1 = (val->intval - 2600000) / 100000;
> +               if (val1 < 0 || val1 > AXP20X_V_OFF_MASK)
> +                       return -EINVAL;
> +
> +               return regmap_update_bits(axp20x_batt->regmap, AXP20X_V_OFF,
> +                                         AXP20X_V_OFF_MASK, val1);
> +
> +       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
> +               return axp20x_battery_set_max_voltage(axp20x_batt, val->intval);
> +
> +       case POWER_SUPPLY_PROP_CURRENT_MAX:
> +               if (axp20x_batt->axp_id == AXP209_ID)
> +                       val1 = (val->intval - 300000) / 100000;
> +               else
> +                       val1 = (val->intval - 300000) / 150000;
> +
> +               if (val1 > AXP20X_CHRG_CTRL1_TGT_CURR || val1 < 0)
> +                       return -EINVAL;
> +
> +               return regmap_update_bits(axp20x_batt->regmap,
> +                                         AXP20X_CHRG_CTRL1,
> +                                         AXP20X_CHRG_CTRL1_TGT_CURR, val1);
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static enum power_supply_property axp20x_battery_props[] = {
> +       POWER_SUPPLY_PROP_PRESENT,
> +       POWER_SUPPLY_PROP_ONLINE,
> +       POWER_SUPPLY_PROP_STATUS,
> +       POWER_SUPPLY_PROP_VOLTAGE_NOW,
> +       POWER_SUPPLY_PROP_CURRENT_NOW,
> +       POWER_SUPPLY_PROP_CURRENT_MAX,
> +       POWER_SUPPLY_PROP_HEALTH,
> +       POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
> +       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
> +       POWER_SUPPLY_PROP_CAPACITY,

You can also add POWER_SUPPLY_PROP_TECHNOLOGY, which would return
POWER_SUPPLY_TECHNOLOGY_LIPO.

It is also possible to do POWER_SUPPLY_PROP_CHARGE_TYPE. According
to the manual, if the battery is charging, it is in constant current
mode (POWER_SUPPLY_CHARGE_TYPE_FAST) when V_battery < V_target.
When V_battery == V_target, it is in constant voltage mode, though
I don't think this is the same as POWER_SUPPLY_CHARGE_TYPE_TRICKLE.
When it is not charging, you can return POWER_SUPPLY_CHARGE_TYPE_NONE.

Regards
ChenYu

> +};
> +
> +static int axp20x_battery_prop_writeable(struct power_supply *psy,
> +                                        enum power_supply_property psp)
> +{
> +       return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN ||
> +              psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN ||
> +              psp == POWER_SUPPLY_PROP_CURRENT_MAX;
> +}
> +
> +static const struct power_supply_desc axp20x_batt_ps_desc = {
> +       .name = "axp20x-battery",
> +       .type = POWER_SUPPLY_TYPE_BATTERY,
> +       .properties = axp20x_battery_props,
> +       .num_properties = ARRAY_SIZE(axp20x_battery_props),
> +       .property_is_writeable = axp20x_battery_prop_writeable,
> +       .get_property = axp20x_battery_get_prop,
> +       .set_property = axp20x_battery_set_prop,
> +};
> +
> +static const struct of_device_id axp20x_battery_ps_id[] = {
> +       {
> +               .compatible = "x-powers,axp209-battery-power-supply",
> +               .data = (void *)AXP209_ID,
> +       }, {
> +               .compatible = "x-powers,axp221-battery-power-supply",
> +               .data = (void *)AXP221_ID,
> +       }, { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
> +
> +static int axp20x_power_probe(struct platform_device *pdev)
> +{
> +       struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> +       struct axp20x_batt_ps *axp20x_batt;
> +       struct power_supply_config psy_cfg = {};
> +
> +       axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
> +                                  GFP_KERNEL);
> +       if (!axp20x_batt)
> +               return -ENOMEM;
> +
> +       axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
> +       if (IS_ERR(axp20x_batt->batt_v)) {
> +               if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV)
> +                       return -EPROBE_DEFER;
> +               return PTR_ERR(axp20x_batt->batt_v);
> +       }
> +
> +       axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
> +                                                       "batt_chrg_i");
> +       if (IS_ERR(axp20x_batt->batt_chrg_i)) {
> +               if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV)
> +                       return -EPROBE_DEFER;
> +               return PTR_ERR(axp20x_batt->batt_chrg_i);
> +       }
> +
> +       axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
> +                                                          "batt_dischrg_i");
> +       if (IS_ERR(axp20x_batt->batt_dischrg_i)) {
> +               if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV)
> +                       return -EPROBE_DEFER;
> +               return PTR_ERR(axp20x_batt->batt_dischrg_i);
> +       }
> +
> +       axp20x_batt->regmap = axp20x->regmap;
> +       platform_set_drvdata(pdev, axp20x_batt);
> +
> +       psy_cfg.drv_data = axp20x_batt;
> +       psy_cfg.of_node = pdev->dev.of_node;
> +
> +       axp20x_batt->axp_id = (int)of_device_get_match_data(&pdev->dev);
> +
> +       axp20x_batt->batt = devm_power_supply_register(&pdev->dev,
> +                                                      &axp20x_batt_ps_desc,
> +                                                      &psy_cfg);
> +       return PTR_ERR_OR_ZERO(axp20x_batt->batt);
> +}
> +
> +static struct platform_driver axp20x_batt_driver = {
> +       .probe    = axp20x_power_probe,
> +       .driver   = {
> +               .name  = "axp20x-battery-power-supply",
> +               .of_match_table = axp20x_battery_ps_id,
> +       },
> +};
> +
> +module_platform_driver(axp20x_batt_driver);
> +
> +MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs");
> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> --
> 2.9.3
>

^ permalink raw reply

* [PATCH v6 0/4] arm64: arch_timer: Add workaround for hisilicon-161601 erratum
From: Ding Tianhong @ 2017-01-06  3:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483594317-10732-1-git-send-email-dingtianhong@huawei.com>

Hi Marc, Will:

Please help reviewing the new version, I think it is nearly close to the final solution and it is very important to our chip or something else chip has similar erratum.
If there is any dissatisfaction, please inform me and I will fix it. :)
Thanks a lot.

Ding

On 2017/1/5 13:31, Ding Tianhong wrote:
> Erratum Hisilicon-161601 says that the ARM generic timer counter "has the
> potential to contain an erroneous value when the timer value changes".
> Accesses to TVAL (both read and write) are also affected due to the implicit counter
> read.  Accesses to CVAL are not affected.
> 
> The workaround is to reread the system count registers until the value of the second
> read is larger than the first one by less than 32, the system counter can be guaranteed
> not to return wrong value twice by back-to-back read and the error value is always larger
> than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.
> 
> v2: Introducing a new generic erratum handling mechanism for fsl,a008585 and hisilicon,161601.
>     Significant rework based on feedback, including seperate the fsl erratum a008585
>     to another patch, update the erratum name and remove unwanted code.
> 
> v3: Introducing the erratum_workaround_set_sne generic function for fsl erratum a008585
>     and make the #define __fsl_a008585_read_reg to be private to the .c file instead of
>     being globally visible. After discussion with Marc and Will, a consensus decision was
>     made to remove the commandline parameter for enabling fsl,erratum-a008585 erratum,
>     and make some generic name more specific, export timer_unstable_counter_workaround
>     for module access.
>     
>     Significant rework based on feedback, including fix some alignment problem, make the
>     #define __hisi_161601_read_reg to be private to the .c file instead of being globally
>     visible, add more accurate annotation and modify a bit of logical format to enable
>     arch_timer_read_ool_enabled, remove the kernel commandline parameter
>     clocksource.arm_arch_timer.hisilicon-161601.
> 
>     Introduce a generic aquick framework for erratum in ACPI mode.
> 
> v4: rename the quirk handler parameter to make it more generic, and
>     avoid break loop when handling the quirk becasue it need to
>     support multi quirks handler.
> 
>     update some data structures for acpi mode. 
> 
> v5: Adapt the new kernel-parameters.txt for latest kernel version.
>     Set the retries of reread system counter to 50, because it is possible 
>     that some interrupts may lead to more than twice read errors and break the loop,
>     it will trigger the warning, so we set the number of retries far beyond the number of
>     iterations the loop has been observed to take.
> 
> v6: The last 2 patches in the previous version about the ACPI mode will conflict witch Fuwei's
>     GTDT patches, so remove the ACPI part and only support the DT base code for this patch set.
> 
>     We have trigger a bug when select the CONFIG_FUNCTION_GRAPH_TRACER and enable function_graph
>     to /sys/kernel/debug/tracing/current_tracer, the system will stall into an endless loop, it looks
>     like that the ftrace_graph_caller will be related to xxx.read_cntvct_el0 and read the system counter
>     again, so mark the xxx.read_cntvct_el0 with notrace to fix the problem.
> 
> Ding Tianhong (4):
>   arm64: arch_timer: Add device tree binding for hisilicon-161601
>     erratum
>   arm64: arch_timer: Introduce a generic erratum handing mechanism for
>     fsl-a008585
>   arm64: arch_timer: Work around Erratum Hisilicon-161601
>   arm64: arch timer: Add timer erratum property for Hip05-d02 and
>     Hip06-d03
> 
>  Documentation/admin-guide/kernel-parameters.txt    |   9 --
>  Documentation/arm64/silicon-errata.txt             |   1 +
>  .../devicetree/bindings/arm/arch_timer.txt         |   8 ++
>  arch/arm64/boot/dts/hisilicon/hip05.dtsi           |   1 +
>  arch/arm64/boot/dts/hisilicon/hip06.dtsi           |   1 +
>  arch/arm64/include/asm/arch_timer.h                |  38 ++----
>  drivers/clocksource/Kconfig                        |   9 ++
>  drivers/clocksource/arm_arch_timer.c               | 146 ++++++++++++++++-----
>  8 files changed, 143 insertions(+), 70 deletions(-)
> 

^ permalink raw reply

* [PATCH 2/2] media: rc: add driver for IR remote receiver on MT7623 SoC
From: Andi Shyti @ 2017-01-06  3:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483632384-8107-3-git-send-email-sean.wang@mediatek.com>

Hi Sean,

> +	ir->rc = rc_allocate_device();

Yes, you should use devm_rc_allocate_device(...)

Besides, standing to this patch which is not in yet:

https://lkml.org/lkml/2016/12/18/39

rc_allocate_device should provide the driver type during
allocation, so it should be:

	ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);

and this line can be removed:

> +	ir->rc->driver_type = RC_DRIVER_IR_RAW;

I don't know when Mauro will take the patch above.

Andi

^ permalink raw reply

* [PATCH v2 2/4] watchdog: bcm2835_wdt: Use watchdog core to install restart handler
From: Guenter Roeck @ 2017-01-06  3:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483674720-4870-1-git-send-email-linux@roeck-us.net>

Use the infrastructure provided by the watchdog core to install
the restart handler.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Need to call watchdog_set_restart_priority()

 drivers/watchdog/bcm2835_wdt.c | 57 ++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index c32c45bd8b09..4e0adb6c88f0 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -14,7 +14,6 @@
  */
 
 #include <linux/delay.h>
-#include <linux/reboot.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/io.h>
@@ -49,7 +48,6 @@
 struct bcm2835_wdt {
 	void __iomem		*base;
 	spinlock_t		lock;
-	struct notifier_block	restart_handler;
 };
 
 static unsigned int heartbeat;
@@ -99,11 +97,37 @@ static unsigned int bcm2835_wdt_get_timeleft(struct watchdog_device *wdog)
 	return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET);
 }
 
+static void __bcm2835_restart(struct bcm2835_wdt *wdt)
+{
+	u32 val;
+
+	/* use a timeout of 10 ticks (~150us) */
+	writel_relaxed(10 | PM_PASSWORD, wdt->base + PM_WDOG);
+	val = readl_relaxed(wdt->base + PM_RSTC);
+	val &= PM_RSTC_WRCFG_CLR;
+	val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
+	writel_relaxed(val, wdt->base + PM_RSTC);
+
+	/* No sleeping, possibly atomic. */
+	mdelay(1);
+}
+
+static int bcm2835_restart(struct watchdog_device *wdog,
+			   unsigned long action, void *data)
+{
+	struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
+
+	__bcm2835_restart(wdt);
+
+	return 0;
+}
+
 static const struct watchdog_ops bcm2835_wdt_ops = {
 	.owner =	THIS_MODULE,
 	.start =	bcm2835_wdt_start,
 	.stop =		bcm2835_wdt_stop,
 	.get_timeleft =	bcm2835_wdt_get_timeleft,
+	.restart =	bcm2835_restart,
 };
 
 static const struct watchdog_info bcm2835_wdt_info = {
@@ -120,26 +144,6 @@ static struct watchdog_device bcm2835_wdt_wdd = {
 	.timeout =	WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET),
 };
 
-static int
-bcm2835_restart(struct notifier_block *this, unsigned long mode, void *cmd)
-{
-	struct bcm2835_wdt *wdt = container_of(this, struct bcm2835_wdt,
-					       restart_handler);
-	u32 val;
-
-	/* use a timeout of 10 ticks (~150us) */
-	writel_relaxed(10 | PM_PASSWORD, wdt->base + PM_WDOG);
-	val = readl_relaxed(wdt->base + PM_RSTC);
-	val &= PM_RSTC_WRCFG_CLR;
-	val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
-	writel_relaxed(val, wdt->base + PM_RSTC);
-
-	/* No sleeping, possibly atomic. */
-	mdelay(1);
-
-	return 0;
-}
-
 /*
  * We can't really power off, but if we do the normal reset scheme, and
  * indicate to bootcode.bin not to reboot, then most of the chip will be
@@ -163,7 +167,7 @@ static void bcm2835_power_off(void)
 	writel_relaxed(val, wdt->base + PM_RSTS);
 
 	/* Continue with normal reset mechanism */
-	bcm2835_restart(&wdt->restart_handler, REBOOT_HARD, NULL);
+	__bcm2835_restart(wdt);
 }
 
 static int bcm2835_wdt_probe(struct platform_device *pdev)
@@ -201,6 +205,9 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
 		 */
 		set_bit(WDOG_HW_RUNNING, &bcm2835_wdt_wdd.status);
 	}
+
+	watchdog_set_restart_priority(&bcm2835_wdt_wdd, 128);
+
 	err = watchdog_register_device(&bcm2835_wdt_wdd);
 	if (err) {
 		dev_err(dev, "Failed to register watchdog device");
@@ -208,9 +215,6 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	wdt->restart_handler.notifier_call = bcm2835_restart;
-	wdt->restart_handler.priority = 128;
-	register_restart_handler(&wdt->restart_handler);
 	if (pm_power_off == NULL)
 		pm_power_off = bcm2835_power_off;
 
@@ -222,7 +226,6 @@ static int bcm2835_wdt_remove(struct platform_device *pdev)
 {
 	struct bcm2835_wdt *wdt = platform_get_drvdata(pdev);
 
-	unregister_restart_handler(&wdt->restart_handler);
 	if (pm_power_off == bcm2835_power_off)
 		pm_power_off = NULL;
 	watchdog_unregister_device(&bcm2835_wdt_wdd);
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 4/4] watchdog: tangox: Use watchdog core to install restart handler
From: Guenter Roeck @ 2017-01-06  3:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483674720-4870-1-git-send-email-linux@roeck-us.net>

Use the infrastructure provided by the watchdog core to install
the restart handler.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Need to call watchdog_set_restart_priority()

 drivers/watchdog/tangox_wdt.c | 34 +++++++++++++---------------------
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/drivers/watchdog/tangox_wdt.c b/drivers/watchdog/tangox_wdt.c
index 202c4b9cc921..d5fcce062920 100644
--- a/drivers/watchdog/tangox_wdt.c
+++ b/drivers/watchdog/tangox_wdt.c
@@ -15,9 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/notifier.h>
 #include <linux/platform_device.h>
-#include <linux/reboot.h>
 #include <linux/watchdog.h>
 
 #define DEFAULT_TIMEOUT 30
@@ -47,7 +45,6 @@ struct tangox_wdt_device {
 	void __iomem *base;
 	unsigned long clk_rate;
 	struct clk *clk;
-	struct notifier_block restart;
 };
 
 static int tangox_wdt_set_timeout(struct watchdog_device *wdt,
@@ -96,24 +93,24 @@ static const struct watchdog_info tangox_wdt_info = {
 	.identity = "tangox watchdog",
 };
 
+static int tangox_wdt_restart(struct watchdog_device *wdt,
+			      unsigned long action, void *data)
+{
+	struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt);
+
+	writel(1, dev->base + WD_COUNTER);
+
+	return 0;
+}
+
 static const struct watchdog_ops tangox_wdt_ops = {
 	.start		= tangox_wdt_start,
 	.stop		= tangox_wdt_stop,
 	.set_timeout	= tangox_wdt_set_timeout,
 	.get_timeleft	= tangox_wdt_get_timeleft,
+	.restart	= tangox_wdt_restart,
 };
 
-static int tangox_wdt_restart(struct notifier_block *nb, unsigned long action,
-			      void *data)
-{
-	struct tangox_wdt_device *dev =
-		container_of(nb, struct tangox_wdt_device, restart);
-
-	writel(1, dev->base + WD_COUNTER);
-
-	return NOTIFY_DONE;
-}
-
 static int tangox_wdt_probe(struct platform_device *pdev)
 {
 	struct tangox_wdt_device *dev;
@@ -174,18 +171,14 @@ static int tangox_wdt_probe(struct platform_device *pdev)
 		tangox_wdt_start(&dev->wdt);
 	}
 
+	watchdog_set_restart_priority(&dev->wdt, 128);
+
 	err = watchdog_register_device(&dev->wdt);
 	if (err)
 		goto err;
 
 	platform_set_drvdata(pdev, dev);
 
-	dev->restart.notifier_call = tangox_wdt_restart;
-	dev->restart.priority = 128;
-	err = register_restart_handler(&dev->restart);
-	if (err)
-		dev_warn(&pdev->dev, "failed to register restart handler\n");
-
 	dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n");
 
 	return 0;
@@ -202,7 +195,6 @@ static int tangox_wdt_remove(struct platform_device *pdev)
 	tangox_wdt_stop(&dev->wdt);
 	clk_disable_unprepare(dev->clk);
 
-	unregister_restart_handler(&dev->restart);
 	watchdog_unregister_device(&dev->wdt);
 
 	return 0;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 0/5] Add touch key driver support for TM2
From: Jaechul Lee @ 2017-01-06  3:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CGME20170106035913epcas5p2b7d66596e467c6169786eea56beb8ffc@epcas5p2.samsung.com>

Hi,

This patchset adds support for the tm2 touchkey device.

The driver has been ported from Tizen Kernel, originally written
by Beomho. I ported it to the latest mainline Kernel.

This patch need to apply after this one:
https://lkml.org/lkml/2016/12/29/319

Changes in v3:
 - Changed the commit ordering, the tm2-touchkey related patches
   are the last 3.
 - Added Chanwoo's patch which fixes the wrong voltage of ldo23
   and ldo25.
 - Andi (patch 3) moves the ldo31 and ldo38 in the tm2 and tm2e
   files as they have different values.

Changes in v2:
 - fixed reviews from Javier, Dmitry
 - refactored power enable/disable functions.
 - reordered signed-offs in patch 2, while patch 4 is left as it
   was as Andi copy pasted the node to the new tm2.dts file
 - added Jarvier's (patch 1,2,4) and Krzysztof's (patch 4) reviews
   and Rob's Ack
 - patch 3 diff has been generated with -B50%


Andi Shyti (1):
  arm64: dts: exynos: make tm2 and tm2e independent from each other

Chanwoo Choi (1):
  arm64: dts: exynos5433: TM2/E: Fix wrong information of ldo23 and
    ldo25

Jaechul Lee (3):
  input: Add support for the tm2 touchkey device driver
  input: tm2-touchkey: Add touchkey driver support for TM2
  arm64: dts: exynos: Add tm2 touchkey node

 .../bindings/input/samsung,tm2-touchkey.txt        |   27 +
 .../boot/dts/exynos/exynos5433-tm2-common.dtsi     | 1118 ++++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos5433-tm2.dts      | 1113 +------------------
 arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts     |   32 +-
 drivers/input/keyboard/Kconfig                     |   11 +
 drivers/input/keyboard/Makefile                    |    1 +
 drivers/input/keyboard/tm2-touchkey.c              |  280 +++++
 7 files changed, 1469 insertions(+), 1113 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt
 create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
 create mode 100644 drivers/input/keyboard/tm2-touchkey.c

-- 
2.7.4

^ permalink raw reply

* [PATCH v3 1/5] arm64: dts: exynos5433: TM2/E: Fix wrong information of ldo23 and ldo25
From: Jaechul Lee @ 2017-01-06  3:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483675149-32598-1-git-send-email-jcsing.lee@samsung.com>

From: Chanwoo Choi <cw00.choi@samsung.com>

This patch fixes the wrong information of ldo23 and ldo25 on both TM2 and TM2E.

Fixes: 01e5d2352152 ("arm64: dts: exynos: Add dts file for Exynos5433-based TM2 board")
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Andi Shyti <andi.shyti@samsung.com>
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
---
 arch/arm64/boot/dts/exynos/exynos5433-tm2.dts  |  7 ++++---
 arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts | 10 ----------
 2 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
index 3b5215c..e8971f4 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -504,9 +504,9 @@
 			};
 
 			ldo23_reg: LDO23 {
-				regulator-name = "CAM_SEN_CORE_1.2V_AP";
+				regulator-name = "CAM_SEN_CORE_1.05V_AP";
 				regulator-min-microvolt = <1050000>;
-				regulator-max-microvolt = <1200000>;
+				regulator-max-microvolt = <1050000>;
 			};
 
 			ldo24_reg: LDO24 {
@@ -516,9 +516,10 @@
 			};
 
 			ldo25_reg: LDO25 {
-				regulator-name = "CAM_SEN_A2.8V_AP";
+				regulator-name = "UNUSED_LDO25";
 				regulator-min-microvolt = <2800000>;
 				regulator-max-microvolt = <2800000>;
+				regulator-always-off;
 			};
 
 			ldo26_reg: LDO26 {
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
index 1db4e7f..854c583 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
@@ -18,16 +18,6 @@
 	compatible = "samsung,tm2e", "samsung,exynos5433";
 };
 
-&ldo23_reg {
-	regulator-name = "CAM_SEN_CORE_1.025V_AP";
-	regulator-max-microvolt = <1050000>;
-};
-
-&ldo25_reg {
-	regulator-name = "UNUSED_LDO25";
-	regulator-always-off;
-};
-
 &ldo31_reg {
 	regulator-name = "TSP_VDD_1.8V_AP";
 	regulator-min-microvolt = <1800000>;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 2/5] arm64: dts: exynos: make tm2 and tm2e independent from each other
From: Jaechul Lee @ 2017-01-06  3:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483675149-32598-1-git-send-email-jcsing.lee@samsung.com>

From: Andi Shyti <andi.shyti@samsung.com>

Currently tm2e dts includes tm2 but there are some differences
between the two boards and tm2 has some properties that tm2e
doesn't have.

That's why it's important to keep the two dts files independent
and put all the commonalities in a tm2-common.dtsi file.

At the current status the only two differences between the two
dts files (besides the board name) are ldo31 and ldo38.

Signed-off-by: Andi Shyti <andi.shyti@samsung.com>
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
---
 .../boot/dts/exynos/exynos5433-tm2-common.dtsi     | 1118 +++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos5433-tm2.dts      | 1153 +-------------------
 arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts     |   22 +-
 3 files changed, 1163 insertions(+), 1130 deletions(-)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
 rewrite arch/arm64/boot/dts/exynos/exynos5433-tm2.dts (98%)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
new file mode 100644
index 0000000..c43f9a3
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
@@ -0,0 +1,1118 @@
+/*
+ * SAMSUNG Exynos5433 TM2 board device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Common device tree source file for Samsung's TM2 and TM2E boards
+ * which are based on Samsung Exynos5433 SoC.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+#include "exynos5433.dtsi"
+#include <dt-bindings/clock/samsung,s2mps11.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "Samsung TM2 board";
+	compatible = "samsung,tm2", "samsung,exynos5433";
+
+	aliases {
+		gsc0 = &gsc_0;
+		gsc1 = &gsc_1;
+		gsc2 = &gsc_2;
+		pinctrl0 = &pinctrl_alive;
+		pinctrl1 = &pinctrl_aud;
+		pinctrl2 = &pinctrl_cpif;
+		pinctrl3 = &pinctrl_ese;
+		pinctrl4 = &pinctrl_finger;
+		pinctrl5 = &pinctrl_fsys;
+		pinctrl6 = &pinctrl_imem;
+		pinctrl7 = &pinctrl_nfc;
+		pinctrl8 = &pinctrl_peric;
+		pinctrl9 = &pinctrl_touch;
+		serial0 = &serial_0;
+		serial1 = &serial_1;
+		serial2 = &serial_2;
+		serial3 = &serial_3;
+		spi0 = &spi_0;
+		spi1 = &spi_1;
+		spi2 = &spi_2;
+		spi3 = &spi_3;
+		spi4 = &spi_4;
+		mshc0 = &mshc_0;
+		mshc2 = &mshc_2;
+	};
+
+	chosen {
+		stdout-path = &serial_1;
+	};
+
+	memory at 20000000 {
+		device_type = "memory";
+		reg = <0x0 0x20000000 0x0 0xc0000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		power-key {
+			gpios = <&gpa2 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+			label = "power key";
+			debounce-interval = <10>;
+		};
+
+		volume-up-key {
+			gpios = <&gpa2 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEUP>;
+			label = "volume-up key";
+			debounce-interval = <10>;
+		};
+
+		volume-down-key {
+			gpios = <&gpa2 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEDOWN>;
+			label = "volume-down key";
+			debounce-interval = <10>;
+		};
+
+		homepage-key {
+			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_MENU>;
+			label = "homepage key";
+			debounce-interval = <10>;
+		};
+	};
+
+	i2c_max98504: i2c-gpio-0 {
+		compatible = "i2c-gpio";
+		gpios = <&gpd0 1 GPIO_ACTIVE_HIGH /* SPK_AMP_SDA */
+			 &gpd0 0 GPIO_ACTIVE_HIGH /* SPK_AMP_SCL */ >;
+		i2c-gpio,delay-us = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+
+		max98504: max98504 at 31 {
+			compatible = "maxim,max98504";
+			reg = <0x31>;
+			maxim,rx-path = <1>;
+			maxim,tx-path = <1>;
+			maxim,tx-channel-mask = <3>;
+			maxim,tx-channel-source = <2>;
+		};
+	};
+
+	sound {
+		compatible = "samsung,tm2-audio";
+		audio-codec = <&wm5110>;
+		i2s-controller = <&i2s0>;
+		audio-amplifier = <&max98504>;
+		mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
+		model = "wm5110";
+		samsung,audio-routing =
+			/* Headphone */
+			"HP", "HPOUT1L",
+			"HP", "HPOUT1R",
+
+			/* Speaker */
+			"SPK", "SPKOUT",
+			"SPKOUT", "HPOUT2L",
+			"SPKOUT", "HPOUT2R",
+
+			/* Receiver */
+			"RCV", "HPOUT3L",
+			"RCV", "HPOUT3R";
+		status = "okay";
+	};
+};
+
+&adc {
+	vdd-supply = <&ldo3_reg>;
+	status = "okay";
+
+	thermistor-ap {
+		compatible = "murata,ncp03wf104";
+		pullup-uv = <1800000>;
+		pullup-ohm = <100000>;
+		pulldown-ohm = <0>;
+		io-channels = <&adc 0>;
+	};
+
+	thermistor-battery {
+		compatible = "murata,ncp03wf104";
+		pullup-uv = <1800000>;
+		pullup-ohm = <100000>;
+		pulldown-ohm = <0>;
+		io-channels = <&adc 1>;
+		#thermal-sensor-cells = <0>;
+	};
+
+	thermistor-charger {
+		compatible = "murata,ncp03wf104";
+		pullup-uv = <1800000>;
+		pullup-ohm = <100000>;
+		pulldown-ohm = <0>;
+		io-channels = <&adc 2>;
+	};
+};
+
+&bus_g2d_400 {
+	devfreq-events = <&ppmu_event0_d0_general>, <&ppmu_event0_d1_general>;
+	vdd-supply = <&buck4_reg>;
+	exynos,saturation-ratio = <10>;
+	status = "okay";
+};
+
+&bus_g2d_266 {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&bus_gscl {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&bus_hevc {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&bus_jpeg {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&bus_mfc {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&bus_mscl {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&bus_noc0 {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&bus_noc1 {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&bus_noc2 {
+	devfreq = <&bus_g2d_400>;
+	status = "okay";
+};
+
+&cmu_aud {
+	assigned-clocks = <&cmu_aud CLK_MOUT_AUD_PLL_USER>;
+	assigned-clock-parents = <&cmu_top CLK_FOUT_AUD_PLL>;
+};
+
+&cmu_fsys {
+	assigned-clocks = <&cmu_top CLK_MOUT_SCLK_USBDRD30>,
+		<&cmu_top CLK_MOUT_SCLK_USBHOST30>,
+		<&cmu_fsys CLK_MOUT_SCLK_USBDRD30_USER>,
+		<&cmu_fsys CLK_MOUT_SCLK_USBHOST30_USER>,
+		<&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_USER>,
+		<&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_USER>,
+		<&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_USER>,
+		<&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_USER>,
+		<&cmu_top CLK_DIV_SCLK_USBDRD30>,
+		<&cmu_top CLK_DIV_SCLK_USBHOST30>;
+	assigned-clock-parents = <&cmu_top CLK_MOUT_BUS_PLL_USER>,
+		<&cmu_top CLK_MOUT_BUS_PLL_USER>,
+		<&cmu_top CLK_SCLK_USBDRD30_FSYS>,
+		<&cmu_top CLK_SCLK_USBHOST30_FSYS>,
+		<&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY>,
+		<&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY>,
+		<&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY>,
+		<&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY>;
+	assigned-clock-rates = <0>, <0>, <0>, <0>, <0>, <0>, <0>, <0>,
+			       <66700000>, <66700000>;
+};
+
+&cmu_gscl {
+	assigned-clocks = <&cmu_gscl CLK_MOUT_ACLK_GSCL_111_USER>,
+			  <&cmu_gscl CLK_MOUT_ACLK_GSCL_333_USER>;
+	assigned-clock-parents = <&cmu_top CLK_ACLK_GSCL_111>,
+				 <&cmu_top CLK_ACLK_GSCL_333>;
+};
+
+&cmu_mfc {
+	assigned-clocks = <&cmu_mfc CLK_MOUT_ACLK_MFC_400_USER>;
+	assigned-clock-parents = <&cmu_top CLK_ACLK_MFC_400>;
+};
+
+&cmu_mscl {
+	assigned-clocks = <&cmu_mscl CLK_MOUT_ACLK_MSCL_400_USER>,
+			  <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
+			  <&cmu_mscl CLK_MOUT_SCLK_JPEG>,
+			  <&cmu_top CLK_MOUT_SCLK_JPEG_A>;
+	assigned-clock-parents = <&cmu_top CLK_ACLK_MSCL_400>,
+				 <&cmu_top CLK_SCLK_JPEG_MSCL>,
+				 <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
+				 <&cmu_top CLK_MOUT_BUS_PLL_USER>;
+};
+
+&cpu0 {
+	cpu-supply = <&buck3_reg>;
+};
+
+&cpu4 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&decon {
+	status = "okay";
+
+	i80-if-timings {
+	};
+};
+
+&dsi {
+	status = "okay";
+	vddcore-supply = <&ldo6_reg>;
+	vddio-supply = <&ldo7_reg>;
+	samsung,pll-clock-frequency = <24000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&te_irq>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 1 {
+			reg = <1>;
+
+			dsi_out: endpoint {
+				samsung,burst-clock-frequency = <512000000>;
+				samsung,esc-clock-frequency = <16000000>;
+			};
+		};
+	};
+};
+
+&hsi2c_0 {
+	status = "okay";
+	clock-frequency = <2500000>;
+
+	s2mps13-pmic at 66 {
+		compatible = "samsung,s2mps13-pmic";
+		interrupt-parent = <&gpa0>;
+		interrupts = <7 IRQ_TYPE_NONE>;
+		reg = <0x66>;
+		samsung,s2mps11-wrstbi-ground;
+
+		s2mps13_osc: clocks {
+			compatible = "samsung,s2mps13-clk";
+			#clock-cells = <1>;
+			clock-output-names = "s2mps13_ap", "s2mps13_cp",
+				"s2mps13_bt";
+		};
+
+		regulators: regulators {
+			ldo1_reg: LDO1 {
+				regulator-name = "VDD_ALIVE_0.9V_AP";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-always-on;
+			};
+
+			ldo2_reg: LDO2 {
+				regulator-name = "VDDQ_MMC2_2.8V_AP";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo3_reg: LDO3 {
+				regulator-name = "VDD1_E_1.8V_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			ldo4_reg: LDO4 {
+				regulator-name = "VDD10_MIF_PLL_1.0V_AP";
+				regulator-min-microvolt = <1300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo5_reg: LDO5 {
+				regulator-name = "VDD10_DPLL_1.0V_AP";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo6_reg: LDO6 {
+				regulator-name = "VDD10_MIPI2L_1.0V_AP";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo7_reg: LDO7 {
+				regulator-name = "VDD18_MIPI2L_1.8V_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo8_reg: LDO8 {
+				regulator-name = "VDD18_LLI_1.8V_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo9_reg: LDO9 {
+				regulator-name = "VDD18_ABB_ETC_1.8V_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo10_reg: LDO10 {
+				regulator-name = "VDD33_USB30_3.0V_AP";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo11_reg: LDO11 {
+				regulator-name = "VDD_INT_M_1.0V_AP";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo12_reg: LDO12 {
+				regulator-name = "VDD_KFC_M_1.1V_AP";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+			};
+
+			ldo13_reg: LDO13 {
+				regulator-name = "VDD_G3D_M_0.95V_AP";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <950000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo14_reg: LDO14 {
+				regulator-name = "VDDQ_M1_LDO_1.2V_AP";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo15_reg: LDO15 {
+				regulator-name = "VDDQ_M2_LDO_1.2V_AP";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo16_reg: LDO16 {
+				regulator-name = "VDDQ_EFUSE";
+				regulator-min-microvolt = <1400000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-always-on;
+			};
+
+			ldo17_reg: LDO17 {
+				regulator-name = "V_TFLASH_2.8V_AP";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+			};
+
+			ldo18_reg: LDO18 {
+				regulator-name = "V_CODEC_1.8V_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo19_reg: LDO19 {
+				regulator-name = "VDDA_1.8V_COMP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			ldo20_reg: LDO20 {
+				regulator-name = "VCC_2.8V_AP";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+			};
+
+			ldo21_reg: LDO21 {
+				regulator-name = "VT_CAM_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo22_reg: LDO22 {
+				regulator-name = "CAM_IO_1.8V_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo23_reg: LDO23 {
+				regulator-name = "CAM_SEN_CORE_1.05V_AP";
+				regulator-min-microvolt = <1050000>;
+				regulator-max-microvolt = <1050000>;
+			};
+
+			ldo24_reg: LDO24 {
+				regulator-name = "VT_CAM_1.2V";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+			};
+
+			ldo25_reg: LDO25 {
+				regulator-name = "UNUSED_LDO25";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-off;
+			};
+
+			ldo26_reg: LDO26 {
+				regulator-name = "CAM_AF_2.8V_AP";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+			};
+
+			ldo27_reg: LDO27 {
+				regulator-name = "VCC_3.0V_LCD_AP";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+			};
+
+			ldo28_reg: LDO28 {
+				regulator-name = "VCC_1.8V_LCD_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo29_reg: LDO29 {
+				regulator-name = "VT_CAM_2.8V";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+			};
+
+			ldo30_reg: LDO30 {
+				regulator-name = "TSP_AVDD_3.3V_AP";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			/*
+			 * LDO31 differs from target to target,
+			 * its definition is in the .dts
+			 */
+
+			ldo32_reg: LDO32 {
+				regulator-name = "VTOUCH_1.8V_AP";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo33_reg: LDO33 {
+				regulator-name = "VTOUCH_LED_3.3V";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-ramp-delay = <12500>;
+			};
+
+			ldo34_reg: LDO34 {
+				regulator-name = "VCC_1.8V_MHL_AP";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <2100000>;
+			};
+
+			ldo35_reg: LDO35 {
+				regulator-name = "OIS_VM_2.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <2800000>;
+			};
+
+			ldo36_reg: LDO36 {
+				regulator-name = "VSIL_1.0V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+			};
+
+			ldo37_reg: LDO37 {
+				regulator-name = "VF_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			/*
+			 * LDO38 differs from target to target,
+			 * its definition is in the .dts
+			 */
+
+			ldo39_reg: LDO39 {
+				regulator-name = "V_HRM_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo40_reg: LDO40 {
+				regulator-name = "V_HRM_3.3V";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			buck1_reg: BUCK1 {
+				regulator-name = "VDD_MIF_0.9V_AP";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck2_reg: BUCK2 {
+				regulator-name = "VDD_EGL_1.0V_AP";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck3_reg: BUCK3 {
+				regulator-name = "VDD_KFC_1.0V_AP";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck4_reg: BUCK4 {
+				regulator-name = "VDD_INT_0.95V_AP";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck5_reg: BUCK5 {
+				regulator-name = "VDD_DISP_CAM0_0.9V_AP";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck6_reg: BUCK6 {
+				regulator-name = "VDD_G3D_0.9V_AP";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck7_reg: BUCK7 {
+				regulator-name = "VDD_MEM1_1.2V_AP";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+
+			buck8_reg: BUCK8 {
+				regulator-name = "VDD_LLDO_1.35V_AP";
+				regulator-min-microvolt = <1350000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			buck9_reg: BUCK9 {
+				regulator-name = "VDD_MLDO_2.0V_AP";
+				regulator-min-microvolt = <1350000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			buck10_reg: BUCK10 {
+				regulator-name = "vdd_mem2";
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&hsi2c_8 {
+	status = "okay";
+
+	max77843 at 66 {
+		compatible = "maxim,max77843";
+		interrupt-parent = <&gpa1>;
+		interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+		reg = <0x66>;
+
+		muic: max77843-muic {
+			compatible = "maxim,max77843-muic";
+		};
+
+		regulators {
+			compatible = "maxim,max77843-regulator";
+			safeout1_reg: SAFEOUT1 {
+				regulator-name = "SAFEOUT1";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <4950000>;
+			};
+
+			safeout2_reg: SAFEOUT2 {
+				regulator-name = "SAFEOUT2";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <4950000>;
+			};
+
+			charger_reg: CHARGER {
+				regulator-name = "CHARGER";
+				regulator-min-microamp = <100000>;
+				regulator-max-microamp = <3150000>;
+			};
+		};
+
+		haptic: max77843-haptic {
+			compatible = "maxim,max77843-haptic";
+			haptic-supply = <&ldo38_reg>;
+			pwms = <&pwm 0 33670 0>;
+			pwm-names = "haptic";
+		};
+	};
+};
+
+&i2s0 {
+	status = "okay";
+};
+
+&mshc_0 {
+	status = "okay";
+	num-slots = <1>;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-highspeed;
+	non-removable;
+	card-detect-delay = <200>;
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-hs400-timing = <0 3>;
+	samsung,read-strobe-delay = <90>;
+	fifo-depth = <0x80>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4
+			&sd0_bus8 &sd0_rdqs>;
+	bus-width = <8>;
+	assigned-clocks = <&cmu_top CLK_SCLK_MMC0_FSYS>;
+	assigned-clock-rates = <800000000>;
+};
+
+&mshc_2 {
+	status = "okay";
+	num-slots = <1>;
+	cap-sd-highspeed;
+	disable-wp;
+	cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>;
+	cd-inverted;
+	card-detect-delay = <200>;
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	fifo-depth = <0x80>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>;
+	bus-width = <4>;
+};
+
+&ppmu_d0_general {
+	status = "okay";
+	events {
+		ppmu_event0_d0_general: ppmu-event0-d0-general {
+			event-name = "ppmu-event0-d0-general";
+		};
+	};
+};
+
+&ppmu_d1_general {
+	status = "okay";
+	events {
+		ppmu_event0_d1_general: ppmu-event0-d1-general {
+		       event-name = "ppmu-event0-d1-general";
+	       };
+       };
+};
+
+&pinctrl_alive {
+	pinctrl-names = "default";
+	pinctrl-0 = <&initial_alive>;
+
+	initial_alive: initial-state {
+		PIN(INPUT, gpa0-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpa0-1, NONE, FAST_SR1);
+		PIN(INPUT, gpa0-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpa0-3, NONE, FAST_SR1);
+		PIN(INPUT, gpa0-4, NONE, FAST_SR1);
+		PIN(INPUT, gpa0-5, DOWN, FAST_SR1);
+		PIN(INPUT, gpa0-6, NONE, FAST_SR1);
+		PIN(INPUT, gpa0-7, NONE, FAST_SR1);
+
+		PIN(INPUT, gpa1-0, UP, FAST_SR1);
+		PIN(INPUT, gpa1-1, NONE, FAST_SR1);
+		PIN(INPUT, gpa1-2, NONE, FAST_SR1);
+		PIN(INPUT, gpa1-3, DOWN, FAST_SR1);
+		PIN(INPUT, gpa1-4, DOWN, FAST_SR1);
+		PIN(INPUT, gpa1-5, NONE, FAST_SR1);
+		PIN(INPUT, gpa1-6, NONE, FAST_SR1);
+		PIN(INPUT, gpa1-7, NONE, FAST_SR1);
+
+		PIN(INPUT, gpa2-0, NONE, FAST_SR1);
+		PIN(INPUT, gpa2-1, NONE, FAST_SR1);
+		PIN(INPUT, gpa2-2, NONE, FAST_SR1);
+		PIN(INPUT, gpa2-3, DOWN, FAST_SR1);
+		PIN(INPUT, gpa2-4, NONE, FAST_SR1);
+		PIN(INPUT, gpa2-5, DOWN, FAST_SR1);
+		PIN(INPUT, gpa2-6, DOWN, FAST_SR1);
+		PIN(INPUT, gpa2-7, NONE, FAST_SR1);
+
+		PIN(INPUT, gpa3-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpa3-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpa3-2, NONE, FAST_SR1);
+		PIN(INPUT, gpa3-3, DOWN, FAST_SR1);
+		PIN(INPUT, gpa3-4, NONE, FAST_SR1);
+		PIN(INPUT, gpa3-5, DOWN, FAST_SR1);
+		PIN(INPUT, gpa3-6, DOWN, FAST_SR1);
+		PIN(INPUT, gpa3-7, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpf1-0, NONE, FAST_SR1);
+		PIN(INPUT, gpf1-1, NONE, FAST_SR1);
+		PIN(INPUT, gpf1-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpf1-4, UP, FAST_SR1);
+		PIN(OUTPUT, gpf1-5, NONE, FAST_SR1);
+		PIN(INPUT, gpf1-6, DOWN, FAST_SR1);
+		PIN(INPUT, gpf1-7, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpf2-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpf2-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpf2-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpf2-3, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpf3-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpf3-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpf3-2, NONE, FAST_SR1);
+		PIN(INPUT, gpf3-3, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpf4-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpf4-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpf4-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpf4-3, DOWN, FAST_SR1);
+		PIN(INPUT, gpf4-4, DOWN, FAST_SR1);
+		PIN(INPUT, gpf4-5, DOWN, FAST_SR1);
+		PIN(INPUT, gpf4-6, DOWN, FAST_SR1);
+		PIN(INPUT, gpf4-7, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpf5-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpf5-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpf5-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpf5-3, DOWN, FAST_SR1);
+		PIN(OUTPUT, gpf5-4, NONE, FAST_SR1);
+		PIN(INPUT, gpf5-5, DOWN, FAST_SR1);
+		PIN(INPUT, gpf5-6, DOWN, FAST_SR1);
+		PIN(INPUT, gpf5-7, DOWN, FAST_SR1);
+	};
+
+	te_irq: te_irq {
+		samsung,pins = "gpf1-3";
+		samsung,pin-function = <0xf>;
+	};
+};
+
+&pinctrl_cpif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&initial_cpif>;
+
+	initial_cpif: initial-state {
+		PIN(INPUT, gpv6-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpv6-1, DOWN, FAST_SR1);
+	};
+};
+
+&pinctrl_ese {
+	pinctrl-names = "default";
+	pinctrl-0 = <&initial_ese>;
+
+	initial_ese: initial-state {
+		PIN(INPUT, gpj2-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpj2-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpj2-2, DOWN, FAST_SR1);
+	};
+};
+
+&pinctrl_fsys {
+	pinctrl-names = "default";
+	pinctrl-0 = <&initial_fsys>;
+
+	initial_fsys: initial-state {
+		PIN(INPUT, gpr3-0, NONE, FAST_SR1);
+		PIN(INPUT, gpr3-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpr3-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpr3-3, DOWN, FAST_SR1);
+		PIN(INPUT, gpr3-7, NONE, FAST_SR1);
+	};
+};
+
+&pinctrl_imem {
+	pinctrl-names = "default";
+	pinctrl-0 = <&initial_imem>;
+
+	initial_imem: initial-state {
+		PIN(INPUT, gpf0-0, UP, FAST_SR1);
+		PIN(INPUT, gpf0-1, UP, FAST_SR1);
+		PIN(INPUT, gpf0-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpf0-3, UP, FAST_SR1);
+		PIN(INPUT, gpf0-4, DOWN, FAST_SR1);
+		PIN(INPUT, gpf0-5, NONE, FAST_SR1);
+		PIN(INPUT, gpf0-6, DOWN, FAST_SR1);
+		PIN(INPUT, gpf0-7, UP, FAST_SR1);
+	};
+};
+
+&pinctrl_nfc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&initial_nfc>;
+
+	initial_nfc: initial-state {
+		PIN(INPUT, gpj0-2, DOWN, FAST_SR1);
+	};
+};
+
+&pinctrl_peric {
+	pinctrl-names = "default";
+	pinctrl-0 = <&initial_peric>;
+
+	initial_peric: initial-state {
+		PIN(INPUT, gpv7-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpv7-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpv7-2, NONE, FAST_SR1);
+		PIN(INPUT, gpv7-3, DOWN, FAST_SR1);
+		PIN(INPUT, gpv7-4, DOWN, FAST_SR1);
+		PIN(INPUT, gpv7-5, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpb0-4, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpc0-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpc0-5, DOWN, FAST_SR1);
+		PIN(INPUT, gpc0-7, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpc1-1, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpc3-4, NONE, FAST_SR1);
+		PIN(INPUT, gpc3-5, NONE, FAST_SR1);
+		PIN(INPUT, gpc3-6, NONE, FAST_SR1);
+		PIN(INPUT, gpc3-7, NONE, FAST_SR1);
+
+		PIN(OUTPUT, gpg0-0, NONE, FAST_SR1);
+		PIN(2, gpg0-1, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpd2-5, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpd4-0, NONE, FAST_SR1);
+		PIN(INPUT, gpd4-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpd4-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpd4-3, DOWN, FAST_SR1);
+		PIN(INPUT, gpd4-4, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpd6-3, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpd8-1, UP, FAST_SR1);
+
+		PIN(INPUT, gpg1-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpg1-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpg1-2, DOWN, FAST_SR1);
+		PIN(INPUT, gpg1-3, DOWN, FAST_SR1);
+		PIN(INPUT, gpg1-4, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpg2-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpg2-1, DOWN, FAST_SR1);
+
+		PIN(INPUT, gpg3-0, DOWN, FAST_SR1);
+		PIN(INPUT, gpg3-1, DOWN, FAST_SR1);
+		PIN(INPUT, gpg3-5, DOWN, FAST_SR1);
+		PIN(INPUT, gpg3-7, DOWN, FAST_SR1);
+	};
+};
+
+&pinctrl_touch {
+	pinctrl-names = "default";
+	pinctrl-0 = <&initial_touch>;
+
+	initial_touch: initial-state {
+		PIN(INPUT, gpj1-2, DOWN, FAST_SR1);
+	};
+};
+
+&pwm {
+	pinctrl-0 = <&pwm0_out>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&mic {
+	status = "okay";
+
+	i80-if-timings {
+	};
+};
+
+&pmu_system_controller {
+	assigned-clocks = <&pmu_system_controller 0>;
+	assigned-clock-parents = <&xxti>;
+};
+
+&serial_1 {
+	status = "okay";
+};
+
+&spi_1 {
+	cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+
+	wm5110: wm5110-codec at 0 {
+		compatible = "wlf,wm5110";
+		reg = <0x0>;
+		spi-max-frequency = <20000000>;
+		interrupt-parent = <&gpa0>;
+		interrupts = <4 IRQ_TYPE_NONE>;
+		clocks = <&pmu_system_controller 0>,
+			<&s2mps13_osc S2MPS11_CLK_BT>;
+		clock-names = "mclk1", "mclk2";
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		wlf,micd-detect-debounce = <300>;
+		wlf,micd-bias-start-time = <0x1>;
+		wlf,micd-rate = <0x7>;
+		wlf,micd-dbtime = <0x1>;
+		wlf,micd-force-micbias;
+		wlf,micd-configs = <0x0 1 0>;
+		wlf,hpdet-channel = <1>;
+		wlf,gpsw = <0x1>;
+		wlf,inmode = <2 0 2 0>;
+
+		wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+		wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+		/* core supplies */
+		AVDD-supply = <&ldo18_reg>;
+		DBVDD1-supply = <&ldo18_reg>;
+		CPVDD-supply = <&ldo18_reg>;
+		DBVDD2-supply = <&ldo18_reg>;
+		DBVDD3-supply = <&ldo18_reg>;
+
+		controller-data {
+			samsung,spi-feedback-delay = <0>;
+		};
+	};
+};
+
+&timer {
+	clock-frequency = <24000000>;
+};
+
+&tmu_atlas0 {
+	vtmu-supply = <&ldo3_reg>;
+	status = "okay";
+};
+
+&tmu_apollo {
+	vtmu-supply = <&ldo3_reg>;
+	status = "okay";
+};
+
+&tmu_g3d {
+	vtmu-supply = <&ldo3_reg>;
+	status = "okay";
+};
+
+&usbdrd30 {
+	vdd33-supply = <&ldo10_reg>;
+	vdd10-supply = <&ldo6_reg>;
+	status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+	dr_mode = "otg";
+};
+
+&usbdrd30_phy {
+	vbus-supply = <&safeout1_reg>;
+	status = "okay";
+};
+
+&xxti {
+	clock-frequency = <24000000>;
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
dissimilarity index 98%
index e8971f4..d30b45a 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -1,1120 +1,33 @@
-/*
- * SAMSUNG Exynos5433 TM2 board device tree source
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Device tree source file for Samsung's TM2 board which is based on
- * Samsung Exynos5433 SoC.
- *
- * 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.
- */
-
-/dts-v1/;
-#include "exynos5433.dtsi"
-#include <dt-bindings/clock/samsung,s2mps11.h>
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-
-/ {
-	model = "Samsung TM2 board";
-	compatible = "samsung,tm2", "samsung,exynos5433";
-
-	aliases {
-		gsc0 = &gsc_0;
-		gsc1 = &gsc_1;
-		gsc2 = &gsc_2;
-		pinctrl0 = &pinctrl_alive;
-		pinctrl1 = &pinctrl_aud;
-		pinctrl2 = &pinctrl_cpif;
-		pinctrl3 = &pinctrl_ese;
-		pinctrl4 = &pinctrl_finger;
-		pinctrl5 = &pinctrl_fsys;
-		pinctrl6 = &pinctrl_imem;
-		pinctrl7 = &pinctrl_nfc;
-		pinctrl8 = &pinctrl_peric;
-		pinctrl9 = &pinctrl_touch;
-		serial0 = &serial_0;
-		serial1 = &serial_1;
-		serial2 = &serial_2;
-		serial3 = &serial_3;
-		spi0 = &spi_0;
-		spi1 = &spi_1;
-		spi2 = &spi_2;
-		spi3 = &spi_3;
-		spi4 = &spi_4;
-		mshc0 = &mshc_0;
-		mshc2 = &mshc_2;
-	};
-
-	chosen {
-		stdout-path = &serial_1;
-	};
-
-	memory at 20000000 {
-		device_type = "memory";
-		reg = <0x0 0x20000000 0x0 0xc0000000>;
-	};
-
-	gpio-keys {
-		compatible = "gpio-keys";
-
-		power-key {
-			gpios = <&gpa2 7 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_POWER>;
-			label = "power key";
-			debounce-interval = <10>;
-		};
-
-		volume-up-key {
-			gpios = <&gpa2 0 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_VOLUMEUP>;
-			label = "volume-up key";
-			debounce-interval = <10>;
-		};
-
-		volume-down-key {
-			gpios = <&gpa2 1 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_VOLUMEDOWN>;
-			label = "volume-down key";
-			debounce-interval = <10>;
-		};
-
-		homepage-key {
-			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_MENU>;
-			label = "homepage key";
-			debounce-interval = <10>;
-		};
-	};
-
-	i2c_max98504: i2c-gpio-0 {
-		compatible = "i2c-gpio";
-		gpios = <&gpd0 1 GPIO_ACTIVE_HIGH /* SPK_AMP_SDA */
-			 &gpd0 0 GPIO_ACTIVE_HIGH /* SPK_AMP_SCL */ >;
-		i2c-gpio,delay-us = <2>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		status = "okay";
-
-		max98504: max98504 at 31 {
-			compatible = "maxim,max98504";
-			reg = <0x31>;
-			maxim,rx-path = <1>;
-			maxim,tx-path = <1>;
-			maxim,tx-channel-mask = <3>;
-			maxim,tx-channel-source = <2>;
-		};
-	};
-
-	sound {
-		compatible = "samsung,tm2-audio";
-		audio-codec = <&wm5110>;
-		i2s-controller = <&i2s0>;
-		audio-amplifier = <&max98504>;
-		mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
-		model = "wm5110";
-		samsung,audio-routing =
-			/* Headphone */
-			"HP", "HPOUT1L",
-			"HP", "HPOUT1R",
-
-			/* Speaker */
-			"SPK", "SPKOUT",
-			"SPKOUT", "HPOUT2L",
-			"SPKOUT", "HPOUT2R",
-
-			/* Receiver */
-			"RCV", "HPOUT3L",
-			"RCV", "HPOUT3R";
-		status = "okay";
-	};
-};
-
-&adc {
-	vdd-supply = <&ldo3_reg>;
-	status = "okay";
-
-	thermistor-ap {
-		compatible = "murata,ncp03wf104";
-		pullup-uv = <1800000>;
-		pullup-ohm = <100000>;
-		pulldown-ohm = <0>;
-		io-channels = <&adc 0>;
-	};
-
-	thermistor-battery {
-		compatible = "murata,ncp03wf104";
-		pullup-uv = <1800000>;
-		pullup-ohm = <100000>;
-		pulldown-ohm = <0>;
-		io-channels = <&adc 1>;
-		#thermal-sensor-cells = <0>;
-	};
-
-	thermistor-charger {
-		compatible = "murata,ncp03wf104";
-		pullup-uv = <1800000>;
-		pullup-ohm = <100000>;
-		pulldown-ohm = <0>;
-		io-channels = <&adc 2>;
-	};
-};
-
-&bus_g2d_400 {
-	devfreq-events = <&ppmu_event0_d0_general>, <&ppmu_event0_d1_general>;
-	vdd-supply = <&buck4_reg>;
-	exynos,saturation-ratio = <10>;
-	status = "okay";
-};
-
-&bus_g2d_266 {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&bus_gscl {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&bus_hevc {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&bus_jpeg {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&bus_mfc {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&bus_mscl {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&bus_noc0 {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&bus_noc1 {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&bus_noc2 {
-	devfreq = <&bus_g2d_400>;
-	status = "okay";
-};
-
-&cmu_aud {
-	assigned-clocks = <&cmu_aud CLK_MOUT_AUD_PLL_USER>;
-	assigned-clock-parents = <&cmu_top CLK_FOUT_AUD_PLL>;
-};
-
-&cmu_fsys {
-	assigned-clocks = <&cmu_top CLK_MOUT_SCLK_USBDRD30>,
-		<&cmu_top CLK_MOUT_SCLK_USBHOST30>,
-		<&cmu_fsys CLK_MOUT_SCLK_USBDRD30_USER>,
-		<&cmu_fsys CLK_MOUT_SCLK_USBHOST30_USER>,
-		<&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_USER>,
-		<&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_USER>,
-		<&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_USER>,
-		<&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_USER>,
-		<&cmu_top CLK_DIV_SCLK_USBDRD30>,
-		<&cmu_top CLK_DIV_SCLK_USBHOST30>;
-	assigned-clock-parents = <&cmu_top CLK_MOUT_BUS_PLL_USER>,
-		<&cmu_top CLK_MOUT_BUS_PLL_USER>,
-		<&cmu_top CLK_SCLK_USBDRD30_FSYS>,
-		<&cmu_top CLK_SCLK_USBHOST30_FSYS>,
-		<&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY>,
-		<&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY>,
-		<&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY>,
-		<&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY>;
-	assigned-clock-rates = <0>, <0>, <0>, <0>, <0>, <0>, <0>, <0>,
-			       <66700000>, <66700000>;
-};
-
-&cmu_gscl {
-	assigned-clocks = <&cmu_gscl CLK_MOUT_ACLK_GSCL_111_USER>,
-			  <&cmu_gscl CLK_MOUT_ACLK_GSCL_333_USER>;
-	assigned-clock-parents = <&cmu_top CLK_ACLK_GSCL_111>,
-				 <&cmu_top CLK_ACLK_GSCL_333>;
-};
-
-&cmu_mfc {
-	assigned-clocks = <&cmu_mfc CLK_MOUT_ACLK_MFC_400_USER>;
-	assigned-clock-parents = <&cmu_top CLK_ACLK_MFC_400>;
-};
-
-&cmu_mscl {
-	assigned-clocks = <&cmu_mscl CLK_MOUT_ACLK_MSCL_400_USER>,
-			  <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
-			  <&cmu_mscl CLK_MOUT_SCLK_JPEG>,
-			  <&cmu_top CLK_MOUT_SCLK_JPEG_A>;
-	assigned-clock-parents = <&cmu_top CLK_ACLK_MSCL_400>,
-				 <&cmu_top CLK_SCLK_JPEG_MSCL>,
-				 <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
-				 <&cmu_top CLK_MOUT_BUS_PLL_USER>;
-};
-
-&cpu0 {
-	cpu-supply = <&buck3_reg>;
-};
-
-&cpu4 {
-	cpu-supply = <&buck2_reg>;
-};
-
-&decon {
-	status = "okay";
-
-	i80-if-timings {
-	};
-};
-
-&dsi {
-	status = "okay";
-	vddcore-supply = <&ldo6_reg>;
-	vddio-supply = <&ldo7_reg>;
-	samsung,pll-clock-frequency = <24000000>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&te_irq>;
-
-	ports {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		port at 1 {
-			reg = <1>;
-
-			dsi_out: endpoint {
-				samsung,burst-clock-frequency = <512000000>;
-				samsung,esc-clock-frequency = <16000000>;
-			};
-		};
-	};
-};
-
-&hsi2c_0 {
-	status = "okay";
-	clock-frequency = <2500000>;
-
-	s2mps13-pmic at 66 {
-		compatible = "samsung,s2mps13-pmic";
-		interrupt-parent = <&gpa0>;
-		interrupts = <7 IRQ_TYPE_NONE>;
-		reg = <0x66>;
-		samsung,s2mps11-wrstbi-ground;
-
-		s2mps13_osc: clocks {
-			compatible = "samsung,s2mps13-clk";
-			#clock-cells = <1>;
-			clock-output-names = "s2mps13_ap", "s2mps13_cp",
-				"s2mps13_bt";
-		};
-
-		regulators {
-			ldo1_reg: LDO1 {
-				regulator-name = "VDD_ALIVE_0.9V_AP";
-				regulator-min-microvolt = <900000>;
-				regulator-max-microvolt = <900000>;
-				regulator-always-on;
-			};
-
-			ldo2_reg: LDO2 {
-				regulator-name = "VDDQ_MMC2_2.8V_AP";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo3_reg: LDO3 {
-				regulator-name = "VDD1_E_1.8V_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-always-on;
-			};
-
-			ldo4_reg: LDO4 {
-				regulator-name = "VDD10_MIF_PLL_1.0V_AP";
-				regulator-min-microvolt = <1300000>;
-				regulator-max-microvolt = <1300000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo5_reg: LDO5 {
-				regulator-name = "VDD10_DPLL_1.0V_AP";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo6_reg: LDO6 {
-				regulator-name = "VDD10_MIPI2L_1.0V_AP";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo7_reg: LDO7 {
-				regulator-name = "VDD18_MIPI2L_1.8V_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo8_reg: LDO8 {
-				regulator-name = "VDD18_LLI_1.8V_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo9_reg: LDO9 {
-				regulator-name = "VDD18_ABB_ETC_1.8V_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo10_reg: LDO10 {
-				regulator-name = "VDD33_USB30_3.0V_AP";
-				regulator-min-microvolt = <3000000>;
-				regulator-max-microvolt = <3000000>;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo11_reg: LDO11 {
-				regulator-name = "VDD_INT_M_1.0V_AP";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo12_reg: LDO12 {
-				regulator-name = "VDD_KFC_M_1.1V_AP";
-				regulator-min-microvolt = <800000>;
-				regulator-max-microvolt = <1350000>;
-				regulator-always-on;
-			};
-
-			ldo13_reg: LDO13 {
-				regulator-name = "VDD_G3D_M_0.95V_AP";
-				regulator-min-microvolt = <950000>;
-				regulator-max-microvolt = <950000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo14_reg: LDO14 {
-				regulator-name = "VDDQ_M1_LDO_1.2V_AP";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo15_reg: LDO15 {
-				regulator-name = "VDDQ_M2_LDO_1.2V_AP";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			ldo16_reg: LDO16 {
-				regulator-name = "VDDQ_EFUSE";
-				regulator-min-microvolt = <1400000>;
-				regulator-max-microvolt = <3400000>;
-				regulator-always-on;
-			};
-
-			ldo17_reg: LDO17 {
-				regulator-name = "V_TFLASH_2.8V_AP";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-			};
-
-			ldo18_reg: LDO18 {
-				regulator-name = "V_CODEC_1.8V_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo19_reg: LDO19 {
-				regulator-name = "VDDA_1.8V_COMP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-always-on;
-			};
-
-			ldo20_reg: LDO20 {
-				regulator-name = "VCC_2.8V_AP";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-				regulator-always-on;
-			};
-
-			ldo21_reg: LDO21 {
-				regulator-name = "VT_CAM_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo22_reg: LDO22 {
-				regulator-name = "CAM_IO_1.8V_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo23_reg: LDO23 {
-				regulator-name = "CAM_SEN_CORE_1.05V_AP";
-				regulator-min-microvolt = <1050000>;
-				regulator-max-microvolt = <1050000>;
-			};
-
-			ldo24_reg: LDO24 {
-				regulator-name = "VT_CAM_1.2V";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-			};
-
-			ldo25_reg: LDO25 {
-				regulator-name = "UNUSED_LDO25";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-				regulator-always-off;
-			};
-
-			ldo26_reg: LDO26 {
-				regulator-name = "CAM_AF_2.8V_AP";
-				regulator-min-microvolt = <2800000>;
-				regulator-max-microvolt = <2800000>;
-			};
-
-			ldo27_reg: LDO27 {
-				regulator-name = "VCC_3.0V_LCD_AP";
-				regulator-min-microvolt = <3000000>;
-				regulator-max-microvolt = <3000000>;
-			};
-
-			ldo28_reg: LDO28 {
-				regulator-name = "VCC_1.8V_LCD_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo29_reg: LDO29 {
-				regulator-name = "VT_CAM_2.8V";
-				regulator-min-microvolt = <3000000>;
-				regulator-max-microvolt = <3000000>;
-			};
-
-			ldo30_reg: LDO30 {
-				regulator-name = "TSP_AVDD_3.3V_AP";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-			};
-
-			ldo31_reg: LDO31 {
-				regulator-name = "TSP_VDD_1.85V_AP";
-				regulator-min-microvolt = <1850000>;
-				regulator-max-microvolt = <1850000>;
-			};
-
-			ldo32_reg: LDO32 {
-				regulator-name = "VTOUCH_1.8V_AP";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo33_reg: LDO33 {
-				regulator-name = "VTOUCH_LED_3.3V";
-				regulator-min-microvolt = <2500000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-ramp-delay = <12500>;
-			};
-
-			ldo34_reg: LDO34 {
-				regulator-name = "VCC_1.8V_MHL_AP";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <2100000>;
-			};
-
-			ldo35_reg: LDO35 {
-				regulator-name = "OIS_VM_2.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <2800000>;
-			};
-
-			ldo36_reg: LDO36 {
-				regulator-name = "VSIL_1.0V";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-			};
-
-			ldo37_reg: LDO37 {
-				regulator-name = "VF_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo38_reg: LDO38 {
-				regulator-name = "VCC_3.0V_MOTOR_AP";
-				regulator-min-microvolt = <3000000>;
-				regulator-max-microvolt = <3000000>;
-			};
-
-			ldo39_reg: LDO39 {
-				regulator-name = "V_HRM_1.8V";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			ldo40_reg: LDO40 {
-				regulator-name = "V_HRM_3.3V";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-			};
-
-			buck1_reg: BUCK1 {
-				regulator-name = "VDD_MIF_0.9V_AP";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <1500000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck2_reg: BUCK2 {
-				regulator-name = "VDD_EGL_1.0V_AP";
-				regulator-min-microvolt = <900000>;
-				regulator-max-microvolt = <1300000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck3_reg: BUCK3 {
-				regulator-name = "VDD_KFC_1.0V_AP";
-				regulator-min-microvolt = <800000>;
-				regulator-max-microvolt = <1200000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck4_reg: BUCK4 {
-				regulator-name = "VDD_INT_0.95V_AP";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <1500000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck5_reg: BUCK5 {
-				regulator-name = "VDD_DISP_CAM0_0.9V_AP";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <1500000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck6_reg: BUCK6 {
-				regulator-name = "VDD_G3D_0.9V_AP";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <1500000>;
-				regulator-always-on;
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			buck7_reg: BUCK7 {
-				regulator-name = "VDD_MEM1_1.2V_AP";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-				regulator-always-on;
-			};
-
-			buck8_reg: BUCK8 {
-				regulator-name = "VDD_LLDO_1.35V_AP";
-				regulator-min-microvolt = <1350000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-
-			buck9_reg: BUCK9 {
-				regulator-name = "VDD_MLDO_2.0V_AP";
-				regulator-min-microvolt = <1350000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-
-			buck10_reg: BUCK10 {
-				regulator-name = "vdd_mem2";
-				regulator-min-microvolt = <550000>;
-				regulator-max-microvolt = <1500000>;
-				regulator-always-on;
-			};
-		};
-	};
-};
-
-&hsi2c_8 {
-	status = "okay";
-
-	max77843 at 66 {
-		compatible = "maxim,max77843";
-		interrupt-parent = <&gpa1>;
-		interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
-		reg = <0x66>;
-
-		muic: max77843-muic {
-			compatible = "maxim,max77843-muic";
-		};
-
-		regulators {
-			compatible = "maxim,max77843-regulator";
-			safeout1_reg: SAFEOUT1 {
-				regulator-name = "SAFEOUT1";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <4950000>;
-			};
-
-			safeout2_reg: SAFEOUT2 {
-				regulator-name = "SAFEOUT2";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <4950000>;
-			};
-
-			charger_reg: CHARGER {
-				regulator-name = "CHARGER";
-				regulator-min-microamp = <100000>;
-				regulator-max-microamp = <3150000>;
-			};
-		};
-
-		haptic: max77843-haptic {
-			compatible = "maxim,max77843-haptic";
-			haptic-supply = <&ldo38_reg>;
-			pwms = <&pwm 0 33670 0>;
-			pwm-names = "haptic";
-		};
-	};
-};
-
-&i2s0 {
-	status = "okay";
-};
-
-&mshc_0 {
-	status = "okay";
-	num-slots = <1>;
-	mmc-hs200-1_8v;
-	mmc-hs400-1_8v;
-	cap-mmc-highspeed;
-	non-removable;
-	card-detect-delay = <200>;
-	samsung,dw-mshc-ciu-div = <3>;
-	samsung,dw-mshc-sdr-timing = <0 4>;
-	samsung,dw-mshc-ddr-timing = <0 2>;
-	samsung,dw-mshc-hs400-timing = <0 3>;
-	samsung,read-strobe-delay = <90>;
-	fifo-depth = <0x80>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4
-			&sd0_bus8 &sd0_rdqs>;
-	bus-width = <8>;
-	assigned-clocks = <&cmu_top CLK_SCLK_MMC0_FSYS>;
-	assigned-clock-rates = <800000000>;
-};
-
-&mshc_2 {
-	status = "okay";
-	num-slots = <1>;
-	cap-sd-highspeed;
-	disable-wp;
-	cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>;
-	cd-inverted;
-	card-detect-delay = <200>;
-	samsung,dw-mshc-ciu-div = <3>;
-	samsung,dw-mshc-sdr-timing = <0 4>;
-	samsung,dw-mshc-ddr-timing = <0 2>;
-	fifo-depth = <0x80>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>;
-	bus-width = <4>;
-};
-
-&ppmu_d0_general {
-	status = "okay";
-	events {
-		ppmu_event0_d0_general: ppmu-event0-d0-general {
-			event-name = "ppmu-event0-d0-general";
-		};
-	};
-};
-
-&ppmu_d1_general {
-	status = "okay";
-	events {
-		ppmu_event0_d1_general: ppmu-event0-d1-general {
-		       event-name = "ppmu-event0-d1-general";
-	       };
-       };
-};
-
-&pinctrl_alive {
-	pinctrl-names = "default";
-	pinctrl-0 = <&initial_alive>;
-
-	initial_alive: initial-state {
-		PIN(INPUT, gpa0-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpa0-1, NONE, FAST_SR1);
-		PIN(INPUT, gpa0-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpa0-3, NONE, FAST_SR1);
-		PIN(INPUT, gpa0-4, NONE, FAST_SR1);
-		PIN(INPUT, gpa0-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpa0-6, NONE, FAST_SR1);
-		PIN(INPUT, gpa0-7, NONE, FAST_SR1);
-
-		PIN(INPUT, gpa1-0, UP, FAST_SR1);
-		PIN(INPUT, gpa1-1, NONE, FAST_SR1);
-		PIN(INPUT, gpa1-2, NONE, FAST_SR1);
-		PIN(INPUT, gpa1-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpa1-4, DOWN, FAST_SR1);
-		PIN(INPUT, gpa1-5, NONE, FAST_SR1);
-		PIN(INPUT, gpa1-6, NONE, FAST_SR1);
-		PIN(INPUT, gpa1-7, NONE, FAST_SR1);
-
-		PIN(INPUT, gpa2-0, NONE, FAST_SR1);
-		PIN(INPUT, gpa2-1, NONE, FAST_SR1);
-		PIN(INPUT, gpa2-2, NONE, FAST_SR1);
-		PIN(INPUT, gpa2-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpa2-4, NONE, FAST_SR1);
-		PIN(INPUT, gpa2-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpa2-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpa2-7, NONE, FAST_SR1);
-
-		PIN(INPUT, gpa3-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-2, NONE, FAST_SR1);
-		PIN(INPUT, gpa3-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-4, NONE, FAST_SR1);
-		PIN(INPUT, gpa3-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-7, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf1-0, NONE, FAST_SR1);
-		PIN(INPUT, gpf1-1, NONE, FAST_SR1);
-		PIN(INPUT, gpf1-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf1-4, UP, FAST_SR1);
-		PIN(OUTPUT, gpf1-5, NONE, FAST_SR1);
-		PIN(INPUT, gpf1-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpf1-7, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf2-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpf2-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpf2-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf2-3, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf3-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpf3-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpf3-2, NONE, FAST_SR1);
-		PIN(INPUT, gpf3-3, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf4-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-4, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-7, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf5-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-3, DOWN, FAST_SR1);
-		PIN(OUTPUT, gpf5-4, NONE, FAST_SR1);
-		PIN(INPUT, gpf5-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-7, DOWN, FAST_SR1);
-	};
-
-	te_irq: te_irq {
-		samsung,pins = "gpf1-3";
-		samsung,pin-function = <0xf>;
-	};
-};
-
-&pinctrl_cpif {
-	pinctrl-names = "default";
-	pinctrl-0 = <&initial_cpif>;
-
-	initial_cpif: initial-state {
-		PIN(INPUT, gpv6-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpv6-1, DOWN, FAST_SR1);
-	};
-};
-
-&pinctrl_ese {
-	pinctrl-names = "default";
-	pinctrl-0 = <&initial_ese>;
-
-	initial_ese: initial-state {
-		PIN(INPUT, gpj2-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpj2-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpj2-2, DOWN, FAST_SR1);
-	};
-};
-
-&pinctrl_fsys {
-	pinctrl-names = "default";
-	pinctrl-0 = <&initial_fsys>;
-
-	initial_fsys: initial-state {
-		PIN(INPUT, gpr3-0, NONE, FAST_SR1);
-		PIN(INPUT, gpr3-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpr3-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpr3-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpr3-7, NONE, FAST_SR1);
-	};
-};
-
-&pinctrl_imem {
-	pinctrl-names = "default";
-	pinctrl-0 = <&initial_imem>;
-
-	initial_imem: initial-state {
-		PIN(INPUT, gpf0-0, UP, FAST_SR1);
-		PIN(INPUT, gpf0-1, UP, FAST_SR1);
-		PIN(INPUT, gpf0-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf0-3, UP, FAST_SR1);
-		PIN(INPUT, gpf0-4, DOWN, FAST_SR1);
-		PIN(INPUT, gpf0-5, NONE, FAST_SR1);
-		PIN(INPUT, gpf0-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpf0-7, UP, FAST_SR1);
-	};
-};
-
-&pinctrl_nfc {
-	pinctrl-names = "default";
-	pinctrl-0 = <&initial_nfc>;
-
-	initial_nfc: initial-state {
-		PIN(INPUT, gpj0-2, DOWN, FAST_SR1);
-	};
-};
-
-&pinctrl_peric {
-	pinctrl-names = "default";
-	pinctrl-0 = <&initial_peric>;
-
-	initial_peric: initial-state {
-		PIN(INPUT, gpv7-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpv7-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpv7-2, NONE, FAST_SR1);
-		PIN(INPUT, gpv7-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpv7-4, DOWN, FAST_SR1);
-		PIN(INPUT, gpv7-5, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpb0-4, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpc0-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpc0-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpc0-7, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpc1-1, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpc3-4, NONE, FAST_SR1);
-		PIN(INPUT, gpc3-5, NONE, FAST_SR1);
-		PIN(INPUT, gpc3-6, NONE, FAST_SR1);
-		PIN(INPUT, gpc3-7, NONE, FAST_SR1);
-
-		PIN(OUTPUT, gpg0-0, NONE, FAST_SR1);
-		PIN(2, gpg0-1, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpd2-5, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpd4-0, NONE, FAST_SR1);
-		PIN(INPUT, gpd4-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpd4-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpd4-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpd4-4, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpd6-3, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpd8-1, UP, FAST_SR1);
-
-		PIN(INPUT, gpg1-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpg1-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpg1-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpg1-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpg1-4, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpg2-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpg2-1, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpg3-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpg3-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpg3-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpg3-7, DOWN, FAST_SR1);
-	};
-};
-
-&pinctrl_touch {
-	pinctrl-names = "default";
-	pinctrl-0 = <&initial_touch>;
-
-	initial_touch: initial-state {
-		PIN(INPUT, gpj1-2, DOWN, FAST_SR1);
-	};
-};
-
-&pwm {
-	pinctrl-0 = <&pwm0_out>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&mic {
-	status = "okay";
-
-	i80-if-timings {
-	};
-};
-
-&pmu_system_controller {
-	assigned-clocks = <&pmu_system_controller 0>;
-	assigned-clock-parents = <&xxti>;
-};
-
-&serial_1 {
-	status = "okay";
-};
-
-&spi_1 {
-	cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
-	status = "okay";
-
-	wm5110: wm5110-codec at 0 {
-		compatible = "wlf,wm5110";
-		reg = <0x0>;
-		spi-max-frequency = <20000000>;
-		interrupt-parent = <&gpa0>;
-		interrupts = <4 IRQ_TYPE_NONE>;
-		clocks = <&pmu_system_controller 0>,
-			<&s2mps13_osc S2MPS11_CLK_BT>;
-		clock-names = "mclk1", "mclk2";
-
-		gpio-controller;
-		#gpio-cells = <2>;
-
-		wlf,micd-detect-debounce = <300>;
-		wlf,micd-bias-start-time = <0x1>;
-		wlf,micd-rate = <0x7>;
-		wlf,micd-dbtime = <0x1>;
-		wlf,micd-force-micbias;
-		wlf,micd-configs = <0x0 1 0>;
-		wlf,hpdet-channel = <1>;
-		wlf,gpsw = <0x1>;
-		wlf,inmode = <2 0 2 0>;
-
-		wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
-		wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
-
-		/* core supplies */
-		AVDD-supply = <&ldo18_reg>;
-		DBVDD1-supply = <&ldo18_reg>;
-		CPVDD-supply = <&ldo18_reg>;
-		DBVDD2-supply = <&ldo18_reg>;
-		DBVDD3-supply = <&ldo18_reg>;
-
-		controller-data {
-			samsung,spi-feedback-delay = <0>;
-		};
-	};
-};
-
-&timer {
-	clock-frequency = <24000000>;
-};
-
-&tmu_atlas0 {
-	vtmu-supply = <&ldo3_reg>;
-	status = "okay";
-};
-
-&tmu_apollo {
-	vtmu-supply = <&ldo3_reg>;
-	status = "okay";
-};
-
-&tmu_g3d {
-	vtmu-supply = <&ldo3_reg>;
-	status = "okay";
-};
-
-&usbdrd30 {
-	vdd33-supply = <&ldo10_reg>;
-	vdd10-supply = <&ldo6_reg>;
-	status = "okay";
-};
-
-&usbdrd_dwc3_0 {
-	dr_mode = "otg";
-};
-
-&usbdrd30_phy {
-	vbus-supply = <&safeout1_reg>;
-	status = "okay";
-};
-
-&xxti {
-	clock-frequency = <24000000>;
-};
+/*
+ * SAMSUNG Exynos5433 TM2 board device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Device tree source file for Samsung's TM2 board which is based on
+ * Samsung Exynos5433 SoC.
+ *
+ * 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 "exynos5433-tm2-common.dtsi"
+
+/ {
+	model = "Samsung TM2E board";
+	compatible = "samsung,tm2e", "samsung,exynos5433";
+};
+
+&regulators {
+	ldo31_reg: LDO31 {
+		regulator-name = "TSP_VDD_1.85V_AP";
+		regulator-min-microvolt = <1850000>;
+		regulator-max-microvolt = <1850000>;
+	};
+
+	ldo38_reg: LDO38 {
+		regulator-name = "VCC_3.0V_MOTOR_AP";
+		regulator-min-microvolt = <3000000>;
+		regulator-max-microvolt = <3000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
index 854c583..53e361f 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
@@ -11,21 +11,23 @@
  * published by the Free Software Foundation.
  */
 
-#include "exynos5433-tm2.dts"
+#include "exynos5433-tm2-common.dtsi"
 
 / {
 	model = "Samsung TM2E board";
 	compatible = "samsung,tm2e", "samsung,exynos5433";
 };
 
-&ldo31_reg {
-	regulator-name = "TSP_VDD_1.8V_AP";
-	regulator-min-microvolt = <1800000>;
-	regulator-max-microvolt = <1800000>;
-};
+&regulators {
+	ldo31_reg: LDO31 {
+		regulator-name = "TSP_VDD_1.8V_AP";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
 
-&ldo38_reg {
-	regulator-name = "VCC_3.3V_MOTOR_AP";
-	regulator-min-microvolt = <3300000>;
-	regulator-max-microvolt = <3300000>;
+	ldo38_reg: LDO38 {
+		regulator-name = "VCC_3.3V_MOTOR_AP";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 3/5] input: Add support for the tm2 touchkey device driver
From: Jaechul Lee @ 2017-01-06  3:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483675149-32598-1-git-send-email-jcsing.lee@samsung.com>

This patch adds the binding description of the tm2 touchkey
device driver.

Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Reviewed-by: Andi Shyti <andi.shyti@samsung.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../bindings/input/samsung,tm2-touchkey.txt        | 27 ++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt

diff --git a/Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt b/Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt
new file mode 100644
index 0000000..4de1af0
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt
@@ -0,0 +1,27 @@
+Samsung tm2-touchkey
+
+Required properties:
+- compatible: must be "samsung,tm2-touchkey"
+- reg: I2C address of the chip.
+- interrupt-parent: a phandle for the interrupt controller (see interrupt
+	binding[0]).
+- interrupts: interrupt to which the chip is connected (see interrupt
+	binding[0]).
+- vcc-supply : internal regulator output. 1.8V
+- vdd-supply : power supply for IC 3.3V
+
+[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example:
+	&i2c0 {
+		/* ... */
+
+		touchkey at 20 {
+			compatible = "samsung,tm2-touchkey";
+			reg = <0x20>;
+			interrupt-parent = <&gpa3>;
+			interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+			vcc-supply=<&ldo32_reg>;
+			vdd-supply=<&ldo33_reg>;
+		};
+	};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 4/5] input: tm2-touchkey: Add touchkey driver support for TM2
From: Jaechul Lee @ 2017-01-06  3:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483675149-32598-1-git-send-email-jcsing.lee@samsung.com>

This patch adds support for the TM2 touch key and led
functionality.

The driver interfaces with userspace through an input device and
reports KEY_PHONE and KEY_BACK event types. LED brightness can be
controlled by "/sys/class/leds/tm2-touchkey/brightness".

Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Reviewed-by: Andi Shyti <andi.shyti@samsung.com>
---
 drivers/input/keyboard/Kconfig        |  11 ++
 drivers/input/keyboard/Makefile       |   1 +
 drivers/input/keyboard/tm2-touchkey.c | 280 ++++++++++++++++++++++++++++++++++
 3 files changed, 292 insertions(+)
 create mode 100644 drivers/input/keyboard/tm2-touchkey.c

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index cbd75cf..e6e9858 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -666,6 +666,17 @@ config KEYBOARD_TC3589X
 	  To compile this driver as a module, choose M here: the
 	  module will be called tc3589x-keypad.
 
+config KEYBOARD_TM2_TOUCHKEY
+	tristate "tm2-touchkey support"
+	depends on I2C
+	depends on LEDS_CLASS
+	help
+	  Say Y here to enable device driver for tm2-touchkey with
+	  LED control for the Exynos5433 TM2 board.
+
+	  To compile this driver as a module, choose M here.
+	  module will be called tm2-touchkey.
+
 config KEYBOARD_TWL4030
 	tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
 	depends on TWL4030_CORE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index d9f4cfc..7d9acff 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_KEYBOARD_SUN4I_LRADC)	+= sun4i-lradc-keys.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
 obj-$(CONFIG_KEYBOARD_TC3589X)		+= tc3589x-keypad.o
 obj-$(CONFIG_KEYBOARD_TEGRA)		+= tegra-kbc.o
+obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY)	+= tm2-touchkey.o
 obj-$(CONFIG_KEYBOARD_TWL4030)		+= twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
 obj-$(CONFIG_KEYBOARD_W90P910)		+= w90p910_keypad.o
diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c
new file mode 100644
index 0000000..92eacb6
--- /dev/null
+++ b/drivers/input/keyboard/tm2-touchkey.c
@@ -0,0 +1,280 @@
+/*
+ * TM2 touchkey device driver
+ *
+ * Copyright 2005 Phil Blundell
+ * Copyright 2016 Samsung Electronics Co., Ltd.
+ *
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ * Author: Jaechul Lee <jcsing.lee@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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/regulator/consumer.h>
+
+#define TM2_TOUCHKEY_DEV_NAME		"tm2-touchkey"
+#define TM2_TOUCHKEY_KEYCODE_REG	0x03
+#define TM2_TOUCHKEY_BASE_REG		0x00
+#define TM2_TOUCHKEY_CMD_LED_ON		0x10
+#define TM2_TOUCHKEY_CMD_LED_OFF	0x20
+#define TM2_TOUCHKEY_BIT_PRESS_EV	BIT(3)
+#define TM2_TOUCHKEY_BIT_KEYCODE	GENMASK(2, 0)
+#define TM2_TOUCHKEY_LED_VOLTAGE_MIN	2500000
+#define TM2_TOUCHKEY_LED_VOLTAGE_MAX	3300000
+
+enum {
+	TM2_TOUCHKEY_KEY_MENU = 0x1,
+	TM2_TOUCHKEY_KEY_BACK,
+};
+
+struct tm2_touchkey_data {
+	struct i2c_client *client;
+	struct input_dev *input_dev;
+	struct led_classdev led_dev;
+	struct regulator_bulk_data regulators[2];
+
+	u8 keycode_type;
+	u8 pressed;
+};
+
+static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev,
+						enum led_brightness brightness)
+{
+	struct tm2_touchkey_data *touchkey =
+	    container_of(led_dev, struct tm2_touchkey_data, led_dev);
+	u32 volt;
+	u8 data;
+
+	if (brightness == LED_OFF) {
+		volt = TM2_TOUCHKEY_LED_VOLTAGE_MIN;
+		data = TM2_TOUCHKEY_CMD_LED_OFF;
+	} else {
+		volt = TM2_TOUCHKEY_LED_VOLTAGE_MAX;
+		data = TM2_TOUCHKEY_CMD_LED_ON;
+	}
+
+	regulator_set_voltage(touchkey->regulators[1].consumer, volt, volt);
+	i2c_smbus_write_byte_data(touchkey->client,
+						TM2_TOUCHKEY_BASE_REG, data);
+}
+
+static int tm2_touchkey_power_enable(struct tm2_touchkey_data *touchkey)
+{
+	int ret = 0;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators),
+						touchkey->regulators);
+	if (ret)
+		return ret;
+
+	/* waiting for device initialization, at least 150ms */
+	msleep(150);
+
+	return 0;
+}
+
+static void tm2_touchkey_power_disable(void *data)
+{
+	struct tm2_touchkey_data *touchkey = data;
+
+	regulator_bulk_disable(ARRAY_SIZE(touchkey->regulators),
+						touchkey->regulators);
+}
+
+static irqreturn_t tm2_touchkey_irq_handler(int irq, void *devid)
+{
+	struct tm2_touchkey_data *touchkey = devid;
+	u32 data;
+
+	data = i2c_smbus_read_byte_data(touchkey->client,
+					TM2_TOUCHKEY_KEYCODE_REG);
+
+	if (data < 0) {
+		dev_err(&touchkey->client->dev, "Failed to read i2c data\n");
+		return IRQ_HANDLED;
+	}
+
+	touchkey->keycode_type = data & TM2_TOUCHKEY_BIT_KEYCODE;
+	touchkey->pressed = !(data & TM2_TOUCHKEY_BIT_PRESS_EV);
+
+	if (touchkey->keycode_type != TM2_TOUCHKEY_KEY_MENU &&
+	    touchkey->keycode_type != TM2_TOUCHKEY_KEY_BACK) {
+		dev_warn(&touchkey->client->dev, "Skip unhandled keycode(%d)\n",
+							touchkey->keycode_type);
+		return IRQ_HANDLED;
+	}
+
+	if (!touchkey->pressed) {
+		input_report_key(touchkey->input_dev, KEY_PHONE, 0);
+		input_report_key(touchkey->input_dev, KEY_BACK, 0);
+	} else {
+		if (touchkey->keycode_type == TM2_TOUCHKEY_KEY_MENU)
+			input_report_key(touchkey->input_dev,
+					 KEY_PHONE, 1);
+		else
+			input_report_key(touchkey->input_dev,
+					 KEY_BACK, 1);
+	}
+	input_sync(touchkey->input_dev);
+
+	return IRQ_HANDLED;
+}
+
+static int tm2_touchkey_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct tm2_touchkey_data *touchkey;
+	int ret;
+
+	ret = i2c_check_functionality(client->adapter,
+				      I2C_FUNC_SMBUS_BYTE |
+				      I2C_FUNC_SMBUS_BYTE_DATA);
+	if (!ret) {
+		dev_err(&client->dev, "No I2C functionality found\n");
+		return -ENODEV;
+	}
+
+	touchkey = devm_kzalloc(&client->dev, sizeof(*touchkey), GFP_KERNEL);
+	if (!touchkey)
+		return -ENOMEM;
+
+	touchkey->client = client;
+	i2c_set_clientdata(client, touchkey);
+
+	/* regulators */
+	touchkey->regulators[0].supply = "vcc";
+	touchkey->regulators[1].supply = "vdd";
+	ret = devm_regulator_bulk_get(&client->dev,
+					ARRAY_SIZE(touchkey->regulators),
+					touchkey->regulators);
+	if (ret) {
+		dev_err(&client->dev, "Failed to get regulators\n");
+		return ret;
+	}
+
+	/* power */
+	ret = tm2_touchkey_power_enable(touchkey);
+	if (ret) {
+		dev_err(&client->dev, "Failed to enable power\n");
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(&client->dev,
+					tm2_touchkey_power_disable, touchkey);
+	if (ret)
+		return ret;
+
+	/* input device */
+	touchkey->input_dev = devm_input_allocate_device(&client->dev);
+	if (!touchkey->input_dev) {
+		dev_err(&client->dev, "Failed to alloc input device\n");
+		return -ENOMEM;
+	}
+	touchkey->input_dev->name = TM2_TOUCHKEY_DEV_NAME;
+	touchkey->input_dev->id.bustype = BUS_I2C;
+
+	set_bit(EV_KEY, touchkey->input_dev->evbit);
+	input_set_capability(touchkey->input_dev, EV_KEY, KEY_PHONE);
+	input_set_capability(touchkey->input_dev, EV_KEY, KEY_BACK);
+
+	input_set_drvdata(touchkey->input_dev, touchkey);
+
+	ret = input_register_device(touchkey->input_dev);
+	if (ret) {
+		dev_err(&client->dev, "Failed to register input device\n");
+		return ret;
+	}
+
+	/* irq */
+	ret = devm_request_threaded_irq(&client->dev,
+					client->irq, NULL,
+					tm2_touchkey_irq_handler,
+					IRQF_ONESHOT, TM2_TOUCHKEY_DEV_NAME,
+					touchkey);
+	if (ret) {
+		dev_err(&client->dev, "Failed to request threaded irq\n");
+		return ret;
+	}
+
+	/* led device */
+	touchkey->led_dev.name = TM2_TOUCHKEY_DEV_NAME;
+	touchkey->led_dev.brightness = LED_FULL;
+	touchkey->led_dev.max_brightness = LED_FULL;
+	touchkey->led_dev.brightness_set = tm2_touchkey_led_brightness_set;
+
+	ret = devm_led_classdev_register(&client->dev, &touchkey->led_dev);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed to register touchkey led\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused tm2_touchkey_suspend(struct device *dev)
+{
+	struct tm2_touchkey_data *touchkey = dev_get_drvdata(dev);
+
+	disable_irq(touchkey->client->irq);
+	tm2_touchkey_power_disable(touchkey);
+
+	return 0;
+}
+
+static int __maybe_unused tm2_touchkey_resume(struct device *dev)
+{
+	struct tm2_touchkey_data *touchkey = dev_get_drvdata(dev);
+	int ret;
+
+	enable_irq(touchkey->client->irq);
+	ret = tm2_touchkey_power_enable(touchkey);
+	if (ret)
+		dev_err(dev, "Failed to enable power\n");
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops, tm2_touchkey_suspend,
+							tm2_touchkey_resume);
+
+static const struct i2c_device_id tm2_touchkey_id_table[] = {
+	{TM2_TOUCHKEY_DEV_NAME, 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, tm2_touchkey_id_table);
+
+static const struct of_device_id tm2_touchkey_of_match[] = {
+	{.compatible = "samsung,tm2-touchkey",},
+	{},
+};
+MODULE_DEVICE_TABLE(of, tm2_touchkey_of_match);
+
+static struct i2c_driver tm2_touchkey_driver = {
+	.driver = {
+		.name = TM2_TOUCHKEY_DEV_NAME,
+		.pm = &tm2_touchkey_pm_ops,
+		.of_match_table = of_match_ptr(tm2_touchkey_of_match),
+	},
+	.probe = tm2_touchkey_probe,
+	.id_table = tm2_touchkey_id_table,
+};
+
+module_i2c_driver(tm2_touchkey_driver);
+
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_AUTHOR("Jaechul Lee <jcsing.lee@samsung.com>");
+MODULE_DESCRIPTION("Samsung touchkey driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4

^ permalink raw reply related


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