Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/3] ARM: dts: socfpga: Enable QSPI on the Cyclone5 sockit
From: Steffen Trumtrar @ 2016-10-20  7:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476908324-12313-3-git-send-email-dinguyen@opensource.altera.com>

Hi!

On Wed, Oct 19, 2016 at 03:18:44PM -0500, dinguyen at opensource.altera.com wrote:
> From: Dinh Nguyen <dinguyen@opensource.altera.com>
> 
> Enable the QSPI node and add the flash chip.
> 
> Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
> ---
>  arch/arm/boot/dts/socfpga_cyclone5_sockit.dts |   33 +++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
> index 02e22f5..2f75e0f 100644
> --- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
> +++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
> @@ -175,6 +175,39 @@
>  	status = "okay";
>  };
>  
> +&qspi {
> +	status = "okay";
> +
> +	flash: flash at 0 {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "n25q256a";
> +		reg = <0>;
> +		spi-max-frequency = <100000000>;
> +
> +		m25p,fast-read;
> +		cdns,page-size = <256>;
> +		cdns,block-size = <16>;
> +		cdns,read-delay = <4>;
> +		cdns,tshsl-ns = <50>;
> +		cdns,tsd2d-ns = <50>;
> +		cdns,tchsh-ns = <4>;
> +		cdns,tslch-ns = <4>;
> +
> +		partition at qspi-boot {
> +			/* 8MB for raw data. */
> +			label = "Flash 0 Raw Data";
> +			reg = <0x0 0x800000>;
> +		};
> +
> +		partition at qspi-rootfs {
> +			/* 120MB for jffs2 data. */
> +			label = "Flash 0 jffs2 Filesystem";
> +			reg = <0x800000 0x7800000>;
> +		};
> +	};
> +};
> +

What is the current preferred way of handling the partitions?
This doesn't fit my Sockit configuration for example. So I would always
have to patch the devicetree.

On the Socrates I didn't specify the partitions, because I did not
want to force a specific configuration.

Regards,
Steffen

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH v5 11/23] usb: chipidea: Emulate OTGSC interrupt enable path
From: Stephen Boyd @ 2016-10-20  6:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019080211.GA1968@b29397-desktop>

Quoting Peter Chen (2016-10-19 01:02:11)
> On Tue, Oct 18, 2016 at 06:53:07PM -0700, Stephen Boyd wrote:
> > If you're asking if I've made modifications to extcon-usb-gpio, then the
> > answer is no. The branch on linaro.org git server from the cover-letter
> > is the branch I've used to test this with. This patch is specifically to
> > fix issues with that design on the db410c board that has only one pin
> > for ID and vbus detection. It's the schematic that we've discussed in
> > another thread.
> > 
> > extcon-usb-gpio sends two extcon events, EXTCON_USB_HOST (for the id
> > pin) and EXTCON_USB (for the vbus). So afaik it does support vbus
> > events.
> > 
> 
> Hmm, in fact, your ID event is the same with vbus event, you take
> external vbus event as ID event for extcon-usb-gpio handling. Yes,
> it can work due to it sends EXTCON_USB_HOST event first.
> 
> Where you change the USB_SW_SEL_PM pin?

Currently that is done with the mux driver I sent based on the extcon
event. We don't know if that's before or after the controller handles
the extcon event though, so the pin should probably be changed from the
chipidea driver instead to be more explicit. Why do you ask though?

> 
> > > - When the ID from 0->1, the chipidea driver will do role switch, and
> > >   set BSVIE, why it does not occur for your case?
> > 
> > Right, that happens with this line in the sequence I describe below:
> > 
> >   hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE, OTGSC_BSVIS | OTGSC_BSVIE);
> > 
> > but that happens much later than when the extcon event happens so we
> > miss the interrupt. Technically, the driver isn't expecting the BSVIS
> > interrupt to happen until BSVIE is set, but the extcon can come whenever
> > it wants regardless of how the registers are configured in the
> > controller.  So we have to do some sort of 'caching' here to remember
> > that the vbus event happened and replay it when BSVIE is set. At least I
> > imagine this is how the hardware would work? Or if vbus goes high before
> > we enable the interrupt would it just be missed? It seems like polling
> > the BSV bit and then enabling BSVIE is sort of racy there.
> > 
> > Plus, we poll the BSV bit when we role switch, but in my case id bit
> > toggles and vbus goes high at exactly the same time because that is all
> > happening from a single cable being connected, so it's not possible for
> > BSV to go low and see it after the id pin from 0 to 1.
> 
> Now, I understand your case, but your changes are a little complicated.
> Would you try if below patch can fix your issue?
> 
> From 8b8baf31dcaca53612d0fd91068c84fe09d66f6c Mon Sep 17 00:00:00 2001
> From: Peter Chen <peter.chen@nxp.com>
> Date: Wed, 19 Oct 2016 15:32:58 +0800
> Subject: [PATCH 1/1] usb: chipidea: vbus event may exist before starting
>  gadget
> 
> At some situations, the vbus may already be there before starting
> gadget. So we need to check vbus event after switch to gadget in
> order to handle missing vbus event. The typical use cases are plugging
> vbus cable before driver load or the vbus has already been there
> after stopping host but before starting gadget.
> 
> Signed-off-by: Peter Chen <peter.chen@nxp.com>

Yes this should work. Light testing doesn't show any problems so far.
 
> ---
>  drivers/usb/chipidea/core.c |  4 ----
>  drivers/usb/chipidea/otg.c  | 10 ++++++----
>  drivers/usb/chipidea/udc.c  |  2 ++
>  3 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index b814d91..a7d2c68 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -992,10 +992,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>         }
>  
>         if (!ci_otg_is_fsm_mode(ci)) {
> -               /* only update vbus status for peripheral */
> -               if (ci->role == CI_ROLE_GADGET)
> -                       ci_handle_vbus_change(ci);
> -
>                 ret = ci_role_start(ci, ci->role);
>                 if (ret) {
>                         dev_err(dev, "can't start %s role\n",
> diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
> index 695f3fe..99c0709 100644
> --- a/drivers/usb/chipidea/otg.c
> +++ b/drivers/usb/chipidea/otg.c
> @@ -134,9 +134,9 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
>         if (!ci->is_otg)
>                 return;
>  
> -       if (hw_read_otgsc(ci, OTGSC_BSV))
> +       if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active)
>                 usb_gadget_vbus_connect(&ci->gadget);
> -       else
> +       else if (!hw_read_otgsc(ci, OTGSC_BSV) && ci->vbus_active)
>                 usb_gadget_vbus_disconnect(&ci->gadget);
>  }
>  
> @@ -175,10 +175,12 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
>  
>                 ci_role_stop(ci);
>  
> -               if (role == CI_ROLE_GADGET)
> +               if (role == CI_ROLE_GADGET &&
> +                               IS_ERR(ci->platdata->vbus_extcon.edev))
>                         /*
>                          * wait vbus lower than OTGSC_BSV before connecting
> -                        * to host
> +                        * to host. And if vbus's status is an external
> +                        * connector, it doesn't need to wait here.

because OTGSC_BSV will toggle based on the extcon state and not when the
phy connects to the host? It would be good to explain why it's not
needed instead of just repeating what the code is doing.

>                          */
>                         hw_wait_vbus_lower_bsv(ci);
>  
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 001c2fa..184ffba 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1963,6 +1963,8 @@ static int udc_id_switch_for_device(struct ci_hdrc *ci)
>                 /* Clear and enable BSV irq */
>                 hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
>                                         OTGSC_BSVIS | OTGSC_BSVIE);
> +       /* vbus change may has already been occurred */

"vbus change may have already occurred"?

> +       ci_handle_vbus_change(ci);
>  
>         return 0;
>  }

^ permalink raw reply

* [PATCH] video: ARM CLCD: fix Vexpress regression
From: Linus Walleij @ 2016-10-20  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

The CLCD does not come up on Versatile Express as it does not
(currently) have a syscon node for controlling the block apart
from the CLCD itself. Make sure the .init() function can bail
out without an error making it probe again.

Reported-by: Amit Pundir <amit.pundir@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/video/fbdev/amba-clcd-versatile.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/amba-clcd-versatile.c b/drivers/video/fbdev/amba-clcd-versatile.c
index 19ad8645d93c..d909b7dda14d 100644
--- a/drivers/video/fbdev/amba-clcd-versatile.c
+++ b/drivers/video/fbdev/amba-clcd-versatile.c
@@ -527,7 +527,8 @@ int versatile_clcd_init_panel(struct clcd_fb *fb,
 					     &clcd_id);
 	if (!np) {
 		dev_err(dev, "no Versatile syscon node\n");
-		return -ENODEV;
+		/* Vexpress does not have this */
+		return 0;
 	}
 	versatile_clcd_type = (enum versatile_clcd)clcd_id->data;
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH 1/3] ARM: socfpga: dtsi: add qspi node
From: Steffen Trumtrar @ 2016-10-20  6:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.02.1610191054120.29731@linux-builds1>

On Wed, Oct 19, 2016 at 10:55:46AM -0500, Dinh Nguyen wrote:
> On Tue, 18 Oct 2016, Steffen Trumtrar wrote:
> 
> > Add the qspi node to the socfpga dtsi file.
> > 
> > Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> > ---
> >  arch/arm/boot/dts/socfpga.dtsi | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
> > index 9f48141270b8..0dc96d2248a6 100644
> > --- a/arch/arm/boot/dts/socfpga.dtsi
> > +++ b/arch/arm/boot/dts/socfpga.dtsi
> > @@ -705,6 +705,20 @@
> >  			reg = <0xffff0000 0x10000>;
> >  		};
> >  
> > +		qspi: spi at ff705000 {
> > +			compatible = "cdns,qspi-nor";
> > +                        #address-cells = <1>;
> > +			#size-cells = <0>;
> > +			reg = <0xff705000 0x1000>,
> > +			      <0xffa00000 0x1000>;
> 
> I think the QSPI data address space has a length of 0x100000. I've fixed it up locally.
> 

Yeah, you are right. Good catch.

Thanks,
Steffen

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH 1/2] arm64/numa: fix pcpu_cpu_distance() to get correct CPU proximity
From: Leizhen (ThunderTown) @ 2016-10-20  6:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476935576-59941-1-git-send-email-guohanjun@huawei.com>



On 2016/10/20 11:52, Hanjun Guo wrote:
> From: Yisheng Xie <xieyisheng1@huawei.com>
> 
> The pcpu_build_alloc_info() function group CPUs according to their
> proximity, by call callback function @cpu_distance_fn from different
> ARCHs.
> 
> For arm64 the callback of @cpu_distance_fn is
>     pcpu_cpu_distance(from, to)
>         -> node_distance(from, to)
> The @from and @to for function node_distance() should be nid.
> 
> However, pcpu_cpu_distance() in arch/arm64/mm/numa.c just past the
> cpu id for @from and @to.
> 
> For this incorrect cpu proximity get from ARCH, it may cause each CPU
> in one group and make group_cnt out of bound:
> 
> 	setup_per_cpu_areas()
> 		pcpu_embed_first_chunk()
> 			pcpu_build_alloc_info()
> in pcpu_build_alloc_info, since cpu_distance_fn will return
> REMOTE_DISTANCE if we pass cpu ids (0,1,2...), so
> cpu_distance_fn(cpu, tcpu) > LOCAL_DISTANCE will wrongly be ture.
> 
> This may results in triggering the BUG_ON(unit != nr_units) later:
> 
> [    0.000000] kernel BUG at mm/percpu.c:1916!
> [    0.000000] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
> [    0.000000] Modules linked in:
> [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.9.0-rc1-00003-g14155ca-dirty #26
> [    0.000000] Hardware name: Hisilicon Hi1616 Evaluation Board (DT)
> [    0.000000] task: ffff000008d6e900 task.stack: ffff000008d60000
> [    0.000000] PC is at pcpu_embed_first_chunk+0x420/0x704
> [    0.000000] LR is at pcpu_embed_first_chunk+0x3bc/0x704
> [    0.000000] pc : [<ffff000008c754f4>] lr : [<ffff000008c75490>] pstate: 800000c5
> [    0.000000] sp : ffff000008d63eb0
> [    0.000000] x29: ffff000008d63eb0 [    0.000000] x28: 0000000000000000
> [    0.000000] x27: 0000000000000040 [    0.000000] x26: ffff8413fbfcef00
> [    0.000000] x25: 0000000000000042 [    0.000000] x24: 0000000000000042
> [    0.000000] x23: 0000000000001000 [    0.000000] x22: 0000000000000046
> [    0.000000] x21: 0000000000000001 [    0.000000] x20: ffff000008cb3bc8
> [    0.000000] x19: ffff8413fbfcf570 [    0.000000] x18: 0000000000000000
> [    0.000000] x17: ffff000008e49ae0 [    0.000000] x16: 0000000000000003
> [    0.000000] x15: 000000000000001e [    0.000000] x14: 0000000000000004
> [    0.000000] x13: 0000000000000000 [    0.000000] x12: 000000000000006f
> [    0.000000] x11: 00000413fbffff00 [    0.000000] x10: 0000000000000004
> [    0.000000] x9 : 0000000000000000 [    0.000000] x8 : 0000000000000001
> [    0.000000] x7 : ffff8413fbfcf63c [    0.000000] x6 : ffff000008d65d28
> [    0.000000] x5 : ffff000008d65e50 [    0.000000] x4 : 0000000000000000
> [    0.000000] x3 : ffff000008cb3cc8 [    0.000000] x2 : 0000000000000040
> [    0.000000] x1 : 0000000000000040 [    0.000000] x0 : 0000000000000000
> [...]
> [    0.000000] Call trace:
> [    0.000000] Exception stack(0xffff000008d63ce0 to 0xffff000008d63e10)
> [    0.000000] 3ce0: ffff8413fbfcf570 0001000000000000 ffff000008d63eb0 ffff000008c754f4
> [    0.000000] 3d00: ffff000008d63d50 ffff0000081af210 00000413fbfff010 0000000000001000
> [    0.000000] 3d20: ffff000008d63d50 ffff0000081af220 00000413fbfff010 0000000000001000
> [    0.000000] 3d40: 00000413fbfcef00 0000000000000004 ffff000008d63db0 ffff0000081af390
> [    0.000000] 3d60: 00000413fbfcef00 0000000000001000 0000000000000000 0000000000001000
> [    0.000000] 3d80: 0000000000000000 0000000000000040 0000000000000040 ffff000008cb3cc8
> [    0.000000] 3da0: 0000000000000000 ffff000008d65e50 ffff000008d65d28 ffff8413fbfcf63c
> [    0.000000] 3dc0: 0000000000000001 0000000000000000 0000000000000004 00000413fbffff00
> [    0.000000] 3de0: 000000000000006f 0000000000000000 0000000000000004 000000000000001e
> [    0.000000] 3e00: 0000000000000003 ffff000008e49ae0
> [    0.000000] [<ffff000008c754f4>] pcpu_embed_first_chunk+0x420/0x704
> [    0.000000] [<ffff000008c6658c>] setup_per_cpu_areas+0x38/0xc8
> [    0.000000] [<ffff000008c608d8>] start_kernel+0x10c/0x390
> [    0.000000] [<ffff000008c601d8>] __primary_switched+0x5c/0x64
> [    0.000000] Code: b8018660 17ffffd7 6b16037f 54000080 (d4210000)
> [    0.000000] ---[ end trace 0000000000000000 ]---
> [    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
> 
> Fix by getting CPUs proximity through its node. We only care about
> whether it is LOCAL_DISTANCE or not, for pcpu_build_alloc_info() only
> use this to group CPUs.
> 
> Fixes: 7af3a0a99252 ("arm64/numa: support HAVE_SETUP_PER_CPU_AREA")
> Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Zhen Lei <thunder.leizhen@huawei.com>
> ---
>  arch/arm64/mm/numa.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
> index 778a985..34415fc 100644
> --- a/arch/arm64/mm/numa.c
> +++ b/arch/arm64/mm/numa.c
> @@ -147,7 +147,10 @@ static int __init early_cpu_to_node(int cpu)
>  
>  static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
>  {
> -	return node_distance(from, to);
> +	if (early_cpu_to_node(from) == early_cpu_to_node(to))
> +		return LOCAL_DISTANCE;
> +	else
> +		return REMOTE_DISTANCE;
>  }
Reviewd-by: Zhen Lei <thunder.leizhen@huawei.com>

>  
>  static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size,
> 

^ permalink raw reply

* [PATCH] drm: convert DT component matching to component_match_add_release()
From: Daniel Vetter @ 2016-10-20  6:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1bwo6l-0005Io-Q1@rmk-PC.armlinux.org.uk>

On Wed, Oct 19, 2016 at 11:28:27AM +0100, Russell King wrote:
> Convert DT component matching to use component_match_add_release().
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
> Can we please get this patch from May merged into the drm-misc or
> whatever trees so that we don't end up with conflicts?  I've no idea
> who looks after drm-misc, as they have _still_ failed to add
> themselves to MAINTAINERS.

Can pick, once someone from the arm world smashes at least an ack on this.
But I have no clue about of/DT, so won't just merge it.

And yes drm-misc will get a MAINTAINERS entry, after ks, because there's
some things to discuss about what that one needs to look like.
-Daniel

> 
>  drivers/gpu/drm/arm/hdlcd_drv.c                 |  3 ++-
>  drivers/gpu/drm/arm/malidp_drv.c                |  4 +++-
>  drivers/gpu/drm/armada/armada_drv.c             |  2 +-
>  drivers/gpu/drm/drm_of.c                        | 28 +++++++++++++++++++++++--
>  drivers/gpu/drm/etnaviv/etnaviv_drv.c           |  5 +++--
>  drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c |  7 ++++---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c          |  4 +++-
>  drivers/gpu/drm/msm/msm_drv.c                   | 12 ++++++-----
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.c     |  6 ++++--
>  drivers/gpu/drm/sti/sti_drv.c                   |  5 +++--
>  drivers/gpu/drm/sun4i/sun4i_drv.c               |  3 ++-
>  drivers/gpu/drm/tilcdc/tilcdc_external.c        |  4 +++-
>  include/drm/drm_of.h                            | 12 +++++++++++
>  13 files changed, 73 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> index fb6a418ce6be..6477d1a65266 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> @@ -453,7 +453,8 @@ static int hdlcd_probe(struct platform_device *pdev)
>  		return -EAGAIN;
>  	}
>  
> -	component_match_add(&pdev->dev, &match, compare_dev, port);
> +	drm_of_component_match_add(&pdev->dev, &match, compare_dev, port);
> +	of_node_put(port);
>  
>  	return component_master_add_with_match(&pdev->dev, &hdlcd_master_ops,
>  					       match);
> diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
> index 9280358b8f15..9f4739452a25 100644
> --- a/drivers/gpu/drm/arm/malidp_drv.c
> +++ b/drivers/gpu/drm/arm/malidp_drv.c
> @@ -493,7 +493,9 @@ static int malidp_platform_probe(struct platform_device *pdev)
>  		return -EAGAIN;
>  	}
>  
> -	component_match_add(&pdev->dev, &match, malidp_compare_dev, port);
> +	drm_of_component_match_add(&pdev->dev, &match, malidp_compare_dev,
> +				   port);
> +	of_node_put(port);
>  	return component_master_add_with_match(&pdev->dev, &malidp_master_ops,
>  					       match);
>  }
> diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
> index 1e0e68f608e4..94e46da9a758 100644
> --- a/drivers/gpu/drm/armada/armada_drv.c
> +++ b/drivers/gpu/drm/armada/armada_drv.c
> @@ -254,7 +254,7 @@ static void armada_add_endpoints(struct device *dev,
>  			continue;
>  		}
>  
> -		component_match_add(dev, match, compare_of, remote);
> +		drm_of_component_match_add(dev, match, compare_of, remote);
>  		of_node_put(remote);
>  	}
>  }
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index bc98bb94264d..47848ed8ca48 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -6,6 +6,11 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_of.h>
>  
> +static void drm_release_of(struct device *dev, void *data)
> +{
> +	of_node_put(data);
> +}
> +
>  /**
>   * drm_crtc_port_mask - find the mask of a registered CRTC by port OF node
>   * @dev: DRM device
> @@ -64,6 +69,24 @@ uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
>  EXPORT_SYMBOL(drm_of_find_possible_crtcs);
>  
>  /**
> + * drm_of_component_match_add - Add a component helper OF node match rule
> + * @master: master device
> + * @matchptr: component match pointer
> + * @compare: compare function used for matching component
> + * @node: of_node
> + */
> +void drm_of_component_match_add(struct device *master,
> +				struct component_match **matchptr,
> +				int (*compare)(struct device *, void *),
> +				struct device_node *node)
> +{
> +	of_node_get(node);
> +	component_match_add_release(master, matchptr, drm_release_of,
> +				    compare, node);
> +}
> +EXPORT_SYMBOL_GPL(drm_of_component_match_add);
> +
> +/**
>   * drm_of_component_probe - Generic probe function for a component based master
>   * @dev: master device containing the OF node
>   * @compare_of: compare function used for matching components
> @@ -101,7 +124,7 @@ int drm_of_component_probe(struct device *dev,
>  			continue;
>  		}
>  
> -		component_match_add(dev, &match, compare_of, port);
> +		drm_of_component_match_add(dev, &match, compare_of, port);
>  		of_node_put(port);
>  	}
>  
> @@ -140,7 +163,8 @@ int drm_of_component_probe(struct device *dev,
>  				continue;
>  			}
>  
> -			component_match_add(dev, &match, compare_of, remote);
> +			drm_of_component_match_add(dev, &match, compare_of,
> +						   remote);
>  			of_node_put(remote);
>  		}
>  		of_node_put(port);
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> index aa687669e22b..0dee6acbd880 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> @@ -16,6 +16,7 @@
>  
>  #include <linux/component.h>
>  #include <linux/of_platform.h>
> +#include <drm/drm_of.h>
>  
>  #include "etnaviv_drv.h"
>  #include "etnaviv_gpu.h"
> @@ -629,8 +630,8 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
>  			if (!core_node)
>  				break;
>  
> -			component_match_add(&pdev->dev, &match, compare_of,
> -					    core_node);
> +			drm_of_component_match_add(&pdev->dev, &match,
> +						   compare_of, core_node);
>  			of_node_put(core_node);
>  		}
>  	} else if (dev->platform_data) {
> diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
> index 90377a609c98..e88fde18c946 100644
> --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
> +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
> @@ -24,6 +24,7 @@
>  #include <drm/drm_fb_cma_helper.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_crtc_helper.h>
> +#include <drm/drm_of.h>
>  
>  #include "kirin_drm_drv.h"
>  
> @@ -260,14 +261,13 @@ static struct device_node *kirin_get_remote_node(struct device_node *np)
>  		DRM_ERROR("no valid endpoint node\n");
>  		return ERR_PTR(-ENODEV);
>  	}
> -	of_node_put(endpoint);
>  
>  	remote = of_graph_get_remote_port_parent(endpoint);
> +	of_node_put(endpoint);
>  	if (!remote) {
>  		DRM_ERROR("no valid remote node\n");
>  		return ERR_PTR(-ENODEV);
>  	}
> -	of_node_put(remote);
>  
>  	if (!of_device_is_available(remote)) {
>  		DRM_ERROR("not available for remote node\n");
> @@ -294,7 +294,8 @@ static int kirin_drm_platform_probe(struct platform_device *pdev)
>  	if (IS_ERR(remote))
>  		return PTR_ERR(remote);
>  
> -	component_match_add(dev, &match, compare_of, remote);
> +	drm_of_component_match_add(dev, &match, compare_of, remote);
> +	of_node_put(remote);
>  
>  	return component_master_add_with_match(dev, &kirin_drm_ops, match);
>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index cf83f6507ec8..9c5430fb82a2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -18,6 +18,7 @@
>  #include <drm/drm_crtc_helper.h>
>  #include <drm/drm_gem.h>
>  #include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_of.h>
>  #include <linux/component.h>
>  #include <linux/iommu.h>
>  #include <linux/of_address.h>
> @@ -415,7 +416,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  		    comp_type == MTK_DPI) {
>  			dev_info(dev, "Adding component match for %s\n",
>  				 node->full_name);
> -			component_match_add(dev, &match, compare_of, node);
> +			drm_of_component_match_add(dev, &match, compare_of,
> +						   node);
>  		} else {
>  			struct mtk_ddp_comp *comp;
>  
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index fb5c0b0a7594..84d38eaea585 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -15,6 +15,8 @@
>   * this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <drm/drm_of.h>
> +
>  #include "msm_drv.h"
>  #include "msm_debugfs.h"
>  #include "msm_fence.h"
> @@ -919,8 +921,8 @@ static int add_components_mdp(struct device *mdp_dev,
>  			continue;
>  		}
>  
> -		component_match_add(master_dev, matchptr, compare_of, intf);
> -
> +		drm_of_component_match_add(master_dev, matchptr, compare_of,
> +					   intf);
>  		of_node_put(intf);
>  		of_node_put(ep_node);
>  	}
> @@ -962,8 +964,8 @@ static int add_display_components(struct device *dev,
>  		put_device(mdp_dev);
>  
>  		/* add the MDP component itself */
> -		component_match_add(dev, matchptr, compare_of,
> -				    mdp_dev->of_node);
> +		drm_of_component_match_add(dev, matchptr, compare_of,
> +					   mdp_dev->of_node);
>  	} else {
>  		/* MDP4 */
>  		mdp_dev = dev;
> @@ -996,7 +998,7 @@ static int add_gpu_components(struct device *dev,
>  	if (!np)
>  		return 0;
>  
> -	component_match_add(dev, matchptr, compare_of, np);
> +	drm_of_component_match_add(dev, matchptr, compare_of, np);
>  
>  	of_node_put(np);
>  
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index 8c8cbe837e61..6fe161192bb4 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -20,6 +20,7 @@
>  #include <drm/drm_crtc_helper.h>
>  #include <drm/drm_fb_helper.h>
>  #include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_of.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/module.h>
> @@ -388,7 +389,7 @@ static void rockchip_add_endpoints(struct device *dev,
>  			continue;
>  		}
>  
> -		component_match_add(dev, match, compare_of, remote);
> +		drm_of_component_match_add(dev, match, compare_of, remote);
>  		of_node_put(remote);
>  	}
>  }
> @@ -437,7 +438,8 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
>  		}
>  
>  		of_node_put(iommu);
> -		component_match_add(dev, &match, compare_of, port->parent);
> +		drm_of_component_match_add(dev, &match, compare_of,
> +					   port->parent);
>  		of_node_put(port);
>  	}
>  
> diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
> index 2784919a7366..5e819876e642 100644
> --- a/drivers/gpu/drm/sti/sti_drv.c
> +++ b/drivers/gpu/drm/sti/sti_drv.c
> @@ -17,6 +17,7 @@
>  #include <drm/drm_crtc_helper.h>
>  #include <drm/drm_gem_cma_helper.h>
>  #include <drm/drm_fb_cma_helper.h>
> +#include <drm/drm_of.h>
>  
>  #include "sti_crtc.h"
>  #include "sti_drv.h"
> @@ -423,8 +424,8 @@ static int sti_platform_probe(struct platform_device *pdev)
>  	child_np = of_get_next_available_child(node, NULL);
>  
>  	while (child_np) {
> -		component_match_add(dev, &match, compare_of, child_np);
> -		of_node_put(child_np);
> +		drm_of_component_match_add(dev, &match, compare_of,
> +					   child_np);
>  		child_np = of_get_next_available_child(node, child_np);
>  	}
>  
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
> index 0da9862ad8ed..b3c4ad605e81 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -18,6 +18,7 @@
>  #include <drm/drm_fb_cma_helper.h>
>  #include <drm/drm_gem_cma_helper.h>
>  #include <drm/drm_fb_helper.h>
> +#include <drm/drm_of.h>
>  
>  #include "sun4i_crtc.h"
>  #include "sun4i_drv.h"
> @@ -239,7 +240,7 @@ static int sun4i_drv_add_endpoints(struct device *dev,
>  		/* Add current component */
>  		DRM_DEBUG_DRIVER("Adding component %s\n",
>  				 of_node_full_name(node));
> -		component_match_add(dev, match, compare_of, node);
> +		drm_of_component_match_add(dev, match, compare_of, node);
>  		count++;
>  	}
>  
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c
> index 68e895021005..06a4c584f3cb 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
> @@ -10,6 +10,7 @@
>  
>  #include <linux/component.h>
>  #include <linux/of_graph.h>
> +#include <drm/drm_of.h>
>  
>  #include "tilcdc_drv.h"
>  #include "tilcdc_external.h"
> @@ -160,7 +161,8 @@ int tilcdc_get_external_components(struct device *dev,
>  
>  		dev_dbg(dev, "Subdevice node '%s' found\n", node->name);
>  		if (match)
> -			component_match_add(dev, match, dev_match_of, node);
> +			drm_of_component_match_add(dev, match, dev_match_of,
> +						   node);
>  		of_node_put(node);
>  		count++;
>  	}
> diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
> index 3fd87b386ed7..d6b4c5587bbe 100644
> --- a/include/drm/drm_of.h
> +++ b/include/drm/drm_of.h
> @@ -4,6 +4,7 @@
>  #include <linux/of_graph.h>
>  
>  struct component_master_ops;
> +struct component_match;
>  struct device;
>  struct drm_device;
>  struct drm_encoder;
> @@ -12,6 +13,10 @@ struct device_node;
>  #ifdef CONFIG_OF
>  extern uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
>  					   struct device_node *port);
> +extern void drm_of_component_match_add(struct device *master,
> +				       struct component_match **matchptr,
> +				       int (*compare)(struct device *, void *),
> +				       struct device_node *node);
>  extern int drm_of_component_probe(struct device *dev,
>  				  int (*compare_of)(struct device *, void *),
>  				  const struct component_master_ops *m_ops);
> @@ -25,6 +30,13 @@ static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
>  	return 0;
>  }
>  
> +static void drm_of_component_match_add(struct device *master,
> +				       struct component_match **matchptr,
> +				       int (*compare)(struct device *, void *),
> +				       struct device_node *node)
> +{
> +}
> +
>  static inline int
>  drm_of_component_probe(struct device *dev,
>  		       int (*compare_of)(struct device *, void *),
> -- 
> 2.1.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply

* [PATCH] ARM: dts: berlin2q-marvell-dmp: fix typo in chosen node
From: Antoine Tenart @ 2016-10-20  6:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476924731-14975-1-git-send-email-yamada.masahiro@socionext.com>

Hello,

On Thu, Oct 20, 2016 at 09:52:11AM +0900, Masahiro Yamada wrote:
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

Acked-by: Antoine Tenart <antoine.tenart@free-electrons.com>

Thanks!

Antoine

> ---
> 
>  arch/arm/boot/dts/berlin2q-marvell-dmp.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
> index f485308..d57d675 100644
> --- a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
> +++ b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
> @@ -48,7 +48,7 @@
>  		reg = <0x00000000 0x80000000>;
>  	};
>  
> -	choosen {
> +	chosen {
>  		bootargs = "earlyprintk";
>  		stdout-path = "serial0:115200n8";
>  	};
> -- 
> 1.9.1
> 

-- 
Antoine T?nart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161020/8d11fa4f/attachment.sig>

^ permalink raw reply

* [PATCH 2/3] arm64: hw_breakpoint: Handle inexact watchpoint addresses
From: Pratyush Anand @ 2016-10-20  5:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019120714.GM9193@arm.com>

Hi Will,

On Wednesday 19 October 2016 05:37 PM, Will Deacon wrote:
> On Fri, Oct 14, 2016 at 08:45:43AM +0530, Pratyush Anand wrote:
>>
>>
>> On Thursday 13 October 2016 10:33 PM, Pavel Labath wrote:
>>>> I think, its easier to go with your implementation. So, I have taken
>>>>> your patch and updated my perf/upstream_arm64_devel branch. May be you
>>>>> can give it a test for your test cases.
>>> I've checked out the new version of your branch, and it works great.
>>> I'll write a patch with additional test cases to go on top of your
>>> branch, as the tests there do not capture the bug I was fixing.
>>
>> That would be great. We can send them all together as V2.
>
> Did you send a v2? I've been holding off reviewing this, but I just want
> to make sure I didn't miss the update.

I just posted V2.

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

~Pratyush

^ permalink raw reply

* [PATCH V2 5/5] selftests: arm64: add test for unaligned/inexact watchpoint handling
From: Pratyush Anand @ 2016-10-20  5:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1476941895.git.panand@redhat.com>

ARM64 hardware expects 64bit aligned address for watchpoint invocation.
However, it provides byte selection method to select any number of
consecutive byte set within the range of 1-8.

This patch adds support to test all such byte selection option for
different memory write sizes.

Patch also adds a test for handling the case when the cpu does not
report an address which exactly matches one of the regions we have
been watching (which is a situation permitted by the spec if an
instruction accesses both watched and unwatched regions). The test
was failing on a MSM8996pro before this patch series and is
passing now.

Signed-off-by: Pavel Labath <labath@google.com>
Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 tools/testing/selftests/breakpoints/Makefile       |   5 +-
 .../selftests/breakpoints/breakpoint_test_arm64.c  | 236 +++++++++++++++++++++
 2 files changed, 240 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/breakpoints/breakpoint_test_arm64.c

diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile
index 74e533fd4bc5..61b79e8df1f4 100644
--- a/tools/testing/selftests/breakpoints/Makefile
+++ b/tools/testing/selftests/breakpoints/Makefile
@@ -5,6 +5,9 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
 ifeq ($(ARCH),x86)
 TEST_PROGS := breakpoint_test
 endif
+ifeq ($(ARCH),aarch64)
+TEST_PROGS := breakpoint_test_arm64
+endif
 
 TEST_PROGS += step_after_suspend_test
 
@@ -13,4 +16,4 @@ all: $(TEST_PROGS)
 include ../lib.mk
 
 clean:
-	rm -fr breakpoint_test step_after_suspend_test
+	rm -fr breakpoint_test breakpoint_test_arm64 step_after_suspend_test
diff --git a/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c b/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
new file mode 100644
index 000000000000..3897e996541e
--- /dev/null
+++ b/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ * Original Code by Pavel Labath <labath@google.com>
+ *
+ * Code modified by Pratyush Anand <panand@redhat.com>
+ * for testing different byte select for each access size.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ptrace.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <elf.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "../kselftest.h"
+
+static volatile uint8_t var[96] __attribute__((__aligned__(32)));
+
+static void child(int size, int wr)
+{
+	volatile uint8_t *addr = &var[32 + wr];
+
+	if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) != 0) {
+		perror("ptrace(PTRACE_TRACEME) failed");
+		_exit(1);
+	}
+
+	if (raise(SIGSTOP) != 0) {
+		perror("raise(SIGSTOP) failed");
+		_exit(1);
+	}
+
+	if ((uintptr_t) addr % size) {
+		perror("Wrong address write for the given size\n");
+		_exit(1);
+	}
+	switch (size) {
+	case 1:
+		*addr = 47;
+		break;
+	case 2:
+		*(uint16_t *)addr = 47;
+		break;
+	case 4:
+		*(uint32_t *)addr = 47;
+		break;
+	case 8:
+		*(uint64_t *)addr = 47;
+		break;
+	case 16:
+		__asm__ volatile ("stp x29, x30, %0" : "=m" (addr[0]));
+		break;
+	case 32:
+		__asm__ volatile ("stp q29, q30, %0" : "=m" (addr[0]));
+		break;
+	}
+
+	_exit(0);
+}
+
+static bool set_watchpoint(pid_t pid, int size, int wp)
+{
+	const volatile uint8_t *addr = &var[32 + wp];
+	const int offset = (uintptr_t)addr % 8;
+	const unsigned int byte_mask = ((1 << size) - 1) << offset;
+	const unsigned int type = 2; /* Write */
+	const unsigned int enable = 1;
+	const unsigned int control = byte_mask << 5 | type << 3 | enable;
+	struct user_hwdebug_state dreg_state;
+	struct iovec iov;
+
+	memset(&dreg_state, 0, sizeof(dreg_state));
+	dreg_state.dbg_regs[0].addr = (uintptr_t)(addr - offset);
+	dreg_state.dbg_regs[0].ctrl = control;
+	iov.iov_base = &dreg_state;
+	iov.iov_len = offsetof(struct user_hwdebug_state, dbg_regs) +
+				sizeof(dreg_state.dbg_regs[0]);
+	if (ptrace(PTRACE_SETREGSET, pid, NT_ARM_HW_WATCH, &iov) == 0)
+		return true;
+
+	if (errno == EIO) {
+		printf("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) "
+			"not supported on this hardware\n");
+		ksft_exit_skip();
+	}
+	perror("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) failed");
+	return false;
+}
+
+static bool run_test(int wr_size, int wp_size, int wr, int wp)
+{
+	int status;
+	siginfo_t siginfo;
+	pid_t pid = fork();
+	pid_t wpid;
+
+	if (pid < 0) {
+		perror("fork() failed");
+		return false;
+	}
+	if (pid == 0)
+		child(wr_size, wr);
+
+	wpid = waitpid(pid, &status, __WALL);
+	if (wpid != pid) {
+		perror("waitpid() failed");
+		return false;
+	}
+	if (!WIFSTOPPED(status)) {
+		printf("child did not stop\n");
+		return false;
+	}
+	if (WSTOPSIG(status) != SIGSTOP) {
+		printf("child did not stop with SIGSTOP\n");
+		return false;
+	}
+
+	if (!set_watchpoint(pid, wp_size, wp))
+		return false;
+
+	if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) {
+		perror("ptrace(PTRACE_SINGLESTEP) failed");
+		return false;
+	}
+
+	alarm(3);
+	wpid = waitpid(pid, &status, __WALL);
+	if (wpid != pid) {
+		perror("waitpid() failed");
+		return false;
+	}
+	alarm(0);
+	if (WIFEXITED(status)) {
+		printf("child did not single-step\t");
+		return false;
+	}
+	if (!WIFSTOPPED(status)) {
+		printf("child did not stop\n");
+		return false;
+	}
+	if (WSTOPSIG(status) != SIGTRAP) {
+		printf("child did not stop with SIGTRAP\n");
+		return false;
+	}
+	if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0) {
+		perror("ptrace(PTRACE_GETSIGINFO)");
+		return false;
+	}
+	if (siginfo.si_code != TRAP_HWBKPT) {
+		printf("Unexpected si_code %d\n", siginfo.si_code);
+		return false;
+	}
+
+	kill(pid, SIGKILL);
+	wpid = waitpid(pid, &status, 0);
+	if (wpid != pid) {
+		perror("waitpid() failed");
+		return false;
+	}
+	return true;
+}
+
+static void sigalrm(int sig)
+{
+}
+
+int main(int argc, char **argv)
+{
+	int opt;
+	bool succeeded = true;
+	struct sigaction act;
+	int wr, wp, size;
+	bool result;
+
+	act.sa_handler = sigalrm;
+	sigemptyset(&act.sa_mask);
+	act.sa_flags = 0;
+	sigaction(SIGALRM, &act, NULL);
+	for (size = 1; size <= 32; size = size*2) {
+		for (wr = 0; wr <= 32; wr = wr + size) {
+			for (wp = wr - size; wp <= wr + size; wp = wp + size) {
+				printf("Test size = %d write offset = %d watchpoint offset = %d\t", size, wr, wp);
+				result = run_test(size, MIN(size, 8), wr, wp);
+				if ((result && wr == wp) || (!result && wr != wp)) {
+					printf("[OK]\n");
+					ksft_inc_pass_cnt();
+				} else {
+					printf("[FAILED]\n");
+					ksft_inc_fail_cnt();
+					succeeded = false;
+				}
+			}
+		}
+	}
+
+	for (size = 1; size <= 32; size = size*2) {
+		printf("Test size = %d write offset = %d watchpoint offset = -8\t", size, -size);
+
+		if (run_test(size, 8, -size, -8)) {
+			printf("[OK]\n");
+			ksft_inc_pass_cnt();
+		} else {
+			printf("[FAILED]\n");
+			ksft_inc_fail_cnt();
+			succeeded = false;
+		}
+	}
+
+	ksft_print_cnts();
+	if (succeeded)
+		ksft_exit_pass();
+	else
+		ksft_exit_fail();
+}
-- 
2.7.4

^ permalink raw reply related

* [PATCH V2 4/5] arm64: Allow hw watchpoint of length 3,5,6 and 7
From: Pratyush Anand @ 2016-10-20  5:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1476941895.git.panand@redhat.com>

Since, arm64 can support all offset within a double word limit. Therefore,
now support other lengths within that range as well.

Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 arch/arm64/include/asm/hw_breakpoint.h |  4 ++++
 arch/arm64/kernel/hw_breakpoint.c      | 36 ++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 4f4e58bee9bc..7a18c8520588 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -76,7 +76,11 @@ static inline void decode_ctrl_reg(u32 reg,
 /* Lengths */
 #define ARM_BREAKPOINT_LEN_1	0x1
 #define ARM_BREAKPOINT_LEN_2	0x3
+#define ARM_BREAKPOINT_LEN_3	0x7
 #define ARM_BREAKPOINT_LEN_4	0xf
+#define ARM_BREAKPOINT_LEN_5	0x1f
+#define ARM_BREAKPOINT_LEN_6	0x3f
+#define ARM_BREAKPOINT_LEN_7	0x7f
 #define ARM_BREAKPOINT_LEN_8	0xff
 
 /* Kernel stepping */
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index c57bc90b8286..4125c2152e85 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -317,9 +317,21 @@ static int get_hbp_len(u8 hbp_len)
 	case ARM_BREAKPOINT_LEN_2:
 		len_in_bytes = 2;
 		break;
+	case ARM_BREAKPOINT_LEN_3:
+		len_in_bytes = 3;
+		break;
 	case ARM_BREAKPOINT_LEN_4:
 		len_in_bytes = 4;
 		break;
+	case ARM_BREAKPOINT_LEN_5:
+		len_in_bytes = 5;
+		break;
+	case ARM_BREAKPOINT_LEN_6:
+		len_in_bytes = 6;
+		break;
+	case ARM_BREAKPOINT_LEN_7:
+		len_in_bytes = 7;
+		break;
 	case ARM_BREAKPOINT_LEN_8:
 		len_in_bytes = 8;
 		break;
@@ -379,9 +391,21 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
 	case ARM_BREAKPOINT_LEN_2:
 		*gen_len = HW_BREAKPOINT_LEN_2;
 		break;
+	case ARM_BREAKPOINT_LEN_3:
+		*gen_len = HW_BREAKPOINT_LEN_3;
+		break;
 	case ARM_BREAKPOINT_LEN_4:
 		*gen_len = HW_BREAKPOINT_LEN_4;
 		break;
+	case ARM_BREAKPOINT_LEN_5:
+		*gen_len = HW_BREAKPOINT_LEN_5;
+		break;
+	case ARM_BREAKPOINT_LEN_6:
+		*gen_len = HW_BREAKPOINT_LEN_6;
+		break;
+	case ARM_BREAKPOINT_LEN_7:
+		*gen_len = HW_BREAKPOINT_LEN_7;
+		break;
 	case ARM_BREAKPOINT_LEN_8:
 		*gen_len = HW_BREAKPOINT_LEN_8;
 		break;
@@ -425,9 +449,21 @@ static int arch_build_bp_info(struct perf_event *bp)
 	case HW_BREAKPOINT_LEN_2:
 		info->ctrl.len = ARM_BREAKPOINT_LEN_2;
 		break;
+	case HW_BREAKPOINT_LEN_3:
+		info->ctrl.len = ARM_BREAKPOINT_LEN_3;
+		break;
 	case HW_BREAKPOINT_LEN_4:
 		info->ctrl.len = ARM_BREAKPOINT_LEN_4;
 		break;
+	case HW_BREAKPOINT_LEN_5:
+		info->ctrl.len = ARM_BREAKPOINT_LEN_5;
+		break;
+	case HW_BREAKPOINT_LEN_6:
+		info->ctrl.len = ARM_BREAKPOINT_LEN_6;
+		break;
+	case HW_BREAKPOINT_LEN_7:
+		info->ctrl.len = ARM_BREAKPOINT_LEN_7;
+		break;
 	case HW_BREAKPOINT_LEN_8:
 		info->ctrl.len = ARM_BREAKPOINT_LEN_8;
 		break;
-- 
2.7.4

^ permalink raw reply related

* [PATCH V2 3/5] arm64: hw_breakpoint: Handle inexact watchpoint addresses
From: Pratyush Anand @ 2016-10-20  5:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1476941895.git.panand@redhat.com>

From: Pavel Labath <test.tberghammer@gmail.com>

Arm64 hardware does not always report a watchpoint hit address that
matches one of the watchpoints set. It can also report an address
"near" the watchpoint if a single instruction access both watched and
unwatched addresses. There is no straight-forward way, short of
disassembling the offending instruction, to map that address back to
the watchpoint.

Previously, when the hardware reported a watchpoint hit on an address
that did not match our watchpoint (this happens in case of instructions
which access large chunks of memory such as "stp") the process would
enter a loop where we would be continually resuming it (because we did
not recognise that watchpoint hit) and it would keep hitting the
watchpoint again and again. The tracing process would never get
notified of the watchpoint hit.

This commit fixes the problem by looking at the watchpoints near the
address reported by the hardware. If the address does not exactly match
one of the watchpoints we have set, it attributes the hit to the
nearest watchpoint we have.  This heuristic is a bit dodgy, but I don't
think we can do much more, given the hardware limitations.

[panand: reworked to rebase on his patches]

Signed-off-by: Pavel Labath <labath@google.com>
Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 arch/arm64/kernel/hw_breakpoint.c | 94 +++++++++++++++++++++++++++------------
 1 file changed, 66 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 3c2b96803eba..c57bc90b8286 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -662,11 +662,46 @@ unlock:
 }
 NOKPROBE_SYMBOL(breakpoint_handler);
 
+/*
+ * Arm64 hardware does not always report a watchpoint hit address that matches
+ * one of the watchpoints set. It can also report an address "near" the
+ * watchpoint if a single instruction access both watched and unwatched
+ * addresses. There is no straight-forward way, short of disassembling the
+ * offending instruction, to map that address back to the watchpoint. This
+ * function computes the distance of the memory access from the watchpoint as a
+ * heuristic for the likelyhood that a given access triggered the watchpoint.
+ *
+ * See Section D2.10.5 "Determining the memory location that caused a Watchpoint
+ * exception" of ARMv8 Architecture Reference Manual for details.
+ *
+ * The function returns the distance of the address from the bytes watched by
+ * the watchpoint. In case of an exact match, it returns 0.
+ */
+static u64 get_distance_from_watchpoint(unsigned long addr, u64 val,
+					struct arch_hw_breakpoint_ctrl *ctrl)
+{
+	u64 wp_low, wp_high;
+	u32 lens, lene;
+
+	lens = ffs(ctrl->len) - 1;
+	lene = fls(ctrl->len) - 1;
+
+	wp_low = val + lens;
+	wp_high = val + lene;
+	if (addr < wp_low)
+		return wp_low - addr;
+	else if (addr > wp_high)
+		return addr - wp_high;
+	else
+		return 0;
+}
+
 static int watchpoint_handler(unsigned long addr, unsigned int esr,
 			      struct pt_regs *regs)
 {
-	int i, step = 0, *kernel_step, access;
-	u32 ctrl_reg, lens, lene;
+	int i, step = 0, *kernel_step, access, closest_match = 0;
+	u64 min_dist = -1, dist;
+	u32 ctrl_reg;
 	u64 val;
 	struct perf_event *wp, **slots;
 	struct debug_info *debug_info;
@@ -676,31 +711,15 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
 	slots = this_cpu_ptr(wp_on_reg);
 	debug_info = &current->thread.debug;
 
+	/*
+	 * Find all watchpoints that match the reported address. If no exact
+	 * match is found. Attribute the hit to the closest watchpoint.
+	 */
+	rcu_read_lock();
 	for (i = 0; i < core_num_wrps; ++i) {
-		rcu_read_lock();
-
 		wp = slots[i];
-
 		if (wp == NULL)
-			goto unlock;
-
-		info = counter_arch_bp(wp);
-
-		/* Check if the watchpoint value and byte select match. */
-		val = read_wb_reg(AARCH64_DBG_REG_WVR, i);
-		ctrl_reg = read_wb_reg(AARCH64_DBG_REG_WCR, i);
-		decode_ctrl_reg(ctrl_reg, &ctrl);
-		lens = ffs(ctrl.len) - 1;
-		lene = fls(ctrl.len) - 1;
-		/*
-		 * FIXME: reported address can be anywhere between "the
-		 * lowest address accessed by the memory access that
-		 * triggered the watchpoint" and "the highest watchpointed
-		 * address accessed by the memory access". So, it may not
-		 * lie in the interval of watchpoint address range.
-		 */
-		if (addr < val + lens || addr > val + lene)
-			goto unlock;
+			continue;
 
 		/*
 		 * Check that the access type matches.
@@ -709,18 +728,37 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
 		access = (esr & AARCH64_ESR_ACCESS_MASK) ? HW_BREAKPOINT_W :
 			 HW_BREAKPOINT_R;
 		if (!(access & hw_breakpoint_type(wp)))
-			goto unlock;
+			continue;
+
+		/* Check if the watchpoint value and byte select match. */
+		val = read_wb_reg(AARCH64_DBG_REG_WVR, i);
+		ctrl_reg = read_wb_reg(AARCH64_DBG_REG_WCR, i);
+		decode_ctrl_reg(ctrl_reg, &ctrl);
+		dist = get_distance_from_watchpoint(addr, val, &ctrl);
+		if (dist < min_dist) {
+			min_dist = dist;
+			closest_match = i;
+		}
+		/* Is this an exact match? */
+		if (dist != 0)
+			continue;
 
+		info = counter_arch_bp(wp);
 		info->trigger = addr;
 		perf_bp_event(wp, regs);
 
 		/* Do we need to handle the stepping? */
 		if (is_default_overflow_handler(wp))
 			step = 1;
-
-unlock:
-		rcu_read_unlock();
 	}
+	if (min_dist > 0 && min_dist != -1) {
+		/* No exact match found. */
+		wp = slots[closest_match];
+		info = counter_arch_bp(wp);
+		info->trigger = addr;
+		perf_bp_event(wp, regs);
+	}
+	rcu_read_unlock();
 
 	if (!step)
 		return 0;
-- 
2.7.4

^ permalink raw reply related

* [PATCH V2 2/5] arm64: Allow hw watchpoint at varied offset from base address
From: Pratyush Anand @ 2016-10-20  5:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1476941895.git.panand@redhat.com>

ARM64 hardware supports watchpoint at any double word aligned address.
However, it can select any consecutive bytes from offset 0 to 7 from that
base address. For example, if base address is programmed as 0x420030 and
byte select is 0x1C, then access of 0x420032,0x420033 and 0x420034 will
generate a watchpoint exception.

Currently, we do not have such modularity. We can only program byte,
halfword, word and double word access exception from any base address.

This patch adds support to overcome above limitations.

Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 arch/arm64/include/asm/hw_breakpoint.h |  2 +-
 arch/arm64/kernel/hw_breakpoint.c      | 45 ++++++++++++++++------------------
 arch/arm64/kernel/ptrace.c             |  5 ++--
 3 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 115ea2a64520..4f4e58bee9bc 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -118,7 +118,7 @@ struct perf_event;
 struct pmu;
 
 extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
-				  int *gen_len, int *gen_type);
+				  int *gen_len, int *gen_type, int *offset);
 extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
 extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 26a6bf77d272..3c2b96803eba 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -349,7 +349,7 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp)
  * to generic breakpoint descriptions.
  */
 int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
-			   int *gen_len, int *gen_type)
+			   int *gen_len, int *gen_type, int *offset)
 {
 	/* Type */
 	switch (ctrl.type) {
@@ -369,8 +369,10 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
 		return -EINVAL;
 	}
 
+	*offset = ffs(ctrl.len) - 1;
+
 	/* Len */
-	switch (ctrl.len) {
+	switch (ctrl.len >> *offset) {
 	case ARM_BREAKPOINT_LEN_1:
 		*gen_len = HW_BREAKPOINT_LEN_1;
 		break;
@@ -517,18 +519,17 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
 		default:
 			return -EINVAL;
 		}
-
-		info->address &= ~alignment_mask;
-		info->ctrl.len <<= offset;
 	} else {
 		if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE)
 			alignment_mask = 0x3;
 		else
 			alignment_mask = 0x7;
-		if (info->address & alignment_mask)
-			return -EINVAL;
+		offset = info->address & alignment_mask;
 	}
 
+	info->address &= ~alignment_mask;
+	info->ctrl.len <<= offset;
+
 	/*
 	 * Disallow per-task kernel breakpoints since these would
 	 * complicate the stepping code.
@@ -665,8 +666,8 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
 			      struct pt_regs *regs)
 {
 	int i, step = 0, *kernel_step, access;
-	u32 ctrl_reg;
-	u64 val, alignment_mask;
+	u32 ctrl_reg, lens, lene;
+	u64 val;
 	struct perf_event *wp, **slots;
 	struct debug_info *debug_info;
 	struct arch_hw_breakpoint *info;
@@ -684,25 +685,21 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
 			goto unlock;
 
 		info = counter_arch_bp(wp);
-		/* AArch32 watchpoints are either 4 or 8 bytes aligned. */
-		if (is_compat_task()) {
-			if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
-				alignment_mask = 0x7;
-			else
-				alignment_mask = 0x3;
-		} else {
-			alignment_mask = 0x7;
-		}
 
-		/* Check if the watchpoint value matches. */
+		/* Check if the watchpoint value and byte select match. */
 		val = read_wb_reg(AARCH64_DBG_REG_WVR, i);
-		if (val != (addr & ~alignment_mask))
-			goto unlock;
-
-		/* Possible match, check the byte address select to confirm. */
 		ctrl_reg = read_wb_reg(AARCH64_DBG_REG_WCR, i);
 		decode_ctrl_reg(ctrl_reg, &ctrl);
-		if (!((1 << (addr & alignment_mask)) & ctrl.len))
+		lens = ffs(ctrl.len) - 1;
+		lene = fls(ctrl.len) - 1;
+		/*
+		 * FIXME: reported address can be anywhere between "the
+		 * lowest address accessed by the memory access that
+		 * triggered the watchpoint" and "the highest watchpointed
+		 * address accessed by the memory access". So, it may not
+		 * lie in the interval of watchpoint address range.
+		 */
+		if (addr < val + lens || addr > val + lene)
 			goto unlock;
 
 		/*
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index e0c81da60f76..0eb366a94382 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -327,13 +327,13 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
 				     struct arch_hw_breakpoint_ctrl ctrl,
 				     struct perf_event_attr *attr)
 {
-	int err, len, type, disabled = !ctrl.enabled;
+	int err, len, type, offset, disabled = !ctrl.enabled;
 
 	attr->disabled = disabled;
 	if (disabled)
 		return 0;
 
-	err = arch_bp_generic_fields(ctrl, &len, &type);
+	err = arch_bp_generic_fields(ctrl, &len, &type, &offset);
 	if (err)
 		return err;
 
@@ -352,6 +352,7 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
 
 	attr->bp_len	= len;
 	attr->bp_type	= type;
+	attr->bp_addr	+= offset;
 
 	return 0;
 }
-- 
2.7.4

^ permalink raw reply related

* [PATCH V2 1/5] hw_breakpoint: Allow watchpoint of length 3,5,6 and 7
From: Pratyush Anand @ 2016-10-20  5:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1476941895.git.panand@redhat.com>

We only support breakpoint/watchpoint of length 1, 2, 4 and 8. If we can
support other length as well, then user may watch more data with less
number of watchpoints (provided hardware supports it). For example: if we
have to watch only 4th, 5th and 6th byte from a 64 bit aligned address, we
will have to use two slots to implement it currently. One slot will watch a
half word at offset 4 and other a byte at offset 6. If we can have a
watchpoint of length 3 then we can watch it with single slot as well.

ARM64 hardware does support such functionality, therefore adding these new
definitions in generic layer.

Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 include/uapi/linux/hw_breakpoint.h       | 4 ++++
 tools/include/uapi/linux/hw_breakpoint.h | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/include/uapi/linux/hw_breakpoint.h b/include/uapi/linux/hw_breakpoint.h
index b04000a2296a..2b65efd19a46 100644
--- a/include/uapi/linux/hw_breakpoint.h
+++ b/include/uapi/linux/hw_breakpoint.h
@@ -4,7 +4,11 @@
 enum {
 	HW_BREAKPOINT_LEN_1 = 1,
 	HW_BREAKPOINT_LEN_2 = 2,
+	HW_BREAKPOINT_LEN_3 = 3,
 	HW_BREAKPOINT_LEN_4 = 4,
+	HW_BREAKPOINT_LEN_5 = 5,
+	HW_BREAKPOINT_LEN_6 = 6,
+	HW_BREAKPOINT_LEN_7 = 7,
 	HW_BREAKPOINT_LEN_8 = 8,
 };
 
diff --git a/tools/include/uapi/linux/hw_breakpoint.h b/tools/include/uapi/linux/hw_breakpoint.h
index b04000a2296a..2b65efd19a46 100644
--- a/tools/include/uapi/linux/hw_breakpoint.h
+++ b/tools/include/uapi/linux/hw_breakpoint.h
@@ -4,7 +4,11 @@
 enum {
 	HW_BREAKPOINT_LEN_1 = 1,
 	HW_BREAKPOINT_LEN_2 = 2,
+	HW_BREAKPOINT_LEN_3 = 3,
 	HW_BREAKPOINT_LEN_4 = 4,
+	HW_BREAKPOINT_LEN_5 = 5,
+	HW_BREAKPOINT_LEN_6 = 6,
+	HW_BREAKPOINT_LEN_7 = 7,
 	HW_BREAKPOINT_LEN_8 = 8,
 };
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH V2 0/5] ARM64: More flexible HW watchpoint
From: Pratyush Anand @ 2016-10-20  5:48 UTC (permalink / raw)
  To: linux-arm-kernel

Currently, we do not support all the byte select option provided by ARM64
specs for a HW watchpoint.

This patch set will help user to instrument a watchpoint with all possible
byte select options.

Changes since v1:
Introduced a new patch 3/5 where it takes care of the situation when HW
does not report a watchpoint hit with the address that matches one of the
watchpoints set.
Added corresponding test case to test that functionality.

Pavel Labath (1):
  arm64: hw_breakpoint: Handle inexact watchpoint addresses

Pratyush Anand (4):
  hw_breakpoint: Allow watchpoint of length 3,5,6 and 7
  arm64: Allow hw watchpoint at varied offset from base address
  arm64: Allow hw watchpoint of length 3,5,6 and 7
  selftests: arm64: add test for unaligned/inexact watchpoint handling

 arch/arm64/include/asm/hw_breakpoint.h             |   6 +-
 arch/arm64/kernel/hw_breakpoint.c                  | 149 +++++++++----
 arch/arm64/kernel/ptrace.c                         |   5 +-
 include/uapi/linux/hw_breakpoint.h                 |   4 +
 tools/include/uapi/linux/hw_breakpoint.h           |   4 +
 tools/testing/selftests/breakpoints/Makefile       |   5 +-
 .../selftests/breakpoints/breakpoint_test_arm64.c  | 236 +++++++++++++++++++++
 7 files changed, 366 insertions(+), 43 deletions(-)
 create mode 100644 tools/testing/selftests/breakpoints/breakpoint_test_arm64.c

-- 
2.7.4

^ permalink raw reply

* [PATCH 0/5] Switch to the DT cpufreq policy on the Integrator
From: Viresh Kumar @ 2016-10-20  4:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161020042012.GI11766@vireshk-i7>

On 20-10-16, 09:50, Viresh Kumar wrote:
> On 19-10-16, 11:59, Linus Walleij wrote:
> > This switches the ARM Integrator/AP and Integrator/CP to use the
> > Device Tree cpufreq policy with its definition of operating points
> > using the generic OPP library.
> > 
> > The Integrators does not need to control a regulator to switch
> > frequency, only a clock. This clock and its device tree bindings
> > have been defined in the device tree and merged upstream for v4.9.
> > 
> > This approach provides a little better granularity on the
> > Integrator/AP where I defined a few operating points: before
> > this change the Integrator would just switch between min speed
> > (12 MHz) and max speed (71 MHz). Now it can switch between a
> > few arbitrarily chosen OPPs as in the examples below:
> > 
> > The following tests were made on the Integrator/AP:
> > 
> > /sys/devices/system/cpu/cpufreq/policy0 echo ondemand > scaling_governor
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 71000000 Hz --> 24000000 Hz
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 24000000 Hz --> 12000000 Hz
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 12000000 Hz --> 24000000 Hz
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 24000000 Hz --> 12000000 Hz
> > 
> > The switch from 12 to 24 MHz is triggered by as little as using the
> > command line with the ondemand governor. If we do this:
> > 
> > yes > /dev/null &
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 12000000 Hz --> 36000000 Hz
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 36000000 Hz --> 71000000 Hz
> > pkill yes
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 71000000 Hz --> 12000000 Hz
> > 
> > So the algorithm is indeed using all the OPPs.
> > 
> > Also as a confirmation test to make sure performance is affected by the
> > speed changes, we set the performance governor and:
> > 
> > echo 12000 > scaling_max_freq
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 71000000 Hz --> 12000000 Hz
> > time find /sys|sort|uniq > /dev/null
> > real    0m 45.51s
> > user    0m 11.15s
> > sys     0m 26.74s
> > 
> > echo 71000 > scaling_max_freq
> > cpu cpu0: dev_pm_opp_set_rate: switching OPP: 12000000 Hz --> 71000000 Hz
> > time find /sys|sort|uniq
> >  > /dev/null
> > real    0m 9.13s
> > user    0m 2.35s
> > sys     0m 5.50s
> > 
> > So it is working.
> > 
> > If people are happy with this approach and approve of the patches
> > I'd like an ACK from the cpufreq people and then merge the whole set
> > through ARM SoC.
> 
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

Integrator is an UP, right? Otherwise you may want to use operating-points-v2
bindings instead.

-- 
viresh

^ permalink raw reply

* [PATCH v3 1/2] arm64: dts: uniphier: add CPU clock and OPP table for LD11 SoC
From: Viresh Kumar @ 2016-10-20  4:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476938647-26376-1-git-send-email-yamada.masahiro@socionext.com>

On 20-10-16, 13:44, Masahiro Yamada wrote:
> Add a CPU clock to every CPU node and a CPU OPP table to use the
> generic cpufreq driver.
> 
> Note:
> clock-latency-ns (300ns) was calculated based on the CPU-gear switch
> sequencer spec; it takes 12 clock cycles on the sequencer running
> at 50 MHz, plus a bit additional latency.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
> ---
> 
> Changes in v2:
>   - Match the node name to the opp-hz property.

For both the patches ..

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

-- 
viresh

^ permalink raw reply

* [PATCH v3 2/2] arm64: dts: uniphier: add CPU clocks and OPP tables for LD20 SoC
From: Masahiro Yamada @ 2016-10-20  4:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476938647-26376-1-git-send-email-yamada.masahiro@socionext.com>

Add a CPU clock to every CPU node and CPU OPP tables to use the
generic cpufreq driver.  All the CPUs in each cluster share the
same OPP table.

Note:
clock-latency-ns (300ns) was calculated based on the CPU-gear switch
sequencer spec; it takes 12 clock cycles on the sequencer running
at 50 MHz, plus a bit additional latency.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
  - Fix cluster1 OPP as well.

---

Changes in v2:
  - Match the node name to the opp-hz property.

 arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi | 84 ++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
index 6f48e82..a9a08dd 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
@@ -79,28 +79,36 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a72", "arm,armv8";
 			reg = <0 0x000>;
+			clocks = <&sys_clk 32>;
 			enable-method = "psci";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu1: cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a72", "arm,armv8";
 			reg = <0 0x001>;
+			clocks = <&sys_clk 32>;
 			enable-method = "psci";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu2: cpu at 100 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0 0x100>;
+			clocks = <&sys_clk 33>;
 			enable-method = "psci";
+			operating-points-v2 = <&cluster1_opp>;
 		};
 
 		cpu3: cpu at 101 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0 0x101>;
+			clocks = <&sys_clk 33>;
 			enable-method = "psci";
+			operating-points-v2 = <&cluster1_opp>;
 		};
 	};
 
@@ -109,6 +117,82 @@
 		method = "smc";
 	};
 
+	cluster0_opp: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp at 250000000 {
+			opp-hz = /bits/ 64 <250000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 275000000 {
+			opp-hz = /bits/ 64 <275000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 550000000 {
+			opp-hz = /bits/ 64 <550000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 666667000 {
+			opp-hz = /bits/ 64 <666667000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 733334000 {
+			opp-hz = /bits/ 64 <733334000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 1100000000 {
+			opp-hz = /bits/ 64 <1100000000>;
+			clock-latency-ns = <300>;
+		};
+	};
+
+	cluster1_opp: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp at 250000000 {
+			opp-hz = /bits/ 64 <250000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 275000000 {
+			opp-hz = /bits/ 64 <275000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 550000000 {
+			opp-hz = /bits/ 64 <550000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 666667000 {
+			opp-hz = /bits/ 64 <666667000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 733334000 {
+			opp-hz = /bits/ 64 <733334000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 1100000000 {
+			opp-hz = /bits/ 64 <1100000000>;
+			clock-latency-ns = <300>;
+		};
+	};
+
 	clocks {
 		refclk: ref {
 			compatible = "fixed-clock";
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 1/2] arm64: dts: uniphier: add CPU clock and OPP table for LD11 SoC
From: Masahiro Yamada @ 2016-10-20  4:44 UTC (permalink / raw)
  To: linux-arm-kernel

Add a CPU clock to every CPU node and a CPU OPP table to use the
generic cpufreq driver.

Note:
clock-latency-ns (300ns) was calculated based on the CPU-gear switch
sequencer spec; it takes 12 clock cycles on the sequencer running
at 50 MHz, plus a bit additional latency.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v2:
  - Match the node name to the opp-hz property.

 arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi | 38 ++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
index 73e0acf..bb05f0a 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
@@ -70,14 +70,18 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0 0x000>;
+			clocks = <&sys_clk 33>;
 			enable-method = "psci";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu1: cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53", "arm,armv8";
 			reg = <0 0x001>;
+			clocks = <&sys_clk 33>;
 			enable-method = "psci";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 	};
 
@@ -86,6 +90,40 @@
 		method = "smc";
 	};
 
+	cluster0_opp: opp_table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp at 245000000 {
+			opp-hz = /bits/ 64 <245000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 250000000 {
+			opp-hz = /bits/ 64 <250000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 490000000 {
+			opp-hz = /bits/ 64 <490000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 653334000 {
+			opp-hz = /bits/ 64 <653334000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 666667000 {
+			opp-hz = /bits/ 64 <666667000>;
+			clock-latency-ns = <300>;
+		};
+		opp at 980000000 {
+			opp-hz = /bits/ 64 <980000000>;
+			clock-latency-ns = <300>;
+		};
+	};
+
 	clocks {
 		refclk: ref {
 			compatible = "fixed-clock";
-- 
1.9.1

^ permalink raw reply related

* [PATCH 0/5] Switch to the DT cpufreq policy on the Integrator
From: Viresh Kumar @ 2016-10-20  4:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476871154-32243-1-git-send-email-linus.walleij@linaro.org>

On 19-10-16, 11:59, Linus Walleij wrote:
> This switches the ARM Integrator/AP and Integrator/CP to use the
> Device Tree cpufreq policy with its definition of operating points
> using the generic OPP library.
> 
> The Integrators does not need to control a regulator to switch
> frequency, only a clock. This clock and its device tree bindings
> have been defined in the device tree and merged upstream for v4.9.
> 
> This approach provides a little better granularity on the
> Integrator/AP where I defined a few operating points: before
> this change the Integrator would just switch between min speed
> (12 MHz) and max speed (71 MHz). Now it can switch between a
> few arbitrarily chosen OPPs as in the examples below:
> 
> The following tests were made on the Integrator/AP:
> 
> /sys/devices/system/cpu/cpufreq/policy0 echo ondemand > scaling_governor
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 71000000 Hz --> 24000000 Hz
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 24000000 Hz --> 12000000 Hz
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 12000000 Hz --> 24000000 Hz
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 24000000 Hz --> 12000000 Hz
> 
> The switch from 12 to 24 MHz is triggered by as little as using the
> command line with the ondemand governor. If we do this:
> 
> yes > /dev/null &
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 12000000 Hz --> 36000000 Hz
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 36000000 Hz --> 71000000 Hz
> pkill yes
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 71000000 Hz --> 12000000 Hz
> 
> So the algorithm is indeed using all the OPPs.
> 
> Also as a confirmation test to make sure performance is affected by the
> speed changes, we set the performance governor and:
> 
> echo 12000 > scaling_max_freq
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 71000000 Hz --> 12000000 Hz
> time find /sys|sort|uniq > /dev/null
> real    0m 45.51s
> user    0m 11.15s
> sys     0m 26.74s
> 
> echo 71000 > scaling_max_freq
> cpu cpu0: dev_pm_opp_set_rate: switching OPP: 12000000 Hz --> 71000000 Hz
> time find /sys|sort|uniq
>  > /dev/null
> real    0m 9.13s
> user    0m 2.35s
> sys     0m 5.50s
> 
> So it is working.
> 
> If people are happy with this approach and approve of the patches
> I'd like an ACK from the cpufreq people and then merge the whole set
> through ARM SoC.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

-- 
viresh

^ permalink raw reply

* [PATCH 1/2] arm64/numa: fix pcpu_cpu_distance() to get correct CPU proximity
From: Hanjun Guo @ 2016-10-20  4:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476935576-59941-1-git-send-email-guohanjun@huawei.com>

On 2016/10/20 11:52, Hanjun Guo wrote:
> From: Yisheng Xie <xieyisheng1@huawei.com>
>
> The pcpu_build_alloc_info() function group CPUs according to their
> proximity, by call callback function @cpu_distance_fn from different
> ARCHs.
>
> For arm64 the callback of @cpu_distance_fn is
>     pcpu_cpu_distance(from, to)
>         -> node_distance(from, to)
> The @from and @to for function node_distance() should be nid.
>
> However, pcpu_cpu_distance() in arch/arm64/mm/numa.c just past the
> cpu id for @from and @to.
>
> For this incorrect cpu proximity get from ARCH, it may cause each CPU
> in one group and make group_cnt out of bound:
>
> 	setup_per_cpu_areas()
> 		pcpu_embed_first_chunk()
> 			pcpu_build_alloc_info()
> in pcpu_build_alloc_info, since cpu_distance_fn will return
> REMOTE_DISTANCE if we pass cpu ids (0,1,2...), so
> cpu_distance_fn(cpu, tcpu) > LOCAL_DISTANCE will wrongly be ture.
>
> This may results in triggering the BUG_ON(unit != nr_units) later:
>
> [    0.000000] kernel BUG at mm/percpu.c:1916!
> [    0.000000] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
> [    0.000000] Modules linked in:
> [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.9.0-rc1-00003-g14155ca-dirty #26
> [    0.000000] Hardware name: Hisilicon Hi1616 Evaluation Board (DT)
> [    0.000000] task: ffff000008d6e900 task.stack: ffff000008d60000
> [    0.000000] PC is at pcpu_embed_first_chunk+0x420/0x704
> [    0.000000] LR is at pcpu_embed_first_chunk+0x3bc/0x704
> [    0.000000] pc : [<ffff000008c754f4>] lr : [<ffff000008c75490>] pstate: 800000c5
> [    0.000000] sp : ffff000008d63eb0
> [    0.000000] x29: ffff000008d63eb0 [    0.000000] x28: 0000000000000000
> [    0.000000] x27: 0000000000000040 [    0.000000] x26: ffff8413fbfcef00
> [    0.000000] x25: 0000000000000042 [    0.000000] x24: 0000000000000042
> [    0.000000] x23: 0000000000001000 [    0.000000] x22: 0000000000000046
> [    0.000000] x21: 0000000000000001 [    0.000000] x20: ffff000008cb3bc8
> [    0.000000] x19: ffff8413fbfcf570 [    0.000000] x18: 0000000000000000
> [    0.000000] x17: ffff000008e49ae0 [    0.000000] x16: 0000000000000003
> [    0.000000] x15: 000000000000001e [    0.000000] x14: 0000000000000004
> [    0.000000] x13: 0000000000000000 [    0.000000] x12: 000000000000006f
> [    0.000000] x11: 00000413fbffff00 [    0.000000] x10: 0000000000000004
> [    0.000000] x9 : 0000000000000000 [    0.000000] x8 : 0000000000000001
> [    0.000000] x7 : ffff8413fbfcf63c [    0.000000] x6 : ffff000008d65d28
> [    0.000000] x5 : ffff000008d65e50 [    0.000000] x4 : 0000000000000000
> [    0.000000] x3 : ffff000008cb3cc8 [    0.000000] x2 : 0000000000000040
> [    0.000000] x1 : 0000000000000040 [    0.000000] x0 : 0000000000000000
> [...]
> [    0.000000] Call trace:
> [    0.000000] Exception stack(0xffff000008d63ce0 to 0xffff000008d63e10)
> [    0.000000] 3ce0: ffff8413fbfcf570 0001000000000000 ffff000008d63eb0 ffff000008c754f4
> [    0.000000] 3d00: ffff000008d63d50 ffff0000081af210 00000413fbfff010 0000000000001000
> [    0.000000] 3d20: ffff000008d63d50 ffff0000081af220 00000413fbfff010 0000000000001000
> [    0.000000] 3d40: 00000413fbfcef00 0000000000000004 ffff000008d63db0 ffff0000081af390
> [    0.000000] 3d60: 00000413fbfcef00 0000000000001000 0000000000000000 0000000000001000
> [    0.000000] 3d80: 0000000000000000 0000000000000040 0000000000000040 ffff000008cb3cc8
> [    0.000000] 3da0: 0000000000000000 ffff000008d65e50 ffff000008d65d28 ffff8413fbfcf63c
> [    0.000000] 3dc0: 0000000000000001 0000000000000000 0000000000000004 00000413fbffff00
> [    0.000000] 3de0: 000000000000006f 0000000000000000 0000000000000004 000000000000001e
> [    0.000000] 3e00: 0000000000000003 ffff000008e49ae0
> [    0.000000] [<ffff000008c754f4>] pcpu_embed_first_chunk+0x420/0x704
> [    0.000000] [<ffff000008c6658c>] setup_per_cpu_areas+0x38/0xc8
> [    0.000000] [<ffff000008c608d8>] start_kernel+0x10c/0x390
> [    0.000000] [<ffff000008c601d8>] __primary_switched+0x5c/0x64
> [    0.000000] Code: b8018660 17ffffd7 6b16037f 54000080 (d4210000)
> [    0.000000] ---[ end trace 0000000000000000 ]---
> [    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
>
> Fix by getting CPUs proximity through its node. We only care about
> whether it is LOCAL_DISTANCE or not, for pcpu_build_alloc_info() only
> use this to group CPUs.
>
> Fixes: 7af3a0a99252 ("arm64/numa: support HAVE_SETUP_PER_CPU_AREA")
> Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Zhen Lei <thunder.leizhen@huawei.com>
> ---
>  arch/arm64/mm/numa.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
> index 778a985..34415fc 100644
> --- a/arch/arm64/mm/numa.c
> +++ b/arch/arm64/mm/numa.c
> @@ -147,7 +147,10 @@ static int __init early_cpu_to_node(int cpu)
>  
>  static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
>  {
> -	return node_distance(from, to);
> +	if (early_cpu_to_node(from) == early_cpu_to_node(to))
> +		return LOCAL_DISTANCE;
> +	else
> +		return REMOTE_DISTANCE;
>  }
>  
>  static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size,

We trigger this bug with NR_CPUS=64 in the config instead of 4096 in defconfig
for arm64, and we have 64 cpus in the system. I think that's why this bug wasn't
triggered yet on other ARM64 NUMA platforms, this bug should generic for all ARM64
platforms.

Thanks
Hanjun

^ permalink raw reply

* [PATCH v2 2/2] arm64: dts: uniphier: add CPU clocks and OPP tables for LD20 SoC
From: Masahiro Yamada @ 2016-10-20  3:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161020035542.GG11766@vireshk-i7>

2016-10-20 12:55 GMT+09:00 Viresh Kumar <viresh.kumar@linaro.org>:
> On 20-10-16, 10:15, Masahiro Yamada wrote:
>> +             opp at 666666666 {
>> +                     opp-hz = /bits/ 64 <666667000>;
>> +                     clock-latency-ns = <300>;
>> +             };
>> +             opp at 733333333 {
>> +                     opp-hz = /bits/ 64 <733334000>;
>> +                     clock-latency-ns = <300>;
>> +             };
>
> Forgot changing these ? Please make sure to update all of them.
>

Oops, I missed that.

Will fix soon.

Thanks!



-- 
Best Regards
Masahiro Yamada

^ permalink raw reply

* [PATCH v2 2/2] arm64: dts: uniphier: add CPU clocks and OPP tables for LD20 SoC
From: Viresh Kumar @ 2016-10-20  3:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476926126-6079-2-git-send-email-yamada.masahiro@socionext.com>

On 20-10-16, 10:15, Masahiro Yamada wrote:
> +		opp at 666666666 {
> +			opp-hz = /bits/ 64 <666667000>;
> +			clock-latency-ns = <300>;
> +		};
> +		opp at 733333333 {
> +			opp-hz = /bits/ 64 <733334000>;
> +			clock-latency-ns = <300>;
> +		};

Forgot changing these ? Please make sure to update all of them.

-- 
viresh

^ permalink raw reply

* [PATCH 2/2] arm64/numa: fix incorrect print of end_pfn
From: Hanjun Guo @ 2016-10-20  3:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476935576-59941-1-git-send-email-guohanjun@huawei.com>

From: Hanjun Guo <hanjun.guo@linaro.org>

When booting on NUMA system with memory-less node (no
memory dimm on this memory controller), the print
for setup_node_data() is incorrect:

NUMA: Initmem setup node 2 [mem 0x00000000-0xffffffffffffffff]

It should be 0, not 0xffffffffffffffff as there is
no memory on that node.

Fixes: 1a2db300348b ("arm64, numa: Add NUMA support for arm64 platforms.")
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/mm/numa.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
index 34415fc..148e1fc 100644
--- a/arch/arm64/mm/numa.c
+++ b/arch/arm64/mm/numa.c
@@ -227,7 +227,8 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
 	int tnid;
 
 	pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
-		nid, start_pfn << PAGE_SHIFT, (end_pfn << PAGE_SHIFT) - 1);
+		nid, start_pfn << PAGE_SHIFT,
+		end_pfn ? (end_pfn << PAGE_SHIFT) - 1 : 0);
 
 	nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
 	nd = __va(nd_pa);
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 1/2] arm64/numa: fix pcpu_cpu_distance() to get correct CPU proximity
From: Hanjun Guo @ 2016-10-20  3:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Yisheng Xie <xieyisheng1@huawei.com>

The pcpu_build_alloc_info() function group CPUs according to their
proximity, by call callback function @cpu_distance_fn from different
ARCHs.

For arm64 the callback of @cpu_distance_fn is
    pcpu_cpu_distance(from, to)
        -> node_distance(from, to)
The @from and @to for function node_distance() should be nid.

However, pcpu_cpu_distance() in arch/arm64/mm/numa.c just past the
cpu id for @from and @to.

For this incorrect cpu proximity get from ARCH, it may cause each CPU
in one group and make group_cnt out of bound:

	setup_per_cpu_areas()
		pcpu_embed_first_chunk()
			pcpu_build_alloc_info()
in pcpu_build_alloc_info, since cpu_distance_fn will return
REMOTE_DISTANCE if we pass cpu ids (0,1,2...), so
cpu_distance_fn(cpu, tcpu) > LOCAL_DISTANCE will wrongly be ture.

This may results in triggering the BUG_ON(unit != nr_units) later:

[    0.000000] kernel BUG at mm/percpu.c:1916!
[    0.000000] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.9.0-rc1-00003-g14155ca-dirty #26
[    0.000000] Hardware name: Hisilicon Hi1616 Evaluation Board (DT)
[    0.000000] task: ffff000008d6e900 task.stack: ffff000008d60000
[    0.000000] PC is at pcpu_embed_first_chunk+0x420/0x704
[    0.000000] LR is at pcpu_embed_first_chunk+0x3bc/0x704
[    0.000000] pc : [<ffff000008c754f4>] lr : [<ffff000008c75490>] pstate: 800000c5
[    0.000000] sp : ffff000008d63eb0
[    0.000000] x29: ffff000008d63eb0 [    0.000000] x28: 0000000000000000
[    0.000000] x27: 0000000000000040 [    0.000000] x26: ffff8413fbfcef00
[    0.000000] x25: 0000000000000042 [    0.000000] x24: 0000000000000042
[    0.000000] x23: 0000000000001000 [    0.000000] x22: 0000000000000046
[    0.000000] x21: 0000000000000001 [    0.000000] x20: ffff000008cb3bc8
[    0.000000] x19: ffff8413fbfcf570 [    0.000000] x18: 0000000000000000
[    0.000000] x17: ffff000008e49ae0 [    0.000000] x16: 0000000000000003
[    0.000000] x15: 000000000000001e [    0.000000] x14: 0000000000000004
[    0.000000] x13: 0000000000000000 [    0.000000] x12: 000000000000006f
[    0.000000] x11: 00000413fbffff00 [    0.000000] x10: 0000000000000004
[    0.000000] x9 : 0000000000000000 [    0.000000] x8 : 0000000000000001
[    0.000000] x7 : ffff8413fbfcf63c [    0.000000] x6 : ffff000008d65d28
[    0.000000] x5 : ffff000008d65e50 [    0.000000] x4 : 0000000000000000
[    0.000000] x3 : ffff000008cb3cc8 [    0.000000] x2 : 0000000000000040
[    0.000000] x1 : 0000000000000040 [    0.000000] x0 : 0000000000000000
[...]
[    0.000000] Call trace:
[    0.000000] Exception stack(0xffff000008d63ce0 to 0xffff000008d63e10)
[    0.000000] 3ce0: ffff8413fbfcf570 0001000000000000 ffff000008d63eb0 ffff000008c754f4
[    0.000000] 3d00: ffff000008d63d50 ffff0000081af210 00000413fbfff010 0000000000001000
[    0.000000] 3d20: ffff000008d63d50 ffff0000081af220 00000413fbfff010 0000000000001000
[    0.000000] 3d40: 00000413fbfcef00 0000000000000004 ffff000008d63db0 ffff0000081af390
[    0.000000] 3d60: 00000413fbfcef00 0000000000001000 0000000000000000 0000000000001000
[    0.000000] 3d80: 0000000000000000 0000000000000040 0000000000000040 ffff000008cb3cc8
[    0.000000] 3da0: 0000000000000000 ffff000008d65e50 ffff000008d65d28 ffff8413fbfcf63c
[    0.000000] 3dc0: 0000000000000001 0000000000000000 0000000000000004 00000413fbffff00
[    0.000000] 3de0: 000000000000006f 0000000000000000 0000000000000004 000000000000001e
[    0.000000] 3e00: 0000000000000003 ffff000008e49ae0
[    0.000000] [<ffff000008c754f4>] pcpu_embed_first_chunk+0x420/0x704
[    0.000000] [<ffff000008c6658c>] setup_per_cpu_areas+0x38/0xc8
[    0.000000] [<ffff000008c608d8>] start_kernel+0x10c/0x390
[    0.000000] [<ffff000008c601d8>] __primary_switched+0x5c/0x64
[    0.000000] Code: b8018660 17ffffd7 6b16037f 54000080 (d4210000)
[    0.000000] ---[ end trace 0000000000000000 ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!

Fix by getting CPUs proximity through its node. We only care about
whether it is LOCAL_DISTANCE or not, for pcpu_build_alloc_info() only
use this to group CPUs.

Fixes: 7af3a0a99252 ("arm64/numa: support HAVE_SETUP_PER_CPU_AREA")
Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Zhen Lei <thunder.leizhen@huawei.com>
---
 arch/arm64/mm/numa.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
index 778a985..34415fc 100644
--- a/arch/arm64/mm/numa.c
+++ b/arch/arm64/mm/numa.c
@@ -147,7 +147,10 @@ static int __init early_cpu_to_node(int cpu)
 
 static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
 {
-	return node_distance(from, to);
+	if (early_cpu_to_node(from) == early_cpu_to_node(to))
+		return LOCAL_DISTANCE;
+	else
+		return REMOTE_DISTANCE;
 }
 
 static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size,
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH v2 8/8] ARM: dts: sun6i: hummingbird-a31: Enable display output through VGA bridge
From: Chen-Yu Tsai @ 2016-10-20  3:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161020034344.14154-1-wens@csie.org>

The Hummingbird A31 board has a RGB-to-VGA bridge which converts RGB
output from the LCD interface to VGA signals.

Enable this part of the display pipeline.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 56 +++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index 9a74637f677f..05a49b2147f1 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -63,6 +63,49 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	bridge {
+		compatible = "dumb-vga-dac";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+
+				vga_bridge_in: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&tcon0_out_vga>;
+				};
+			};
+
+			port at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+
+				vga_bridge_out: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	vga {
+		compatible = "vga-connector";
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_bridge_out>;
+			};
+		};
+	};
+
 	wifi_pwrseq: wifi_pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 */
@@ -245,6 +288,19 @@
 	status = "okay";
 };
 
+&tcon0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd0_rgb888_pins>;
+	status = "okay";
+};
+
+&tcon0_out {
+	tcon0_out_vga: endpoint at 0 {
+		reg = <0>;
+		remote-endpoint = <&vga_bridge_in>;
+	};
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
-- 
2.9.3

^ permalink raw reply related


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