Re: [PATCH 1/5] arm: sunxi: add support for V3s SoC

2017-01-12 Thread Maxime Ripard
1;4601;0c
On Thu, Jan 12, 2017 at 03:40:32AM +0800, Icenowy Zheng wrote:
> 
> 
> 11.01.2017, 02:09, "Maxime Ripard" :
> > On Tue, Jan 03, 2017 at 11:16:25PM +0800, Icenowy Zheng wrote:
> >>  Allwinner V3s is a low-end single-core Cortex-A7 SoC, with 64MB
> >>  integrated DRAM, and several peripherals.
> >>
> >>  Signed-off-by: Icenowy Zheng 
> >>  ---
> >>   Documentation/arm/sunxi/README | 4 
> >>   arch/arm/mach-sunxi/sunxi.c | 1 +
> >>   2 files changed, 5 insertions(+)
> >>
> >>  diff --git a/Documentation/arm/sunxi/README 
> >> b/Documentation/arm/sunxi/README
> >>  index cd0243302bc1..91ec8f2055be 100644
> >>  --- a/Documentation/arm/sunxi/README
> >>  +++ b/Documentation/arm/sunxi/README
> >>  @@ -67,6 +67,10 @@ SunXi family
> >>   + Datasheet
> >> http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf
> >>
> >>  + - Allwinner V3s (sun8i)
> >>  + + Datasheet
> >>  + 
> >> https://www.goprawn.com/forum/allwinner-cams/783-allwinner-v3s-soc-datasheet
> >>  +
> >
> > Please don't put random links in there, but at least something that we
> > know will be there in a couple of weeks/monthes/years
> 
> Is http://linux-sunxi.org/File:Allwinner_V3s_Datasheet_V1.0.pdf acceptable?

It's much better, yes.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH v2] ARM64: dts: meson-gxbb-odroidc2: Disable SCPI DVFS

2017-01-12 Thread Martin Blumenstingl
Hi Neil,

(adding Brian Kim, one of the Hardkernel developers to this conversation)

On Fri, Jan 6, 2017 at 9:04 AM, Neil Armstrong  wrote:
> The current hardware is not able to run with all cores enabled at a
> cluster frequency superior at 1536MHz.
> But the currently shipped u-boot for the platform still reports an OPP
> table with possible DVFS frequency up to 2GHz, and will not change since
> the off-tree linux tree supports limiting the OPPs with a kernel parameter.
> A recent u-boot change reports the boot-time DVFS around 100MHz and
> the default performance cpufreq governor sets the maximum frequency.
> Previous version of u-boot reported to be already at the max OPP and
> left the OPP as is.
> Nevertheless, other governors like ondemand could setup the max frequency
> and make the system crash.
>
> This patch disables the DVFS clock and disables cpufreq.
I don't have any Odroid-C2 board, but having to live without cpufreq
sounds bad for the Odroid-C2 users.
What would we expect from a kernel perspective (maybe the Hardkernel
guys would adjust their u-boot instead of us adjusting to the behavior
of one specific device? one solution that I could think of involves
the "maxcpus" kernel parameter (see [0]), if this is not set u-boot
should report a max CPU frequency of 1536MHz (= max frequency for 4
active cores). Based on the "maxcpus" value additional frequencies can
be unlocked (this could be step-by-step if there are different
frequencies for one core/two cores/etc.). However, I'd like to hear
other opinions as well.


Regards,
Martin


[0] 
http://lxr.free-electrons.com/source/Documentation/kernel-parameters.txt?v=4.8#L2163


Re: [PATCHv7 00/11] CONFIG_DEBUG_VIRTUAL for arm64

2017-01-12 Thread Will Deacon
On Tue, Jan 10, 2017 at 01:35:39PM -0800, Laura Abbott wrote:
> This is v7 of the patches to add CONFIG_DEBUG_VIRTUAL for arm64. This is
> a simple reordering of patches from v6 per request of Will Deacon for ease
> of merging support for arm which depends on this series.
> 
> Laura Abbott (11):
>   lib/Kconfig.debug: Add ARCH_HAS_DEBUG_VIRTUAL
>   mm/cma: Cleanup highmem check
>   mm: Introduce lm_alias
>   kexec: Switch to __pa_symbol
>   mm/kasan: Switch to using __pa_symbol and lm_alias
>   mm/usercopy: Switch to using lm_alias
>   drivers: firmware: psci: Use __pa_symbol for kernel symbol
>   arm64: Move some macros under #ifndef __ASSEMBLY__
>   arm64: Add cast for virt_to_pfn
>   arm64: Use __pa_symbol for kernel symbols
>   arm64: Add support for CONFIG_DEBUG_VIRTUAL

I've pushed this into linux-next and, assuming it survives the
autobuilders etc I'll co-ordinate with Russell to get the common parts
pulled into the ARM tree too (so he can take Florian's series). They're
currently split out on the arm64 for-next/debug-virtual branch.

Thanks!

Will


[PATCH v5] DAX: enable iostat for read/write

2017-01-12 Thread Toshi Kani
DAX IO path does not support iostat, but its metadata IO path does.
Therefore, iostat shows metadata IO statistics only, which has been
confusing to users.

Add iostat support to the DAX read/write path.

Note, iostat still does not support the DAX mmap path as it allows
user applications to access directly.

Signed-off-by: Toshi Kani 
Cc: Andrew Morton 
Cc: Dan Williams 
Cc: Alexander Viro 
Cc: Dave Chinner 
Cc: Ross Zwisler 
Cc: Joe Perches 
---
v5:
 - Add a flag in case 'start' is 0 after 'jiffies' rolls over.
   (Dan Williams)
 - Fix a signed/unsigned conversion. (Joe Perches)
---
 fs/dax.c |   15 +++
 1 file changed, 15 insertions(+)

diff --git a/fs/dax.c b/fs/dax.c
index 5c74f60..a3e406a 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -1058,12 +1058,24 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
 {
struct address_space *mapping = iocb->ki_filp->f_mapping;
struct inode *inode = mapping->host;
+   struct gendisk *disk = inode->i_sb->s_bdev->bd_disk;
loff_t pos = iocb->ki_pos, ret = 0, done = 0;
unsigned flags = 0;
+   unsigned long start = 0;
+   int do_acct = blk_queue_io_stat(disk->queue);
 
if (iov_iter_rw(iter) == WRITE)
flags |= IOMAP_WRITE;
 
+   if (do_acct) {
+   sector_t sec = iov_iter_count(iter) >> 9;
+
+   start = jiffies;
+   generic_start_io_acct(iov_iter_rw(iter),
+ min_t(unsigned long, 1, sec),
+ &disk->part0);
+   }
+
while (iov_iter_count(iter)) {
ret = iomap_apply(inode, pos, iov_iter_count(iter), flags, ops,
iter, dax_iomap_actor);
@@ -1073,6 +1085,9 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
done += ret;
}
 
+   if (do_acct)
+   generic_end_io_acct(iov_iter_rw(iter), &disk->part0, start);
+
iocb->ki_pos += done;
return done ? done : ret;
 }


Re: [PATCH v8 2/2] tpm: add securityfs support for TPM 2.0 firmware event log

2017-01-12 Thread Jarkko Sakkinen
On Wed, Jan 11, 2017 at 02:54:22AM -0500, Nayna Jain wrote:
> Unlike the device driver support for TPM 1.2, the TPM 2.0 does
> not support the securityfs pseudo files for displaying the
> firmware event log.
> 
> This patch enables support for providing the TPM 2.0 event log in
> binary form. TPM 2.0 event log supports a crypto agile format that
> records multiple digests, which is different from TPM 1.2. This
> patch enables the tpm_bios_log_setup for TPM 2.0  and adds the
> event log parser which understand the TPM 2.0 crypto agile format.
> 
> Signed-off-by: Nayna Jain 

Overally looks good but I cannot test this.

/Jarkko

> ---
>  drivers/char/tpm/Makefile  |   2 +-
>  .../char/tpm/{tpm_eventlog.c => tpm1_eventlog.c}   |  35 ++--
>  drivers/char/tpm/tpm2_eventlog.c   | 203 
> +
>  drivers/char/tpm/tpm_acpi.c|   3 +
>  drivers/char/tpm/tpm_eventlog.h|  63 +++
>  5 files changed, 291 insertions(+), 15 deletions(-)
>  rename drivers/char/tpm/{tpm_eventlog.c => tpm1_eventlog.c} (95%)
>  create mode 100644 drivers/char/tpm/tpm2_eventlog.c
> 
> diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
> index a05b1eb..3d386a8 100644
> --- a/drivers/char/tpm/Makefile
> +++ b/drivers/char/tpm/Makefile
> @@ -3,7 +3,7 @@
>  #
>  obj-$(CONFIG_TCG_TPM) += tpm.o
>  tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
> - tpm_eventlog.o
> + tpm1_eventlog.o tpm2_eventlog.o
>  tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o
>  tpm-$(CONFIG_OF) += tpm_of.o
>  obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
> diff --git a/drivers/char/tpm/tpm_eventlog.c 
> b/drivers/char/tpm/tpm1_eventlog.c
> similarity index 95%
> rename from drivers/char/tpm/tpm_eventlog.c
> rename to drivers/char/tpm/tpm1_eventlog.c
> index 11bb113..9a8605e 100644
> --- a/drivers/char/tpm/tpm_eventlog.c
> +++ b/drivers/char/tpm/tpm1_eventlog.c
> @@ -390,9 +390,6 @@ int tpm_bios_log_setup(struct tpm_chip *chip)
>   unsigned int cnt;
>   int rc = 0;
>  
> - if (chip->flags & TPM_CHIP_FLAG_TPM2)
> - return 0;
> -
>   rc = tpm_read_log(chip);
>   if (rc)
>   return rc;
> @@ -407,7 +404,13 @@ int tpm_bios_log_setup(struct tpm_chip *chip)
>   cnt++;
>  
>   chip->bin_log_seqops.chip = chip;
> - chip->bin_log_seqops.seqops = &tpm_binary_b_measurements_seqops;
> + if (chip->flags & TPM_CHIP_FLAG_TPM2)
> + chip->bin_log_seqops.seqops =
> + &tpm2_binary_b_measurements_seqops;
> + else
> + chip->bin_log_seqops.seqops =
> + &tpm_binary_b_measurements_seqops;
> +
>  
>   chip->bios_dir[cnt] =
>   securityfs_create_file("binary_bios_measurements",
> @@ -418,17 +421,21 @@ int tpm_bios_log_setup(struct tpm_chip *chip)
>   goto err;
>   cnt++;
>  
> - chip->ascii_log_seqops.chip = chip;
> - chip->ascii_log_seqops.seqops = &tpm_ascii_b_measurements_seqops;
> + if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
>  
> - chip->bios_dir[cnt] =
> - securityfs_create_file("ascii_bios_measurements",
> -0440, chip->bios_dir[0],
> -(void *)&chip->ascii_log_seqops,
> -&tpm_bios_measurements_ops);
> - if (IS_ERR(chip->bios_dir[cnt]))
> - goto err;
> - cnt++;
> + chip->ascii_log_seqops.chip = chip;
> + chip->ascii_log_seqops.seqops =
> + &tpm_ascii_b_measurements_seqops;
> +
> + chip->bios_dir[cnt] =
> + securityfs_create_file("ascii_bios_measurements",
> +0440, chip->bios_dir[0],
> +(void *)&chip->ascii_log_seqops,
> +&tpm_bios_measurements_ops);
> + if (IS_ERR(chip->bios_dir[cnt]))
> + goto err;
> + cnt++;
> + }
>  
>   return 0;
>  
> diff --git a/drivers/char/tpm/tpm2_eventlog.c 
> b/drivers/char/tpm/tpm2_eventlog.c
> new file mode 100644
> index 000..1063b09
> --- /dev/null
> +++ b/drivers/char/tpm/tpm2_eventlog.c
> @@ -0,0 +1,203 @@
> +/*
> + * Copyright (C) 2016 IBM Corporation
> + *
> + * Authors:
> + *  Nayna Jain 
> + *
> + * Access to TPM 2.0 event log as written by Firmware.
> + * It assumes that writer of event log has followed TCG Specification
> + * for Family "2.0" and written the event data in little endian.
> + * With that, it doesn't need any endian conversion for structure
> + * content.
> + *
> + * 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.
> + */
> +
> 

Re: [PATCH 2/5] clk: sunxi-ng: add support for V3s CCU

2017-01-12 Thread Maxime Ripard
On Fri, Jan 13, 2017 at 01:31:41AM +0800, Icenowy Zheng wrote:
> 
> 2017年1月13日 01:19于 Maxime Ripard 写道:
> >
> > On Thu, Jan 12, 2017 at 03:44:53AM +0800, Icenowy Zheng wrote: 
> > > 
> > > 
> > > 12.01.2017, 03:40, "Icenowy Zheng" : 
> > > > 11.01.2017, 02:10, "Maxime Ripard" : 
> > > >>  On Tue, Jan 03, 2017 at 11:16:26PM +0800, Icenowy Zheng wrote: 
> > > >>>   V3s has a similar but cut-down CCU to H3. 
> > > >>> 
> > > >>>   Add support for it. 
> > > >>> 
> > > >>>   Signed-off-by: Icenowy Zheng  
> > > >> 
> > > >>  It looks like there's nothing different but the clocks that you 
> > > >>  register with the H3, please just use the H3 driver. 
> > > > 
> > > > Nope. 
> > > > 
> > > > It has a different PLL (PLL_ISP) at different address, and some 
> > > > different muxes. 
> > > 
> > > Forgot to mention the missing of PLL_DE and related misses. 
> >
> > Those are not conflicting, it's just a slightly different set of 
> > clocks. 
> 
> If saying so, we can have only one ccu driver, and make every ccu
> register different set ;-)
> 
> V3s itself is a totally different SoC with H3.
> 
> The relationship of V3s and H3 can be farther than the relationship
> of A33 and H3😃

A33 and H3 are an entirely different story. The H3 and A33 have
conflicting clocks (ie same clocks with different parameters). This is
not your case.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH v2 2/2] Support for DW CSI-2 Host IPK

2017-01-12 Thread Ramiro Oliveira
Hi Hans,

Thank you for your feedback.

On 1/11/2017 11:54 AM, Hans Verkuil wrote:
> Hi Ramiro,
> 
> See my review comments below:
> 
> On 12/12/16 16:00, Ramiro Oliveira wrote:
>> Add support for the DesignWare CSI-2 Host IP Prototyping Kit
>>
>> Signed-off-by: Ramiro Oliveira 

[snip]

>> +static int
>> +dw_mipi_csi_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config 
>> *cfg,
>> +struct v4l2_subdev_format *fmt)
>> +{
>> +struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd);
>> +struct mipi_fmt const *dev_fmt;
>> +struct v4l2_mbus_framefmt *mf;
>> +unsigned int i = 0;
>> +const struct v4l2_bt_timings *bt_r = &v4l2_dv_timings_presets[0].bt;
>> +
>> +mf = __dw_mipi_csi_get_format(dev, cfg, fmt->which);
>> +
>> +dev_fmt = dw_mipi_csi_try_format(&fmt->format);
>> +if (dev_fmt) {
>> +*mf = fmt->format;
>> +if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
>> +dev->fmt = dev_fmt;
>> +dw_mipi_csi_set_ipi_fmt(dev);
>> +}
>> +while (v4l2_dv_timings_presets[i].bt.width) {
>> +const struct v4l2_bt_timings *bt =
>> +&v4l2_dv_timings_presets[i].bt;
>> +if (mf->width == bt->width && mf->height == bt->width) {
>> +__dw_mipi_csi_fill_timings(dev, bt);
>> +return 0;
>> +}
>> +i++;
>> +}
>> +
>> +__dw_mipi_csi_fill_timings(dev, bt_r);
> 
> This code is weird. The video source can be either from a sensor or from an
> HDMI input, right?
> 
> But if it is from a sensor, then using v4l2_dv_timings_presets since that's 
> for
> an HDMI input. Sensors will typically not follow these preset timings.
> 
> For HDMI input I expect that this driver supports the s_dv_timings op and will
> just use the timings set there and override the width/height in 
> v4l2_subdev_format.
> 
> For sensors I am actually not quite certain how this is done. I've CC-ed 
> Sakari
> since he'll know. But let us know first whether it is indeed the intention 
> that
> this should also work with a sensor.
> 

Actually the video source, at the moment, can only be from a sensor. I'm using
v4l2_dv_timings_presets as a reference since we usually use this setup with a
Test Equipment in which we can configure every parameter.

I'll wait for Sakari to answer, and change it to what he recommends.

>> +return 0;
>> +
>> +}
>> +
>> +static int
>> +dw_mipi_csi_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config 
>> *cfg,
>> +struct v4l2_subdev_format *fmt)
>> +{
>> +struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd);
>> +struct v4l2_mbus_framefmt *mf;
>> +
>> +mf = __dw_mipi_csi_get_format(dev, cfg, fmt->which);
>> +if (!mf)
>> +return -EINVAL;
>> +
>> +mutex_lock(&dev->lock);
>> +fmt->format = *mf;
>> +mutex_unlock(&dev->lock);
>> +return 0;
>> +}
>> +
>> +static int
>> +dw_mipi_csi_s_power(struct v4l2_subdev *sd, int on)
>> +{
>> +struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd);
>> +
>> +if (on) {
>> +dw_mipi_csi_hw_stdby(dev);
>> +dw_mipi_csi_start(dev);
>> +} else {
>> +dw_mipi_csi_mask_irq_power_off(dev);
>> +}
>> +
>> +return 0;
>> +}
>> +
>> +static int
>> +dw_mipi_csi_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
>> +{
>> +struct v4l2_mbus_framefmt *format =
>> +v4l2_subdev_get_try_format(sd, fh->pad, 0);
>> +
>> +format->colorspace = V4L2_COLORSPACE_SRGB;
>> +format->code = dw_mipi_csi_formats[0].code;
>> +format->width = MIN_WIDTH;
>> +format->height = MIN_HEIGHT;
>> +format->field = V4L2_FIELD_NONE;
> 
> Don't do this. Instead implement the init_cfg pad op and initialize this 
> there.
> 
> You can then drop this function.
> 

I'll do that.

>> +
>> +return 0;
>> +}
>> +
>> +static const struct v4l2_subdev_internal_ops dw_mipi_csi_sd_internal_ops = {
>> +.open = dw_mipi_csi_open,
>> +};
>> +
>> +static struct v4l2_subdev_core_ops dw_mipi_csi_core_ops = {
>> +.s_power = dw_mipi_csi_s_power,
>> +};
>> +
>> +static struct v4l2_subdev_pad_ops dw_mipi_csi_pad_ops = {
>> +.enum_mbus_code = dw_mipi_csi_enum_mbus_code,
>> +.get_fmt = dw_mipi_csi_get_fmt,
>> +.set_fmt = dw_mipi_csi_set_fmt,
>> +};
>> +
>> +static struct v4l2_subdev_ops dw_mipi_csi_subdev_ops = {
>> +.core = &dw_mipi_csi_core_ops,
>> +.pad = &dw_mipi_csi_pad_ops,
>> +};
>> +
>> +static irqreturn_t
>> +dw_mipi_csi_irq1(int irq, void *dev_id)
>> +{
>> +struct mipi_csi_dev *csi_dev = dev_id;
>> +u32 global_int_status, i_sts;
>> +unsigned long flags;
>> +struct device *dev = &csi_dev->pdev->dev;
>> +
>> +global_int_status = dw_mipi_csi_read(csi_dev, R_CSI2_INTERRUPT);
>> +spin_lock_irqsave(&csi_dev->slock, flags);
>> +
>> +if (global_int_status & CSI2_INT_PHY_FATAL) {
>> +i_sts = dw_mipi_csi_read(csi_dev, R_CSI2_INT_PHY_FATAL);
>> +dev_dbg_ratelimited(dev, "CSI INT PHY FATAL: %08X\n", i_sts);
>> +}
>> +
>> +i

[PATCH RFC v2 5/5] tpm2: expose resource manager via a device link /dev/tpms

2017-01-12 Thread Jarkko Sakkinen
From: James Bottomley 

Currently the Resource Manager (RM) is not exposed to userspace.  Make
this exposure via a separate device, which can now be opened multiple
times because each read/write transaction goes separately via the RM.

Concurrency is protected by the chip->tpm_mutex for each read/write
transaction separately.  The TPM is cleared of all transient objects
by the time the mutex is dropped, so there should be no interference
between the kernel and userspace.

Signed-off-by: James Bottomley 
---
 drivers/char/tpm/Makefile|  2 +-
 drivers/char/tpm/tpm-chip.c  | 54 ++---
 drivers/char/tpm/tpm-interface.c | 13 +++--
 drivers/char/tpm/tpm.h   |  6 +++--
 drivers/char/tpm/tpms-dev.c  | 57 
 5 files changed, 124 insertions(+), 8 deletions(-)
 create mode 100644 drivers/char/tpm/tpms-dev.c

diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index 13ff5da..e50d768 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -3,7 +3,7 @@
 #
 obj-$(CONFIG_TCG_TPM) += tpm.o
 tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
-tpm_eventlog.o tpm2-space.o tpm-dev-common.o
+tpm_eventlog.o tpm2-space.o tpm-dev-common.o tpms-dev.o
 tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o
 tpm-$(CONFIG_OF) += tpm_of.o
 obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 993b9ae..0d2be04 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -33,6 +33,7 @@ DEFINE_IDR(dev_nums_idr);
 static DEFINE_MUTEX(idr_lock);
 
 struct class *tpm_class;
+struct class *tpm_rm_class;
 dev_t tpm_devt;
 
 /**
@@ -168,27 +169,40 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
chip->dev_num = rc;
 
device_initialize(&chip->dev);
+   device_initialize(&chip->devrm);
 
chip->dev.class = tpm_class;
chip->dev.release = tpm_dev_release;
chip->dev.parent = pdev;
chip->dev.groups = chip->groups;
 
+   chip->devrm.parent = pdev;
+   chip->devrm.class = tpm_rm_class;
+
if (chip->dev_num == 0)
chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
else
chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
 
+   chip->devrm.devt =
+   MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
+
rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
if (rc)
goto out;
+   rc = dev_set_name(&chip->devrm, "tpms%d", chip->dev_num);
+   if (rc)
+   goto out;
 
if (!pdev)
chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
 
cdev_init(&chip->cdev, &tpm_fops);
+   cdev_init(&chip->cdevrm, &tpm_rm_fops);
chip->cdev.owner = THIS_MODULE;
+   chip->cdevrm.owner = THIS_MODULE;
chip->cdev.kobj.parent = &chip->dev.kobj;
+   chip->cdevrm.kobj.parent = &chip->devrm.kobj;
 
chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
if (!chip->work_space.context_buf) {
@@ -200,6 +214,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
 
 out:
put_device(&chip->dev);
+   put_device(&chip->devrm);
return ERR_PTR(rc);
 }
 EXPORT_SYMBOL_GPL(tpm_chip_alloc);
@@ -244,7 +259,7 @@ static int tpm_add_char_device(struct tpm_chip *chip)
dev_name(&chip->dev), MAJOR(chip->dev.devt),
MINOR(chip->dev.devt), rc);
 
-   return rc;
+   goto err_1;
}
 
rc = device_add(&chip->dev);
@@ -254,16 +269,44 @@ static int tpm_add_char_device(struct tpm_chip *chip)
dev_name(&chip->dev), MAJOR(chip->dev.devt),
MINOR(chip->dev.devt), rc);
 
-   cdev_del(&chip->cdev);
-   return rc;
+   goto err_2;
+   }
+
+   if (chip->flags & TPM_CHIP_FLAG_TPM2)
+   rc = cdev_add(&chip->cdevrm, chip->devrm.devt, 1);
+   if (rc) {
+   dev_err(&chip->dev,
+   "unable to cdev_add() %s, major %d, minor %d, err=%d\n",
+   dev_name(&chip->devrm), MAJOR(chip->devrm.devt),
+   MINOR(chip->devrm.devt), rc);
+
+   goto err_3;
}
 
+   if (chip->flags & TPM_CHIP_FLAG_TPM2)
+   rc = device_add(&chip->devrm);
+   if (rc) {
+   dev_err(&chip->dev,
+   "unable to device_register() %s, major %d, minor %d, 
err=%d\n",
+   dev_name(&chip->devrm), MAJOR(chip->devrm.devt),
+   MINOR(chip->devrm.devt), rc);
+
+   goto err_4;
+   }
/* Make the chip available. */
mutex_lock(&idr_lock);
idr_replace(&dev_nums_idr, chip, chip->dev_num);
mutex_unlock(&idr_lock);
 
return rc;
+ err_4:
+   cdev_del(&ch

[PATCH RFC v2 4/5] tpm: split out tpm-dev.c into tpm-dev.c and tpm-common-dev.c

2017-01-12 Thread Jarkko Sakkinen
From: James Bottomley 

Signed-off-by: James Bottomley 
---
 drivers/char/tpm/Makefile |   2 +-
 drivers/char/tpm/tpm-dev-common.c | 145 ++
 drivers/char/tpm/tpm-dev.c| 141 
 drivers/char/tpm/tpm-dev.h|  27 +++
 4 files changed, 187 insertions(+), 128 deletions(-)
 create mode 100644 drivers/char/tpm/tpm-dev-common.c
 create mode 100644 drivers/char/tpm/tpm-dev.h

diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index 251d0ed..13ff5da 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -3,7 +3,7 @@
 #
 obj-$(CONFIG_TCG_TPM) += tpm.o
 tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
-tpm_eventlog.o tpm2-space.o
+tpm_eventlog.o tpm2-space.o tpm-dev-common.o
 tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o
 tpm-$(CONFIG_OF) += tpm_of.o
 obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
diff --git a/drivers/char/tpm/tpm-dev-common.c 
b/drivers/char/tpm/tpm-dev-common.c
new file mode 100644
index 000..0156562
--- /dev/null
+++ b/drivers/char/tpm/tpm-dev-common.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ * Authors:
+ * Leendert van Doorn 
+ * Dave Safford 
+ * Reiner Sailer 
+ * Kylene Hall 
+ *
+ * Copyright (C) 2013 Obsidian Research Corp
+ * Jason Gunthorpe 
+ *
+ * Device file system interface to the TPM
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ */
+#include 
+#include 
+#include "tpm.h"
+#include "tpm-dev.h"
+
+static void user_reader_timeout(unsigned long ptr)
+{
+   struct file_priv *priv = (struct file_priv *)ptr;
+
+   schedule_work(&priv->work);
+}
+
+static void timeout_work(struct work_struct *work)
+{
+   struct file_priv *priv = container_of(work, struct file_priv, work);
+
+   mutex_lock(&priv->buffer_mutex);
+   atomic_set(&priv->data_pending, 0);
+   memset(priv->data_buffer, 0, sizeof(priv->data_buffer));
+   mutex_unlock(&priv->buffer_mutex);
+}
+
+void tpm_common_open(struct file *file, struct tpm_chip *chip,
+struct file_priv *priv)
+{
+   priv->chip = chip;
+   atomic_set(&priv->data_pending, 0);
+   mutex_init(&priv->buffer_mutex);
+   setup_timer(&priv->user_read_timer, user_reader_timeout,
+   (unsigned long)priv);
+   INIT_WORK(&priv->work, timeout_work);
+
+   file->private_data = priv;
+}
+
+ssize_t tpm_common_read(struct file *file, char __user *buf,
+   size_t size, loff_t *off)
+{
+   struct file_priv *priv = file->private_data;
+   ssize_t ret_size;
+   ssize_t orig_ret_size;
+   int rc;
+
+   del_singleshot_timer_sync(&priv->user_read_timer);
+   flush_work(&priv->work);
+   ret_size = atomic_read(&priv->data_pending);
+   if (ret_size > 0) { /* relay data */
+   orig_ret_size = ret_size;
+   if (size < ret_size)
+   ret_size = size;
+
+   mutex_lock(&priv->buffer_mutex);
+   rc = copy_to_user(buf, priv->data_buffer, ret_size);
+   memset(priv->data_buffer, 0, orig_ret_size);
+   if (rc)
+   ret_size = -EFAULT;
+
+   mutex_unlock(&priv->buffer_mutex);
+   }
+
+   atomic_set(&priv->data_pending, 0);
+
+   return ret_size;
+}
+
+ssize_t tpm_common_write(struct file *file, const char __user *buf,
+size_t size, loff_t *off, struct tpm_space *space)
+{
+   struct file_priv *priv = file->private_data;
+   size_t in_size = size;
+   ssize_t out_size;
+
+   /* Cannot perform a write until the read has cleared either via
+* tpm_read or a user_read_timer timeout. This also prevents split
+* buffered writes from blocking here.
+*/
+   if (atomic_read(&priv->data_pending) != 0)
+   return -EBUSY;
+
+   if (in_size > TPM_BUFSIZE)
+   return -E2BIG;
+
+   mutex_lock(&priv->buffer_mutex);
+
+   if (copy_from_user
+   (priv->data_buffer, (void __user *) buf, in_size)) {
+   mutex_unlock(&priv->buffer_mutex);
+   return -EFAULT;
+   }
+
+   /* atomic tpm command send and result receive. We only hold the ops
+* lock during this period so that the tpm can be unregistered even if
+* the char dev is held open.
+*/
+   if (tpm_try_get_ops(priv->chip)) {
+   mutex_unlock(&priv->buffer_mutex);
+   return -EPIPE;
+   }
+   out_size = tpm_transmit(priv->chip, space, priv->data_buffer,
+   sizeof(priv->data_buffer), 0);
+
+   tpm_put_ops(priv->chip);
+   if (out_size < 0) {
+   mutex_unlock(&priv->buffer_mutex);
+   

Applied "spi: davinci: use dma_mapping_error()" to the spi tree

2017-01-12 Thread Mark Brown
The patch

   spi: davinci: use dma_mapping_error()

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From c5a2a394835f473ae23931eda5066d3771d7b2f8 Mon Sep 17 00:00:00 2001
From: Kevin Hilman 
Date: Wed, 11 Jan 2017 18:18:40 -0800
Subject: [PATCH] spi: davinci: use dma_mapping_error()

The correct error checking for dma_map_single() is to use
dma_mapping_error().

Signed-off-by: Kevin Hilman 
Signed-off-by: Mark Brown 
---
 drivers/spi/spi-davinci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index d36c11b73a35..02fb96797ac8 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -646,7 +646,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct 
spi_transfer *t)
buf = t->rx_buf;
t->rx_dma = dma_map_single(&spi->dev, buf,
t->len, DMA_FROM_DEVICE);
-   if (!t->rx_dma) {
+   if (dma_mapping_error(&spi->dev, !t->rx_dma)) {
ret = -EFAULT;
goto err_rx_map;
}
@@ -660,7 +660,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct 
spi_transfer *t)
buf = (void *)t->tx_buf;
t->tx_dma = dma_map_single(&spi->dev, buf,
t->len, DMA_TO_DEVICE);
-   if (!t->tx_dma) {
+   if (dma_mapping_error(&spi->dev, t->tx_dma)) {
ret = -EFAULT;
goto err_tx_map;
}
-- 
2.11.0



Re: [PATCH] Input: silead: use msleep() for long delays

2017-01-12 Thread Hans de Goede

Hi,

On 01/12/2017 05:21 PM, Nicholas Mc Guire wrote:

the delays here are in the 10 to 20ms range so msleep() will do - no
need to burden the highres timer subsystem.

Signed-off-by: Nicholas Mc Guire 
---

Problem found by coccinelle script

While msleep(10) has a worst case uncertainty of 10ms (on HZ=100 systems)
this seems ok here as the delays are not called frequently (init and
reset functions)


By the same logic, this is not much of a burden on the high-res timer
subsys though.


and the uncertainty of 10ms fits the permitted range of
the original usleep_ranges().


Either way this patch is fine with me.

Regards,

Hans





Patch was compile tested with: x86_64_defconfig +
CONFIG_TOUCHSCREEN_SILEAD=m

Patch is against 4.10-rc3 (localversion-next is next-20170112)

 drivers/input/touchscreen/silead.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/input/touchscreen/silead.c 
b/drivers/input/touchscreen/silead.c
index 404830a..3aa885c 100644
--- a/drivers/input/touchscreen/silead.c
+++ b/drivers/input/touchscreen/silead.c
@@ -58,8 +58,7 @@
 #define SILEAD_POINT_X_MSB_OFF 0x03
 #define SILEAD_TOUCH_ID_MASK   0xF0

-#define SILEAD_CMD_SLEEP_MIN   1
-#define SILEAD_CMD_SLEEP_MAX   2
+#define SILEAD_CMD_SLEEP_MIN   10  /* 10+ ms */
 #define SILEAD_POWER_SLEEP 20
 #define SILEAD_STARTUP_SLEEP   30

@@ -190,25 +189,25 @@ static int silead_ts_init(struct i2c_client *client)
  SILEAD_CMD_RESET);
if (error)
goto i2c_write_err;
-   usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
+   msleep(SILEAD_CMD_SLEEP_MIN);

error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR,
data->max_fingers);
if (error)
goto i2c_write_err;
-   usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
+   msleep(SILEAD_CMD_SLEEP_MIN);

error = i2c_smbus_write_byte_data(client, SILEAD_REG_CLOCK,
  SILEAD_CLOCK);
if (error)
goto i2c_write_err;
-   usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
+   msleep(SILEAD_CMD_SLEEP_MIN);

error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET,
  SILEAD_CMD_START);
if (error)
goto i2c_write_err;
-   usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
+   msleep(SILEAD_CMD_SLEEP_MIN);

return 0;

@@ -225,19 +224,19 @@ static int silead_ts_reset(struct i2c_client *client)
  SILEAD_CMD_RESET);
if (error)
goto i2c_write_err;
-   usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
+   msleep(SILEAD_CMD_SLEEP_MIN);

error = i2c_smbus_write_byte_data(client, SILEAD_REG_CLOCK,
  SILEAD_CLOCK);
if (error)
goto i2c_write_err;
-   usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
+   msleep(SILEAD_CMD_SLEEP_MIN);

error = i2c_smbus_write_byte_data(client, SILEAD_REG_POWER,
  SILEAD_CMD_START);
if (error)
goto i2c_write_err;
-   usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
+   msleep(SILEAD_CMD_SLEEP_MIN);

return 0;




[PATCH RFC v2 1/5] tpm: validate TPM 2.0 commands

2017-01-12 Thread Jarkko Sakkinen
Check for every TPM 2.0 command that the command code is supported and
the command buffer has at least the length that can contain the header
and the handle area.

Signed-off-by: Jarkko Sakkinen 
---
 drivers/char/tpm/tpm-interface.c | 32 -
 drivers/char/tpm/tpm.h   | 27 +
 drivers/char/tpm/tpm2-cmd.c  | 51 
 3 files changed, 105 insertions(+), 5 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index fecdd3f..0c5aba1 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -328,6 +328,36 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip 
*chip,
 }
 EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
 
+static bool tpm_validate_command(struct tpm_chip *chip, const u8 *cmd,
+size_t len)
+{
+   const struct tpm_input_header *header = (const void *)cmd;
+   u32 cc;
+   size_t len_min = TPM_HEADER_SIZE;
+   u32 attrs;
+
+   if ((len >= len_min) && (chip->flags & TPM_CHIP_FLAG_TPM2) &&
+   chip->nr_commands) {
+   cc = be32_to_cpu(header->ordinal);
+   if (!tpm2_find_cc_attrs(chip, cc, &attrs)) {
+   dev_dbg(&chip->dev, "0x%04x is an invalid command\n",
+   cc);
+   return false;
+   }
+   len_min +=
+   4 * ((attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0));
+   }
+
+   if (len < len_min) {
+   dev_dbg(&chip->dev,
+   "%s: insufficient command length %zu < %zu\n",
+   __func__, len, len_min);
+   return false;
+   }
+
+   return true;
+}
+
 /**
  * tmp_transmit - Internal kernel interface to transmit TPM commands.
  *
@@ -347,7 +377,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, 
size_t bufsiz,
u32 count, ordinal;
unsigned long stop;
 
-   if (bufsiz < TPM_HEADER_SIZE)
+   if (!tpm_validate_command(chip, buf, bufsiz))
return -EINVAL;
 
if (bufsiz > TPM_BUFSIZE)
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 1ae9768..80fa606 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -127,7 +127,12 @@ enum tpm2_permanent_handles {
 };
 
 enum tpm2_capabilities {
-   TPM2_CAP_TPM_PROPERTIES = 6,
+   TPM2_CAP_COMMANDS   = 2,
+   TPM2_CAP_TPM_PROPERTIES = 6,
+};
+
+enum tpm2_properties {
+   TPM_PT_TOTAL_COMMANDS   = 0x0129,
 };
 
 enum tpm2_startup_types {
@@ -135,6 +140,11 @@ enum tpm2_startup_types {
TPM2_SU_STATE   = 0x0001,
 };
 
+enum tpm2_cc_attrs {
+   TPM2_CC_ATTR_CHANDLES   = 25,
+   TPM2_CC_ATTR_RHANDLE= 28,
+};
+
 #define TPM_VID_INTEL0x8086
 #define TPM_VID_WINBOND  0x1050
 #define TPM_VID_STM  0x104A
@@ -191,6 +201,9 @@ struct tpm_chip {
acpi_handle acpi_dev_handle;
char ppi_version[TPM_PPI_VERSION_LEN + 1];
 #endif /* CONFIG_ACPI */
+
+   u32 nr_commands;
+   u32 *cc_attrs_tbl;
 };
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
@@ -393,7 +406,8 @@ struct tpm_cmd_t {
  */
 
 enum tpm_buf_flags {
-   TPM_BUF_OVERFLOW= BIT(0),
+   TPM_BUF_INITIALIZED = BIT(0),
+   TPM_BUF_OVERFLOW= BIT(1),
 };
 
 struct tpm_buf {
@@ -419,13 +433,17 @@ static inline int tpm_buf_init(struct tpm_buf *buf, u16 
tag, u32 ordinal)
head->length = cpu_to_be32(sizeof(*head));
head->ordinal = cpu_to_be32(ordinal);
 
+   buf->flags = TPM_BUF_INITIALIZED;
+
return 0;
 }
 
 static inline void tpm_buf_destroy(struct tpm_buf *buf)
 {
-   kunmap(buf->data_page);
-   __free_page(buf->data_page);
+   if (buf->flags & TPM_BUF_INITIALIZED) {
+   kunmap(buf->data_page);
+   __free_page(buf->data_page);
+   }
 }
 
 static inline u32 tpm_buf_length(struct tpm_buf *buf)
@@ -545,4 +563,5 @@ int tpm2_auto_startup(struct tpm_chip *chip);
 void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
 unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
 int tpm2_probe(struct tpm_chip *chip);
+bool tpm2_find_cc_attrs(struct tpm_chip *chip, u32 cc, u32 *attrs);
 #endif
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 6eda239..c4d25b2 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -969,7 +969,10 @@ EXPORT_SYMBOL_GPL(tpm2_probe);
  */
 int tpm2_auto_startup(struct tpm_chip *chip)
 {
+   struct tpm_buf buf;
+   u32 nr_commands;
int rc;
+   int i;
 
rc = tpm_get_timeouts(chip);
if (rc)
@@ -993,8 +996,56 @@ int tpm2_auto_startup(struct tpm_chip *chip)
}
}
 
+   rc = tpm2_get_tpm_pt(chip, TPM_PT_TOTAL_COMMANDS, &nr_commands, NULL);
+   if (rc)
+   goto out;
+
+   chip->

Applied "regulator: core: Don't use regulators as supplies until the parent is bound" to the regulator tree

2017-01-12 Thread Mark Brown
The patch

   regulator: core: Don't use regulators as supplies until the parent is bound

has been applied to the regulator tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 66d228a2bf03b163ddaeca5f24f1ff89a84ad668 Mon Sep 17 00:00:00 2001
From: Jon Hunter 
Date: Wed, 11 Jan 2017 17:44:25 +
Subject: [PATCH] regulator: core: Don't use regulators as supplies until the
 parent is bound

When regulators are successfully registered, we check to see if the
regulator is a supply for any other registered regulator and if so
add the new regulator as the supply for the existing regulator(s).

Some devices, such as Power Management ICs, may register a series of
regulators when probed and there are cases where one of the regulators
may fail to register and defer the probing of the parent device. In this
case any successfully registered regulators would be unregistered so
that they can be re-registered at some time later when the probe is
attempted again. However, if one of the regulators that was registered
was added as a supply to another registered regulator (that did not
belong to the same parent device), then this supply regulator was
unregister again because the parent device is probe deferred, then a
regulator could be holding an invalid reference to a supply regulator
that has been unregistered. This will lead to a system crash if that
regulator is then used.

Although it would be possible to check when unregistering a regulator
if any other regulator in the system is using it as a supply, it still
may not be possible to remove it as a supply if this other regulator is
in use. Therefore, fix this by preventing any regulator from adding
another regulator as a supply if the parent device for the supply
regulator has not been bound and if the parent device for the supply
and the regulator are different. This will allow a parent device that is
registering regulators to be probe deferred and ensure that none of the
regulators it has registered are used as supplies for any other
regulator from another device.

Signed-off-by: Jon Hunter 
Signed-off-by: Mark Brown 
---
 drivers/regulator/core.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 04baac9a165b..bcf67abd1cd2 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1553,6 +1553,19 @@ static int regulator_resolve_supply(struct regulator_dev 
*rdev)
}
}
 
+   /*
+* If the supply's parent device is not the same as the
+* regulator's parent device, then ensure the parent device
+* is bound before we resolve the supply, in case the parent
+* device get probe deferred and unregisters the supply.
+*/
+   if (r->dev.parent && r->dev.parent != rdev->dev.parent) {
+   if (!device_is_bound(r->dev.parent)) {
+   put_device(&r->dev);
+   return -EPROBE_DEFER;
+   }
+   }
+
/* Recursively resolve the supply of the supply */
ret = regulator_resolve_supply(r);
if (ret < 0) {
-- 
2.11.0



Applied "regmap: Fixup the kernel-doc comments on functions/structures" to the regmap tree

2017-01-12 Thread Mark Brown
The patch

   regmap: Fixup the kernel-doc comments on functions/structures

has been applied to the regmap tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 2cf8e2dfdf88363476f23bc600745250b94dbbed Mon Sep 17 00:00:00 2001
From: Charles Keepax 
Date: Thu, 12 Jan 2017 11:17:39 +
Subject: [PATCH] regmap: Fixup the kernel-doc comments on functions/structures

Most of the kernel-doc comments in regmap don't actually generate
correctly. This patch fixes up a few common issues, corrects some typos
and adds some missing argument descriptions.

The most common issues being using a : after the function name which
causes the short description to not render correctly and not separating
the long and short descriptions of the function. There are quite a few
instances of arguments not being described or given the wrong name as
well.

This patch doesn't fixup functions/structures that are currently missing
descriptions.

Signed-off-by: Charles Keepax 
Signed-off-by: Mark Brown 
---
 drivers/base/regmap/regcache.c   |  20 +++
 drivers/base/regmap/regmap-irq.c |  62 ++-
 drivers/base/regmap/regmap.c | 125 +--
 include/linux/regmap.h   | 115 ---
 4 files changed, 179 insertions(+), 143 deletions(-)

diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 4e582561e1e7..b0a0dcf32fb7 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -224,7 +224,7 @@ void regcache_exit(struct regmap *map)
 }
 
 /**
- * regcache_read: Fetch the value of a given register from the cache.
+ * regcache_read - Fetch the value of a given register from the cache.
  *
  * @map: map to configure.
  * @reg: The register index.
@@ -255,7 +255,7 @@ int regcache_read(struct regmap *map,
 }
 
 /**
- * regcache_write: Set the value of a given register in the cache.
+ * regcache_write - Set the value of a given register in the cache.
  *
  * @map: map to configure.
  * @reg: The register index.
@@ -328,7 +328,7 @@ static int regcache_default_sync(struct regmap *map, 
unsigned int min,
 }
 
 /**
- * regcache_sync: Sync the register cache with the hardware.
+ * regcache_sync - Sync the register cache with the hardware.
  *
  * @map: map to configure.
  *
@@ -396,7 +396,7 @@ int regcache_sync(struct regmap *map)
 EXPORT_SYMBOL_GPL(regcache_sync);
 
 /**
- * regcache_sync_region: Sync part  of the register cache with the hardware.
+ * regcache_sync_region - Sync part  of the register cache with the hardware.
  *
  * @map: map to sync.
  * @min: first register to sync
@@ -452,7 +452,7 @@ int regcache_sync_region(struct regmap *map, unsigned int 
min,
 EXPORT_SYMBOL_GPL(regcache_sync_region);
 
 /**
- * regcache_drop_region: Discard part of the register cache
+ * regcache_drop_region - Discard part of the register cache
  *
  * @map: map to operate on
  * @min: first register to discard
@@ -483,10 +483,10 @@ int regcache_drop_region(struct regmap *map, unsigned int 
min,
 EXPORT_SYMBOL_GPL(regcache_drop_region);
 
 /**
- * regcache_cache_only: Put a register map into cache only mode
+ * regcache_cache_only - Put a register map into cache only mode
  *
  * @map: map to configure
- * @cache_only: flag if changes should be written to the hardware
+ * @enable: flag if changes should be written to the hardware
  *
  * When a register map is marked as cache only writes to the register
  * map API will only update the register cache, they will not cause
@@ -505,7 +505,7 @@ void regcache_cache_only(struct regmap *map, bool enable)
 EXPORT_SYMBOL_GPL(regcache_cache_only);
 
 /**
- * regcache_mark_dirty: Indicate that HW registers were reset to default values
+ * regcache_mark_dirty - Indicate that HW registers were reset to default 
values
  *
  * @map: map to mark
  *
@@ -527,10 +527,10 @@ void regcache_mark_dirty(struct regmap *map)
 EXPORT_SYMBOL_GPL(regcache_mark_dirty);
 
 /**
- * regcache_cache_bypass: Put a register map into cache bypass mode
+ * regcache_cache_bypass - Put a register map into cache bypass mode
  *
  * @map: map to configure
- * @cache_bypass: flag if changes should not be written to the cache
+ * @enabl

[PATCH RFC v2 2/5] tpm: export tpm2_flush_context_cmd

2017-01-12 Thread Jarkko Sakkinen
Signed-off-by: Jarkko Sakkinen 
---
 drivers/char/tpm/tpm.h  |  2 ++
 drivers/char/tpm/tpm2-cmd.c | 65 ++---
 2 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 80fa606..c87c221 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -550,6 +550,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
 int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
 int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
 int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
+void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
+   unsigned int flags);
 int tpm2_seal_trusted(struct tpm_chip *chip,
  struct trusted_key_payload *payload,
  struct trusted_key_options *options);
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index c4d25b2..e2b4c75 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -401,6 +401,38 @@ static const struct tpm_input_header 
tpm2_get_tpm_pt_header = {
 };
 
 /**
+ * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command
+ * @chip: TPM chip to use
+ * @payload: the key data in clear and encrypted form
+ * @options: authentication values and other options
+ *
+ * Return: same as with tpm_transmit_cmd
+ */
+void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
+   unsigned int flags)
+{
+   struct tpm_buf buf;
+   int rc;
+
+   rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT);
+   if (rc) {
+   dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n",
+handle);
+   return;
+   }
+
+   tpm_buf_append_u32(&buf, handle);
+
+   rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags,
+"flushing context");
+   if (rc)
+   dev_warn(&chip->dev, "0x%08x was not flushed, rc=%d\n", handle,
+rc);
+
+   tpm_buf_destroy(&buf);
+}
+
+/**
  * tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer.
  *
  * @buf: an allocated tpm_buf instance
@@ -603,39 +635,6 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
 }
 
 /**
- * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command
- *
- * @chip: TPM chip to use
- * @handle: the key data in clear and encrypted form
- * @flags: tpm transmit flags
- *
- * Return: Same as with tpm_transmit_cmd.
- */
-static void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
-  unsigned int flags)
-{
-   struct tpm_buf buf;
-   int rc;
-
-   rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT);
-   if (rc) {
-   dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n",
-handle);
-   return;
-   }
-
-   tpm_buf_append_u32(&buf, handle);
-
-   rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags,
- "flushing context");
-   if (rc)
-   dev_warn(&chip->dev, "0x%08x was not flushed, rc=%d\n", handle,
-rc);
-
-   tpm_buf_destroy(&buf);
-}
-
-/**
  * tpm2_unseal_cmd() - execute a TPM2_Unload command
  *
  * @chip: TPM chip to use
-- 
2.9.3



[PATCH RFC v2 0/5] RFC: in-kernel resource manager

2017-01-12 Thread Jarkko Sakkinen
This patch set adds support for TPM spaces that provide a context
for isolating and swapping transient objects. This patch set does
not yet include support for isolating policy and HMAC sessions but
it is trivial to add once the basic approach is settled (and that's
why I created an RFC patch set).

v2:
Changed to James' proposal of API. I did not make any other changes
except split core TPM space code its own patch because I want to find
consensus on the API before polishing the corners. Thus, this version
also carries the RFC tag. I have not yet locked in my standpoint whether
ioctl or a device file is a better deal.

James Bottomley (2):
  tpm: split out tpm-dev.c into tpm-dev.c and tpm-common-dev.c
  tpm2: expose resource manager via a device link /dev/tpms

Jarkko Sakkinen (3):
  tpm: validate TPM 2.0 commands
  tpm: export tpm2_flush_context_cmd
  tpm: infrastructure for TPM spaces

 drivers/char/tpm/Makefile |   2 +-
 drivers/char/tpm/tpm-chip.c   |  61 +++-
 drivers/char/tpm/tpm-dev-common.c | 145 +++
 drivers/char/tpm/tpm-dev.c| 141 ++
 drivers/char/tpm/tpm-dev.h|  27 
 drivers/char/tpm/tpm-interface.c  | 106 ++
 drivers/char/tpm/tpm-sysfs.c  |   2 +-
 drivers/char/tpm/tpm.h|  57 ++--
 drivers/char/tpm/tpm2-cmd.c   | 144 --
 drivers/char/tpm/tpm2-space.c | 298 ++
 drivers/char/tpm/tpms-dev.c   |  57 
 11 files changed, 826 insertions(+), 214 deletions(-)
 create mode 100644 drivers/char/tpm/tpm-dev-common.c
 create mode 100644 drivers/char/tpm/tpm-dev.h
 create mode 100644 drivers/char/tpm/tpm2-space.c
 create mode 100644 drivers/char/tpm/tpms-dev.c

-- 
2.9.3



[PATCH RFC v2 3/5] tpm: infrastructure for TPM spaces

2017-01-12 Thread Jarkko Sakkinen
Added ability to tpm_transmit() to supply a TPM space that contains
mapping from virtual handles to physical handles and backing storage for
swapping transient objects. TPM space is isolated from other users of
the TPM.

Signed-off-by: Jarkko Sakkinen 
---
 drivers/char/tpm/Makefile|   2 +-
 drivers/char/tpm/tpm-chip.c  |   7 +
 drivers/char/tpm/tpm-dev.c   |   2 +-
 drivers/char/tpm/tpm-interface.c |  61 
 drivers/char/tpm/tpm-sysfs.c |   2 +-
 drivers/char/tpm/tpm.h   |  22 ++-
 drivers/char/tpm/tpm2-cmd.c  |  34 +++--
 drivers/char/tpm/tpm2-space.c| 298 +++
 8 files changed, 382 insertions(+), 46 deletions(-)
 create mode 100644 drivers/char/tpm/tpm2-space.c

diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index a05b1eb..251d0ed 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -3,7 +3,7 @@
 #
 obj-$(CONFIG_TCG_TPM) += tpm.o
 tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
-   tpm_eventlog.o
+tpm_eventlog.o tpm2-space.o
 tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o
 tpm-$(CONFIG_OF) += tpm_of.o
 obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index c406343..993b9ae 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -128,6 +128,7 @@ static void tpm_dev_release(struct device *dev)
mutex_unlock(&idr_lock);
 
kfree(chip->log.bios_event_log);
+   kfree(chip->work_space.context_buf);
kfree(chip);
 }
 
@@ -189,6 +190,12 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
chip->cdev.owner = THIS_MODULE;
chip->cdev.kobj.parent = &chip->dev.kobj;
 
+   chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+   if (!chip->work_space.context_buf) {
+   rc = -ENOMEM;
+   goto out;
+   }
+
return chip;
 
 out:
diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
index 912ad30..249eeb0 100644
--- a/drivers/char/tpm/tpm-dev.c
+++ b/drivers/char/tpm/tpm-dev.c
@@ -144,7 +144,7 @@ static ssize_t tpm_write(struct file *file, const char 
__user *buf,
mutex_unlock(&priv->buffer_mutex);
return -EPIPE;
}
-   out_size = tpm_transmit(priv->chip, priv->data_buffer,
+   out_size = tpm_transmit(priv->chip, NULL, priv->data_buffer,
sizeof(priv->data_buffer), 0);
 
tpm_put_ops(priv->chip);
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 0c5aba1..65fcd04c 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -370,10 +370,11 @@ static bool tpm_validate_command(struct tpm_chip *chip, 
const u8 *cmd,
  * 0 when the operation is successful.
  * A negative number for system errors (errno).
  */
-ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
-unsigned int flags)
+ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
+u8 *buf, size_t bufsiz, unsigned int flags)
 {
-   ssize_t rc;
+   int rc;
+   ssize_t len = 0;
u32 count, ordinal;
unsigned long stop;
 
@@ -399,10 +400,14 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 
*buf, size_t bufsiz,
if (chip->dev.parent)
pm_runtime_get_sync(chip->dev.parent);
 
+   rc = tpm2_prepare_space(chip, space, ordinal, buf, bufsiz);
+   if (rc)
+   goto out;
+
rc = chip->ops->send(chip, (u8 *) buf, count);
if (rc < 0) {
dev_err(&chip->dev,
-   "tpm_transmit: tpm_send: error %zd\n", rc);
+   "tpm_transmit: tpm_send: error %d\n", rc);
goto out;
}
 
@@ -435,17 +440,23 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 
*buf, size_t bufsiz,
goto out;
 
 out_recv:
-   rc = chip->ops->recv(chip, (u8 *) buf, bufsiz);
-   if (rc < 0)
+   len = chip->ops->recv(chip, (u8 *) buf, bufsiz);
+   if (len < 0) {
dev_err(&chip->dev,
-   "tpm_transmit: tpm_recv: error %zd\n", rc);
+   "tpm_transmit: tpm_recv: error %d\n", rc);
+   rc = len;
+   goto out;
+   }
+
+   rc = tpm2_commit_space(chip, space, ordinal, buf, bufsiz);
+
 out:
if (chip->dev.parent)
pm_runtime_put_sync(chip->dev.parent);
 
if (!(flags & TPM_TRANSMIT_UNLOCKED))
mutex_unlock(&chip->tpm_mutex);
-   return rc;
+   return rc ? rc : len;
 }
 
 /**
@@ -463,13 +474,14 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 
*buf, size_t bufsiz,
  * A negative number for system errors (errno).
  * A positive number for a TPM error.
  */
-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd

[PATCH] xen-netback: fix memory leaks on XenBus disconnect

2017-01-12 Thread Igor Druzhinin
Eliminate memory leaks introduced several years ago by cleaning the queue
resources which are allocated on XenBus connection event. Namely, queue
structure array and pages used for IO rings.
vif->lock is used to protect statistics gathering agents from using the
queue structure during cleaning.

Signed-off-by: Igor Druzhinin 
---
 drivers/net/xen-netback/interface.c |  6 --
 drivers/net/xen-netback/xenbus.c| 13 +
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/xen-netback/interface.c 
b/drivers/net/xen-netback/interface.c
index e30ffd2..5795213 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -221,18 +221,18 @@ static struct net_device_stats *xenvif_get_stats(struct 
net_device *dev)
 {
struct xenvif *vif = netdev_priv(dev);
struct xenvif_queue *queue = NULL;
-   unsigned int num_queues = vif->num_queues;
unsigned long rx_bytes = 0;
unsigned long rx_packets = 0;
unsigned long tx_bytes = 0;
unsigned long tx_packets = 0;
unsigned int index;
 
+   spin_lock(&vif->lock);
if (vif->queues == NULL)
goto out;
 
/* Aggregate tx and rx stats from each queue */
-   for (index = 0; index < num_queues; ++index) {
+   for (index = 0; index < vif->num_queues; ++index) {
queue = &vif->queues[index];
rx_bytes += queue->stats.rx_bytes;
rx_packets += queue->stats.rx_packets;
@@ -241,6 +241,8 @@ static struct net_device_stats *xenvif_get_stats(struct 
net_device *dev)
}
 
 out:
+   spin_unlock(&vif->lock);
+
vif->dev->stats.rx_bytes = rx_bytes;
vif->dev->stats.rx_packets = rx_packets;
vif->dev->stats.tx_bytes = tx_bytes;
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 3124eae..85b742e 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -493,11 +493,22 @@ static int backend_create_xenvif(struct backend_info *be)
 static void backend_disconnect(struct backend_info *be)
 {
if (be->vif) {
+   unsigned int queue_index;
+
xen_unregister_watchers(be->vif);
 #ifdef CONFIG_DEBUG_FS
xenvif_debugfs_delif(be->vif);
 #endif /* CONFIG_DEBUG_FS */
xenvif_disconnect_data(be->vif);
+   for (queue_index = 0; queue_index < be->vif->num_queues; 
++queue_index)
+   xenvif_deinit_queue(&be->vif->queues[queue_index]);
+
+   spin_lock(&be->vif->lock);
+   vfree(be->vif->queues);
+   be->vif->num_queues = 0;
+   be->vif->queues = NULL;
+   spin_unlock(&be->vif->lock);
+
xenvif_disconnect_ctrl(be->vif);
}
 }
@@ -1034,6 +1045,8 @@ static void connect(struct backend_info *be)
 err:
if (be->vif->num_queues > 0)
xenvif_disconnect_data(be->vif); /* Clean up existing queues */
+   for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index)
+   xenvif_deinit_queue(&be->vif->queues[queue_index]);
vfree(be->vif->queues);
be->vif->queues = NULL;
be->vif->num_queues = 0;
-- 
1.8.3.1



Re: [PATCH v7 7/7] perf/amd/iommu: Enable support for multiple IOMMUs

2017-01-12 Thread Borislav Petkov
On Mon, Jan 09, 2017 at 09:33:47PM -0600, Suravee Suthikulpanit wrote:
> This patch adds multi-IOMMU support for perf by exposing
> an AMD IOMMU PMU for each IOMMU found in the system via:
> 
>   /sys/device/amd_iommu_x /* where x is the IOMMU index. */

Straight into the top-level devices hierarchy?

Why not add a proper hierarchy to

/sys/devices/system/iommu/ ...

?

Jörg, don't you have a sane iommu hierarchy already in sysfs?

> This allows users to specify different events to be programed
> onto performance counters of each IOMMU.
> 
> Cc: Peter Zijlstra 
> Cc: Borislav Petkov 
> Signed-off-by: Suravee Suthikulpanit 
> ---
>  arch/x86/events/amd/iommu.c | 119 
> 
>  1 file changed, 64 insertions(+), 55 deletions(-)
> 
> diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c
> index 2403c78..5fd97b5 100644
> --- a/arch/x86/events/amd/iommu.c
> +++ b/arch/x86/events/amd/iommu.c
> @@ -35,10 +35,13 @@
>  #define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xULL)
>  #define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xULL)
>  
> -static struct perf_amd_iommu __perf_iommu;
> +#define PERF_AMD_IOMMU_NAME_SZ 16
>  
>  struct perf_amd_iommu {
> + struct list_head list;
>   struct pmu pmu;
> + uint idx;

This uint thing has crept in:

$ git grep "uint " arch/x86/
arch/x86/crypto/crc32-pclmul_asm.S:101: *  uint crc32_pclmul_le_16(unsigned 
char const *buffer,
arch/x86/crypto/crc32-pclmul_asm.S:102: *size_t 
len, uint crc32)
arch/x86/events/amd/iommu.h:32:extern u8 amd_iommu_pc_get_max_banks(uint idx);
arch/x86/events/amd/iommu.h:34:extern u8 amd_iommu_pc_get_max_counters(uint 
idx);
arch/x86/events/amd/iommu.h:36:extern int amd_iommu_pc_set_reg(uint idx, u16 
devid, u8 bank, u8 cntr,
arch/x86/events/amd/iommu.h:39:extern int amd_iommu_pc_set_counter(uint idx, u8 
bank, u8 cntr, u64 *value);
arch/x86/events/amd/iommu.h:41:extern int amd_iommu_pc_get_counter(uint idx, u8 
bank, u8 cntr, u64 *value);

"unsigned int" please.

> + char name[PERF_AMD_IOMMU_NAME_SZ];
>   u8 max_banks;
>   u8 max_counters;
>   u64 cntr_assign_mask;
> @@ -46,6 +49,8 @@ struct perf_amd_iommu {
>   const struct attribute_group *attr_groups[4];
>  };
>  
> +LIST_HEAD(perf_amd_iommu_list);

static

> +
>  #define format_group attr_groups[0]
>  #define cpumask_groupattr_groups[1]
>  #define events_group attr_groups[2]
> @@ -204,8 +209,7 @@ static int clear_avail_iommu_bnk_cntr(struct 
> perf_amd_iommu *perf_iommu,
>  static int perf_iommu_event_init(struct perf_event *event)
>  {
>   struct hw_perf_event *hwc = &event->hw;
> - struct perf_amd_iommu *perf_iommu;
> - u64 config, config1;
> + struct perf_amd_iommu *pi = container_of(event->pmu, struct 
> perf_amd_iommu, pmu);

Do this deref when you actually need it:

struct perf_amd_iommu *pi;

because you might exit earlier and end up doing it for nothing.

>  
>   /* test the event attr type check for PMU enumeration */
>   if (event->attr.type != event->pmu->type)
> @@ -227,27 +231,17 @@ static int perf_iommu_event_init(struct perf_event 
> *event)
>   if (event->cpu < 0)
>   return -EINVAL;
>  
> - perf_iommu = &__perf_iommu;
> -
> - if (event->pmu != &perf_iommu->pmu)
> - return -ENOENT;
> -
> - if (perf_iommu) {
> - config = event->attr.config;
> - config1 = event->attr.config1;
> - } else {
> - return -EINVAL;
> - }
> -
>   /* update the hw_perf_event struct with the iommu config data */
> - hwc->config = config;
> - hwc->extra_reg.config = config1;

---> here:

pi = container_of(event->pmu, struct perf_amd_iommu, pmu);

> + hwc->idx = pi->idx;
> + hwc->config = event->attr.config;
> + hwc->extra_reg.config = event->attr.config1;

Align vertically on the = sign.

>  
>   return 0;
>  }
>  
>  static void perf_iommu_enable_event(struct perf_event *ev)
>  {
> + struct hw_perf_event *hwc = &ev->hw;
>   u8 csource = _GET_CSOURCE(ev);
>   u16 devid = _GET_DEVID(ev);
>   u8 bank = _GET_BANK(ev);

...

>  static void perf_iommu_disable_event(struct perf_event *event)
>  {
> + struct hw_perf_event *hwc = &event->hw;
>   u64 reg = 0ULL;
>  
> - amd_iommu_pc_set_reg(0, _GET_DEVID(event), _GET_BANK(event),
> + amd_iommu_pc_set_reg(hwc->idx, _GET_DEVID(event), _GET_BANK(event),
>_GET_CNTR(event), IOMMU_PC_COUNTER_SRC_REG, ®);
>  }
>  
> @@ -301,7 +296,7 @@ static void perf_iommu_start(struct perf_event *event, 
> int flags)
>  
>   val = local64_read(&hwc->prev_count);
>  
> - amd_iommu_pc_set_counter(0, _GET_BANK(event), _GET_CNTR(event), &val);
> + amd_iommu_pc_set_counter(hwc->idx, _GET_BANK(event), _GET_CNTR(event), 
> &val);
>  enable:
>   perf_iommu_enable_event(event);
>   perf_event_update_userpage(

Re: [PATCH/RESEND v2 3/5] z3fold: extend compaction function

2017-01-12 Thread Dan Streetman
On Wed, Jan 11, 2017 at 3:52 PM, Vitaly Wool  wrote:
> On Wed, 11 Jan 2017 17:43:13 +0100
> Vitaly Wool  wrote:
>
>> On Wed, Jan 11, 2017 at 5:28 PM, Dan Streetman  wrote:
>> > On Wed, Jan 11, 2017 at 10:06 AM, Vitaly Wool  wrote:
>> >> z3fold_compact_page() currently only handles the situation when
>> >> there's a single middle chunk within the z3fold page. However it
>> >> may be worth it to move middle chunk closer to either first or
>> >> last chunk, whichever is there, if the gap between them is big
>> >> enough.
>> >>
>> >> This patch adds the relevant code, using BIG_CHUNK_GAP define as
>> >> a threshold for middle chunk to be worth moving.
>> >>
>> >> Signed-off-by: Vitaly Wool 
>> >> ---
>> >>  mm/z3fold.c | 26 +-
>> >>  1 file changed, 25 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/mm/z3fold.c b/mm/z3fold.c
>> >> index 98ab01f..fca3310 100644
>> >> --- a/mm/z3fold.c
>> >> +++ b/mm/z3fold.c
>> >> @@ -268,6 +268,7 @@ static inline void *mchunk_memmove(struct 
>> >> z3fold_header *zhdr,
>> >>zhdr->middle_chunks << CHUNK_SHIFT);
>> >>  }
>> >>
>> >> +#define BIG_CHUNK_GAP  3
>> >>  /* Has to be called with lock held */
>> >>  static int z3fold_compact_page(struct z3fold_header *zhdr)
>> >>  {
>> >> @@ -286,8 +287,31 @@ static int z3fold_compact_page(struct z3fold_header 
>> >> *zhdr)
>> >> zhdr->middle_chunks = 0;
>> >> zhdr->start_middle = 0;
>> >> zhdr->first_num++;
>> >> +   return 1;
>> >> }
>> >> -   return 1;
>> >> +
>> >> +   /*
>> >> +* moving data is expensive, so let's only do that if
>> >> +* there's substantial gain (at least BIG_CHUNK_GAP chunks)
>> >> +*/
>> >> +   if (zhdr->first_chunks != 0 && zhdr->last_chunks == 0 &&
>> >> +   zhdr->start_middle - (zhdr->first_chunks + ZHDR_CHUNKS) >=
>> >> +   BIG_CHUNK_GAP) {
>> >> +   mchunk_memmove(zhdr, zhdr->first_chunks + 1);
>> >> +   zhdr->start_middle = zhdr->first_chunks + 1;
>> >
>> > this should be first_chunks + ZHDR_CHUNKS, not + 1.
>> >
>> >> +   return 1;
>> >> +   } else if (zhdr->last_chunks != 0 && zhdr->first_chunks == 0 &&
>> >> +  TOTAL_CHUNKS - (zhdr->last_chunks + zhdr->start_middle
>> >> +   + zhdr->middle_chunks) >=
>> >> +   BIG_CHUNK_GAP) {
>> >> +   unsigned short new_start = NCHUNKS - zhdr->last_chunks -
>> >
>> > this should be TOTAL_CHUNKS, not NCHUNKS.
>>
>> Right :/
>
> So here we go:
>
>
> z3fold_compact_page() currently only handles the situation when
> there's a single middle chunk within the z3fold page. However it
> may be worth it to move middle chunk closer to either first or
> last chunk, whichever is there, if the gap between them is big
> enough.
>
> This patch adds the relevant code, using BIG_CHUNK_GAP define as
> a threshold for middle chunk to be worth moving.
>
> Signed-off-by: Vitaly Wool 

Acked-by: Dan Streetman 

> ---
>  mm/z3fold.c | 26 +-
>  1 file changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/mm/z3fold.c b/mm/z3fold.c
> index 98ab01f..fca3310 100644
> --- a/mm/z3fold.c
> +++ b/mm/z3fold.c
> @@ -268,6 +268,7 @@ static inline void *mchunk_memmove(struct z3fold_header 
> *zhdr,
>zhdr->middle_chunks << CHUNK_SHIFT);
>  }
>
> +#define BIG_CHUNK_GAP  3
>  /* Has to be called with lock held */
>  static int z3fold_compact_page(struct z3fold_header *zhdr)
>  {
> @@ -286,8 +287,31 @@ static int z3fold_compact_page(struct z3fold_header 
> *zhdr)
> zhdr->middle_chunks = 0;
> zhdr->start_middle = 0;
> zhdr->first_num++;
> +   return 1;
> }
> -   return 1;
> +
> +   /*
> +* moving data is expensive, so let's only do that if
> +* there's substantial gain (at least BIG_CHUNK_GAP chunks)
> +*/
> +   if (zhdr->first_chunks != 0 && zhdr->last_chunks == 0 &&
> +   zhdr->start_middle - (zhdr->first_chunks + ZHDR_CHUNKS) >=
> +   BIG_CHUNK_GAP) {
> +   mchunk_memmove(zhdr, zhdr->first_chunks + ZHDR_CHUNKS);
> +   zhdr->start_middle = zhdr->first_chunks + ZHDR_CHUNKS;
> +   return 1;
> +   } else if (zhdr->last_chunks != 0 && zhdr->first_chunks == 0 &&
> +  TOTAL_CHUNKS - (zhdr->last_chunks + zhdr->start_middle
> +   + zhdr->middle_chunks) >=
> +   BIG_CHUNK_GAP) {
> +   unsigned short new_start = TOTAL_CHUNKS - zhdr->last_chunks -
> +   zhdr->middle_chunks;
> +   mchunk_memmove(zhdr, new_start);
> +   zhdr->start_middle = new_start;
> +   return 1;
> +   }
> +
> +   return 0;
>  }
>
>  /**
> --
> 2.4.2


Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7

2017-01-12 Thread Dave Hansen
On 01/12/2017 08:50 AM, Khalid Aziz wrote:
> 2. Any shared page that has ADI protection enabled on it, must stay ADI
> protected across all processes sharing it.

Is that true?

What happens if a page with ADI tags set is accessed via a PTE without
the ADI enablement bit set?

> COW creates an intersection of the two. It creates a new copy of the
> shared data. It is a new data page and hence the process creating it
> must be the one responsible for enabling ADI protection on it.

Do you mean that the application must be responsible?  Or the kernel
running in the context of the new process must be responsible?

> It is also a copy of what was ADI protected data, so should it
> inherit the protection instead?

I think the COW'd copy must inherit the VMA bit, the PTE bits, and the
tags on the cachelines.

> I misspoke earlier. I had misinterpreted the results of test I ran.
> Changing the tag on shared memory is allowed by memory controller. The
> requirement is every one sharing the page must switch to the new tag or
> else they get SIGSEGV.

I asked this in the last mail, but I guess I'll ask it again.  Please
answer this directly.

If we require that everyone coordinate their tags on the backing
physical memory, and we allow a lower-privileged program to access the
same data as a more-privileged one, then the lower-privilege app can
cause arbitrary crashes in the privileged application.

For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to protect
the mapping.  Couldn't any other app in the system prevent sudo from
working?

How can we *EVER* allow tags to be set on non-writable mappings?

> I am inclined to suggest we copy the tags to the new data page on COW
> and that will continue to enforce ADI on the COW'd pages even though
> COW'd pages are new data pages. This is the logically consistent
> behavior. Does that make sense?

Yes, I think this is what you have to do.


Re: [PATCH/RESEND v2 5/5] z3fold: add kref refcounting

2017-01-12 Thread Dan Streetman
On Wed, Jan 11, 2017 at 3:51 PM, Vitaly Wool  wrote:
> On Wed, 11 Jan 2017 13:03:06 -0500
> Dan Streetman  wrote:
>
> 
>> >>> provided that I take the lock for the headless case above. That will
>> >>> work won't it?
>> >>
>> >> in this specific case - since every single kref_put in the driver is
>> >> protected by the pool lock - yeah, you can do that, since you know
>> >> that specific kref_put didn't free the page and no other kref_put
>> >> could happen since you're holding the pool lock.
>> >>
>> >> but that specific requirement isn't made obvious by the code, and I
>> >> can see how a future patch could release the pool lock between the
>> >> kref_put and lru list add, without realizing that introduces a bug.
>> >> isn't it better to just add it to the lru list before you put the
>> >> kref?  just a suggestion.
>> >
>> > That would require to add it to the lru separately for headless pages
>> > above, I don't think it makes things better or less error prone.
>> > I would rather add a comment before list_add.
>> >
>> >> i'd also suggest the pages_nr dec go into the page release function,
>> >> instead of checking every kref_put return value; that's easier and
>> >> less prone to forgetting to check one of the kref_puts.
>> >
>> > That will mean z3fold_header should contain a pointer to its pool. I'm
>> > not sure it is worth it but I can do that :)
>>
>> the header's already rounded up to chunk size, so if there's room then
>> it won't take any extra memory.  but it works either way.
>
> So let's have it like this then:
>
>
> With both coming and already present locking optimizations,
> introducing kref to reference-count z3fold objects is the right
> thing to do. Moreover, it makes buddied list no longer necessary,
> and allows for a simpler handling of headless pages.
>
> Signed-off-by: Vitaly Wool 

Reviewed-by: Dan Streetman 

> ---
>  mm/z3fold.c | 151 
> ++--
>  1 file changed, 66 insertions(+), 85 deletions(-)
>
> diff --git a/mm/z3fold.c b/mm/z3fold.c
> index 4325bde..f0d2eaf 100644
> --- a/mm/z3fold.c
> +++ b/mm/z3fold.c
> @@ -52,6 +52,7 @@ enum buddy {
>   * z3fold page, except for HEADLESS pages
>   * @buddy: links the z3fold page into the relevant list in the pool
>   * @page_lock: per-page lock
> + * @refcount:  reference cound for the z3fold page
>   * @first_chunks:  the size of the first buddy in chunks, 0 if free
>   * @middle_chunks: the size of the middle buddy in chunks, 0 if free
>   * @last_chunks:   the size of the last buddy in chunks, 0 if free
> @@ -60,6 +61,7 @@ enum buddy {
>  struct z3fold_header {
> struct list_head buddy;
> spinlock_t page_lock;
> +   struct kref refcount;
> unsigned short first_chunks;
> unsigned short middle_chunks;
> unsigned short last_chunks;
> @@ -95,8 +97,6 @@ struct z3fold_header {
>   * @unbuddied: array of lists tracking z3fold pages that contain 2- buddies;
>   * the lists each z3fold page is added to depends on the size of
>   * its free region.
> - * @buddied:   list tracking the z3fold pages that contain 3 buddies;
> - * these z3fold pages are full
>   * @lru:   list tracking the z3fold pages in LRU order by most recently
>   * added buddy.
>   * @pages_nr:  number of z3fold pages in the pool.
> @@ -109,7 +109,6 @@ struct z3fold_header {
>  struct z3fold_pool {
> spinlock_t lock;
> struct list_head unbuddied[NCHUNKS];
> -   struct list_head buddied;
> struct list_head lru;
> atomic64_t pages_nr;
> const struct z3fold_ops *ops;
> @@ -121,8 +120,7 @@ struct z3fold_pool {
>   * Internal z3fold page flags
>   */
>  enum z3fold_page_flags {
> -   UNDER_RECLAIM = 0,
> -   PAGE_HEADLESS,
> +   PAGE_HEADLESS = 0,
> MIDDLE_CHUNK_MAPPED,
>  };
>
> @@ -146,11 +144,11 @@ static struct z3fold_header *init_z3fold_page(struct 
> page *page)
> struct z3fold_header *zhdr = page_address(page);
>
> INIT_LIST_HEAD(&page->lru);
> -   clear_bit(UNDER_RECLAIM, &page->private);
> clear_bit(PAGE_HEADLESS, &page->private);
> clear_bit(MIDDLE_CHUNK_MAPPED, &page->private);
>
> spin_lock_init(&zhdr->page_lock);
> +   kref_init(&zhdr->refcount);
> zhdr->first_chunks = 0;
> zhdr->middle_chunks = 0;
> zhdr->last_chunks = 0;
> @@ -161,9 +159,21 @@ static struct z3fold_header *init_z3fold_page(struct 
> page *page)
>  }
>
>  /* Resets the struct page fields and frees the page */
> -static void free_z3fold_page(struct z3fold_header *zhdr)
> +static void free_z3fold_page(struct page *page)
>  {
> -   __free_page(virt_to_page(zhdr));
> +   __free_page(page);
> +}
> +
> +static void release_z3fold_page(struct kref *ref)
> +{
> +   struct z3fold_header *zhdr = container_of(ref, struct z3fold_header,
> +  

Re: [PATCH] power: reset: Add MAX77620 support

2017-01-12 Thread Laxman Dewangan


On Thursday 12 January 2017 11:05 PM, Thierry Reding wrote:

* PGP Signed by an unknown key

On Thu, Jan 12, 2017 at 10:06:24PM +0530, Laxman Dewangan wrote:

On Thursday 12 January 2017 09:45 PM, Thierry Reding wrote:


+   dev_dbg(&pdev->dev, "event recorder: %#x\n", value);
+
+   system_power_controller = power;
+   pm_power_off = max77620_pm_power_off;
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+   arm_pm_restart = max77620_pm_restart;

What if we want to reset via the Tegra and not through PMIC?

In that case I assume we either don't have a PMIC, or we should not add
the system-power-controller device tree property to the PMIC node. In
the latter case this driver won't install any power off or restart
callbacks.



We need reset from Tegra and power of from PMIC. Tegra does not support 
power OFF.






Re: [PATCH v8 2/5] i2c: Add STM32F4 I2C driver

2017-01-12 Thread Uwe Kleine-König
On Thu, Jan 12, 2017 at 02:47:42PM +0100, M'boumba Cedric Madianga wrote:
> 2017-01-12 13:03 GMT+01:00 Uwe Kleine-König :
> > Hello Cedric,
> >
> > On Thu, Jan 12, 2017 at 12:23:12PM +0100, M'boumba Cedric Madianga wrote:
> >> 2017-01-11 16:39 GMT+01:00 Uwe Kleine-König 
> >> :
> >> > On Wed, Jan 11, 2017 at 02:58:44PM +0100, M'boumba Cedric Madianga wrote:
> >> >> 2017-01-11 9:22 GMT+01:00 Uwe Kleine-König 
> >> >> :
> >> >> > This is surprising. I didn't recheck the manual, but that looks very
> >> >> > uncomfortable.
> >> >>
> >> >> I agree but this exactly the hardware way of working described in the
> >> >> reference manual.
> >> >
> >> > IMHO that's a hw bug. This makes it for example impossible to implement
> >> > SMBus block transfers (I think).
> >>
> >> This is not correct.
> >> Setting STOP/START bit does not mean the the pulse will be sent right now.
> >> Here we have just to prepare the hardware for the 2 next pulse but the
> >> STOP/START/ACK pulse will be generated at the right time as required
> >> by I2C specification.
> >> So SMBus block transfer will be possible.
> >
> > A block transfer consists of a byte that specifies the count of bytes
> > yet to come. So the device sends for example:
> >
> > 0x01 0xab
> >
> > So when you read the 1 in the first byte it's already too late to set
> > STOP to get it after the 2nd byte.
> >
> > Not sure I got all the required details right, though.
> 
> Ok I understand your use case but I always think that the harware manages it.
> If I take the above example, the I2C SMBus block read transaction will
> be as below:
> S Addr Wr [A] Comm [A]
>S Addr Rd [A] [Count] A [Data1] A [Data2] NA P
> 
> The first message is a single byte-transmission so there is no problem.
> 
> The second message is a N-byte reception with N = 3
> 
> When the I2C controller has finished to send the device address (S
> Addr Rd), the ADDR flag is set and an interrupt is raised.
> In the routine that handles ADDR event, we set ACK bit in order to
> generate ACK pulse as soon as a data byte is received in the shift
> register and then we clear the ADDR flag.
> Please note that the SCL line is stretched low until ADDR flag is cleared.
> So, as far I understand, the device could not sent any data as long as
> the SCL line is stretched low. Right ?
> 
> Then, as soon as the SCL line is high, the device could send the first
> data byte (Count).
> When this byte is received in the shift register, an ACK is
> automatically generated as defined during adress match phase and the
> data byte is pushed in DR (data register).
> Then, an interrupt is raised as RXNE (RX not empty) flag is set.
> In the routine that handles RXNE event, as N=3, we just clear all
> buffer interrupts in order to avoid another system preemption due to
> RXNE event but we does not read the data in DR.

In my example I want to receive a block of length 1, so only two bytes
are read, a 1 (the length) and the data byte (0xab in my example). I
think that as soon as you read the 1 it's already to late to schedule
the NA after the next byte?

Best regards
Uwe

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | http://www.pengutronix.de/  |


Re: [PATCH 1/2] memory: aemif: allow passing device lookup table as platform data

2017-01-12 Thread santosh.shilim...@oracle.com

On 1/4/17 2:36 AM, Bartosz Golaszewski wrote:

TI aemif driver creates its own subnodes of the device tree in order
to guarantee that all child devices are probed after the AEMIF timing
parameters are configured.

Some devices (e.g. da850) use struct of_dev_auxdata for clock lookup
but nodes created from within the aemif driver can't access the lookup
table.

Create a platform data structure that holds a pointer to
of_dev_auxdata so that we can use it with of_platform_populate().

Signed-off-by: Bartosz Golaszewski 
---

Patch looks fine to me. Did I miss PATCH 2/2 ?
drivers/memory/* patches has been queue via Greg KH tree. Please
repost your series with acks and copy Greg. I will request Greg
to queue these changes via his tree.

Regards,
Santosh


Re: [PATCH V2 1/4] PCI: exynos: replace to one register accessor from each accessors

2017-01-12 Thread Bjorn Helgaas
On Thu, Jan 12, 2017 at 11:17:16AM +0900, Jaehoon Chung wrote:
> There is no reason to maintain *_blk/phy/elbi_* as register accessors.
> It can be replaced to one register accessor.
> 
> Signed-off-by: Jaehoon Chung 
> Reviewed-by: Pankaj Dubey 
> Acked-by: Krzysztof Kozlowski 
> ---
> Changelog on V2;
> - Changes the all pointer names as "ep" instead of "exynos_pcie"

Thanks a lot for making this consistency change.  I should have
mentioned this in the first response, but I would prefer to see this
as two separate patches:

  1) Rename all pointer names from "exynos_pcie" to "ep"
  2) Replace the *_blk/*_phy/*_elb accessors

That makes the patches smaller and easier to review, since each does
only one thing.

>  drivers/pci/host/pci-exynos.c | 354 
> --
>  1 file changed, 167 insertions(+), 187 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index f1c544b..92856cd 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -102,212 +102,190 @@ struct exynos_pcie {
>  #define PCIE_PHY_TRSV3_PD_TSV(0x1 << 7)
>  #define PCIE_PHY_TRSV3_LVCC  0x31c
>  
> -static void exynos_elb_writel(struct exynos_pcie *exynos_pcie, u32 val, u32 
> reg)
> +static void exynos_pcie_writel(void __iomem *base, u32 val, u32 reg)
>  {
> - writel(val, exynos_pcie->elbi_base + reg);
> + writel(val, base + reg);
>  }
>  
> -static u32 exynos_elb_readl(struct exynos_pcie *exynos_pcie, u32 reg)
> +static u32 exynos_pcie_readl(void __iomem *base, u32 reg)
>  {
> - return readl(exynos_pcie->elbi_base + reg);
> + return readl(base + reg);
>  }
>  
> -static void exynos_phy_writel(struct exynos_pcie *exynos_pcie, u32 val, u32 
> reg)
> -{
> - writel(val, exynos_pcie->phy_base + reg);
> -}
> -
> -static u32 exynos_phy_readl(struct exynos_pcie *exynos_pcie, u32 reg)
> -{
> - return readl(exynos_pcie->phy_base + reg);
> -}
> -
> -static void exynos_blk_writel(struct exynos_pcie *exynos_pcie, u32 val, u32 
> reg)
> -{
> - writel(val, exynos_pcie->block_base + reg);
> -}
> -
> -static u32 exynos_blk_readl(struct exynos_pcie *exynos_pcie, u32 reg)
> -{
> - return readl(exynos_pcie->block_base + reg);
> -}
> -
> -static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *exynos_pcie,
> - bool on)
> +static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on)
>  {
>   u32 val;
>  
>   if (on) {
> - val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_AWMISC);
> + val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC);
>   val |= PCIE_ELBI_SLV_DBI_ENABLE;
> - exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_AWMISC);
> + exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC);
>   } else {
> - val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_AWMISC);
> + val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC);
>   val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
> - exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_AWMISC);
> + exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC);
>   }
>  }
>  
> -static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *exynos_pcie,
> - bool on)
> +static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *ep, bool on)
>  {
>   u32 val;
>  
>   if (on) {
> - val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_ARMISC);
> + val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC);
>   val |= PCIE_ELBI_SLV_DBI_ENABLE;
> - exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_ARMISC);
> + exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC);
>   } else {
> - val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_ARMISC);
> + val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC);
>   val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
> - exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_ARMISC);
> + exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC);
>   }
>  }
>  
> -static void exynos_pcie_assert_core_reset(struct exynos_pcie *exynos_pcie)
> +static void exynos_pcie_assert_core_reset(struct exynos_pcie *ep)
>  {
>   u32 val;
>  
> - val = exynos_elb_readl(exynos_pcie, PCIE_CORE_RESET);
> + val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET);
>   val &= ~PCIE_CORE_RESET_ENABLE;
> - exynos_elb_writel(exynos_pcie, val, PCIE_CORE_RESET);
> - exynos_elb_writel(exynos_pcie, 0, PCIE_PWR_RESET);
> - exynos_elb_writel(exynos_pcie, 0, PCIE_STICKY_RESET);
> - exynos_elb_writel(exynos_pcie, 0, PCIE_NONSTICKY_RESET);
> + exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET);
> + exynos_pcie_writel(ep->elbi_base, 0, PCIE_PWR_RESET)

Re: [PATCH v5] DAX: enable iostat for read/write

2017-01-12 Thread Joe Perches
On Thu, 2017-01-12 at 11:38 -0700, Toshi Kani wrote:
> DAX IO path does not support iostat, but its metadata IO path does.
> Therefore, iostat shows metadata IO statistics only, which has been
> confusing to users.
[]
> diff --git a/fs/dax.c b/fs/dax.c
[]
> @@ -1058,12 +1058,24 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter 
> *iter,
>  {
>   struct address_space *mapping = iocb->ki_filp->f_mapping;
>   struct inode *inode = mapping->host;
> + struct gendisk *disk = inode->i_sb->s_bdev->bd_disk;
>   loff_t pos = iocb->ki_pos, ret = 0, done = 0;
>   unsigned flags = 0;
> + unsigned long start = 0;
> + int do_acct = blk_queue_io_stat(disk->queue);
>  
>   if (iov_iter_rw(iter) == WRITE)
>   flags |= IOMAP_WRITE;
>  
> + if (do_acct) {
> + sector_t sec = iov_iter_count(iter) >> 9;
> +
> + start = jiffies;
> + generic_start_io_acct(iov_iter_rw(iter),
> +   min_t(unsigned long, 1, sec),

I believe I mislead you with a thinko.

Your original code was
(!sec) ? 1 : sec
and I suggested incorrectly using min_t

It should of course be max_t.  Sorry.

Also, as sec is now sector_t (u64), perhaps this
unsigned long cast is incorrect.




[PATCH] ASoC: rt5659: fix platform_no_drv_owner.cocci warnings

2017-01-12 Thread kbuild test robot
sound/soc/codecs/rt5659.c:4236:3-8: No need to set .owner here. The core will 
do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Nicholas Mc Guire 
Signed-off-by: Fengguang Wu 
---

 rt5659.c |1 -
 1 file changed, 1 deletion(-)

--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -4233,7 +4233,6 @@ MODULE_DEVICE_TABLE(acpi, rt5659_acpi_ma
 static struct i2c_driver rt5659_i2c_driver = {
.driver = {
.name = "rt5659",
-   .owner = THIS_MODULE,
.of_match_table = of_match_ptr(rt5659_of_match),
.acpi_match_table = ACPI_PTR(rt5659_acpi_match),
},


[PATCH v5 3/3] Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup

2017-01-12 Thread Rajat Jain
The Marvell devices may have many gpio pins, and hence for wakeup
on these out-of-band pins, the chip needs to be told which pin is
to be used for wakeup, using an hci command.

Thus, we read the pin number etc from the device tree node and send
a command to the chip.

Signed-off-by: Rajat Jain 
Reviewed-by: Brian Norris 
Acked-by: Rob Herring 
---
v5: same as v5
v4: same as v3
v3: * remove the Marvell specific id table and check
* Add reference to marvell-bt-8xxx.txt in btusb.txt
* Add "Reviewed-by" and "Acked-by"
v2: Fix the binding document to specify to use "wakeup" interrupt-name

 Documentation/devicetree/bindings/net/btusb.txt|  3 ++
 .../{marvell-bt-sd8xxx.txt => marvell-bt-8xxx.txt} | 46 +++
 drivers/bluetooth/btusb.c  | 51 ++
 3 files changed, 92 insertions(+), 8 deletions(-)
 rename Documentation/devicetree/bindings/net/{marvell-bt-sd8xxx.txt => 
marvell-bt-8xxx.txt} (50%)

diff --git a/Documentation/devicetree/bindings/net/btusb.txt 
b/Documentation/devicetree/bindings/net/btusb.txt
index 2c0355c85972..01fa2d4188d4 100644
--- a/Documentation/devicetree/bindings/net/btusb.txt
+++ b/Documentation/devicetree/bindings/net/btusb.txt
@@ -10,6 +10,9 @@ Required properties:
 
  "usb1286,204e" (Marvell 8997)
 
+Also, vendors that use btusb may have device additional properties, e.g:
+Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt
+
 Optional properties:
 
   - interrupt-parent: phandle of the parent interrupt controller
diff --git a/Documentation/devicetree/bindings/net/marvell-bt-sd8xxx.txt 
b/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt
similarity index 50%
rename from Documentation/devicetree/bindings/net/marvell-bt-sd8xxx.txt
rename to Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt
index 6a9a63cb0543..9be1059ff03f 100644
--- a/Documentation/devicetree/bindings/net/marvell-bt-sd8xxx.txt
+++ b/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt
@@ -1,16 +1,21 @@
-Marvell 8897/8997 (sd8897/sd8997) bluetooth SDIO devices
+Marvell 8897/8997 (sd8897/sd8997) bluetooth devices (SDIO or USB based)
 --
+The 8997 devices supports multiple interfaces. When used on SDIO interfaces,
+the btmrvl driver is used and when used on USB interface, the btusb driver is
+used.
 
 Required properties:
 
   - compatible : should be one of the following:
-   * "marvell,sd8897-bt"
-   * "marvell,sd8997-bt"
+   * "marvell,sd8897-bt" (for SDIO)
+   * "marvell,sd8997-bt" (for SDIO)
+   * "usb1286,204e"  (for USB)
 
 Optional properties:
 
   - marvell,cal-data: Calibration data downloaded to the device during
  initialization. This is an array of 28 values(u8).
+ This is only applicable to SDIO devices.
 
   - marvell,wakeup-pin: It represents wakeup pin number of the bluetooth chip.
firmware will use the pin to wakeup host system (u16).
@@ -18,10 +23,15 @@ Optional properties:
  platform. The value will be configured to firmware. This
  is needed to work chip's sleep feature as expected (u16).
   - interrupt-parent: phandle of the parent interrupt controller
-  - interrupts : interrupt pin number to the cpu. Driver will request an irq 
based
-on this interrupt number. During system suspend, the irq will 
be
-enabled so that the bluetooth chip can wakeup host platform 
under
-certain condition. During system resume, the irq will be 
disabled
+  - interrupt-names: Used only for USB based devices (See below)
+  - interrupts : specifies the interrupt pin number to the cpu. For SDIO, the
+driver will use the first interrupt specified in the interrupt
+array. For USB based devices, the driver will use the interrupt
+named "wakeup" from the interrupt-names and interrupt arrays.
+The driver will request an irq based on this interrupt number.
+During system suspend, the irq will be enabled so that the
+bluetooth chip can wakeup host platform under certain
+conditions. During system resume, the irq will be disabled
 to make sure unnecessary interrupt is not received.
 
 Example:
@@ -29,7 +39,9 @@ Example:
 IRQ pin 119 is used as system wakeup source interrupt.
 wakeup pin 13 and gap 100ms are configured so that firmware can wakeup host
 using this device side pin and wakeup latency.
-calibration data is also available in below example.
+
+Example for SDIO device follows (calibration data is also available in
+below example).
 
 &mmc3 {
status = "okay";
@@ -54,3 +66,21 @@ calibration data is also available in below example.
marvell,wakeup-gap-ms = /bits/ 16 <0x64>;
};
 };
+
+Example for USB device:
+
+&usb_host1_ohci {
+status = "okay";
+#address-cells = <1>;
+#si

[PATCH v5 2/3] Bluetooth: btusb: Add out-of-band wakeup support

2017-01-12 Thread Rajat Jain
Some onboard BT chips (e.g. Marvell 8997) contain a wakeup pin that
can be connected to a gpio on the CPU side, and can be used to wakeup
the host out-of-band. This can be useful in situations where the
in-band wakeup is not possible or not preferable (e.g. the in-band
wakeup may require the USB host controller to remain active, and
hence consuming more system power during system sleep).

The oob gpio interrupt to be used for wakeup on the CPU side, is
read from the device tree node, (using standard interrupt descriptors).
A devcie tree binding document is also added for the driver. The
compatible string is in compliance with
Documentation/devicetree/bindings/usb/usb-device.txt

Signed-off-by: Rajat Jain 
Reviewed-by: Brian Norris 
Acked-by: Rob Herring 
---
v5: Move the call to pm_wakeup_event() to the begining of irq handler.
v4: Move the set_bit(BTUSB_OOB_WAKE_DISABLED,..) call to the beginning of
btusb_config_oob_wake()
v3: Add Brian's "Reviewed-by"
v2: * Use interrupt-names ("wakeup") instead of assuming first interrupt.
* Leave it on device tree to specify IRQ flags (level /edge triggered)
* Mark the device as non wakeable on exit.

 Documentation/devicetree/bindings/net/btusb.txt | 40 
 drivers/bluetooth/btusb.c   | 85 +
 2 files changed, 125 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/btusb.txt

diff --git a/Documentation/devicetree/bindings/net/btusb.txt 
b/Documentation/devicetree/bindings/net/btusb.txt
new file mode 100644
index ..2c0355c85972
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/btusb.txt
@@ -0,0 +1,40 @@
+Generic Bluetooth controller over USB (btusb driver)
+---
+
+Required properties:
+
+  - compatible : should comply with the format "usbVID,PID" specified in
+Documentation/devicetree/bindings/usb/usb-device.txt
+At the time of writing, the only OF supported devices
+(more may be added later) are:
+
+ "usb1286,204e" (Marvell 8997)
+
+Optional properties:
+
+  - interrupt-parent: phandle of the parent interrupt controller
+  - interrupt-names: (see below)
+  - interrupts : The interrupt specified by the name "wakeup" is the interrupt
+that shall be used for out-of-band wake-on-bt. Driver will
+request this interrupt for wakeup. During system suspend, the
+irq will be enabled so that the bluetooth chip can wakeup host
+platform out of band. During system resume, the irq will be
+disabled to make sure unnecessary interrupt is not received.
+
+Example:
+
+Following example uses irq pin number 3 of gpio0 for out of band wake-on-bt:
+
+&usb_host1_ehci {
+status = "okay";
+#address-cells = <1>;
+#size-cells = <0>;
+
+mvl_bt1: bt@1 {
+   compatible = "usb1286,204e";
+   reg = <1>;
+   interrupt-parent = <&gpio0>;
+   interrupt-name = "wakeup";
+   interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+};
+};
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ce22cefceed1..0a777bb407b1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -24,6 +24,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 #include 
@@ -369,6 +371,7 @@ static const struct usb_device_id blacklist_table[] = {
 #define BTUSB_BOOTING  9
 #define BTUSB_RESET_RESUME 10
 #define BTUSB_DIAG_RUNNING 11
+#define BTUSB_OOB_WAKE_DISABLED12
 
 struct btusb_data {
struct hci_dev   *hdev;
@@ -416,6 +419,8 @@ struct btusb_data {
int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);
 
int (*setup_on_usb)(struct hci_dev *hdev);
+
+   int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
 };
 
 static inline void btusb_free_frags(struct btusb_data *data)
@@ -2728,6 +2733,66 @@ static int btusb_bcm_set_diag(struct hci_dev *hdev, bool 
enable)
 }
 #endif
 
+#ifdef CONFIG_PM
+static irqreturn_t btusb_oob_wake_handler(int irq, void *priv)
+{
+   struct btusb_data *data = priv;
+
+   pm_wakeup_event(&data->udev->dev, 0);
+
+   /* Disable only if not already disabled (keep it balanced) */
+   if (!test_and_set_bit(BTUSB_OOB_WAKE_DISABLED, &data->flags)) {
+   disable_irq_nosync(irq);
+   disable_irq_wake(irq);
+   }
+   return IRQ_HANDLED;
+}
+
+static const struct of_device_id btusb_match_table[] = {
+   { .compatible = "usb1286,204e" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, btusb_match_table);
+
+/* Use an oob wakeup pin? */
+static int btusb_config_oob_wake(struct hci_dev *hdev)
+{
+   struct btusb_data *data = hci_get_drvdata(hdev);
+   struct device *dev = &data->udev->dev;
+   int irq, ret;
+
+   set_bit(BTUSB_OOB_WAKE_DISABLED, &data->flags);
+
+   if (!of_match_device(btusb_match_table, dev))
+  

Re: sysfs deferred_probe attribute

2017-01-12 Thread Greg Kroah-Hartman
On Thu, Jan 12, 2017 at 11:27:01AM -0600, Rob Herring wrote:
> I just noticed that we have a new device attribute 'deferred_probe'
> added in 4.10 with this commit:
> 
> commit 6751667a29d6fd64afb9ce30567ad616b68ed789
> Author: Ben Hutchings 
> Date:   Tue Aug 16 14:34:18 2016 +0100
> 
> driver core: Add deferred_probe attribute to devices in sysfs
> 
> It is sometimes useful to know that a device is on the deferred probe
> list rather than, say, not having a driver available.  Expose this
> information to user-space.
> 
> Signed-off-by: Ben Hutchings 
> Signed-off-by: Greg Kroah-Hartman 
> 
> 
> It seems like a bad idea to add an ABI for an internal kernel feature.
> When/if we replace deferred probe with something better based on
> functional dependencies are we going to keep this attr around? Or
> remove it and assume no userspace uses it? Perhaps it should be hidden
> behind CONFIG_DEBUG or just make a debugfs file that lists the
> deferred list. Then you wouldn't have to hunt for what got deferred.

Ah, debugfs would be nice, I'd much prefer that.  I don't know how Ben
is using this, but I think that would make more sense to me.

thanks,

greg k-h


[PATCH v5 1/3] Bluetooth: btusb: Use an error label for error paths

2017-01-12 Thread Rajat Jain
Use a label to remove the repetetive cleanup, for error cases.

Signed-off-by: Rajat Jain 
Reviewed-by: Brian Norris 
---
v5: same as v4
v4: same as v3
v3: Added Brian's "Reviewed-by"
v2: same as v1

 drivers/bluetooth/btusb.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 2f633df9f4e6..ce22cefceed1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2991,18 +2991,15 @@ static int btusb_probe(struct usb_interface *intf,
err = usb_set_interface(data->udev, 0, 0);
if (err < 0) {
BT_ERR("failed to set interface 0, alt 0 %d", err);
-   hci_free_dev(hdev);
-   return err;
+   goto out_free_dev;
}
}
 
if (data->isoc) {
err = usb_driver_claim_interface(&btusb_driver,
 data->isoc, data);
-   if (err < 0) {
-   hci_free_dev(hdev);
-   return err;
-   }
+   if (err < 0)
+   goto out_free_dev;
}
 
 #ifdef CONFIG_BT_HCIBTUSB_BCM
@@ -3016,14 +3013,16 @@ static int btusb_probe(struct usb_interface *intf,
 #endif
 
err = hci_register_dev(hdev);
-   if (err < 0) {
-   hci_free_dev(hdev);
-   return err;
-   }
+   if (err < 0)
+   goto out_free_dev;
 
usb_set_intfdata(intf, data);
 
return 0;
+
+out_free_dev:
+   hci_free_dev(hdev);
+   return err;
 }
 
 static void btusb_disconnect(struct usb_interface *intf)
-- 
2.11.0.390.gc69c2f50cf-goog



Re: [PATCH 1/5] perf, tools: Add probing for xed

2017-01-12 Thread Andi Kleen
On Thu, Jan 12, 2017 at 09:52:53AM +0100, Jiri Olsa wrote:
> On Wed, Jan 11, 2017 at 02:17:56PM -0800, Andi Kleen wrote:
> > > > diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
> > > > index e3fb5ecbdcb6..971a9ef87ca6 100644
> > > > --- a/tools/build/Makefile.feature
> > > > +++ b/tools/build/Makefile.feature
> > > > @@ -63,7 +63,7 @@ FEATURE_TESTS_BASIC :=  \
> > > >  lzma\
> > > >  get_cpuid   \
> > > >  bpf \
> > > > -sdt
> > > > +   sdt \
> > > 
> > > looks like you forgot to add xed in here? why the '\' ?
> > 
> > I removed it, but incompletely.
> > 
> > > anyway, please add it in here so it's visible under make VF=1
> > 
> > If I add it here then it is shown by default (even without VF=1).
> > Arnaldo requested earlier that it shouldn't be shown.
> 
> if you put it to FEATURE_TESTS_BASIC then it's displayed only for VF=1

It's already in FEATURE_TESTS_BASIC:

@ -63,7 +63,8 @@ FEATURE_TESTS_BASIC :=  \
 lzma\
 get_cpuid   \
 bpf \
-sdt
+   sdt \
+   xed

-ANdi


Re: [PATCH 4/4] ARM: dts: sun8i: add OTG function to Lichee Pi Zero

2017-01-12 Thread Maxime Ripard
Hi Bin,

On Thu, Jan 12, 2017 at 08:50:14AM -0600, Bin Liu wrote:
> On Wed, Jan 11, 2017 at 10:06:38PM +0100, Maxime Ripard wrote:
> > On Wed, Jan 11, 2017 at 02:08:11PM -0600, Bin Liu wrote:
> > > On Thu, Jan 12, 2017 at 03:55:33AM +0800, Icenowy Zheng wrote:
> > > > 
> > > > 
> > > > 11.01.2017, 04:24, "Bin Liu" :
> > > > > On Tue, Jan 03, 2017 at 11:25:34PM +0800, Icenowy Zheng wrote:
> > > > >>  Lichee Pi Zero features a USB OTG port.
> > > > >>
> > > > >>  Add support for it.
> > > > >>
> > > > >>  Note: in order to use the Host mode, the board must be powered via 
> > > > >> the
> > > > >>  +5V and GND pins.
> > > > >>
> > > > >>  Signed-off-by: Icenowy Zheng 
> > > > >>  ---
> > > > >>   arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts | 10 ++
> > > > >>   1 file changed, 10 insertions(+)
> > > > >>
> > > > >>  diff --git a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts 
> > > > >> b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
> > > > >>  index 0099affc6ce3..3d9168cbaeca 100644
> > > > >>  --- a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
> > > > >>  +++ b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
> > > > >>  @@ -71,3 +71,13 @@
> > > > >>   pinctrl-names = "default";
> > > > >>   status = "okay";
> > > > >>   };
> > > > >>  +
> > > > >>  +&usb_otg {
> > > > >>  + dr_mode = "otg";
> > > > >
> > > > > Why not set this default mode in dtsi instead?
> > > > >
> > > > > Regards,
> > > > > -Bin.
> > > > 
> > > > There's possibly boards which do not have OTG functions.
> > > 
> > > That is board specific.
> > 
> > Exactly, and this is why it should be done in the board DT.
> 
> I am just suggesting based on the common practice. If a .dtsi exists for
> a family, the .dtsi describes the device and common properties for all
> possible boards, and each board .dts adds or overrides its specific
> implementation. Kernel has many devices/boards done in this way - define
> the default dr_mode in .dtsi.
> 
> In this case, I suggest to set the common dr_mode in .dtsi, then each
> board .dts only overrides it if the implementation is different. 
> 
> > 
> > The controller in the Allwinner SoCs do not handle directly the ID pin
> > and VBUS, but rather rely on a GPIO to do so.
> > 
> > So boards with OTG will need setup anyway, at least to tell which
> > GPIOs are used. There's no point in enforcing a default if it doesn't
> > work by default.
> 
> Then define a default which supposes to work for most boards.
> 
> Why I suggest this, is because defining a default dr_mode which works
> for most cases in dtsi could prevent a little surprise in MUSB function.
> If someone designs a new board but forgets to define dr_mode in the new
> board DT, the MUSB driver will default to org mode, which might not be
> intended.

The point is that there is no sensible default. Some boards don't have
an ID pin and no VBUS (peripheral), some don't have an ID pin but VBUS
(host), and some have an ID pin but no controllable VBUS, some have an
ID pin and a controllable VBUS, but we have no idea which GPIOs are
used.

There's no way we can have something that works on most cases.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH 01/11] perf, tools: Factor out scale conversion code

2017-01-12 Thread Arnaldo Carvalho de Melo
Em Thu, Jan 12, 2017 at 10:31:57AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Sun, Jan 08, 2017 at 07:57:53PM +0100, Jiri Olsa escreveu:
> > On Tue, Jan 03, 2017 at 07:08:23AM -0800, Andi Kleen wrote:
> > 
> > SNIP
> > 
> > > - goto error;
> > > -
> > > - if (scale[sret - 1] == '\n')
> > > - scale[sret - 1] = '\0';
> > > - else
> > > - scale[sret] = '\0';
> > > + int ret = 0;
> > >  
> > >   /*
> > >* save current locale
> > > @@ -133,8 +111,8 @@ static int perf_pmu__parse_scale(struct 
> > > perf_pmu_alias *alias, char *dir, char *
> > >*/
> > >   lc = strdup(lc);
> > >   if (!lc) {
> > > - ret = -ENOMEM;
> > > - goto error;
> > > + ret = -1;
> > > + goto out;
> > 
> > not sure why you changed the -ENOMEM to -1 ;-) but it's ok anyway
> 
> These unrelated things are just that, noise, I'll ditch it to reduce
> patch size while not introducing any functional change.

But then this return is not even being looked at anywhere :-\
  
> > Acked-by: Jiri Olsa 
> 
> Will keep your ack tho :-)
> 
> - Arnaldo
>  
> > thanks,
> > jirka


Re: [PATCH v2 2/2] Support for DW CSI-2 Host IPK

2017-01-12 Thread Hans Verkuil
On 01/12/2017 06:43 PM, Ramiro Oliveira wrote:
> Hi Hans,
> 
> Thank you for your feedback.
> 
> On 1/11/2017 11:54 AM, Hans Verkuil wrote:
>> Hi Ramiro,
>>
>> See my review comments below:
>>
>> On 12/12/16 16:00, Ramiro Oliveira wrote:
>>> Add support for the DesignWare CSI-2 Host IP Prototyping Kit
>>>
>>> Signed-off-by: Ramiro Oliveira 
> 
> [snip]

>>> +
>>> +static int vid_dev_subdev_s_power(struct v4l2_subdev *sd, int on)
>>> +{
>>> +return 0;
>>> +}
>>
>> Just drop this empty function, shouldn't be needed.
>>
> 
> When I start my system I'm hoping all the subdevs have s_power registered. If 
> it
> doesn't exist should I change the way I handle it, or will the core handle it
> for me?

If it isn't provided, then it is just skipped. The general rule is that
you only provide these ops if they do something useful.

> 
>>> +
>>> +static int vid_dev_subdev_registered(struct v4l2_subdev *sd)
>>> +{
>>> +struct video_device_dev *vid_dev = v4l2_get_subdevdata(sd);
>>> +struct vb2_queue *q = &vid_dev->vb_queue;
>>> +struct video_device *vfd = &vid_dev->ve.vdev;
>>> +int ret;
>>> +
>>> +memset(vfd, 0, sizeof(*vfd));
>>> +
>>> +strlcpy(vfd->name, VIDEO_DEVICE_NAME, sizeof(vfd->name));
>>> +
>>> +vfd->fops = &vid_dev_fops;
>>> +vfd->ioctl_ops = &vid_dev_ioctl_ops;
>>> +vfd->v4l2_dev = sd->v4l2_dev;
>>> +vfd->minor = -1;
>>> +vfd->release = video_device_release_empty;
>>> +vfd->queue = q;
>>> +
>>> +INIT_LIST_HEAD(&vid_dev->vidq.active);
>>> +init_waitqueue_head(&vid_dev->vidq.wq);
>>> +memset(q, 0, sizeof(*q));
>>> +q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>>> +q->io_modes = VB2_MMAP | VB2_USERPTR;
>>
>> Add VB2_DMABUF and VB2_READ.
>>
> 
> I'll add them, but I'm not using them, is it standard procedure to add them 
> all
> even if they aren't used?

You may not use them, but others might. And it doesn't cost anything to add 
them.

> 
>>> +q->ops = &vb2_video_qops;
>>> +q->mem_ops = &vb2_vmalloc_memops;
>>
>> Why is vmalloc used? Can't you use dma_contig or dma_sg and avoid having to 
>> copy
>> the image data? That's a really bad design given the amount of video data 
>> that
>> you have to copy.
>>
> 
> When I started development, the arch I was using (ARC) didn't support
> dma_contig, so I was forced to use vmalloc.
> 
> Since then things have changed and I'm already using dma_contig, however it
> wasn't included in this patch. I'll add it to the next patch.

Ah, good. If you are switching to dma_contig, then remove VB2_USERPTR.
VB2_DMABUF should be used instead.

Regards,

Hans


Re: [PATCH] xen-netback: fix memory leaks on XenBus disconnect

2017-01-12 Thread Igor Druzhinin
On 12/01/17 17:51, Igor Druzhinin wrote:
> Eliminate memory leaks introduced several years ago by cleaning the queue
> resources which are allocated on XenBus connection event. Namely, queue
> structure array and pages used for IO rings.
> vif->lock is used to protect statistics gathering agents from using the
> queue structure during cleaning.
> 
> Signed-off-by: Igor Druzhinin 
> ---
>  drivers/net/xen-netback/interface.c |  6 --
>  drivers/net/xen-netback/xenbus.c| 13 +
>  2 files changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/xen-netback/interface.c 
> b/drivers/net/xen-netback/interface.c
> index e30ffd2..5795213 100644
> --- a/drivers/net/xen-netback/interface.c
> +++ b/drivers/net/xen-netback/interface.c
> @@ -221,18 +221,18 @@ static struct net_device_stats *xenvif_get_stats(struct 
> net_device *dev)
>  {
>   struct xenvif *vif = netdev_priv(dev);
>   struct xenvif_queue *queue = NULL;
> - unsigned int num_queues = vif->num_queues;
>   unsigned long rx_bytes = 0;
>   unsigned long rx_packets = 0;
>   unsigned long tx_bytes = 0;
>   unsigned long tx_packets = 0;
>   unsigned int index;
>  
> + spin_lock(&vif->lock);
>   if (vif->queues == NULL)
>   goto out;
>  
>   /* Aggregate tx and rx stats from each queue */
> - for (index = 0; index < num_queues; ++index) {
> + for (index = 0; index < vif->num_queues; ++index) {
>   queue = &vif->queues[index];
>   rx_bytes += queue->stats.rx_bytes;
>   rx_packets += queue->stats.rx_packets;
> @@ -241,6 +241,8 @@ static struct net_device_stats *xenvif_get_stats(struct 
> net_device *dev)
>   }
>  
>  out:
> + spin_unlock(&vif->lock);
> +
>   vif->dev->stats.rx_bytes = rx_bytes;
>   vif->dev->stats.rx_packets = rx_packets;
>   vif->dev->stats.tx_bytes = tx_bytes;
> diff --git a/drivers/net/xen-netback/xenbus.c 
> b/drivers/net/xen-netback/xenbus.c
> index 3124eae..85b742e 100644
> --- a/drivers/net/xen-netback/xenbus.c
> +++ b/drivers/net/xen-netback/xenbus.c
> @@ -493,11 +493,22 @@ static int backend_create_xenvif(struct backend_info 
> *be)
>  static void backend_disconnect(struct backend_info *be)
>  {
>   if (be->vif) {
> + unsigned int queue_index;
> +
>   xen_unregister_watchers(be->vif);
>  #ifdef CONFIG_DEBUG_FS
>   xenvif_debugfs_delif(be->vif);
>  #endif /* CONFIG_DEBUG_FS */
>   xenvif_disconnect_data(be->vif);
> + for (queue_index = 0; queue_index < be->vif->num_queues; 
> ++queue_index)
> + xenvif_deinit_queue(&be->vif->queues[queue_index]);
> +
> + spin_lock(&be->vif->lock);
> + vfree(be->vif->queues);
> + be->vif->num_queues = 0;
> + be->vif->queues = NULL;
> + spin_unlock(&be->vif->lock);
> +
>   xenvif_disconnect_ctrl(be->vif);
>   }
>  }
> @@ -1034,6 +1045,8 @@ static void connect(struct backend_info *be)
>  err:
>   if (be->vif->num_queues > 0)
>   xenvif_disconnect_data(be->vif); /* Clean up existing queues */
> + for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index)
> + xenvif_deinit_queue(&be->vif->queues[queue_index]);
>   vfree(be->vif->queues);
>   be->vif->queues = NULL;
>   be->vif->num_queues = 0;
> 

Add Juergen Gross to CC.

Igor


master - btrfs lockdep splat

2017-01-12 Thread Mike Galbraith
Greetings,

I wanted to do some -rt testing, but seems non-rt kernels aren't
lockdep clean with btrfs /, making -rt testing a bit premature.

(hm, 28a235931 Btrfs: fix lockdep warning on deadlock against an inode's log 
mutex)
 
[  876.622587] =
[  876.622588] [ INFO: possible recursive locking detected ]
[  876.622589] 4.10.0-master #36 Tainted: GE  
[  876.622590] -
[  876.622591] vi/3364 is trying to acquire lock:
[  876.622592]  (&ei->log_mutex){+.+...}, at: [] 
btrfs_log_inode+0x13c/0xbd0 [btrfs]
[  876.622628] but task is already holding lock:
[  876.622629]  (&ei->log_mutex){+.+...}, at: [] 
btrfs_log_inode+0x13c/0xbd0 [btrfs]
[  876.622641] other info that might help us debug this:
[  876.622642]  Possible unsafe locking scenario:
[  876.622643]CPU0
[  876.622644]
[  876.622644]   lock(&ei->log_mutex);
[  876.622648]   lock(&ei->log_mutex);
[  876.622649] *** DEADLOCK ***
[  876.622650]  May be due to missing lock nesting notation
[  876.622651] 3 locks held by vi/3364:
[  876.622651]  #0:  (&sb->s_type->i_mutex_key#11){+.+.+.}, at: 
[] btrfs_sync_file+0x154/0x480 [btrfs]
[  876.622664]  #1:  (sb_internal){.+.+..}, at: [] 
start_transaction+0x2a7/0x540 [btrfs]
[  876.622674]  #2:  (&ei->log_mutex){+.+...}, at: [] 
btrfs_log_inode+0x13c/0xbd0 [btrfs]
[  876.622685] stack backtrace:
[  876.622687] CPU: 3 PID: 3364 Comm: vi Tainted: GE   
4.10.0-master #36
[  876.622688] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
rel-1.8.1-0-g4adadbd-20161202_174313-build11a 04/01/2014
[  876.622689] Call Trace:
[  876.622698]  dump_stack+0x85/0xc9
[  876.622704]  __lock_acquire+0x9f9/0x1550
[  876.622715]  ? __btrfs_release_delayed_node+0x79/0x2d0 [btrfs]
[  876.622717]  lock_acquire+0xbd/0x200
[  876.622726]  ? btrfs_log_inode+0x13c/0xbd0 [btrfs]
[  876.622732]  mutex_lock_nested+0x69/0x660
[  876.622741]  ? btrfs_log_inode+0x13c/0xbd0 [btrfs]
[  876.622750]  ? __btrfs_release_delayed_node+0x79/0x2d0 [btrfs]
[  876.622759]  ? btrfs_commit_inode_delayed_inode+0xeb/0x130 [btrfs]
[  876.622767]  btrfs_log_inode+0x13c/0xbd0 [btrfs]
[  876.622771]  ? __might_sleep+0x4a/0x90
[  876.622781]  ? btrfs_i_callback+0x20/0x20 [btrfs]
[  876.622791]  ? free_extent_buffer+0x4b/0x90 [btrfs]
[  876.622799]  btrfs_log_inode+0x572/0xbd0 [btrfs]
[  876.622808]  btrfs_log_inode_parent+0x26a/0x9b0 [btrfs]
[  876.622812]  ? dget_parent+0x77/0x170
[  876.622821]  btrfs_log_dentry_safe+0x62/0x80 [btrfs]
[  876.622830]  btrfs_sync_file+0x2eb/0x480 [btrfs]
[  876.622834]  vfs_fsync_range+0x3d/0xb0
[  876.622836]  ? trace_hardirqs_on_caller+0xf9/0x1c0
[  876.622837]  do_fsync+0x3d/0x70
[  876.622839]  SyS_fsync+0x10/0x20
[  876.622840]  entry_SYSCALL_64_fastpath+0x1f/0xc2
[  876.622842] RIP: 0033:0x7f7fbe3da290
[  876.622843] RSP: 002b:7ffe2778f0b8 EFLAGS: 0246 ORIG_RAX: 
004a
[  876.622844] RAX: ffda RBX: 0003 RCX: 7f7fbe3da290
[  876.622845] RDX: 103d RSI: 0143e5d0 RDI: 0003
[  876.622846] RBP: 01285f10 R08: 0143e5d0 R09: 
[  876.622847] R10:  R11: 0246 R12: 
[  876.622847] R13: 2000 R14: 0001 R15: 012821a0


[PATCH] tpm_tis: fix iTPM probe via probe_itpm() function

2017-01-12 Thread Maciej S. Szmigiero
probe_itpm() function is supposed to send command without an itpm flag set
and if this fails to repeat it, this time with the itpm flag set.

However, commit 41a5e1cf1fe15 ("tpm/tpm_tis: Split tpm_tis driver into a
core and TCG TIS compliant phy") moved the itpm flag from an "itpm"
variable to a TPM_TIS_ITPM_POSSIBLE chip flag, so setting the
(now function-local) itpm variable no longer had any effect.

Finally, this function-local itpm variable was removed by
commit 56af322156dbe9 ("tpm/tpm_tis: remove unused itpm variable")

Tested only on non-iTPM TIS TPM.

Signed-off-by: Maciej S. Szmigiero 

Fixes: 41a5e1cf1fe15 ("Split tpm_tis driver into a core and TCG TIS compliant 
phy")
Cc: sta...@vger.kernel.org
---
 drivers/char/tpm/tpm_tis_core.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index e42e5a6a3c2f..401f1228547c 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -467,6 +467,9 @@ static int probe_itpm(struct tpm_chip *chip)
size_t len = sizeof(cmd_getticks);
u16 vendor;
 
+   if (priv->flags & TPM_TIS_ITPM_POSSIBLE)
+   return 0;
+
rc = tpm_tis_read16(priv, TPM_DID_VID(0), &vendor);
if (rc < 0)
return rc;
@@ -482,12 +485,15 @@ static int probe_itpm(struct tpm_chip *chip)
tpm_tis_ready(chip);
release_locality(chip, priv->locality, 0);
 
+   priv->flags |= TPM_TIS_ITPM_POSSIBLE;
+
rc = tpm_tis_send_data(chip, cmd_getticks, len);
-   if (rc == 0) {
+   if (rc == 0)
dev_info(&chip->dev, "Detected an iTPM.\n");
-   rc = 1;
-   } else
+   else {
+   priv->flags &= ~TPM_TIS_ITPM_POSSIBLE;
rc = -EFAULT;
+   }
 
 out:
tpm_tis_ready(chip);
@@ -743,15 +749,10 @@ int tpm_tis_core_init(struct device *dev, struct 
tpm_tis_data *priv, int irq,
 (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2",
 vendor >> 16, rid);
 
-   if (!(priv->flags & TPM_TIS_ITPM_POSSIBLE)) {
-   probe = probe_itpm(chip);
-   if (probe < 0) {
-   rc = -ENODEV;
-   goto out_err;
-   }
-
-   if (!!probe)
-   priv->flags |= TPM_TIS_ITPM_POSSIBLE;
+   probe = probe_itpm(chip);
+   if (probe < 0) {
+   rc = -ENODEV;
+   goto out_err;
}
 
/* Figure out the capabilities */



[PATCH] tpm_tis: override reported C and D timeouts for Atmel 3203

2017-01-12 Thread Maciej S. Szmigiero
Since commit 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM
access") Atmel 3203 TPM on ThinkPad X61S (TPM firmware version 13.9) no
longer works.
It turns out the initialization proceeds fine until we get and start using
chip-reported timeouts - and the chip reports C and D timeouts of zero.

Since these are clearly not long enough let's add an override for them
to TPM TIS default values, just as we do for Atmel 3204.
A and B timeouts are set to the same values as the chip normally reports.

Signed-off-by: Maciej S. Szmigiero 

Fixes: 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM access")
Cc: sta...@vger.kernel.org
---
 drivers/char/tpm/tpm_tis_core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 7993678954a2..e42e5a6a3c2f 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -421,6 +421,9 @@ struct tis_vendor_timeout_override {
 };
 
 static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = {
+   /* Atmel 3203 */
+   { 0x32031114, { (10*1000), (10*1000),
+   (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } },
/* Atmel 3204 */
{ 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000),
(TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } },



Re: Linux 4.9.3

2017-01-12 Thread Chris Rankin
Still no sign of the 4.9.3 patches on the FTP site... Oops?

Cheers,
Chris


Nokia N900: mixers changed between 4.6 and 4.10, no longer can use in-call speaker

2017-01-12 Thread Pavel Machek
Hi!

In v4.10 (and probably v4.9, too) I can no longer use the in-call
speaker. I can no longer use the wired headset, either.

v4.4 (and probably v4.6) works ok.

Any ideas? Does wired headset / in-call speaker work for you?

"Mono" and "Mono DAC" options are still there.. but something else
changed, as alsamixer now shows way many more options (meaning they
are shorter?) and I get complains from alsactl:

alsactl: set_control:1328: failed to obtain info for control #49 (No
such file or directory)
...
alsactl: set_control:1328: failed to obtain info for control #229 (No
such file or directory)



Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


[PATCH V7 00/10] Add UEFI 2.6 and ACPI 6.1 updates for RAS on ARM64

2017-01-12 Thread Tyler Baicar
When a memory error, CPU error, PCIe error, or other type of hardware error
that's covered by RAS occurs, firmware should populate the shared GHES memory
location with the proper GHES structures to notify the OS of the error.
For example, platforms that implement firmware first handling may implement
separate GHES sources for corrected errors and uncorrected errors. If the
error is an uncorrectable error, then the firmware will notify the OS
immediately since the error needs to be handled ASAP. The OS will then be able
to take the appropriate action needed such as offlining a page. If the error
is a corrected error, then the firmware will not interrupt the OS immediately.
Instead, the OS will see and report the error the next time it's GHES timer
expires. The kernel will first parse the GHES structures and report the errors
through the kernel logs and then notify the user space through RAS trace
events. This allows user space applications such as RAS Daemon to see the
errors and report them however the user desires. This patchset extends the
kernel functionality for RAS errors based on updates in the UEFI 2.6 and
ACPI 6.1 specifications.

An example flow from firmware to user space could be:

 +---+
   +>|   |
   | |  GHES polling |--+
+-+  |source |  |   +---+   ++
| |  +---+  |   |  Kernel GHES  |   ||
|  Firmware   | +-->|  CPER AER and |-->|  RAS trace |
| |  +---+  |   |  EDAC drivers |   |   event|
+-+  |   |  |   +---+   ++
   | |  GHES sci |--+
   +>|   source  |
 +---+

Add support for Generic Hardware Error Source (GHES) v2, which introduces the
capability for the OS to acknowledge the consumption of the error record
generated by the Reliability, Availability and Serviceability (RAS) controller.
This eliminates potential race conditions between the OS and the RAS controller.

Add support for the timestamp field added to the Generic Error Data Entry v3,
allowing the OS to log the time that the error is generated by the firmware,
rather than the time the error is consumed. This improves the correctness of
event sequences when analyzing error logs. The timestamp is added in
ACPI 6.1, reference Table 18-343 Generic Error Data Entry.

Add support for ARMv8 Common Platform Error Record (CPER) per UEFI 2.6
specification. ARMv8 specific processor error information is reported as part of
the CPER records.  This provides more detail on for processor error logs. This
can help describe ARMv8 cache, tlb, and bus errors.

Synchronous External Abort (SEA) represents a specific processor error condition
in ARM systems. A handler is added to recognize SEA errors, and a notifier is
added to parse and report the errors before the process is killed. Refer to
section N.2.1.1 in the Common Platform Error Record appendix of the UEFI 2.6
specification.

Currently the kernel ignores CPER records that are unrecognized.
On the other hand, UEFI spec allows for non-standard (eg. vendor
proprietary) error section type in CPER (Common Platform Error Record),
as defined in section N2.3 of UEFI version 2.5. Therefore, user
is not able to see hardware error data of non-standard section.

If section Type field of Generic Error Data Entry is unrecognized,
prints out the raw data in dmesg buffer, and also adds a tracepoint
for reporting such hardware errors.

Currently even if an error status block's severity is fatal, the kernel
does not honor the severity level and panic. With the firmware first
model, the platform could inform the OS about a fatal hardware error
through the non-NMI GHES notification type. The OS should panic when a
hardware error record is received with this severity.

Add support to handle SEAs that occur while a KVM guest kernel is
running. Currently these are unsupported by the guest abort handling.

V7: Update a couple prints for ARM processor errors
Add Print notifying if overflow occurred for ARM processor errors
Check for ARM configuration to allow the compiler to ignore ARM code
 on non-ARM systems
Use SEA acronym instead of spelling it out
Update fault_info prints to be more clear
Add NMI locking to SEA notification
Remove error info structure from ARM trace event since there can be
 a variable amount of these structures

V6: Change HEST_TYPE_GENERIC_V2 to IS_HEST_TYPE_GENERIC_V2 for readability
Move APEI helper defines from cper.h to ghes.h
Add data_len decrement back into print loop
Change references to ARMv8 to just ARM
Rewrite ARM processor context info parsing
Check valid bit of ARM error info field before printing it
Add include of linux/uuid.h in ghes.c

V5: Fix GHES goto logic for error conditions
Change ghes_do_read_ack to ghes_ack_error

[PATCH V7 04/10] arm64: exception: handle Synchronous External Abort

2017-01-12 Thread Tyler Baicar
SEA exceptions are often caused by an uncorrected hardware
error, and are handled when data abort and instruction abort
exception classes have specific values for their Fault Status
Code.
When SEA occurs, before killing the process, go through
the handlers registered in the notification list.
Update fault_info[] with specific SEA faults so that the
new SEA handler is used.

Signed-off-by: Tyler Baicar 
Signed-off-by: Jonathan (Zhixiong) Zhang 
Signed-off-by: Naveen Kaje 
---
 arch/arm64/include/asm/system_misc.h | 13 
 arch/arm64/mm/fault.c| 58 +---
 2 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/system_misc.h 
b/arch/arm64/include/asm/system_misc.h
index 57f110b..e7f3440 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -64,4 +64,17 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, 
const char *cmd);
 
 #endif /* __ASSEMBLY__ */
 
+/*
+ * The functions below are used to register and unregister callbacks
+ * that are to be invoked when a Synchronous External Abort (SEA)
+ * occurs. An SEA is raised by certain fault status codes that have
+ * either data or instruction abort as the exception class, and
+ * callbacks may be registered to parse or handle such hardware errors.
+ *
+ * Registered callbacks are run in an interrupt/atomic context. They
+ * are not allowed to block or sleep.
+ */
+int register_sea_notifier(struct notifier_block *nb);
+void unregister_sea_notifier(struct notifier_block *nb);
+
 #endif /* __ASM_SYSTEM_MISC_H */
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 05d2bd7..81039c7 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -39,6 +39,22 @@
 #include 
 #include 
 
+/*
+ * GHES SEA handler code may register a notifier call here to
+ * handle HW error record passed from platform.
+ */
+static ATOMIC_NOTIFIER_HEAD(sea_handler_chain);
+
+int register_sea_notifier(struct notifier_block *nb)
+{
+   return atomic_notifier_chain_register(&sea_handler_chain, nb);
+}
+
+void unregister_sea_notifier(struct notifier_block *nb)
+{
+   atomic_notifier_chain_unregister(&sea_handler_chain, nb);
+}
+
 static const char *fault_name(unsigned int esr);
 
 #ifdef CONFIG_KPROBES
@@ -480,6 +496,28 @@ static int do_bad(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
return 1;
 }
 
+/*
+ * This abort handler deals with Synchronous External Abort.
+ * It calls notifiers, and then returns "fault".
+ */
+static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
+{
+   struct siginfo info;
+
+   atomic_notifier_call_chain(&sea_handler_chain, 0, NULL);
+
+   pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
+fault_name(esr), esr, addr);
+
+   info.si_signo = SIGBUS;
+   info.si_errno = 0;
+   info.si_code  = 0;
+   info.si_addr  = (void __user *)addr;
+   arm64_notify_die("", regs, &info, esr);
+
+   return 0;
+}
+
 static const struct fault_info {
int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs 
*regs);
int sig;
@@ -502,22 +540,22 @@ static const struct fault_info {
{ do_page_fault,SIGSEGV, SEGV_ACCERR,   "level 1 permission 
fault"  },
{ do_page_fault,SIGSEGV, SEGV_ACCERR,   "level 2 permission 
fault"  },
{ do_page_fault,SIGSEGV, SEGV_ACCERR,   "level 3 permission 
fault"  },
-   { do_bad,   SIGBUS,  0, "synchronous external 
abort"},
+   { do_sea,   SIGBUS,  0, "synchronous external 
abort"},
{ do_bad,   SIGBUS,  0, "unknown 17"
},
{ do_bad,   SIGBUS,  0, "unknown 18"
},
{ do_bad,   SIGBUS,  0, "unknown 19"
},
-   { do_bad,   SIGBUS,  0, "synchronous abort 
(translation table walk)" },
-   { do_bad,   SIGBUS,  0, "synchronous abort 
(translation table walk)" },
-   { do_bad,   SIGBUS,  0, "synchronous abort 
(translation table walk)" },
-   { do_bad,   SIGBUS,  0, "synchronous abort 
(translation table walk)" },
-   { do_bad,   SIGBUS,  0, "synchronous parity 
error"  },
+   { do_sea,   SIGBUS,  0, "level 0 SEA 
(translation table walk)"  },
+   { do_sea,   SIGBUS,  0, "level 1 SEA 
(translation table walk)"  },
+   { do_sea,   SIGBUS,  0, "level 2 SEA 
(translation table walk)"  },
+   { do_sea,   SIGBUS,  0, "level 3 SEA 
(translation table walk)"  },
+   { do_sea,   SIGBUS,  0, "synchronous parity or 
ECC err" },
   

[PATCH V7 01/10] acpi: apei: read ack upon ghes record consumption

2017-01-12 Thread Tyler Baicar
A RAS (Reliability, Availability, Serviceability) controller
may be a separate processor running in parallel with OS
execution, and may generate error records for consumption by
the OS. If the RAS controller produces multiple error records,
then they may be overwritten before the OS has consumed them.

The Generic Hardware Error Source (GHES) v2 structure
introduces the capability for the OS to acknowledge the
consumption of the error record generated by the RAS
controller. A RAS controller supporting GHESv2 shall wait for
the acknowledgment before writing a new error record, thus
eliminating the race condition.

Add support for parsing of GHESv2 sub-tables as well.

Signed-off-by: Tyler Baicar 
Signed-off-by: Jonathan (Zhixiong) Zhang 
Signed-off-by: Richard Ruigrok 
Signed-off-by: Naveen Kaje 
Reviewed-by: James Morse 
---
 drivers/acpi/apei/ghes.c | 49 +---
 drivers/acpi/apei/hest.c |  7 +--
 include/acpi/ghes.h  |  5 -
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 60746ef..b23160d 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -45,6 +45,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -79,6 +80,10 @@
((struct acpi_hest_generic_status *)\
 ((struct ghes_estatus_node *)(estatus_node) + 1))
 
+#define IS_HEST_TYPE_GENERIC_V2(ghes)  \
+   ((struct acpi_hest_header *)ghes->generic)->type == \
+ACPI_HEST_TYPE_GENERIC_ERROR_V2
+
 /*
  * This driver isn't really modular, however for the time being,
  * continuing to use module_param is the easiest way to remain
@@ -248,10 +253,18 @@ static struct ghes *ghes_new(struct acpi_hest_generic 
*generic)
ghes = kzalloc(sizeof(*ghes), GFP_KERNEL);
if (!ghes)
return ERR_PTR(-ENOMEM);
+
ghes->generic = generic;
+   if (IS_HEST_TYPE_GENERIC_V2(ghes)) {
+   rc = apei_map_generic_address(
+   &ghes->generic_v2->read_ack_register);
+   if (rc)
+   goto err_free;
+   }
+
rc = apei_map_generic_address(&generic->error_status_address);
if (rc)
-   goto err_free;
+   goto err_unmap_read_ack_addr;
error_block_length = generic->error_block_length;
if (error_block_length > GHES_ESTATUS_MAX_SIZE) {
pr_warning(FW_WARN GHES_PFX
@@ -263,13 +276,17 @@ static struct ghes *ghes_new(struct acpi_hest_generic 
*generic)
ghes->estatus = kmalloc(error_block_length, GFP_KERNEL);
if (!ghes->estatus) {
rc = -ENOMEM;
-   goto err_unmap;
+   goto err_unmap_status_addr;
}
 
return ghes;
 
-err_unmap:
+err_unmap_status_addr:
apei_unmap_generic_address(&generic->error_status_address);
+err_unmap_read_ack_addr:
+   if (IS_HEST_TYPE_GENERIC_V2(ghes))
+   apei_unmap_generic_address(
+   &ghes->generic_v2->read_ack_register);
 err_free:
kfree(ghes);
return ERR_PTR(rc);
@@ -279,6 +296,9 @@ static void ghes_fini(struct ghes *ghes)
 {
kfree(ghes->estatus);
apei_unmap_generic_address(&ghes->generic->error_status_address);
+   if (IS_HEST_TYPE_GENERIC_V2(ghes))
+   apei_unmap_generic_address(
+   &ghes->generic_v2->read_ack_register);
 }
 
 static inline int ghes_severity(int severity)
@@ -648,6 +668,23 @@ static void ghes_estatus_cache_add(
rcu_read_unlock();
 }
 
+static int ghes_ack_error(struct acpi_hest_generic_v2 *generic_v2)
+{
+   int rc;
+   u64 val = 0;
+
+   rc = apei_read(&val, &generic_v2->read_ack_register);
+   if (rc)
+   return rc;
+   val &= generic_v2->read_ack_preserve <<
+   generic_v2->read_ack_register.bit_offset;
+   val |= generic_v2->read_ack_write <<
+   generic_v2->read_ack_register.bit_offset;
+   rc = apei_write(val, &generic_v2->read_ack_register);
+
+   return rc;
+}
+
 static int ghes_proc(struct ghes *ghes)
 {
int rc;
@@ -660,6 +697,12 @@ static int ghes_proc(struct ghes *ghes)
ghes_estatus_cache_add(ghes->generic, ghes->estatus);
}
ghes_do_proc(ghes, ghes->estatus);
+
+   if (IS_HEST_TYPE_GENERIC_V2(ghes)) {
+   rc = ghes_ack_error(ghes->generic_v2);
+   if (rc)
+   return rc;
+   }
 out:
ghes_clear_estatus(ghes);
return 0;
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 792a0d9..ef725a9 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -52,6 +52,7 @@ static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = 
{
[ACPI_HEST_TYPE_AER_ENDPOINT] = sizeof(struct acpi_hest_aer),
[ACPI_HEST_TYPE_AER_BRIDGE] 

[PATCH V7 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1

2017-01-12 Thread Tyler Baicar
Currently when a RAS error is reported it is not timestamped.
The ACPI 6.1 spec adds the timestamp field to the generic error
data entry v3 structure. The timestamp of when the firmware
generated the error is now being reported.

Signed-off-by: Tyler Baicar 
Signed-off-by: Jonathan (Zhixiong) Zhang 
Signed-off-by: Richard Ruigrok 
Signed-off-by: Naveen Kaje 
Reviewed-by: James Morse 
---
 drivers/acpi/apei/ghes.c|  9 ---
 drivers/firmware/efi/cper.c | 63 +++--
 include/acpi/ghes.h | 22 
 3 files changed, 77 insertions(+), 17 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index b23160d..2acbc60 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -420,7 +420,8 @@ static void ghes_handle_memory_failure(struct 
acpi_hest_generic_data *gdata, int
int flags = -1;
int sec_sev = ghes_severity(gdata->error_severity);
struct cper_sec_mem_err *mem_err;
-   mem_err = (struct cper_sec_mem_err *)(gdata + 1);
+
+   mem_err = acpi_hest_generic_data_payload(gdata);
 
if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
return;
@@ -457,7 +458,8 @@ static void ghes_do_proc(struct ghes *ghes,
if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
 CPER_SEC_PLATFORM_MEM)) {
struct cper_sec_mem_err *mem_err;
-   mem_err = (struct cper_sec_mem_err *)(gdata+1);
+
+   mem_err = acpi_hest_generic_data_payload(gdata);
ghes_edac_report_mem_error(ghes, sev, mem_err);
 
arch_apei_report_mem_error(sev, mem_err);
@@ -467,7 +469,8 @@ static void ghes_do_proc(struct ghes *ghes,
else if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
  CPER_SEC_PCIE)) {
struct cper_sec_pcie *pcie_err;
-   pcie_err = (struct cper_sec_pcie *)(gdata+1);
+
+   pcie_err = acpi_hest_generic_data_payload(gdata);
if (sev == GHES_SEV_RECOVERABLE &&
sec_sev == GHES_SEV_RECOVERABLE &&
pcie_err->validation_bits & 
CPER_PCIE_VALID_DEVICE_ID &&
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index d425374..8fa4e23 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -32,6 +32,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define INDENT_SP  " "
 
@@ -386,13 +389,37 @@ static void cper_print_pcie(const char *pfx, const struct 
cper_sec_pcie *pcie,
pfx, pcie->bridge.secondary_status, pcie->bridge.control);
 }
 
+static void cper_estatus_print_section_v300(const char *pfx,
+   const struct acpi_hest_generic_data_v300 *gdata)
+{
+   __u8 hour, min, sec, day, mon, year, century, *timestamp;
+
+   if (gdata->validation_bits & ACPI_HEST_GEN_VALID_TIMESTAMP) {
+   timestamp = (__u8 *)&(gdata->time_stamp);
+   sec = bcd2bin(timestamp[0]);
+   min = bcd2bin(timestamp[1]);
+   hour = bcd2bin(timestamp[2]);
+   day = bcd2bin(timestamp[4]);
+   mon = bcd2bin(timestamp[5]);
+   year = bcd2bin(timestamp[6]);
+   century = bcd2bin(timestamp[7]);
+   printk("%stime: %7s %02d%02d-%02d-%02d %02d:%02d:%02d\n", pfx,
+   0x01 & *(timestamp + 3) ? "precise" : "", century,
+   year, mon, day, hour, min, sec);
+   }
+}
+
 static void cper_estatus_print_section(
-   const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
+   const char *pfx, struct acpi_hest_generic_data *gdata, int sec_no)
 {
uuid_le *sec_type = (uuid_le *)gdata->section_type;
__u16 severity;
char newpfx[64];
 
+   if (acpi_hest_generic_data_version(gdata) >= 3)
+   cper_estatus_print_section_v300(pfx,
+   (const struct acpi_hest_generic_data_v300 *)gdata);
+
severity = gdata->error_severity;
printk("%s""Error %d, type: %s\n", pfx, sec_no,
   cper_severity_str(severity));
@@ -403,14 +430,18 @@ static void cper_estatus_print_section(
 
snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) {
-   struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1);
+   struct cper_sec_proc_generic *proc_err;
+
+   proc_err = acpi_hest_generic_data_payload(gdata);
printk("%s""section_type: general processor error\n", newpfx);
if (gdata->error_data_length >= sizeof(*proc_err))
cper_print_proc_generic(newpfx, proc_err);
else
goto err_section_too_small;
} els

[PATCH V7 05/10] acpi: apei: handle SEA notification type for ARMv8

2017-01-12 Thread Tyler Baicar
ARM APEI extension proposal added SEA (Synchrounous External
Abort) notification type for ARMv8.
Add a new GHES error source handling function for SEA. If an error
source's notification type is SEA, then this function can be registered
into the SEA exception handler. That way GHES will parse and report
SEA exceptions when they occur.

Signed-off-by: Tyler Baicar 
Signed-off-by: Jonathan (Zhixiong) Zhang 
Signed-off-by: Naveen Kaje 
---
 arch/arm64/Kconfig|  2 ++
 drivers/acpi/apei/Kconfig | 14 
 drivers/acpi/apei/ghes.c  | 84 +++
 3 files changed, 100 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b380c87..0465601 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -53,6 +53,8 @@ config ARM64
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_ACPI_APEI if (ACPI && EFI)
+   select HAVE_ACPI_APEI_SEA if (ACPI && EFI)
+   select HAVE_NMI if HAVE_ACPI_APEI_SEA
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_BITREVERSE
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index b0140c8..3786ff1 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -4,6 +4,20 @@ config HAVE_ACPI_APEI
 config HAVE_ACPI_APEI_NMI
bool
 
+config HAVE_ACPI_APEI_SEA
+   bool "APEI Synchronous External Abort logging/recovering support"
+   depends on ARM64
+   help
+ This option should be enabled if the system supports
+ firmware first handling of SEA (Synchronous External Abort).
+ SEA happens with certain faults of data abort or instruction
+ abort synchronous exceptions on ARMv8 systems. If a system
+ supports firmware first handling of SEA, the platform analyzes
+ and handles hardware error notifications with SEA, and it may then
+ form a HW error record for the OS to parse and handle. This
+ option allows the OS to look for such HW error record, and
+ take appropriate action.
+
 config ACPI_APEI
bool "ACPI Platform Error Interface (APEI)"
select MISC_FILESYSTEMS
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 2acbc60..87efe26 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -44,12 +44,17 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 
+#ifdef CONFIG_HAVE_ACPI_APEI_SEA
+#include 
+#endif
+
 #include "apei-internal.h"
 
 #define GHES_PFX   "GHES: "
@@ -767,6 +772,62 @@ static struct notifier_block ghes_notifier_sci = {
.notifier_call = ghes_notify_sci,
 };
 
+#ifdef CONFIG_HAVE_ACPI_APEI_SEA
+static LIST_HEAD(ghes_sea);
+
+static int ghes_notify_sea(struct notifier_block *this,
+ unsigned long event, void *data)
+{
+   struct ghes *ghes;
+   int ret = NOTIFY_DONE;
+
+   nmi_enter();
+   list_for_each_entry_rcu(ghes, &ghes_sea, list) {
+   if (!ghes_proc(ghes))
+   ret = NOTIFY_OK;
+   }
+   nmi_exit();
+
+   return ret;
+}
+
+static struct notifier_block ghes_notifier_sea = {
+   .notifier_call = ghes_notify_sea,
+};
+
+static int ghes_sea_add(struct ghes *ghes)
+{
+   mutex_lock(&ghes_list_mutex);
+   if (list_empty(&ghes_sea))
+   register_sea_notifier(&ghes_notifier_sea);
+   list_add_rcu(&ghes->list, &ghes_sea);
+   mutex_unlock(&ghes_list_mutex);
+   return 0;
+}
+
+static void ghes_sea_remove(struct ghes *ghes)
+{
+   mutex_lock(&ghes_list_mutex);
+   list_del_rcu(&ghes->list);
+   if (list_empty(&ghes_sea))
+   unregister_sea_notifier(&ghes_notifier_sea);
+   mutex_unlock(&ghes_list_mutex);
+}
+#else /* CONFIG_HAVE_ACPI_APEI_SEA */
+static inline int ghes_sea_add(struct ghes *ghes)
+{
+   pr_err(GHES_PFX "ID: %d, trying to add SEA notification which is not 
supported\n",
+  ghes->generic->header.source_id);
+   return -ENOTSUPP;
+}
+
+static inline void ghes_sea_remove(struct ghes *ghes)
+{
+   pr_err(GHES_PFX "ID: %d, trying to remove SEA notification which is not 
supported\n",
+  ghes->generic->header.source_id);
+}
+#endif /* CONFIG_HAVE_ACPI_APEI_SEA */
+
 #ifdef CONFIG_HAVE_ACPI_APEI_NMI
 /*
  * printk is not safe in NMI context.  So in NMI handler, we allocate
@@ -1011,6 +1072,14 @@ static int ghes_probe(struct platform_device *ghes_dev)
case ACPI_HEST_NOTIFY_EXTERNAL:
case ACPI_HEST_NOTIFY_SCI:
break;
+   case ACPI_HEST_NOTIFY_SEA:
+   if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_SEA)) {
+   pr_warn(GHES_PFX "Generic hardware error source: %d 
notified via SEA is not supported\n",
+   generic->header.source_id);
+   rc = -ENOTSUPP;
+   goto err;
+   }

Re: [Intel-gfx] [PATCH v6] drm/i915: Use __sg_alloc_table_from_pages for userptr allocations

2017-01-12 Thread kbuild test robot
Hi Tvrtko,

[auto build test ERROR on drm-intel/for-linux-next]
[also build test ERROR on next-20170111]
[cannot apply to v4.10-rc3]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Tvrtko-Ursulin/drm-i915-Use-__sg_alloc_table_from_pages-for-userptr-allocations/20170113-004619
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: x86_64-rhel (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/i915_drv.c:48:0:
   drivers/gpu/drm/i915/i915_drv.h: In function 'i915_sg_segment_size':
>> drivers/gpu/drm/i915/i915_drv.h:2605:10: error: 'SCATTERLIST_MAX_SEGMENT' 
>> undeclared (first use in this function)
  return SCATTERLIST_MAX_SEGMENT;
 ^~~
   drivers/gpu/drm/i915/i915_drv.h:2605:10: note: each undeclared identifier is 
reported only once for each function it appears in
--
   In file included from drivers/gpu/drm/i915/i915_gem_userptr.c:27:0:
   drivers/gpu/drm/i915/i915_drv.h: In function 'i915_sg_segment_size':
>> drivers/gpu/drm/i915/i915_drv.h:2605:10: error: 'SCATTERLIST_MAX_SEGMENT' 
>> undeclared (first use in this function)
  return SCATTERLIST_MAX_SEGMENT;
 ^~~
   drivers/gpu/drm/i915/i915_drv.h:2605:10: note: each undeclared identifier is 
reported only once for each function it appears in
   drivers/gpu/drm/i915/i915_gem_userptr.c: In function 
'__i915_gem_userptr_alloc_pages':
>> drivers/gpu/drm/i915/i915_gem_userptr.c:406:8: error: implicit declaration 
>> of function '__sg_alloc_table_from_pages' 
>> [-Werror=implicit-function-declaration]
 ret = __sg_alloc_table_from_pages(st, pvec, num_pages,
   ^~~
   cc1: some warnings being treated as errors

vim +/SCATTERLIST_MAX_SEGMENT +2605 drivers/gpu/drm/i915/i915_drv.h

  2599  
  2600  static inline unsigned int i915_sg_segment_size(void)
  2601  {
  2602  unsigned int size = swiotlb_max_segment();
  2603  
  2604  if (size == 0)
> 2605  return SCATTERLIST_MAX_SEGMENT;
  2606  
  2607  size = rounddown(size, PAGE_SIZE);
  2608  /* swiotlb_max_segment_size can return 1 byte when it means one 
page. */

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


[PATCH V7 06/10] acpi: apei: panic OS with fatal error status block

2017-01-12 Thread Tyler Baicar
From: "Jonathan (Zhixiong) Zhang" 

Even if an error status block's severity is fatal, the kernel does not
honor the severity level and panic.

With the firmware first model, the platform could inform the OS about a
fatal hardware error through the non-NMI GHES notification type. The OS
should panic when a hardware error record is received with this
severity.

Call panic() after CPER data in error status block is printed if
severity is fatal, before each error section is handled.

Signed-off-by: Jonathan (Zhixiong) Zhang 
Signed-off-by: Tyler Baicar 
---
 drivers/acpi/apei/ghes.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 87efe26..4e9a20d 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -142,6 +142,8 @@ static unsigned long ghes_estatus_pool_size_request;
 static struct ghes_estatus_cache 
*ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
 static atomic_t ghes_estatus_cache_alloced;
 
+static int ghes_panic_timeout __read_mostly = 30;
+
 static int ghes_ioremap_init(void)
 {
ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES,
@@ -693,6 +695,13 @@ static int ghes_ack_error(struct acpi_hest_generic_v2 
*generic_v2)
return rc;
 }
 
+static void __ghes_call_panic(void)
+{
+   if (panic_timeout == 0)
+   panic_timeout = ghes_panic_timeout;
+   panic("Fatal hardware error!");
+}
+
 static int ghes_proc(struct ghes *ghes)
 {
int rc;
@@ -704,6 +713,10 @@ static int ghes_proc(struct ghes *ghes)
if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus))
ghes_estatus_cache_add(ghes->generic, ghes->estatus);
}
+   if (ghes_severity(ghes->estatus->error_severity) >= GHES_SEV_PANIC) {
+   __ghes_call_panic();
+   }
+
ghes_do_proc(ghes, ghes->estatus);
 
if (IS_HEST_TYPE_GENERIC_V2(ghes)) {
@@ -848,8 +861,6 @@ static atomic_t ghes_in_nmi = ATOMIC_INIT(0);
 
 static LIST_HEAD(ghes_nmi);
 
-static int ghes_panic_timeout  __read_mostly = 30;
-
 static void ghes_proc_in_irq(struct irq_work *irq_work)
 {
struct llist_node *llnode, *next;
@@ -942,9 +953,7 @@ static void __ghes_panic(struct ghes *ghes)
__ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus);
 
/* reboot to log the error! */
-   if (panic_timeout == 0)
-   panic_timeout = ghes_panic_timeout;
-   panic("Fatal hardware error!");
+   __ghes_call_panic();
 }
 
 static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



[PATCH V7 03/10] efi: parse ARM processor error

2017-01-12 Thread Tyler Baicar
Add support for ARM Common Platform Error Record (CPER).
UEFI 2.6 specification adds support for ARM specific
processor error information to be reported as part of the
CPER records. This provides more detail on for processor error logs.

Signed-off-by: Tyler Baicar 
Signed-off-by: Jonathan (Zhixiong) Zhang 
Signed-off-by: Naveen Kaje 
Reviewed-by: James Morse 
---
 drivers/firmware/efi/cper.c | 133 
 include/linux/cper.h|  54 ++
 2 files changed, 187 insertions(+)

diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 8fa4e23..c2b0a12 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -110,12 +110,15 @@ void cper_print_bits(const char *pfx, unsigned int bits,
 static const char * const proc_type_strs[] = {
"IA32/X64",
"IA64",
+   "ARM",
 };
 
 static const char * const proc_isa_strs[] = {
"IA32",
"IA64",
"X64",
+   "ARM A32/T32",
+   "ARM A64",
 };
 
 static const char * const proc_error_type_strs[] = {
@@ -139,6 +142,18 @@ static const char * const proc_flag_strs[] = {
"corrected",
 };
 
+static const char * const arm_reg_ctx_strs[] = {
+   "AArch32 general purpose registers",
+   "AArch32 EL1 context registers",
+   "AArch32 EL2 context registers",
+   "AArch32 secure context registers",
+   "AArch64 general purpose registers",
+   "AArch64 EL1 context registers",
+   "AArch64 EL2 context registers",
+   "AArch64 EL3 context registers",
+   "Misc. system register structure",
+};
+
 static void cper_print_proc_generic(const char *pfx,
const struct cper_sec_proc_generic *proc)
 {
@@ -184,6 +199,114 @@ static void cper_print_proc_generic(const char *pfx,
printk("%s""IP: 0x%016llx\n", pfx, proc->ip);
 }
 
+static void cper_print_proc_arm(const char *pfx,
+   const struct cper_sec_proc_arm *proc)
+{
+   int i, len, max_ctx_type;
+   struct cper_arm_err_info *err_info;
+   struct cper_arm_ctx_info *ctx_info;
+   char newpfx[64];
+
+   printk("%s""section length: %d\n", pfx, proc->section_length);
+   printk("%s""MIDR: 0x%016llx\n", pfx, proc->midr);
+
+   len = proc->section_length - (sizeof(*proc) +
+   proc->err_info_num * (sizeof(*err_info)));
+   if (len < 0) {
+   printk("%s""section length is too small\n", pfx);
+   printk("%s""firmware-generated error record is incorrect\n", 
pfx);
+   printk("%s""ERR_INFO_NUM is %d\n", pfx, proc->err_info_num);
+   return;
+   }
+
+   if (proc->validation_bits & CPER_ARM_VALID_MPIDR)
+   printk("%s""MPIDR: 0x%016llx\n", pfx, proc->mpidr);
+   if (proc->validation_bits & CPER_ARM_VALID_AFFINITY_LEVEL)
+   printk("%s""error affinity level: %d\n", pfx,
+   proc->affinity_level);
+   if (proc->validation_bits & CPER_ARM_VALID_RUNNING_STATE) {
+   printk("%s""running state: 0x%x\n", pfx, proc->running_state);
+   printk("%s""PSCI state: %d\n", pfx, proc->psci_state);
+   }
+
+   snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
+
+   err_info = (struct cper_arm_err_info *)(proc + 1);
+   for (i = 0; i < proc->err_info_num; i++) {
+   printk("%s""Error info structure %d:\n", pfx, i);
+   printk("%s""version:%d\n", newpfx, err_info->version);
+   printk("%s""length:%d\n", newpfx, err_info->length);
+   if (err_info->validation_bits &
+   CPER_ARM_INFO_VALID_MULTI_ERR) {
+   if (err_info->multiple_error == 0)
+   printk("%s""single error\n", newpfx);
+   else if (err_info->multiple_error == 1)
+   printk("%s""multiple errors\n", newpfx);
+   else
+   printk("%s""multiple errors count:%u\n",
+   newpfx, err_info->multiple_error);
+   }
+   if (err_info->validation_bits & CPER_ARM_INFO_VALID_FLAGS) {
+   if (err_info->flags & CPER_ARM_INFO_FLAGS_FIRST)
+   printk("%s""first error captured\n", newpfx);
+   if (err_info->flags & CPER_ARM_INFO_FLAGS_LAST)
+   printk("%s""last error captured\n", newpfx);
+   if (err_info->flags & CPER_ARM_INFO_FLAGS_PROPAGATED)
+   printk("%s""propagated error captured\n",
+  newpfx);
+   if (err_info->flags & CPER_ARM_INFO_FLAGS_OVERFLOW)
+   printk("%s""overflow occurred, error info is 
incomplete\n",
+  newpfx);
+   }
+   pr

Re: [PATCH] Input: silead: use msleep() for long delays

2017-01-12 Thread Dmitry Torokhov
On Thu, Jan 12, 2017 at 9:46 AM, Hans de Goede  wrote:
> Hi,
>
> On 01/12/2017 05:21 PM, Nicholas Mc Guire wrote:
>>
>> the delays here are in the 10 to 20ms range so msleep() will do - no
>> need to burden the highres timer subsystem.
>>
>> Signed-off-by: Nicholas Mc Guire 
>> ---
>>
>> Problem found by coccinelle script
>>
>> While msleep(10) has a worst case uncertainty of 10ms (on HZ=100 systems)
>> this seems ok here as the delays are not called frequently (init and
>> reset functions)
>
>
> By the same logic, this is not much of a burden on the high-res timer
> subsys though.
>
>> and the uncertainty of 10ms fits the permitted range of
>> the original usleep_ranges().
>
>
> Either way this patch is fine with me.

I'd rather not because next will come a checkpatch warrior and I will
have to convince them why msleep is OK here. And another one, and
another one... :(

Thanks.

-- 
Dmitry


[PATCH V7 09/10] trace, ras: add ARM processor error trace event

2017-01-12 Thread Tyler Baicar
Currently there are trace events for the various RAS
errors with the exception of ARM processor type errors.
Add a new trace event for such errors so that the user
will know when they occur. These trace events are
consistent with the ARM processor error section type
defined in UEFI 2.6 spec section N.2.4.4.

Signed-off-by: Tyler Baicar 
Acked-by: Steven Rostedt 
---
 drivers/acpi/apei/ghes.c|  7 ++-
 drivers/firmware/efi/cper.c |  1 +
 drivers/ras/ras.c   |  1 +
 include/ras/ras_event.h | 34 ++
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index a32c1b1..324a032 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -518,7 +518,12 @@ static void ghes_do_proc(struct ghes *ghes,
 
}
 #endif
-   else {
+   else if (!uuid_le_cmp(sec_type, CPER_SEC_PROC_ARM)) {
+   struct cper_sec_proc_arm *arm_err;
+
+   arm_err = acpi_hest_generic_data_payload(gdata);
+   trace_arm_event(arm_err);
+   } else {
void *unknown_err = 
acpi_hest_generic_data_payload(gdata);
trace_unknown_sec_event(&sec_type,
fru_id, fru_text, sec_sev,
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 48cb8ee..0ec678e 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define INDENT_SP  " "
 
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index fb2500b..8ba5a94 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -28,3 +28,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
 #endif
 EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
 EXPORT_TRACEPOINT_SYMBOL_GPL(unknown_sec_event);
+EXPORT_TRACEPOINT_SYMBOL_GPL(arm_event);
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
index 5861b6f..b36db48 100644
--- a/include/ras/ras_event.h
+++ b/include/ras/ras_event.h
@@ -162,6 +162,40 @@ TRACE_EVENT(mc_event,
 );
 
 /*
+ * ARM Processor Events Report
+ *
+ * This event is generated when hardware detects an ARM processor error
+ * has occurred. UEFI 2.6 spec section N.2.4.4.
+ */
+TRACE_EVENT(arm_event,
+
+   TP_PROTO(const struct cper_sec_proc_arm *proc),
+
+   TP_ARGS(proc),
+
+   TP_STRUCT__entry(
+   __field(u64, mpidr)
+   __field(u64, midr)
+   __field(u32, running_state)
+   __field(u32, psci_state)
+   __field(u8, affinity)
+   ),
+
+   TP_fast_assign(
+   __entry->affinity = proc->affinity_level;
+   __entry->mpidr = proc->mpidr;
+   __entry->midr = proc->midr;
+   __entry->running_state = proc->running_state;
+   __entry->psci_state = proc->psci_state;
+   ),
+
+   TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; "
+ "running state: %d; PSCI state: %d",
+ __entry->affinity, __entry->mpidr, __entry->midr,
+ __entry->running_state, __entry->psci_state)
+);
+
+/*
  * Unknown Section Report
  *
  * This event is generated when hardware detected a hardware
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



Re: [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks

2017-01-12 Thread Jarkko Sakkinen
On Thu, Jan 12, 2017 at 11:58:10AM -0500, Nayna Jain wrote:
> The current TPM 2.0 device driver extends only the SHA1 PCR bank
> but the TCG Specification[1] recommends extending all active PCR
> banks, to prevent malicious users from setting unused PCR banks with
> fake measurements and quoting them.
> 
> The existing in-kernel interface(tpm_pcr_extend()) expects only a
> SHA1 digest.  To extend all active PCR banks with differing
> digest sizes, the SHA1 digest is padded with trailing 0's as needed.
> 
> [1] TPM 2.0 Specification referred here is "TCG PC Client Specific
> Platform Firmware Profile for TPM 2.0"
> 
> Signed-off-by: Nayna Jain 
> ---
>  drivers/char/tpm/Kconfig |  1 +
>  drivers/char/tpm/tpm-interface.c | 16 +-
>  drivers/char/tpm/tpm.h   |  3 +-
>  drivers/char/tpm/tpm2-cmd.c  | 68 
> +++-
>  drivers/char/tpm/tpm_eventlog.h  | 18 +++
>  5 files changed, 75 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> index 277186d..af985cc 100644
> --- a/drivers/char/tpm/Kconfig
> +++ b/drivers/char/tpm/Kconfig
> @@ -6,6 +6,7 @@ menuconfig TCG_TPM
>   tristate "TPM Hardware Support"
>   depends on HAS_IOMEM
>   select SECURITYFS
> + select CRYPTO_HASH_INFO

In the commit message you did not mention this.

>   ---help---
> If you have a TPM security chip in your system, which
> implements the Trusted Computing Group's specification,
> diff --git a/drivers/char/tpm/tpm-interface.c 
> b/drivers/char/tpm/tpm-interface.c
> index fecdd3f..e037dd2 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -7,6 +7,7 @@
>   * Dave Safford 
>   * Reiner Sailer 
>   * Kylene Hall 
> + * Nayna Jain 

Remove.

>   *
>   * Maintained by: 
>   *
> @@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = {
>  int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>  {
>   struct tpm_cmd_t cmd;
> + int i;
>   int rc;
>   struct tpm_chip *chip;
>  
> @@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 
> *hash)
>   return -ENODEV;
>  
>   if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> - rc = tpm2_pcr_extend(chip, pcr_idx, hash);
> + struct tpml_digest_values d_values;
> +
> + memset(&d_values, 0, sizeof(d_values));
> +
> + for (i = 0; (chip->active_banks[i] != 0) &&
> +  (i < ARRAY_SIZE(chip->active_banks)); i++) {
> + d_values.digests[i].alg_id = chip->active_banks[i];
> + memcpy(d_values.digests[i].digest, hash,
> +TPM_DIGEST_SIZE);
> + d_values.count++;
> + }
> +
> + rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
>   tpm_put_ops(chip);
>   return rc;
>   }
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 573..dd82d58 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
>  #endif
>  
>  int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> + struct tpml_digest_values *digests);
>  int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
>  int tpm2_seal_trusted(struct tpm_chip *chip,
> struct trusted_key_payload *payload,
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index 87388921..5027a54 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in {
>   __be32  pcr_idx;
>   __be32  auth_area_size;
>   struct tpm2_null_auth_area  auth_area;
> - __be32  digest_cnt;
> - __be16  hash_alg;
> - u8  digest[TPM_DIGEST_SIZE];
> + struct tpml_digest_values   digests;
>  } __packed;
>  
>  struct tpm2_get_tpm_pt_in {
> @@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, 
> u8 *res_buf)
>   return rc;
>  }
>  
> -#define TPM2_GET_PCREXTEND_IN_SIZE \
> - (sizeof(struct tpm_input_header) + \
> -  sizeof(struct tpm2_pcr_extend_in))
> -
> -static const struct tpm_input_header tpm2_pcrextend_header = {
> - .tag = cpu_to_be16(TPM2_ST_SESSIONS),
> - .length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
> - .ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
> -};
> -
>  /**
>   * tpm2_pcr_extend() - extend a PCR value
>   *
>   * @chip:TPM chip to use.
>   * @pcr_idx: index of the PCR.
> - * @hash:hash value to use for the extend operation.
> + * @digests: list of p

[PATCH V7 10/10] arm/arm64: KVM: add guest SEA support

2017-01-12 Thread Tyler Baicar
Currently external aborts are unsupported by the guest abort
handling. Add handling for SEAs so that the host kernel reports
SEAs which occur in the guest kernel.

Signed-off-by: Tyler Baicar 
---
 arch/arm/include/asm/kvm_arm.h   |  1 +
 arch/arm/include/asm/system_misc.h   |  5 +
 arch/arm/kvm/mmu.c   | 18 --
 arch/arm64/include/asm/kvm_arm.h |  1 +
 arch/arm64/include/asm/system_misc.h |  2 ++
 arch/arm64/mm/fault.c| 13 +
 6 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
index e22089f..33a77509 100644
--- a/arch/arm/include/asm/kvm_arm.h
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -187,6 +187,7 @@
 #define FSC_FAULT  (0x04)
 #define FSC_ACCESS (0x08)
 #define FSC_PERM   (0x0c)
+#define FSC_EXTABT (0x10)
 
 /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
 #define HPFAR_MASK (~0xf)
diff --git a/arch/arm/include/asm/system_misc.h 
b/arch/arm/include/asm/system_misc.h
index a3d61ad..ea45d94 100644
--- a/arch/arm/include/asm/system_misc.h
+++ b/arch/arm/include/asm/system_misc.h
@@ -24,4 +24,9 @@ extern unsigned int user_debug;
 
 #endif /* !__ASSEMBLY__ */
 
+static inline int handle_guest_sea(unsigned long addr, unsigned int esr)
+{
+   return -1;
+}
+
 #endif /* __ASM_ARM_SYSTEM_MISC_H */
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index e9a5c0e..1152966 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "trace.h"
 
@@ -1441,8 +1442,21 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
 
/* Check the stage-2 fault is trans. fault or write fault */
fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
-   if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
-   fault_status != FSC_ACCESS) {
+
+   /* The host kernel will handle the synchronous external abort. There
+* is no need to pass the error into the guest.
+*/
+   if (fault_status == FSC_EXTABT) {
+   if(handle_guest_sea((unsigned long)fault_ipa,
+   kvm_vcpu_get_hsr(vcpu))) {
+   kvm_err("Failed to handle guest SEA, FSC: EC=%#x 
xFSC=%#lx ESR_EL2=%#lx\n",
+   kvm_vcpu_trap_get_class(vcpu),
+   (unsigned long)kvm_vcpu_trap_get_fault(vcpu),
+   (unsigned long)kvm_vcpu_get_hsr(vcpu));
+   return -EFAULT;
+   }
+   } else if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
+  fault_status != FSC_ACCESS) {
kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
kvm_vcpu_trap_get_class(vcpu),
(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 4b5c977..be0efb6 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -201,6 +201,7 @@
 #define FSC_FAULT  ESR_ELx_FSC_FAULT
 #define FSC_ACCESS ESR_ELx_FSC_ACCESS
 #define FSC_PERM   ESR_ELx_FSC_PERM
+#define FSC_EXTABT ESR_ELx_FSC_EXTABT
 
 /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
 #define HPFAR_MASK (~UL(0xf))
diff --git a/arch/arm64/include/asm/system_misc.h 
b/arch/arm64/include/asm/system_misc.h
index e7f3440..27816cb 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -77,4 +77,6 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, 
const char *cmd);
 int register_sea_notifier(struct notifier_block *nb);
 void unregister_sea_notifier(struct notifier_block *nb);
 
+int handle_guest_sea(unsigned long addr, unsigned int esr);
+
 #endif /* __ASM_SYSTEM_MISC_H */
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 81039c7..fa8d4d7 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -597,6 +597,19 @@ static const char *fault_name(unsigned int esr)
 }
 
 /*
+ * Handle Synchronous External Aborts that occur in a guest kernel.
+ */
+int handle_guest_sea(unsigned long addr, unsigned int esr)
+{
+   atomic_notifier_call_chain(&sea_handler_chain, 0, NULL);
+
+   pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
+   fault_name(esr), esr, addr);
+
+   return 0;
+}
+
+/*
  * Dispatch a data abort to the relevant handler.
  */
 asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



[PATCH V7 08/10] ras: acpi / apei: generate trace event for unrecognized CPER section

2017-01-12 Thread Tyler Baicar
UEFI spec allows for non-standard section in Common Platform Error
Record. This is defined in section N.2.3 of UEFI version 2.5.

Currently if the CPER section's type (UUID) does not match with
any section type that the kernel knows how to parse, trace event
is not generated for such section. And thus user is not able to know
happening of such hardware error, including error record of
non-standard section.

This commit generates a trace event which contains raw error data
for unrecognized CPER section.

Signed-off-by: Tyler Baicar 
Signed-off-by: Jonathan (Zhixiong) Zhang 
---
 drivers/acpi/apei/ghes.c | 22 --
 drivers/ras/ras.c|  1 +
 include/ras/ras_event.h  | 45 +
 3 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 4e9a20d..a32c1b1 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -45,11 +45,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_HAVE_ACPI_APEI_SEA
 #include 
@@ -458,11 +460,21 @@ static void ghes_do_proc(struct ghes *ghes,
 {
int sev, sec_sev;
struct acpi_hest_generic_data *gdata;
+   uuid_le sec_type;
+   uuid_le *fru_id = &NULL_UUID_LE;
+   char *fru_text = "";
 
sev = ghes_severity(estatus->error_severity);
apei_estatus_for_each_section(estatus, gdata) {
sec_sev = ghes_severity(gdata->error_severity);
-   if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
+   sec_type = *(uuid_le *)gdata->section_type;
+
+   if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
+   fru_id = (uuid_le *)gdata->fru_id;
+   if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
+   fru_text = gdata->fru_text;
+
+   if (!uuid_le_cmp(sec_type,
 CPER_SEC_PLATFORM_MEM)) {
struct cper_sec_mem_err *mem_err;
 
@@ -473,7 +485,7 @@ static void ghes_do_proc(struct ghes *ghes,
ghes_handle_memory_failure(gdata, sev);
}
 #ifdef CONFIG_ACPI_APEI_PCIEAER
-   else if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
+   else if (!uuid_le_cmp(sec_type,
  CPER_SEC_PCIE)) {
struct cper_sec_pcie *pcie_err;
 
@@ -506,6 +518,12 @@ static void ghes_do_proc(struct ghes *ghes,
 
}
 #endif
+   else {
+   void *unknown_err = 
acpi_hest_generic_data_payload(gdata);
+   trace_unknown_sec_event(&sec_type,
+   fru_id, fru_text, sec_sev,
+   unknown_err, gdata->error_data_length);
+   }
}
 }
 
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index b67dd36..fb2500b 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -27,3 +27,4 @@ subsys_initcall(ras_init);
 EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
 #endif
 EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
+EXPORT_TRACEPOINT_SYMBOL_GPL(unknown_sec_event);
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
index 1791a12..5861b6f 100644
--- a/include/ras/ras_event.h
+++ b/include/ras/ras_event.h
@@ -162,6 +162,51 @@ TRACE_EVENT(mc_event,
 );
 
 /*
+ * Unknown Section Report
+ *
+ * This event is generated when hardware detected a hardware
+ * error event, which may be of non-standard section as defined
+ * in UEFI spec appendix "Common Platform Error Record", or may
+ * be of sections for which TRACE_EVENT is not defined.
+ *
+ */
+TRACE_EVENT(unknown_sec_event,
+
+   TP_PROTO(const uuid_le *sec_type,
+const uuid_le *fru_id,
+const char *fru_text,
+const u8 sev,
+const u8 *err,
+const u32 len),
+
+   TP_ARGS(sec_type, fru_id, fru_text, sev, err, len),
+
+   TP_STRUCT__entry(
+   __array(char, sec_type, 16)
+   __array(char, fru_id, 16)
+   __string(fru_text, fru_text)
+   __field(u8, sev)
+   __field(u32, len)
+   __dynamic_array(u8, buf, len)
+   ),
+
+   TP_fast_assign(
+   memcpy(__entry->sec_type, sec_type, sizeof(uuid_le));
+   memcpy(__entry->fru_id, fru_id, sizeof(uuid_le));
+   __assign_str(fru_text, fru_text);
+   __entry->sev = sev;
+   __entry->len = len;
+   memcpy(__get_dynamic_array(buf), err, len);
+   ),
+
+   TP_printk("severity: %d; sec type:%pU; FRU: %pU %s; data len:%d; raw 
data:%s",
+ __entry->sev, __entry->sec_type,
+ __entry->fru_id, __get_str(fru_text),
+ __entry->len,
+ __print_hex(__get_dynamic_array(buf), __entry->len))
+

[PATCH V7 07/10] efi: print unrecognized CPER section

2017-01-12 Thread Tyler Baicar
UEFI spec allows for non-standard section in Common Platform Error
Record. This is defined in section N.2.3 of UEFI version 2.5.

Currently if the CPER section's type (UUID) does not match with
one of the section types that the kernel knows how to parse, the
section is skipped. Therefore, user is not able to see
such CPER data, for instance, error record of non-standard section.

For above mentioned case, this change prints out the raw data in
hex in dmesg buffer. Data length is taken from Error Data length
field of Generic Error Data Entry.

Following is a sample output from dmesg:
[  115.771702] {1}[Hardware Error]: Hardware error from APEI Generic Hardware 
Error Source: 2
[  115.779042] {1}[Hardware Error]: It has been corrected by h/w and requires 
no further action
[  115.787456] {1}[Hardware Error]: event severity: corrected
[  115.792927] {1}[Hardware Error]:  Error 0, type: corrected
[  115.798415] {1}[Hardware Error]:  fru_id: 
----
[  115.805596] {1}[Hardware Error]:  fru_text:
[  115.816105] {1}[Hardware Error]:  section type: 
d2e2621c-f936-468d-0d84-15a4ed015c8b
[  115.823880] {1}[Hardware Error]:  section length: 88
[  115.828779] {1}[Hardware Error]:   : 0101 0002 5f434345 
525f4543
[  115.836153] {1}[Hardware Error]:   0010: 574d   

[  115.843531] {1}[Hardware Error]:   0020:    

[  115.850908] {1}[Hardware Error]:   0030:    

[  115.858288] {1}[Hardware Error]:   0040: fe80  0004 
5f434345
[  115.865665] {1}[Hardware Error]:   0050: 525f4543 574d

Signed-off-by: Tyler Baicar 
Signed-off-by: Jonathan (Zhixiong) Zhang 
---
 drivers/firmware/efi/cper.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index c2b0a12..48cb8ee 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -591,8 +591,16 @@ static void cper_estatus_print_section(
cper_print_proc_arm(newpfx, arm_err);
else
goto err_section_too_small;
-   } else
-   printk("%s""section type: unknown, %pUl\n", newpfx, sec_type);
+   } else {
+   const void *unknown_err;
+
+   unknown_err = acpi_hest_generic_data_payload(gdata);
+   printk("%ssection type: %pUl\n", newpfx, sec_type);
+   printk("%ssection length: %d\n", newpfx,
+  gdata->error_data_length);
+   print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4,
+  unknown_err, gdata->error_data_length, 0);
+   }
 
return;
 
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



Re: [PATCH] ASoC: sunxi: Add bindings for sun8i to SPDIF

2017-01-12 Thread Maxime Ripard
On Thu, Jan 12, 2017 at 06:33:43PM +0100, codekip...@gmail.com wrote:
> From: Marcus Cooper 
> 
> The H3 SoC uses the same SPDIF block as found in earlier SoCs, but the
> transmit fifo is at a different address.
> 
> Signed-off-by: Marcus Cooper 

Acked-by: Maxime Ripard 

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active PCR banks

2017-01-12 Thread Jarkko Sakkinen
On Thu, Jan 12, 2017 at 11:58:09AM -0500, Nayna Jain wrote:
> This patch implements the TPM 2.0 capability TPM_CAP_PCRS to
> retrieve the active PCR banks from the TPM. This is needed
> to enable extending all active banks as recommended by TPM 2.0
> TCG Specification.
> 
> Signed-off-by: Nayna Jain 
> ---
>  drivers/char/tpm/tpm.h  |  4 +++
>  drivers/char/tpm/tpm2-cmd.c | 59 
> +
>  2 files changed, 63 insertions(+)
> 
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 1ae9768..573 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -127,6 +127,7 @@ enum tpm2_permanent_handles {
>  };
>  
>  enum tpm2_capabilities {
> + TPM2_CAP_PCRS   = 5,
>   TPM2_CAP_TPM_PROPERTIES = 6,
>  };
>  
> @@ -187,6 +188,8 @@ struct tpm_chip {
>  
>   const struct attribute_group *groups[3];
>   unsigned int groups_cnt;
> +
> + u16 active_banks[7];
>  #ifdef CONFIG_ACPI
>   acpi_handle acpi_dev_handle;
>   char ppi_version[TPM_PPI_VERSION_LEN + 1];
> @@ -545,4 +548,5 @@ int tpm2_auto_startup(struct tpm_chip *chip);
>  void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
>  unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
>  int tpm2_probe(struct tpm_chip *chip);
> +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
>  #endif
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index 6eda239..87388921 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -83,6 +83,12 @@ struct tpm2_get_tpm_pt_out {
>   __be32  value;
>  } __packed;
>  
> +struct tpm2_tpms_pcr_selection {
> + __be16  hash_alg;
> + u8  size_of_select;
> + u8  pcr_select[3];
> +} __packed;

Please move this right before tpm2_get_pcr_allocation.
Drop 'tpms_'.

> +
>  struct tpm2_get_random_in {
>   __be16  size;
>  } __packed;
> @@ -993,8 +999,61 @@ int tpm2_auto_startup(struct tpm_chip *chip)
>   }
>   }
>  
> + rc = tpm2_get_pcr_allocation(chip);
> +

Please have this call in the commit where you actually use it
Does not make any sense here

>  out:
>   if (rc > 0)
>   rc = -ENODEV;
>   return rc;
>  }
> +
> +/**
> + * tpm2_get_pcr_allocation() - get TPM active PCR banks.
> + *
> + * @chip: TPM chip to use.
> + *
> + * Return: Same as with tpm_transmit_cmd.
> + */
> +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
> +{
> + struct tpm2_tpms_pcr_selection pcr_selection;
> + struct tpm_buf buf;
> + void *marker;
> + unsigned int count = 0;
> + int rc;
> + int i;
> +
> + rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
> + if (rc)
> + return rc;
> +
> + tpm_buf_append_u32(&buf, TPM2_CAP_PCRS);
> + tpm_buf_append_u32(&buf, 0);
> + tpm_buf_append_u32(&buf, 1);
> +
> + rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0,
> +   "get tpm pcr allocation");
> + if (rc < 0)
> + goto out;
> +
> + count = be32_to_cpup(
> + (__be32 *) &buf.data[TPM_HEADER_SIZE + 5]);

Please do not add a space after cast. This has been an issue in your
previous patches too so try to do it right next time.

> +
> + if (count > ARRAY_SIZE(chip->active_banks))
> + return -ENODEV;
> +
> + marker = &buf.data[TPM_HEADER_SIZE + 9];
> + for (i = 0; i < count; i++) {
> + memcpy(&pcr_selection, marker, sizeof(pcr_selection));
> + chip->active_banks[i] = be16_to_cpu(pcr_selection.hash_alg);
> + marker = marker + sizeof(struct tpm2_tpms_pcr_selection);
> + }
> +
> +out:
> + if (count < ARRAY_SIZE(chip->active_banks))
> + chip->active_banks[count] = 0;
> +
> + tpm_buf_destroy(&buf);
> +
> + return rc;
> +}
> -- 
> 2.5.0
> 

/Jarkko


Re: sysfs deferred_probe attribute

2017-01-12 Thread Ben Hutchings
On Thu, 2017-01-12 at 18:41 +0100, Greg Kroah-Hartman wrote:
> On Thu, Jan 12, 2017 at 11:27:01AM -0600, Rob Herring wrote:
> > I just noticed that we have a new device attribute 'deferred_probe'
> > added in 4.10 with this commit:
> > 
> > commit 6751667a29d6fd64afb9ce30567ad616b68ed789
> > Author: Ben Hutchings 
> > Date:   Tue Aug 16 14:34:18 2016 +0100
> > 
> > driver core: Add deferred_probe attribute to devices in sysfs
> > 
> > It is sometimes useful to know that a device is on the deferred probe
> > list rather than, say, not having a driver available.  Expose this
> > information to user-space.
> > 
> > Signed-off-by: Ben Hutchings 
> > Signed-off-by: Greg Kroah-Hartman 
> > 
> > 
> > It seems like a bad idea to add an ABI for an internal kernel feature.
> > When/if we replace deferred probe with something better based on
> > functional dependencies are we going to keep this attr around? Or
> > remove it and assume no userspace uses it?

It should be removed then (and replaced with some kind of representation
of dependencies).

> > Perhaps it should be hidden
> > behind CONFIG_DEBUG or just make a debugfs file that lists the
> > deferred list. Then you wouldn't have to hunt for what got deferred.
> 
> Ah, debugfs would be nice, I'd much prefer that.  I don't know how Ben
> is using this, but I think that would make more sense to me.

I'm not using it any programmatic way, and don't intend to.  debugfs
would be OK, but attaching it to devices was easy to do and seemed to
make sense.

Ben.

-- 
Ben Hutchings
Software Developer, Codethink Ltd.




Re: [PATCH v5] DAX: enable iostat for read/write

2017-01-12 Thread Kani, Toshimitsu
On Thu, 2017-01-12 at 10:02 -0800, Joe Perches wrote:
> On Thu, 2017-01-12 at 11:38 -0700, Toshi Kani wrote:
> > DAX IO path does not support iostat, but its metadata IO path does.
> > Therefore, iostat shows metadata IO statistics only, which has been
> > confusing to users.
> 
> []
> > diff --git a/fs/dax.c b/fs/dax.c
> 
> []
> > @@ -1058,12 +1058,24 @@ dax_iomap_rw(struct kiocb *iocb, struct
> > iov_iter *iter,
> >  {
> >     struct address_space *mapping = iocb->ki_filp->f_mapping;
> >     struct inode *inode = mapping->host;
> > +   struct gendisk *disk = inode->i_sb->s_bdev->bd_disk;
> >     loff_t pos = iocb->ki_pos, ret = 0, done = 0;
> >     unsigned flags = 0;
> > +   unsigned long start = 0;
> > +   int do_acct = blk_queue_io_stat(disk->queue);
> >  
> >     if (iov_iter_rw(iter) == WRITE)
> >     flags |= IOMAP_WRITE;
> >  
> > +   if (do_acct) {
> > +   sector_t sec = iov_iter_count(iter) >> 9;
> > +
> > +   start = jiffies;
> > +   generic_start_io_acct(iov_iter_rw(iter),
> > +     min_t(unsigned long, 1,
> > sec),
> 
> I believe I mislead you with a thinko.
> 
> Your original code was
>   (!sec) ? 1 : sec
> and I suggested incorrectly using min_t
> 
> It should of course be max_t.  Sorry.

My bad. I should have caught it.

> Also, as sec is now sector_t (u64), perhaps this
> unsigned long cast is incorrect.

I see. Since iov_iter_count() returns a size_t value, I will use
'size_t' for 'sec' as you originally suggested. 

Thanks,
-Toshi


Re: [PATCH 01/18] Drivers: hv: vmbus: Move the definition of hv_x64_msr_hypercall_contents

2017-01-12 Thread Stephen Hemminger
On Thu, 12 Jan 2017 02:32:24 +
KY Srinivasan  wrote:

> > -Original Message-
> > From: Greg KH [mailto:gre...@linuxfoundation.org]
> > Sent: Tuesday, January 10, 2017 9:27 AM
> > To: KY Srinivasan 
> > Cc: linux-kernel@vger.kernel.org; de...@linuxdriverproject.org;
> > o...@aepfle.de; a...@canonical.com; vkuzn...@redhat.com;
> > jasow...@redhat.com; leann.ogasaw...@canonical.com;
> > rka...@virtuozzo.com; x...@kernel.org; t...@linutronix.de; h...@zytor.com
> > Subject: Re: [PATCH 01/18] Drivers: hv: vmbus: Move the definition of
> > hv_x64_msr_hypercall_contents
> > 
> > On Fri, Dec 30, 2016 at 01:35:55PM -0800, k...@exchange.microsoft.com
> > wrote:  
> > > From: K. Y. Srinivasan 
> > >
> > > As part of the effort to separate out architecture specific code, move the
> > > definition of hv_x64_msr_hypercall_contents to x86 specific header file.
> > >
> > > Signed-off-by: K. Y. Srinivasan 
> > > ---
> > >  arch/x86/include/asm/mshyperv.h |   12 
> > >  drivers/hv/hyperv_vmbus.h   |   15 ---
> > >  2 files changed, 12 insertions(+), 15 deletions(-)  
> > 
> > This series doesn't apply against my tree.  Can you please refresh it
> > and resend?  
> 
> Will do.
> 
> K. Y

Send me the patches, I have a vmbus-next tree ready for pull request.


[PATCH v2 1/2] of: base: add support to find the level of the last cache

2017-01-12 Thread Sudeep Holla
It is useful to have helper function just to get the number of cache
levels for a given logical cpu. We can obtain the same by just checking
the level at which the last cache is present. This patch adds support
to find the level of the last cache for a given cpu.

It will be used on ARM64 platform where the device tree provides the
information for the additional non-architected/transparent/external
last level caches that are not integrated with the processors.

Suggested-by: Rob Herring 
Cc: Rob Herring 
Cc: Mark Rutland 
Signed-off-by: Sudeep Holla 
---
 drivers/of/base.c  | 27 +++
 include/linux/of.h |  1 +
 2 files changed, 28 insertions(+)

v1->v2:
- Moved to using "cache-level" in the last level cache instead
  of counting through all the nodes as suggested by Rob

diff --git a/drivers/of/base.c b/drivers/of/base.c
index d4bea3c797d6..c1128a077aea 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -2268,6 +2269,32 @@ struct device_node *of_find_next_cache_node(const struct 
device_node *np)
 }

 /**
+ * of_find_last_cache_level - Find the level at which the last cache is
+ * present for the given logical cpu
+ *
+ * @cpu: cpu number(logical index) for which the last cache level is needed
+ *
+ * Returns the the level at which the last cache is present. It is exactly
+ * same as  the total number of cache levels for the given logical cpu.
+ */
+int of_find_last_cache_level(unsigned int cpu)
+{
+   int cache_level = 0;
+   struct device_node *prev = NULL, *np = of_cpu_device_node_get(cpu);
+
+   while (np) {
+   prev = np;
+   of_node_put(np);
+   np = of_find_next_cache_node(np);
+   }
+
+   if (prev)
+   of_property_read_u32(prev, "cache-level", &cache_level);
+
+   return cache_level;
+}
+
+/**
  * of_graph_parse_endpoint() - parse common endpoint node properties
  * @node: pointer to endpoint device_node
  * @endpoint: pointer to the OF endpoint data structure
diff --git a/include/linux/of.h b/include/linux/of.h
index d72f01009297..21e6323de0f3 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -280,6 +280,7 @@ extern struct device_node *of_get_child_by_name(const 
struct device_node *node,

 /* cache lookup */
 extern struct device_node *of_find_next_cache_node(const struct device_node *);
+extern int of_find_last_cache_level(unsigned int cpu);
 extern struct device_node *of_find_node_with_property(
struct device_node *from, const char *prop_name);

--
2.7.4



Re: [PATCH] Input: egalax_ts - do not release gpio if probe successful

2017-01-12 Thread Dmitry Torokhov
Hi Gary,

On Wed, Jan 11, 2017 at 06:28:41PM +0100, Gary Bisson wrote:
> Thus preventing anyone to later modify the interrupt GPIO direction
> and/or state without the driver knowing.

I am afraid not releasing gpio after waking up the controller will cause
request_irq to fail if we are using the same pin for interrupt and
wakeup (as majority of current DTSes do: see
arch/arm/boot/dts/imx53-tx53-x13x.dts for example).

You'll need to figure out if irq is backed by the same gpio as wakeup
and act accordingly.

What setup did you test this on? Was it shared pin or dedicated wakeup?

Thanks.

> 
> Also checking if device is present before allocating the input device.
> 
> Signed-off-by: Gary Bisson 
> ---
>  drivers/input/touchscreen/egalax_ts.c | 56 
> ---
>  1 file changed, 25 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/egalax_ts.c 
> b/drivers/input/touchscreen/egalax_ts.c
> index 1afc08b08155..f6b94bb19bd8 100644
> --- a/drivers/input/touchscreen/egalax_ts.c
> +++ b/drivers/input/touchscreen/egalax_ts.c
> @@ -62,6 +62,7 @@
>  struct egalax_ts {
>   struct i2c_client   *client;
>   struct input_dev*input_dev;
> + struct gpio_desc*wakeup_gpio;
>  };
>  
>  static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
> @@ -120,36 +121,21 @@ static irqreturn_t egalax_ts_interrupt(int irq, void 
> *dev_id)
>  }
>  
>  /* wake up controller by an falling edge of interrupt gpio.  */
> -static int egalax_wake_up_device(struct i2c_client *client)
> +static int egalax_wake_up_device(struct gpio_desc *wakeup_gpio)
>  {
> - struct device_node *np = client->dev.of_node;
> - int gpio;
>   int ret;
>  
> - if (!np)
> - return -ENODEV;
> -
> - gpio = of_get_named_gpio(np, "wakeup-gpios", 0);
> - if (!gpio_is_valid(gpio))
> - return -ENODEV;
> -
> - ret = gpio_request(gpio, "egalax_irq");
> - if (ret < 0) {
> - dev_err(&client->dev,
> - "request gpio failed, cannot wake up controller: %d\n",
> - ret);
> + /* wake up controller via an falling edge on IRQ gpio. */
> + ret = gpiod_direction_output(wakeup_gpio, 0);
> + if (ret < 0)
>   return ret;
> - }
>  
> - /* wake up controller via an falling edge on IRQ gpio. */
> - gpio_direction_output(gpio, 0);
> - gpio_set_value(gpio, 1);
> + gpiod_set_value(wakeup_gpio, 1);
>  
>   /* controller should be waken up, return irq.  */
> - gpio_direction_input(gpio);
> - gpio_free(gpio);
> + ret = gpiod_direction_input(wakeup_gpio);
>  
> - return 0;
> + return ret;
>  }
>  
>  static int egalax_firmware_version(struct i2c_client *client)
> @@ -177,17 +163,15 @@ static int egalax_ts_probe(struct i2c_client *client,
>   return -ENOMEM;
>   }
>  
> - input_dev = devm_input_allocate_device(&client->dev);
> - if (!input_dev) {
> - dev_err(&client->dev, "Failed to allocate memory\n");
> - return -ENOMEM;
> + ts->wakeup_gpio = devm_gpiod_get_index(&client->dev, "wakeup",
> +0, GPIOD_ASIS);
> + if (IS_ERR(ts->wakeup_gpio)) {
> + dev_err(&client->dev, "Failed to get wakeup gpio");
> + return -ENODEV;
>   }
>  
> - ts->client = client;
> - ts->input_dev = input_dev;
> -
>   /* controller may be in sleep, wake it up. */
> - error = egalax_wake_up_device(client);
> + error = egalax_wake_up_device(ts->wakeup_gpio);
>   if (error) {
>   dev_err(&client->dev, "Failed to wake up the controller\n");
>   return error;
> @@ -199,6 +183,15 @@ static int egalax_ts_probe(struct i2c_client *client,
>   return error;
>   }
>  
> + input_dev = devm_input_allocate_device(&client->dev);
> + if (!input_dev) {
> + dev_err(&client->dev, "Failed to allocate memory\n");
> + return -ENOMEM;
> + }
> +
> + ts->client = client;
> + ts->input_dev = input_dev;
> +
>   input_dev->name = "EETI eGalax Touch Screen";
>   input_dev->id.bustype = BUS_I2C;
>  
> @@ -254,8 +247,9 @@ static int __maybe_unused egalax_ts_suspend(struct device 
> *dev)
>  static int __maybe_unused egalax_ts_resume(struct device *dev)
>  {
>   struct i2c_client *client = to_i2c_client(dev);
> + struct egalax_ts *ts = i2c_get_clientdata(client);
>  
> - return egalax_wake_up_device(client);
> + return egalax_wake_up_device(ts->wakeup_gpio);
>  }
>  
>  static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, 
> egalax_ts_resume);
> -- 
> 2.11.0
> 

-- 
Dmitry


Re: [PATCH net-next 1/4] siphash: add cryptographically secure PRF

2017-01-12 Thread Jason A. Donenfeld
On Thu, Jan 12, 2017 at 4:04 PM, Herbert Xu  wrote:
>> typedef struct {
>>u64 v[2];
>> } siphash_key_t;
>
> If it's just an 128-bit value then we have u128 in crypto/b128ops.h
> that could be generalised for this.

Nope, it's actually two 64-bit values. Yes, the user fills it in as
one blob to get_random_bytes, but it's used internally by the
algorithm as two distinct variables (which conveniently fit into
64-bit registers).


[PATCH RFC] sched/fair: unthrottle cfs_rq in FIFO order and only once per period

2017-01-12 Thread Konstantin Khlebnikov
I'm seeing live-locks on 32-core machine with 32 busy-loops running inside
cpu cgroup with limit set equal to 0.33 core (cpu.cfs_quota_us = 33000,
cpu.cfs_period_us = 10) : some threads almost never runs.

This is very nasty behavior: sometimes throttled tasks also hold kernel
locks, for example mmap_sem and block proc files for system-wide "ps ax".

This happens because throttle_cfs_rq() inserts cfs-rq into head and
unthrottle in distribute_cfs_runtime() starts from head too.
Cfs_rqs at the end might never get runtime if limits is set low enough.

Originally untrottle worked in FIFO order but commit c06f04c70489
("sched: Fix potential near-infinite distribute_cfs_runtime() loop")
switched to LIFO because distribute_cfs_runtime() could unthrottle
the same cfq-rq endlessly.

This was happened because loop around distribute_cfs_runtime() in function
do_sched_cfs_period_timer() and because cfs_b->runtime here set to zero to
prevent acquiring runtime from global pool while this loop works.
That zeroing was removed by commit mentioned above. This one removes loop.

This patch reverts unthrottling back to FIFO order and checks expiration
time during distribution: if cfs_rq already was unthrottled during this
period then its expiration is equal to currently distributed. Then we'll
skip it for now and will try to unthottle at next period.

Signed-off-by: Konstantin Khlebnikov 
Fixes: c06f04c70489 ("sched: Fix potential near-infinite 
distribute_cfs_runtime() loop")
Cc: Ben Segall 
Cc: Ingo Molnar 
Cc: Peter Zijlstra 
---
 kernel/sched/fair.c |   38 +-
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 6559d197e08a..b30412e3d7c2 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4162,10 +4162,9 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq)
empty = list_empty(&cfs_b->throttled_cfs_rq);
 
/*
-* Add to the _head_ of the list, so that an already-started
-* distribute_cfs_runtime will not see us
+* Add to the _tail_ of the list, untrottle happens in FIFO order
 */
-   list_add_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq);
+   list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq);
 
/*
 * If we're the first throttled task, make sure the bandwidth
@@ -4240,6 +4239,15 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth 
*cfs_b,
if (!cfs_rq_throttled(cfs_rq))
goto next;
 
+   /*
+* Give throttled cfs_rq 1 ns of runtime. It will take more
+* from global pool when needed. But skip cfs_rq if expiration
+* time equals to ours, this means we already untrottled it in
+* this loop and global pool is already depleted.
+*/
+   if (cfs_rq->runtime_expires == expires)
+   goto next;
+
runtime = -cfs_rq->runtime_remaining + 1;
if (runtime > remaining)
runtime = remaining;
@@ -4302,24 +4310,20 @@ static int do_sched_cfs_period_timer(struct 
cfs_bandwidth *cfs_b, int overrun)
runtime_expires = cfs_b->runtime_expires;
 
/*
-* This check is repeated as we are holding onto the new bandwidth while
-* we unthrottle. This can potentially race with an unthrottled group
-* trying to acquire new bandwidth from the global pool. This can result
-* in us over-using our runtime if it is all used during this loop, but
-* only by limited amounts in that extreme case.
+* This can potentially race with an unthrottled group trying to
+* acquire new bandwidth from the global pool. This can result
+* in us over-using our runtime if it is all used during this loop,
+* but only by limited amounts in that extreme case.
 */
-   while (throttled && cfs_b->runtime > 0) {
-   runtime = cfs_b->runtime;
-   raw_spin_unlock(&cfs_b->lock);
-   /* we can't nest cfs_b->lock while distributing bandwidth */
-   runtime = distribute_cfs_runtime(cfs_b, runtime,
-runtime_expires);
-   raw_spin_lock(&cfs_b->lock);
+   runtime = cfs_b->runtime;
 
-   throttled = !list_empty(&cfs_b->throttled_cfs_rq);
+   /* we can't nest cfs_b->lock while distributing bandwidth */
+   raw_spin_unlock(&cfs_b->lock);
+   runtime = distribute_cfs_runtime(cfs_b, runtime, runtime_expires);
+   raw_spin_lock(&cfs_b->lock);
 
+   if (runtime_expires == cfs_b->runtime_expires)
cfs_b->runtime -= min(runtime, cfs_b->runtime);
-   }
 
/*
 * While we are ensured activity in the period following an



[PATCH v2 2/2] arm64: cacheinfo: add support to override cache levels via device tree

2017-01-12 Thread Sudeep Holla
The cache hierarchy can be identified through Cache Level ID(CLIDR)
architected system register. However in some cases it will provide
only the number of cache levels that are integrated into the processor
itself. In other words, it can't provide any information about the
caches that are external and/or transparent.

Some platforms require to export the information about all such external
caches to the userspace applications via the sysfs interface.

This patch adds support to override the cache levels using device tree
to take such external non-architected caches into account.

Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Mark Rutland 
Signed-off-by: Sudeep Holla 
---
 arch/arm64/kernel/cacheinfo.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c
index 9617301f76b5..3f2250fc391b 100644
--- a/arch/arm64/kernel/cacheinfo.c
+++ b/arch/arm64/kernel/cacheinfo.c
@@ -84,7 +84,7 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,

 static int __init_cache_level(unsigned int cpu)
 {
-   unsigned int ctype, level, leaves;
+   unsigned int ctype, level, leaves, of_level;
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);

for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) {
@@ -97,6 +97,17 @@ static int __init_cache_level(unsigned int cpu)
leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1;
}

+   of_level = of_find_last_cache_level(cpu);
+   if (level < of_level) {
+   /*
+* some external caches not specified in CLIDR_EL1
+* the information may be available in the device tree
+* only unified external caches are considered here
+*/
+   leaves += (of_level - level);
+   level = of_level;
+   }
+
this_cpu_ci->num_levels = level;
this_cpu_ci->num_leaves = leaves;
return 0;
--
2.7.4



Re: [PATCH] livepatch/module: print notice of TAINT_LIVEPATCH

2017-01-12 Thread Josh Poimboeuf
On Thu, Jan 12, 2017 at 11:57:44AM -0500, Joe Lawrence wrote:
> Add back the "tainting kernel with TAINT_LIVEPATCH" kernel log message
> that commit 2992ef29ae01 ("livepatch/module: make TAINT_LIVEPATCH
> module-specific") dropped.  Now that it's a module-specific taint flag,
> include the module name.
> 
> Signed-off-by: Joe Lawrence 

Acked-by: Josh Poimboeuf 

> ---
>  kernel/module.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/kernel/module.c b/kernel/module.c
> index 5088784c0cf9..330f64e7e193 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2812,6 +2812,8 @@ static int check_modinfo_livepatch(struct module *mod, 
> struct load_info *info)
>   if (get_modinfo(info, "livepatch")) {
>   mod->klp = true;
>   add_taint_module(mod, TAINT_LIVEPATCH, LOCKDEP_STILL_OK);
> + pr_notice_once("%s: tainting kernel with TAINT_LIVEPATCH\n",
> +mod->name);
>   }
>  
>   return 0;
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe live-patching" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Josh


Re: [PATCH] partially revert "xen: Remove event channel notification through Xen PCI platform device"

2017-01-12 Thread Boris Ostrovsky
On 01/11/2017 06:36 PM, Stefano Stabellini wrote:
> The following commit:
>
> commit 72a9b186292d98494f26cfd24a1621796209
> Author: KarimAllah Ahmed 
> Date:   Fri Aug 26 23:55:36 2016 +0200
>
> xen: Remove event channel notification through Xen PCI platform device
>
> broke Linux when booting as Dom0 on Xen in a nested Xen environment (Xen
> installed inside a Xen VM). In this scenario, Linux is a PV guest, but
> at the same time it uses the platform-pci driver to receive
> notifications from L0 Xen. vector callbacks are not available because L1
> Xen doesn't allow them.

(+Konrad who has been running nested)

>
> Partially revert the offending commit, by restoring IRQ based
> notifications for PV guests only. I restored only the code which is
> strictly needed and replaced the xen_have_vector_callback checks within
> it with xen_pv_domain() checks.
>
> Signed-off-by: Stefano Stabellini 
>
> ---
> Alternatively, I could also restore the xen_have_vector_callback
> checks. In general, it's best to have feature flag checks than umbrella
> xen_pv/hvm_domain() checks.

I don't think it's worth doing given that we know that HVM we cant' run
without this feature (we have
BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector)) in xen_hvm_guest_init()).


> ---
>
> diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
> index b59c9455..1477f1d 100644
> --- a/drivers/xen/platform-pci.c
> +++ b/drivers/xen/platform-pci.c
> @@ -42,6 +42,7 @@
>  static unsigned long platform_mmio;
>  static unsigned long platform_mmio_alloc;
>  static unsigned long platform_mmiolen;
> +static uint64_t callback_via;
>  
>  static unsigned long alloc_xen_mmio(unsigned long len)
>  {
> @@ -54,6 +55,51 @@ static unsigned long alloc_xen_mmio(unsigned long len)
>   return addr;
>  }
>  
> +static uint64_t get_callback_via(struct pci_dev *pdev)
> +{
> + u8 pin;
> + int irq;
> +
> + irq = pdev->irq;
> + if (irq < 16)
> + return irq; /* ISA IRQ */
> +
> + pin = pdev->pin;
> +
> + /* We don't know the GSI. Specify the PCI INTx line instead. */
> + return ((uint64_t)0x01 << 56) | /* PCI INTx identifier */

You can use HVM_CALLBACK_VIA_TYPE_SHIFT here.

-boris


> + ((uint64_t)pci_domain_nr(pdev->bus) << 32) |
> + ((uint64_t)pdev->bus->number << 16) |
> + ((uint64_t)(pdev->devfn & 0xff) << 8) |
> + ((uint64_t)(pin - 1) & 3);
> +}
> +
>




Re: Nokia N900: mixers changed between 4.6 and 4.10, no longer can use in-call speaker

2017-01-12 Thread Pali Rohár
On Thursday 12 January 2017 19:18:26 Pavel Machek wrote:
> Hi!
> 
> In v4.10 (and probably v4.9, too) I can no longer use the in-call
> speaker. I can no longer use the wired headset, either.
> 
> v4.4 (and probably v4.6) works ok.
> 
> Any ideas? Does wired headset / in-call speaker work for you?
> 
> "Mono" and "Mono DAC" options are still there.. but something else
> changed, as alsamixer now shows way many more options (meaning they
> are shorter?) and I get complains from alsactl:
> 
> alsactl: set_control:1328: failed to obtain info for control #49 (No
> such file or directory)
> ...
> alsactl: set_control:1328: failed to obtain info for control #229 (No
> such file or directory)
> 
> 
> 
>   Pavel

Looks like there are not so much commits related to 
sound/soc/omap/rx51.c Maybe it can be one of these twos?

cb7e62256e99d285e415cf75db67558f0f8bb107
6d2de5ab4328718302c54b20222c6b1a574c3fce

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: This is a digitally signed message part.


[PATCH v3 0/2] reset: Make optional functions really optional.

2017-01-12 Thread Ramiro Oliveira
v3:
 - Improve description of changes ocurring in the patchset
 - Add 2 new return errors.

v2:
 - Make some comments more explicit
 - Add optional flag to reduce code duplication
 - Change shared flag from int to bool to match optional flag 

Up until now optional functions in the reset API were similar to the non
optional.

This patch corrects that, while maintaining compatibility with existing
drivers.

As suggested here: https://lkml.org/lkml/2016/12/14/502

Ramiro Oliveira (2):
  reset: Change shared flag from int to bool
  reset: make optional functions really optional

 drivers/reset/core.c  | 63 +++
 include/linux/reset.h | 45 
 2 files changed, 75 insertions(+), 33 deletions(-)

-- 
2.11.0




[PATCH v3 1/2] reset: Change shared flag from int to bool

2017-01-12 Thread Ramiro Oliveira
Since the new parameter being added is going to be a bool this patch
changes the shared flag from int to bool to match the new parameter.

Signed-off-by: Ramiro Oliveira 
---
 drivers/reset/core.c  |  8 
 include/linux/reset.h | 32 
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 10368ed8fd13..272c1e4ecb5c 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -41,7 +41,7 @@ struct reset_control {
struct list_head list;
unsigned int id;
unsigned int refcnt;
-   int shared;
+   bool shared;
atomic_t deassert_count;
atomic_t triggered_count;
 };
@@ -254,7 +254,7 @@ EXPORT_SYMBOL_GPL(reset_control_status);
 
 static struct reset_control *__reset_control_get(
struct reset_controller_dev *rcdev,
-   unsigned int index, int shared)
+   unsigned int index, bool shared)
 {
struct reset_control *rstc;
 
@@ -299,7 +299,7 @@ static void __reset_control_put(struct reset_control *rstc)
 }
 
 struct reset_control *__of_reset_control_get(struct device_node *node,
-const char *id, int index, int shared)
+const char *id, int index, bool shared)
 {
struct reset_control *rstc;
struct reset_controller_dev *r, *rcdev;
@@ -379,7 +379,7 @@ static void devm_reset_control_release(struct device *dev, 
void *res)
 }
 
 struct reset_control *__devm_reset_control_get(struct device *dev,
-const char *id, int index, int shared)
+const char *id, int index, bool shared)
 {
struct reset_control **ptr, *rstc;
 
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 5daff15722d3..ec1d1fd28f5f 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -13,10 +13,10 @@ int reset_control_deassert(struct reset_control *rstc);
 int reset_control_status(struct reset_control *rstc);
 
 struct reset_control *__of_reset_control_get(struct device_node *node,
-const char *id, int index, int shared);
+const char *id, int index, bool shared);
 void reset_control_put(struct reset_control *rstc);
 struct reset_control *__devm_reset_control_get(struct device *dev,
-const char *id, int index, int shared);
+const char *id, int index, bool shared);
 
 int __must_check device_reset(struct device *dev);
 
@@ -69,14 +69,14 @@ static inline int device_reset_optional(struct device *dev)
 
 static inline struct reset_control *__of_reset_control_get(
struct device_node *node,
-   const char *id, int index, int shared)
+   const char *id, int index, bool shared)
 {
return ERR_PTR(-ENOTSUPP);
 }
 
 static inline struct reset_control *__devm_reset_control_get(
struct device *dev,
-   const char *id, int index, int shared)
+   const char *id, int index, bool shared)
 {
return ERR_PTR(-ENOTSUPP);
 }
@@ -132,19 +132,19 @@ __must_check reset_control_get_exclusive(struct device 
*dev, const char *id)
 static inline struct reset_control *reset_control_get_shared(
struct device *dev, const char *id)
 {
-   return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1);
+   return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true);
 }
 
 static inline struct reset_control *reset_control_get_optional_exclusive(
struct device *dev, const char *id)
 {
-   return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0);
+   return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false);
 }
 
 static inline struct reset_control *reset_control_get_optional_shared(
struct device *dev, const char *id)
 {
-   return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1);
+   return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true);
 }
 
 /**
@@ -185,7 +185,7 @@ static inline struct reset_control 
*of_reset_control_get_exclusive(
 static inline struct reset_control *of_reset_control_get_shared(
struct device_node *node, const char *id)
 {
-   return __of_reset_control_get(node, id, 0, 1);
+   return __of_reset_control_get(node, id, 0, true);
 }
 
 /**
@@ -202,7 +202,7 @@ static inline struct reset_control 
*of_reset_control_get_shared(
 static inline struct reset_control *of_reset_control_get_exclusive_by_index(
 

[PATCH v3 2/2] reset: make optional functions really optional

2017-01-12 Thread Ramiro Oliveira
"The *_get_optional_* functions weren't really optional so this patch
makes them really optional.

These *_get_optional_* functions will now return NULL instead of an error
if no matching reset phandle is found in the DT, and all the
reset_control_* functions now accept NULL rstc pointers.

Signed-off-by: Ramiro Oliveira 
---
 drivers/reset/core.c  | 59 ---
 include/linux/reset.h | 45 ++-
 2 files changed, 73 insertions(+), 31 deletions(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 272c1e4ecb5c..7b679b0bfef8 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -143,12 +143,18 @@ EXPORT_SYMBOL_GPL(devm_reset_controller_register);
  * a no-op.
  * Consumers must not use reset_control_(de)assert on shared reset lines when
  * reset_control_reset has been used.
+ *
+ * If rstc is NULL it is an optional reset and the function will just
+ * return 0.
  */
 int reset_control_reset(struct reset_control *rstc)
 {
int ret;
 
-   if (WARN_ON(IS_ERR_OR_NULL(rstc)))
+   if (!rstc)
+   return 0;
+
+   if (WARN_ON(IS_ERR(rstc)))
return -EINVAL;
 
if (!rstc->rcdev->ops->reset)
@@ -182,10 +188,17 @@ EXPORT_SYMBOL_GPL(reset_control_reset);
  * internal state to be reset, but must be prepared for this to happen.
  * Consumers must not use reset_control_reset on shared reset lines when
  * reset_control_(de)assert has been used.
+ * return 0.
+ *
+ * If rstc is NULL it is an optional reset and the function will just
+ * return 0.
  */
 int reset_control_assert(struct reset_control *rstc)
 {
-   if (WARN_ON(IS_ERR_OR_NULL(rstc)))
+   if (!rstc)
+   return 0;
+
+   if (WARN_ON(IS_ERR(rstc)))
return -EINVAL;
 
if (!rstc->rcdev->ops->assert)
@@ -213,10 +226,17 @@ EXPORT_SYMBOL_GPL(reset_control_assert);
  * After calling this function, the reset is guaranteed to be deasserted.
  * Consumers must not use reset_control_reset on shared reset lines when
  * reset_control_(de)assert has been used.
+ * return 0.
+ *
+ * If rstc is NULL it is an optional reset and the function will just
+ * return 0.
  */
 int reset_control_deassert(struct reset_control *rstc)
 {
-   if (WARN_ON(IS_ERR_OR_NULL(rstc)))
+   if (!rstc)
+   return 0;
+
+   if (WARN_ON(IS_ERR(rstc)))
return -EINVAL;
 
if (!rstc->rcdev->ops->deassert)
@@ -237,12 +257,15 @@ EXPORT_SYMBOL_GPL(reset_control_deassert);
 /**
  * reset_control_status - returns a negative errno if not supported, a
  * positive value if the reset line is asserted, or zero if the reset
- * line is not asserted.
+ * line is not asserted or if the desc is NULL (optional reset).
  * @rstc: reset controller
  */
 int reset_control_status(struct reset_control *rstc)
 {
-   if (WARN_ON(IS_ERR_OR_NULL(rstc)))
+   if (!rstc)
+   return 0;
+
+   if (WARN_ON(IS_ERR(rstc)))
return -EINVAL;
 
if (rstc->rcdev->ops->status)
@@ -299,7 +322,8 @@ static void __reset_control_put(struct reset_control *rstc)
 }
 
 struct reset_control *__of_reset_control_get(struct device_node *node,
-const char *id, int index, bool shared)
+const char *id, int index, bool shared,
+bool optional)
 {
struct reset_control *rstc;
struct reset_controller_dev *r, *rcdev;
@@ -313,14 +337,24 @@ struct reset_control *__of_reset_control_get(struct 
device_node *node,
if (id) {
index = of_property_match_string(node,
 "reset-names", id);
-   if (index < 0)
-   return ERR_PTR(-ENOENT);
+   if (index < 0) {
+   if (optional)
+   return NULL;
+   else
+   return (index == -EILSEQ) ?
+   ERR_PTR(index) : ERR_PTR(-ENOENT);
+   }
}
 
ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
 index, &args);
-   if (ret)
-   return ERR_PTR(ret);
+   if (ret) {
+   if (optional)
+   return NULL;
+   else
+   return (index == -EINVAL) ?
+   ERR_PTR(index) : ERR_PTR(-ENOENT);
+   }
 
mutex_lock(&reset_list_mutex);
rcdev = NULL;
@@ -379,7 +413,8 @@ static void devm_reset_control_release(struct device *dev, 
void *res)
 }
 
 struct reset_control *__devm_reset_control_get(struct device *dev,
-const char *id, int index, bool shared)
+const char *id, int index, bool shared,
+bool 

Re: master - btrfs lockdep splat

2017-01-12 Thread Liu Bo
On Thu, Jan 12, 2017 at 07:12:12PM +0100, Mike Galbraith wrote:
> Greetings,
> 
> I wanted to do some -rt testing, but seems non-rt kernels aren't
> lockdep clean with btrfs /, making -rt testing a bit premature.
> 
> (hm, 28a235931 Btrfs: fix lockdep warning on deadlock against an inode's log 
> mutex)

It's rather a false-positive lockdep warning than a real deadlock, and a
patch[1] has been queued to fix it.

[1]: https://patchwork.kernel.org/patch/9473431/

Thanks,

-liubo
>  
> [  876.622587] =
> [  876.622588] [ INFO: possible recursive locking detected ]
> [  876.622589] 4.10.0-master #36 Tainted: GE  
> [  876.622590] -
> [  876.622591] vi/3364 is trying to acquire lock:
> [  876.622592]  (&ei->log_mutex){+.+...}, at: [] 
> btrfs_log_inode+0x13c/0xbd0 [btrfs]
> [  876.622628] but task is already holding lock:
> [  876.622629]  (&ei->log_mutex){+.+...}, at: [] 
> btrfs_log_inode+0x13c/0xbd0 [btrfs]
> [  876.622641] other info that might help us debug this:
> [  876.622642]  Possible unsafe locking scenario:
> [  876.622643]CPU0
> [  876.622644]
> [  876.622644]   lock(&ei->log_mutex);
> [  876.622648]   lock(&ei->log_mutex);
> [  876.622649] *** DEADLOCK ***
> [  876.622650]  May be due to missing lock nesting notation
> [  876.622651] 3 locks held by vi/3364:
> [  876.622651]  #0:  (&sb->s_type->i_mutex_key#11){+.+.+.}, at: 
> [] btrfs_sync_file+0x154/0x480 [btrfs]
> [  876.622664]  #1:  (sb_internal){.+.+..}, at: [] 
> start_transaction+0x2a7/0x540 [btrfs]
> [  876.622674]  #2:  (&ei->log_mutex){+.+...}, at: [] 
> btrfs_log_inode+0x13c/0xbd0 [btrfs]
> [  876.622685] stack backtrace:
> [  876.622687] CPU: 3 PID: 3364 Comm: vi Tainted: GE   
> 4.10.0-master #36
> [  876.622688] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
> rel-1.8.1-0-g4adadbd-20161202_174313-build11a 04/01/2014
> [  876.622689] Call Trace:
> [  876.622698]  dump_stack+0x85/0xc9
> [  876.622704]  __lock_acquire+0x9f9/0x1550
> [  876.622715]  ? __btrfs_release_delayed_node+0x79/0x2d0 [btrfs]
> [  876.622717]  lock_acquire+0xbd/0x200
> [  876.622726]  ? btrfs_log_inode+0x13c/0xbd0 [btrfs]
> [  876.622732]  mutex_lock_nested+0x69/0x660
> [  876.622741]  ? btrfs_log_inode+0x13c/0xbd0 [btrfs]
> [  876.622750]  ? __btrfs_release_delayed_node+0x79/0x2d0 [btrfs]
> [  876.622759]  ? btrfs_commit_inode_delayed_inode+0xeb/0x130 [btrfs]
> [  876.622767]  btrfs_log_inode+0x13c/0xbd0 [btrfs]
> [  876.622771]  ? __might_sleep+0x4a/0x90
> [  876.622781]  ? btrfs_i_callback+0x20/0x20 [btrfs]
> [  876.622791]  ? free_extent_buffer+0x4b/0x90 [btrfs]
> [  876.622799]  btrfs_log_inode+0x572/0xbd0 [btrfs]
> [  876.622808]  btrfs_log_inode_parent+0x26a/0x9b0 [btrfs]
> [  876.622812]  ? dget_parent+0x77/0x170
> [  876.622821]  btrfs_log_dentry_safe+0x62/0x80 [btrfs]
> [  876.622830]  btrfs_sync_file+0x2eb/0x480 [btrfs]
> [  876.622834]  vfs_fsync_range+0x3d/0xb0
> [  876.622836]  ? trace_hardirqs_on_caller+0xf9/0x1c0
> [  876.622837]  do_fsync+0x3d/0x70
> [  876.622839]  SyS_fsync+0x10/0x20
> [  876.622840]  entry_SYSCALL_64_fastpath+0x1f/0xc2
> [  876.622842] RIP: 0033:0x7f7fbe3da290
> [  876.622843] RSP: 002b:7ffe2778f0b8 EFLAGS: 0246 ORIG_RAX: 
> 004a
> [  876.622844] RAX: ffda RBX: 0003 RCX: 
> 7f7fbe3da290
> [  876.622845] RDX: 103d RSI: 0143e5d0 RDI: 
> 0003
> [  876.622846] RBP: 01285f10 R08: 0143e5d0 R09: 
> 
> [  876.622847] R10:  R11: 0246 R12: 
> 
> [  876.622847] R13: 2000 R14: 0001 R15: 
> 012821a0
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [tpmdd-devel] [PATCH RFC v2 3/5] tpm: infrastructure for TPM spaces

2017-01-12 Thread James Bottomley
On Thu, 2017-01-12 at 19:46 +0200, Jarkko Sakkinen wrote:
> @@ -435,17 +440,23 @@ ssize_t tpm_transmit(struct tpm_chip *chip,
> const u8 *buf, size_t bufsiz,
> goto out;
> 
>  out_recv:
> -   rc = chip->ops->recv(chip, (u8 *) buf, bufsiz);
> -   if (rc < 0)
> +   len = chip->ops->recv(chip, (u8 *) buf, bufsiz);
> +   if (len < 0) {
> dev_err(&chip->dev,
> -   "tpm_transmit: tpm_recv: error %zd\n", rc);
> +   "tpm_transmit: tpm_recv: error %d\n", rc);
> +   rc = len;
> +   goto out;
> +   }
> +
> +   rc = tpm2_commit_space(chip, space, ordinal, buf, bufsiz);

I think this should be

rc = tpm2_commit_space(chip, space, ordinal, buf, len)

because tpm2_commit_space wants to know the length of the response, not
the length of the original command.

James




Re: [PATCH] f2fs: make discard command directly

2017-01-12 Thread Jaegeuk Kim
On 01/12, Christoph Hellwig wrote:
> On Wed, Jan 11, 2017 at 04:48:48PM -0800, Jaegeuk Kim wrote:
> > This can reduce the backporting efforts.
> 
> NAK.  For one that is not a valid excuse for anything, and second
> your remove respecting the granularity.

Okay, I'll try from backporting side without this. :)

Thanks,


[PATCH] firmware: qcom: scm: add a video command for state setting

2017-01-12 Thread Stanimir Varbanov
This scm call is used to change the video core state, more
specifically it is used to suspend and resume the core.

Signed-off-by: Stanimir Varbanov 
---

Removed crypto clock enabling, which is not needed.

 drivers/firmware/qcom_scm-32.c | 18 ++
 drivers/firmware/qcom_scm-64.c | 16 
 drivers/firmware/qcom_scm.c|  6 ++
 drivers/firmware/qcom_scm.h|  2 ++
 include/linux/qcom_scm.h   |  2 ++
 5 files changed, 44 insertions(+)

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index c6aeedbdcbb0..82c1d8d0d36b 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -560,3 +560,21 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool 
reset)
 
return ret ? : le32_to_cpu(out);
 }
+
+int __qcom_scm_video_set_state(struct device *dev, u32 state, u32 spare)
+{
+   struct {
+   __le32 state;
+   __le32 spare;
+   } req;
+   __le32 scm_ret = 0;
+   int ret;
+
+   req.state = cpu_to_le32(state);
+   req.spare = cpu_to_le32(spare);
+
+   ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_VIDEO_SET_STATE,
+   &req, sizeof(req), &scm_ret, sizeof(scm_ret));
+
+   return ret ? : le32_to_cpu(scm_ret);
+}
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index 4a0f5ead4fb5..68484ea2aa51 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -358,3 +358,19 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool 
reset)
 
return ret ? : res.a1;
 }
+
+int __qcom_scm_video_set_state(struct device *dev, u32 state, u32 spare)
+{
+   struct qcom_scm_desc desc = {0};
+   struct arm_smccc_res res;
+   int ret;
+
+   desc.args[0] = state;
+   desc.args[1] = spare;
+   desc.arginfo = QCOM_SCM_ARGS(2);
+
+   ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_VIDEO_SET_STATE,
+   &desc, &res);
+
+   return ret ? : res.a1;
+}
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 893f953eaccf..95d13d8e8871 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -324,6 +324,12 @@ bool qcom_scm_is_available(void)
 }
 EXPORT_SYMBOL(qcom_scm_is_available);
 
+int qcom_scm_video_set_state(u32 state, u32 spare)
+{
+   return __qcom_scm_video_set_state(__scm->dev, state, spare);
+}
+EXPORT_SYMBOL(qcom_scm_video_set_state);
+
 static int qcom_scm_probe(struct platform_device *pdev)
 {
struct qcom_scm *scm;
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index 3584b00fe7e6..4830559b2639 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -15,6 +15,8 @@
 #define QCOM_SCM_SVC_BOOT  0x1
 #define QCOM_SCM_BOOT_ADDR 0x1
 #define QCOM_SCM_BOOT_ADDR_MC  0x11
+#define QCOM_SCM_VIDEO_SET_STATE   0xa
+extern int __qcom_scm_video_set_state(struct device *dev, u32 state, u32 
spare);
 
 #define QCOM_SCM_FLAG_HLOS 0x01
 #define QCOM_SCM_FLAG_COLDBOOT_MC  0x02
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index cc32ab852fbc..2ece81a6b078 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -46,4 +46,6 @@ extern void qcom_scm_cpu_power_down(u32 flags);
 
 extern u32 qcom_scm_get_version(void);
 
+extern int qcom_scm_video_set_state(u32 state, u32 spare);
+
 #endif
-- 
2.7.4



Re: [PATCH RFC v2 5/5] tpm2: expose resource manager via a device link /dev/tpms

2017-01-12 Thread Jason Gunthorpe
On Thu, Jan 12, 2017 at 07:46:08PM +0200, Jarkko Sakkinen wrote:

>  struct tpm_chip {
> - struct device dev;
> - struct cdev cdev;
> + struct device dev, devrm;

Hum.. devrm adds a new kref but doesn't do anything with the release
function, so that is going to use after free, ie here:

>   put_device(&chip->dev);
>+  put_device(&chip->devrm);
>   return ERR_PTR(rc);

And other places.

One solution is to get_device(chip->dev) after
device_initialize(dev->rm) and add a devrm->dev.release function to
do put_device(chip->dev)

Jason


Re: [PATCH] arm64: errata: Provide macro for major and minor cpu revisions

2017-01-12 Thread Robert Richter
On 12.01.17 15:33:15, Will Deacon wrote:
> On Wed, Jan 11, 2017 at 01:11:42PM +0100, Robert Richter wrote:
> > Definition of cpu ranges are hard to read if the cpu variant is not
> > zero. Provide MIDR_CPU_FULL_REV() macro to describe the full hardware
> > revision of a cpu including variant and (minor) revision.
> > 
> > Signed-off-by: Robert Richter 
> > ---
> >  arch/arm64/include/asm/cputype.h |  3 +++
> >  arch/arm64/kernel/cpu_errata.c   | 15 +--
> >  arch/arm64/kernel/cpufeature.c   |  8 +++-
> >  3 files changed, 15 insertions(+), 11 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/cputype.h 
> > b/arch/arm64/include/asm/cputype.h
> > index 26a68ddb11c1..983e59cbdd54 100644
> > --- a/arch/arm64/include/asm/cputype.h
> > +++ b/arch/arm64/include/asm/cputype.h
> > @@ -56,6 +56,9 @@
> > (0xf<< MIDR_ARCHITECTURE_SHIFT) | \
> > ((partnum)  << MIDR_PARTNUM_SHIFT))
> >  
> > +#define MIDR_CPU_FULL_REV(var, rev) \
> > +   (((var) << MIDR_VARIANT_SHIFT) | (rev))
> 
> Minor nit, but could you rename this to MIDR_CPU_VAR_REV instead please?
> The revision field *is* the bottom 4 bits, so "full" rev doesn't really
> make a lot of sense.

Yeah, this is that I had in my first version. I wasn't sure on the
naming, so I am fine with your proposal.

Will resubmit.

Thanks,

-Robert


Re: [PATCH v2] i2c: do not enable fall back to Host Notify by default

2017-01-12 Thread Wolfram Sang
On Wed, Jan 04, 2017 at 08:57:22PM -0800, Dmitry Torokhov wrote:
> Falling back unconditionally to HostNotify as primary client's interrupt
> breaks some drivers which alter their functionality depending on whether
> interrupt is present or not, so let's introduce a board flag telling I2C
> core explicitly if we want wired interrupt or HostNotify-based one:
> I2C_CLIENT_HOST_NOTIFY.
> 
> For DT-based systems we introduce "host-notify" property that we convert
> to I2C_CLIENT_HOST_NOTIFY board flag.
> 
> Tested-by: Benjamin Tissoires 
> Signed-off-by: Dmitry Torokhov 

Applied to for-current, thanks!

How do we handle driver fixes? Shall I take them via I2C to have the
dependency clear? Or can they go seperately?



Re: [PATCH] tpm_tis: override reported C and D timeouts for Atmel 3203

2017-01-12 Thread Jason Gunthorpe
On Thu, Jan 12, 2017 at 07:08:53PM +0100, Maciej S. Szmigiero wrote:
> Since commit 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM
> access") Atmel 3203 TPM on ThinkPad X61S (TPM firmware version 13.9) no
> longer works.
> It turns out the initialization proceeds fine until we get and start using
> chip-reported timeouts - and the chip reports C and D timeouts of zero.
> 
> Since these are clearly not long enough let's add an override for them
> to TPM TIS default values, just as we do for Atmel 3204.
> A and B timeouts are set to the same values as the chip normally reports.
> 
> Signed-off-by: Maciej S. Szmigiero 

>  static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = 
> {
> + /* Atmel 3203 */
> + { 0x32031114, { (10*1000), (10*1000),
> + (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } },
>   /* Atmel 3204 */
>   { 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000),
>   (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } },

Can you also add a check for 0 timeouts in the core code and print a
FW_BUG :\

Jason


Re: [linux-sunxi] Re: [PATCH 2/5] clk: sunxi-ng: add support for V3s CCU

2017-01-12 Thread Maxime Ripard
Hi,

On Wed, Jan 11, 2017 at 11:55:16AM +0800, Icenowy Zheng wrote:
> 
> 2017年1月11日 02:10于 Maxime Ripard 写道:
> >
> > On Tue, Jan 03, 2017 at 11:16:26PM +0800, Icenowy Zheng wrote: 
> > > V3s has a similar but cut-down CCU to H3. 
> > > 
> > > Add support for it. 
> > > 
> > > Signed-off-by: Icenowy Zheng  
> >
> > It looks like there's nothing different but the clocks that you 
> > register with the H3, please just use the H3 driver. 
> 
> USB gate part is different, and many things have gone.

As far as I can see, you're only adding a few clocks, and removing a
bunch. This is definitely something that can be dealt with by simply
registering a slightly different set of clocks, like we're doing on
sun5i.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


[patch net-next] stmmac: indent an if statement

2017-01-12 Thread Dan Carpenter
The break statement should be indented one more tab.

Signed-off-by: Dan Carpenter 

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index ac32f9e..4daa8a3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -191,7 +191,7 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
for_each_child_of_node(np, plat->mdio_node) {
if (of_device_is_compatible(plat->mdio_node,
"snps,dwmac-mdio"))
-   break;
+   break;
}
}
 


[PATCH 0/4] n2rng: add support for m5/m7 rng register layout

2017-01-12 Thread Shannon Nelson
Commit c1e9b3b0eea1 ("hwrng: n2 - Attach on T5/M5, T7/M7 SPARC CPUs")
added config strings to enable the random number generator in the sparc
m5 and m7 platforms.  This worked fine for client LDoms, but not for the
primary LDom, or running on bare metal, because the actual rng hardware
layout changed and self-test would now fail, continually spewing error
messages on the console.

This patch series adds correct support for the new rng register layout,
and adds a limiter to the spewing of error messages.

Orabug: 25127795

Shannon Nelson (4):
  n2rng: limit error spewage when self-test fails
  n2rng: add device data descriptions
  n2rng: support new hardware register layout
  n2rng: update version info

 drivers/char/hw_random/n2-drv.c |  204 +--
 drivers/char/hw_random/n2rng.h  |   51 --
 2 files changed, 196 insertions(+), 59 deletions(-)



[PATCH 1/4] n2rng: limit error spewage when self-test fails

2017-01-12 Thread Shannon Nelson
If the self-test fails, it probably won't actually suddenly
start working.  Currently, this causes an endless spew of
error messages on the console and in the logs, so this patch
adds a limiter to the test.

Reported-by: Sowmini Varadhan 
Signed-off-by: Shannon Nelson 
---
 drivers/char/hw_random/n2-drv.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index 3b06c1d..102560f 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -589,6 +589,7 @@ static void n2rng_work(struct work_struct *work)
 {
struct n2rng *np = container_of(work, struct n2rng, work.work);
int err = 0;
+   static int retries = 4;
 
if (!(np->flags & N2RNG_FLAG_CONTROL)) {
err = n2rng_guest_check(np);
@@ -606,7 +607,9 @@ static void n2rng_work(struct work_struct *work)
dev_info(&np->op->dev, "RNG ready\n");
}
 
-   if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN))
+   if (--retries == 0)
+   dev_err(&np->op->dev, "Self-test retries failed, RNG not 
ready\n");
+   else if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN))
schedule_delayed_work(&np->work, HZ * 2);
 }
 
-- 
1.7.1



[PATCH 2/4] n2rng: add device data descriptions

2017-01-12 Thread Shannon Nelson
Since we're going to need to keep track of more than just one
attribute of the hardware, we'll change the use of the data field
from the match struct from a single flag to a struct pointer.
This patch adds the struct template and initial descriptions.

Signed-off-by: Shannon Nelson 
---
 drivers/char/hw_random/n2-drv.c |   47 --
 drivers/char/hw_random/n2rng.h  |   15 
 2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index 102560f..74c26c7 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -625,24 +625,23 @@ static void n2rng_driver_version(void)
 static int n2rng_probe(struct platform_device *op)
 {
const struct of_device_id *match;
-   int multi_capable;
int err = -ENOMEM;
struct n2rng *np;
 
match = of_match_device(n2rng_match, &op->dev);
if (!match)
return -EINVAL;
-   multi_capable = (match->data != NULL);
 
n2rng_driver_version();
np = devm_kzalloc(&op->dev, sizeof(*np), GFP_KERNEL);
if (!np)
goto out;
np->op = op;
+   np->data = (struct n2rng_template *)match->data;
 
INIT_DELAYED_WORK(&np->work, n2rng_work);
 
-   if (multi_capable)
+   if (np->data->multi_capable)
np->flags |= N2RNG_FLAG_MULTI;
 
err = -ENODEV;
@@ -673,8 +672,9 @@ static int n2rng_probe(struct platform_device *op)
dev_err(&op->dev, "VF RNG lacks rng-#units property\n");
goto out_hvapi_unregister;
}
-   } else
+   } else {
np->num_units = 1;
+   }
 
dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n",
 np->hvapi_major, np->hvapi_minor);
@@ -731,30 +731,61 @@ static int n2rng_remove(struct platform_device *op)
return 0;
 }
 
+static struct n2rng_template n2_template = {
+   .id = N2_n2_rng,
+   .multi_capable = 0,
+   .chip_version = 1,
+};
+
+static struct n2rng_template vf_template = {
+   .id = N2_vf_rng,
+   .multi_capable = 1,
+   .chip_version = 1,
+};
+
+static struct n2rng_template kt_template = {
+   .id = N2_kt_rng,
+   .multi_capable = 1,
+   .chip_version = 1,
+};
+
+static struct n2rng_template m4_template = {
+   .id = N2_m4_rng,
+   .multi_capable = 1,
+   .chip_version = 2,
+};
+
+static struct n2rng_template m7_template = {
+   .id = N2_m7_rng,
+   .multi_capable = 1,
+   .chip_version = 2,
+};
+
 static const struct of_device_id n2rng_match[] = {
{
.name   = "random-number-generator",
.compatible = "SUNW,n2-rng",
+   .data   = &n2_template,
},
{
.name   = "random-number-generator",
.compatible = "SUNW,vf-rng",
-   .data   = (void *) 1,
+   .data   = &vf_template,
},
{
.name   = "random-number-generator",
.compatible = "SUNW,kt-rng",
-   .data   = (void *) 1,
+   .data   = &kt_template,
},
{
.name   = "random-number-generator",
.compatible = "ORCL,m4-rng",
-   .data   = (void *) 1,
+   .data   = &m4_template,
},
{
.name   = "random-number-generator",
.compatible = "ORCL,m7-rng",
-   .data   = (void *) 1,
+   .data   = &m7_template,
},
{},
 };
diff --git a/drivers/char/hw_random/n2rng.h b/drivers/char/hw_random/n2rng.h
index f244ac8..e41e55a 100644
--- a/drivers/char/hw_random/n2rng.h
+++ b/drivers/char/hw_random/n2rng.h
@@ -60,6 +60,20 @@ extern unsigned long sun4v_rng_data_read_diag_v2(unsigned 
long data_ra,
 extern unsigned long sun4v_rng_data_read(unsigned long data_ra,
 unsigned long *tick_delta);
 
+enum n2rng_compat_id {
+   N2_n2_rng,
+   N2_vf_rng,
+   N2_kt_rng,
+   N2_m4_rng,
+   N2_m7_rng,
+};
+
+struct n2rng_template {
+   enum n2rng_compat_id id;
+   int multi_capable;
+   int chip_version;
+};
+
 struct n2rng_unit {
u64 control[HV_RNG_NUM_CONTROL];
 };
@@ -74,6 +88,7 @@ struct n2rng {
 #define N2RNG_FLAG_SHUTDOWN0x0010 /* Driver unregistering*/
 #define N2RNG_FLAG_BUFFER_VALID0x0020 /* u32 buffer holds valid 
data */
 
+   struct n2rng_template   *data;
int num_units;
struct n2rng_unit   *units;
 
-- 
1.7.1



[PATCH 3/4] n2rng: support new hardware register layout

2017-01-12 Thread Shannon Nelson
Add the new register layout constants and the requisite logic
for using them.

Signed-off-by: Shannon Nelson 
---
 drivers/char/hw_random/n2-drv.c |  144 +--
 drivers/char/hw_random/n2rng.h  |   36 +++---
 2 files changed, 134 insertions(+), 46 deletions(-)

diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index 74c26c7..f0bd5ee 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -302,26 +302,57 @@ static int n2rng_try_read_ctl(struct n2rng *np)
return n2rng_hv_err_trans(hv_err);
 }
 
-#define CONTROL_DEFAULT_BASE   \
-   ((2 << RNG_CTL_ASEL_SHIFT) |\
-(N2RNG_ACCUM_CYCLES_DEFAULT << RNG_CTL_WAIT_SHIFT) |   \
-RNG_CTL_LFSR)
-
-#define CONTROL_DEFAULT_0  \
-   (CONTROL_DEFAULT_BASE | \
-(1 << RNG_CTL_VCO_SHIFT) | \
-RNG_CTL_ES1)
-#define CONTROL_DEFAULT_1  \
-   (CONTROL_DEFAULT_BASE | \
-(2 << RNG_CTL_VCO_SHIFT) | \
-RNG_CTL_ES2)
-#define CONTROL_DEFAULT_2  \
-   (CONTROL_DEFAULT_BASE | \
-(3 << RNG_CTL_VCO_SHIFT) | \
-RNG_CTL_ES3)
-#define CONTROL_DEFAULT_3  \
-   (CONTROL_DEFAULT_BASE | \
-RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3)
+static u64 n2rng_control_default(struct n2rng *np, int ctl)
+{
+   u64 val = 0;
+
+   if (np->data->chip_version == 1) {
+   val = ((2 << RNG_v1_CTL_ASEL_SHIFT) |
+   (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_v1_CTL_WAIT_SHIFT) |
+RNG_CTL_LFSR);
+
+   switch (ctl) {
+   case 0:
+   val |= (1 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES1;
+   break;
+   case 1:
+   val |= (2 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES2;
+   break;
+   case 2:
+   val |= (3 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES3;
+   break;
+   case 3:
+   val |= RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3;
+   break;
+   default:
+   break;
+   }
+
+   } else {
+   val = ((2 << RNG_v2_CTL_ASEL_SHIFT) |
+   (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_v2_CTL_WAIT_SHIFT) |
+RNG_CTL_LFSR);
+
+   switch (ctl) {
+   case 0:
+   val |= (1 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES1;
+   break;
+   case 1:
+   val |= (2 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES2;
+   break;
+   case 2:
+   val |= (3 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES3;
+   break;
+   case 3:
+   val |= RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3;
+   break;
+   default:
+   break;
+   }
+   }
+
+   return val;
+}
 
 static void n2rng_control_swstate_init(struct n2rng *np)
 {
@@ -336,10 +367,10 @@ static void n2rng_control_swstate_init(struct n2rng *np)
for (i = 0; i < np->num_units; i++) {
struct n2rng_unit *up = &np->units[i];
 
-   up->control[0] = CONTROL_DEFAULT_0;
-   up->control[1] = CONTROL_DEFAULT_1;
-   up->control[2] = CONTROL_DEFAULT_2;
-   up->control[3] = CONTROL_DEFAULT_3;
+   up->control[0] = n2rng_control_default(np, 0);
+   up->control[1] = n2rng_control_default(np, 1);
+   up->control[2] = n2rng_control_default(np, 2);
+   up->control[3] = n2rng_control_default(np, 3);
}
 
np->hv_state = HV_RNG_STATE_UNCONFIGURED;
@@ -399,6 +430,7 @@ static int n2rng_data_read(struct hwrng *rng, u32 *data)
} else {
int err = n2rng_generic_read_data(ra);
if (!err) {
+   np->flags |= N2RNG_FLAG_BUFFER_VALID;
np->buffer = np->test_data >> 32;
*data = np->test_data & 0x;
len = 4;
@@ -487,9 +519,21 @@ static void n2rng_dump_test_buffer(struct n2rng *np)
 
 static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit)
 {
-   u64 val = SELFTEST_VAL;
+   u64 val;
int err, matches, limit;
 
+   switch (np->data->id) {
+   case N2_n2_rng:
+   case N2_vf_rng:
+   case N2_kt_rng:
+   case N2_m4_rng:  /* yes, m4 uses the old value */
+   val = RNG_v1_SELFTEST_VAL;
+   break;
+   default:
+   val = RNG_v2_SELFTEST_VAL;
+   break;
+   }
+
matches = 0;
for (limit = 0; limit < SELFTEST_LOOPS_MAX; limit++) {
matches += n2rng_test_buffer_find(np, val);
@@ -5

Re: [PATCH] tpm_tis: fix iTPM probe via probe_itpm() function

2017-01-12 Thread Jason Gunthorpe
On Thu, Jan 12, 2017 at 07:12:06PM +0100, Maciej S. Szmigiero wrote:
> probe_itpm() function is supposed to send command without an itpm flag set
> and if this fails to repeat it, this time with the itpm flag set.
> 
> However, commit 41a5e1cf1fe15 ("tpm/tpm_tis: Split tpm_tis driver into a
> core and TCG TIS compliant phy") moved the itpm flag from an "itpm"
> variable to a TPM_TIS_ITPM_POSSIBLE chip flag, so setting the
> (now function-local) itpm variable no longer had any effect.
> 
> Finally, this function-local itpm variable was removed by
> commit 56af322156dbe9 ("tpm/tpm_tis: remove unused itpm variable")
> 
> Tested only on non-iTPM TIS TPM.
> 
> Signed-off-by: Maciej S. Szmigiero 

could you also change the name of TPM_TIS_ITPM_POSSIBLE
to TPM_TIS_ITPM_WORKAROUND ?

Reviewed-by: Jason Gunthorpe 

Jason


[PATCH 4/4] n2rng: update version info

2017-01-12 Thread Shannon Nelson
Signed-off-by: Shannon Nelson 
---
 drivers/char/hw_random/n2-drv.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index f0bd5ee..31cbdbb 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -21,11 +21,11 @@
 
 #define DRV_MODULE_NAME"n2rng"
 #define PFX DRV_MODULE_NAME": "
-#define DRV_MODULE_VERSION "0.2"
-#define DRV_MODULE_RELDATE "July 27, 2011"
+#define DRV_MODULE_VERSION "0.3"
+#define DRV_MODULE_RELDATE "Jan 7, 2017"
 
 static char version[] =
-   DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+   DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
 MODULE_AUTHOR("David S. Miller (da...@davemloft.net)");
 MODULE_DESCRIPTION("Niagara2 RNG driver");
@@ -765,7 +765,7 @@ static int n2rng_probe(struct platform_device *op)
  "multi-unit-capable" : "single-unit"),
 np->num_units);
 
-   np->hwrng.name = "n2rng";
+   np->hwrng.name = DRV_MODULE_NAME;
np->hwrng.data_read = n2rng_data_read;
np->hwrng.priv = (unsigned long) np;
 
-- 
1.7.1



Re: [PATCH] Input: silead: use msleep() for long delays

2017-01-12 Thread Nicholas Mc Guire
On Thu, Jan 12, 2017 at 10:10:44AM -0800, Dmitry Torokhov wrote:
> On Thu, Jan 12, 2017 at 9:46 AM, Hans de Goede  wrote:
> > Hi,
> >
> > On 01/12/2017 05:21 PM, Nicholas Mc Guire wrote:
> >>
> >> the delays here are in the 10 to 20ms range so msleep() will do - no
> >> need to burden the highres timer subsystem.
> >>
> >> Signed-off-by: Nicholas Mc Guire 
> >> ---
> >>
> >> Problem found by coccinelle script
> >>
> >> While msleep(10) has a worst case uncertainty of 10ms (on HZ=100 systems)
> >> this seems ok here as the delays are not called frequently (init and
> >> reset functions)
> >
> >
> > By the same logic, this is not much of a burden on the high-res timer
> > subsys though.
> >
> >> and the uncertainty of 10ms fits the permitted range of
> >> the original usleep_ranges().
> >
> >
> > Either way this patch is fine with me.
> 
> I'd rather not because next will come a checkpatch warrior and I will
> have to convince them why msleep is OK here. And another one, and
> another one... :(
>
there is no checkpatch warning here - checkpatch only throws warnings
of range < 20ms if hardcoded but this is in a #define so its fine with
respect to checkpatch.

But if there are concerns with this - thats fine - its most likely not
critical - the goal is to have a consistent usage of highres timers - 
including limiting there use to the cases where its really needed.

thx!
hofrat


Re: [PATCH v3] arm64: mm: Fix NOMAP page initialization

2017-01-12 Thread Robert Richter
On 12.01.17 16:05:36, Will Deacon wrote:
> On Mon, Jan 09, 2017 at 12:53:20PM +0100, Robert Richter wrote:

> > Kernel compile times (3 runs each):
> > 
> > pfn_valid_within():
> > 
> > real6m4.088s
> > user372m57.607s
> > sys 16m55.158s
> > 
> > real6m1.532s
> > user372m48.453s
> > sys 16m50.370s
> > 
> > real6m4.061s
> > user373m18.753s
> > sys 16m57.027s
> 
> Did you reboot the machine between each build here, or only when changing
> kernel? If the latter, do you see variations in kernel build time by simply
> rebooting the same Image?

I built it in a loop on the shell, so no reboots between builds. Note
that I was building the kernel in /dev/shm to not access harddisks. I
think build times should be comparable then since there is no fs
caching.

-Robert


Re: [PATCH] scripts/spelling.txt: add some typo-words

2017-01-12 Thread Kees Cook
On Thu, Jan 12, 2017 at 3:34 AM, Jinbum Park  wrote:
> I wrote a simple script to find new typo not in spelling.txt.
> (https://github.com/jinb-park/find-linux-kernel-typo)
>
> and get following result:
>
> [ rank ]
> 63 paramaters
> 18 alignement
> 9 strucuture
> 
>
> The number means how many files include the typo.
> This patch adds these common typo.
>
> Signed-off-by: Jinbum Park 

Sounds good to me!

Acked-by: Kees Cook 

-Kees

> ---
>  scripts/spelling.txt | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/scripts/spelling.txt b/scripts/spelling.txt
> index 417ede8..201d0ed 100644
> --- a/scripts/spelling.txt
> +++ b/scripts/spelling.txt
> @@ -74,6 +74,7 @@ algoritms||algorithms
>  algorrithm||algorithm
>  algorritm||algorithm
>  aligment||alignment
> +alignement||alignment
>  allign||align
>  allocatrd||allocated
>  allocte||allocate
> @@ -752,6 +753,7 @@ pakage||package
>  pallette||palette
>  paln||plan
>  paramameters||parameters
> +paramaters||parameters
>  paramater||parameter
>  parametes||parameters
>  parametised||parametrised
> @@ -996,6 +998,7 @@ straming||streaming
>  struc||struct
>  structres||structures
>  stuct||struct
> +strucuture||structure
>  stucture||structure
>  sturcture||structure
>  subdirectoires||subdirectories
> --
> 1.9.1
>



-- 
Kees Cook
Nexus Security


Re: Linux 4.9.3

2017-01-12 Thread Greg KH
On Thu, Jan 12, 2017 at 06:14:13PM +, Chris Rankin wrote:
> Still no sign of the 4.9.3 patches on the FTP site... Oops?

Sorry, should be there now.

greg k-h


Re: [PATCH 2/3] gpio: davinci: Redesign driver to accommodate ngpios in one gpio chip

2017-01-12 Thread Grygorii Strashko



On 01/11/2017 08:00 PM, Keerthy wrote:



On Wednesday 11 January 2017 11:23 PM, Grygorii Strashko wrote:



On 01/10/2017 11:00 PM, Keerthy wrote:

The Davinci GPIO driver is implemented to work with one monolithic
Davinci GPIO platform device which may have up to Y(144) gpios.
The Davinci GPIO driver instantiates number of GPIO chips with
max 32 gpio pins per each during initialization and one IRQ domain.
So, the current GPIO's  opjects structure is:

 Davinci GPIO controller
 |-  --|
 ...|--- irq_domain (hwirq [0..143])
 |-  --|

Current driver creates one chip for every 32 GPIOs in a controller.
This was a limitation earlier now there is no need for that. Hence
redesigning the driver to create one gpio chip for all the ngpio
in the controller.

|-  --|--- irq_domain (hwirq [0..143]).

The previous discussion on this can be found here:
https://www.spinics.net/lists/linux-omap/msg132869.html


nice rework.


Thanks!





Signed-off-by: Keerthy 
---

Boot tested on Davinci platform.

 drivers/gpio/gpio-davinci.c| 127
+


[...]



 #ifdef CONFIG_OF_GPIO
-chips[i].chip.of_gpio_n_cells = 2;
-chips[i].chip.of_xlate = davinci_gpio_of_xlate;
-chips[i].chip.parent = dev;
-chips[i].chip.of_node = dev->of_node;
+chips->chip.of_gpio_n_cells = 2;
+chips->chip.of_xlate = davinci_gpio_of_xlate;


I think It's not necessary to have custom .xlate() and
it can be removed, then gpiolib will assign default one
of_gpio_simple_xlate().


Okay. Can i do that as a separate patch?


I think it's ok.






+chips->chip.parent = dev;
+chips->chip.of_node = dev->of_node;
 #endif
-spin_lock_init(&chips[i].lock);
-


[...]



 irq_set_chip_and_handler_name(irq, &gpio_irqchip,
handle_simple_irq,
 "davinci_gpio");
@@ -459,6 +468,7 @@ static int davinci_gpio_irq_setup(struct
platform_device *pdev)
 struct irq_domain*irq_domain = NULL;
 const struct of_device_id *match;
 struct irq_chip *irq_chip;
+struct davinci_gpio_irq_data *irqdata[MAX_BANKED_IRQS];


You declare irqdata as array here but it has not been used anywhere
except for assignment. Could you remove this array and MAX_BANKED_IRQS
define?


irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler,
 &chips[gpio / 32]);
 irqdata[bank]);

That is hooked as data for each bank. As there is only one controller
now and the differentiating parameters per bank is the irqdata data
structure with the registers pointer and the bank number.
This structure makes it very easy in the irq handler to identify the
register sets that need to be modified and the bank irqs.


That I understood, but why do you need array here?





Seems you can just use struct davinci_gpio_irq_data *irqdata;


why can't you use (see below):
struct davinci_gpio_irq_data *irqdata;



 gpio_get_irq_chip_cb_t gpio_get_irq_chip;

 /*
@@ -514,10 +524,8 @@ static int davinci_gpio_irq_setup(struct
platform_device *pdev)
  * IRQs, while the others use banked IRQs, would need some setup
  * tweaks to recognize hardware which can do that.
  */


[...]



@@ -567,8 +575,19 @@ static int davinci_gpio_irq_setup(struct
platform_device *pdev)
  * gpio irqs. Pass the irq bank's corresponding controller to
  * the chained irq handler.
  */
+irqdata[bank] = devm_kzalloc(&pdev->dev,
+ sizeof(struct
+davinci_gpio_irq_data),
+ GFP_KERNEL);


irqdata = devm_kzalloc(&pdev->dev,
sizeof(struct
davinci_gpio_irq_data),
 GFP_KERNEL);


+if (!irqdata[bank])
+return -ENOMEM;
+
+irqdata[bank]->regs = g;
+irqdata[bank]->bank_num = bank;
+irqdata[bank]->chip = chips;
+
 irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler,
- &chips[gpio / 32]);
+ irqdata[bank]);


 irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler,
 irqdata);


[...]

--
regards,
-grygorii


Re: [PATCH] i2c: print correct device invalid address

2017-01-12 Thread Wolfram Sang
On Fri, Jan 06, 2017 at 07:02:57PM +0800, John Garry wrote:
> In of_i2c_register_device(), when the check for
> device address validity fails we print the info.addr,
> which has not been assigned properly.
> 
> Fix this by printing the actual invalid address.
> 
> Signed-off-by: John Garry 

Applied to for-current, thanks!



[PATCH v2 03/26] treewide: Consolidate set_dma_ops() implementations

2017-01-12 Thread Bart Van Assche
Now that all set_dma_ops() implementations are identical (ignoring
BUG_ON() statements), remove the architecture specific definitions
and add a definition in .

Signed-off-by: Bart Van Assche 
Cc: Benjamin Herrenschmidt 
Cc: Chris Metcalf 
Cc: David Woodhouse 
Cc: linux-a...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linuxppc-...@lists.ozlabs.org
Cc: Paul Mackerras 
Cc: Russell King 
---
 arch/arm/include/asm/dma-mapping.h | 6 --
 arch/powerpc/include/asm/dma-mapping.h | 5 -
 arch/tile/include/asm/dma-mapping.h| 5 -
 include/linux/dma-mapping.h| 5 +
 4 files changed, 5 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/dma-mapping.h 
b/arch/arm/include/asm/dma-mapping.h
index 312f4d0564d6..c7432d647e53 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -31,12 +31,6 @@ static inline const struct dma_map_ops *get_dma_ops(struct 
device *dev)
return __generic_dma_ops(dev);
 }
 
-static inline void set_dma_ops(struct device *dev, const struct dma_map_ops 
*ops)
-{
-   BUG_ON(!dev);
-   dev->dma_ops = ops;
-}
-
 #define HAVE_ARCH_DMA_SUPPORTED 1
 extern int dma_supported(struct device *dev, u64 mask);
 
diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index 59fbd4abcbf8..8275603ba4d5 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -91,11 +91,6 @@ static inline const struct dma_map_ops *get_dma_ops(struct 
device *dev)
return dev->dma_ops;
 }
 
-static inline void set_dma_ops(struct device *dev, const struct dma_map_ops 
*ops)
-{
-   dev->dma_ops = ops;
-}
-
 /*
  * get_dma_offset()
  *
diff --git a/arch/tile/include/asm/dma-mapping.h 
b/arch/tile/include/asm/dma-mapping.h
index c0620697eaad..2562995a6ac9 100644
--- a/arch/tile/include/asm/dma-mapping.h
+++ b/arch/tile/include/asm/dma-mapping.h
@@ -59,11 +59,6 @@ static inline phys_addr_t dma_to_phys(struct device *dev, 
dma_addr_t daddr)
 
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
-static inline void set_dma_ops(struct device *dev, const struct dma_map_ops 
*ops)
-{
-   dev->dma_ops = ops;
-}
-
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t 
size)
 {
if (!dev->dma_mask)
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f1da68b82c63..e97f23e8b2d9 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -164,6 +164,11 @@ int dma_mmap_from_coherent(struct device *dev, struct 
vm_area_struct *vma,
 
 #ifdef CONFIG_HAS_DMA
 #include 
+static inline void set_dma_ops(struct device *dev,
+  const struct dma_map_ops *dma_ops)
+{
+   dev->dma_ops = dma_ops;
+}
 #else
 /*
  * Define the dma api to allow compilation but not linking of
-- 
2.11.0



[PATCH v2 00/26] IB: Optimize DMA mapping

2017-01-12 Thread Bart Van Assche
Hello Doug,

As you know there are two sets of DMA mapping operations in the Linux
kernel:
- One set of DMA mapping operations that is used by most drivers.
- Another set of DMA mapping operations that is only used by the RDMA
  drivers.
Having two sets of DMA mapping operations is not only a source of
confusion but also a source of unnecessary overhead. The DMA mapping
operations are in the hot path so it is important that the overhead
of these operations is as low as possible. Hence this patch series
that converts the RDMA code to the standard DMA mapping API and
thereby eliminates the if (dev->dma_ops) test from the hot path. An
additional benefit is that the size of HW and SW drivers that do not
use DMA is reduced by switching to dma_virt_ops.

The changes compared to version 1 of this patch series are:
- Patch "Move dma_ops from archdata into struct device" has been
  split into three patches.
- Patch "treewide: Inline ib_dma_map_*() functions" has been split
  into 15 patches (one per driver).
- A patch has been added that builds dma_noop_ops only for the
  architectures that need it.
- The new dma_virt_ops is only built if it is used by a driver.
- In these last 15 patches indentation has been adjusted to keep
  the arguments aligned with the opening parenthesis.

Bart Van Assche (26):
  treewide: Constify most dma_map_ops structures
  treewide: Move dma_ops from struct dev_archdata into struct device
  treewide: Consolidate set_dma_ops() implementations
  treewide: Consolidate get_dma_ops() implementations
  lib/dma-noop: Clarify a comment
  lib/dma-noop: Only build dma_noop_ops for m32r and s390
  lib/dma-virt: Add dma_virt_ops
  IB/hf1: Remove DMA mapping code
  IB/qib: Remove DMA mapping code
  IB: Use dma_virt_ops instead of duplicating it
  RDS: IB: Remove an unused structure member
  IB: Convert ib_dma_*_coherent() argument type from u64 into dma_addr_t
  IB/core: Inline ib_dma_map_*() functions
  IB/mlx4: Inline ib_dma_map_*() functions
  IB/mlx5: Inline ib_dma_map_*() functions
  IB/IPoIB: Inline ib_dma_map_*() functions
  IB/iser: Inline ib_dma_map_*() functions
  IB/isert: Inline ib_dma_map_*() functions
  IB/srp: Inline ib_dma_map_*() functions
  IB/srpt: Inline ib_dma_map_*() functions
  staging/lustre: Inline ib_dma_map_*() functions
  nvme-rdma: Inline ib_dma_map_*() functions
  net/9p: Inline ib_dma_map_*() functions
  net/rds: Inline ib_dma_map_*() functions
  xprtrdma: Inline ib_dma_map_*() functions
  IB/core: Remove ib_dma_map_*() functions

 arch/alpha/include/asm/dma-mapping.h   |   4 +-
 arch/alpha/kernel/pci-noop.c   |   4 +-
 arch/alpha/kernel/pci_iommu.c  |   4 +-
 arch/arc/include/asm/dma-mapping.h |   4 +-
 arch/arc/mm/dma.c  |   2 +-
 arch/arm/common/dmabounce.c|   2 +-
 arch/arm/include/asm/device.h  |   1 -
 arch/arm/include/asm/dma-mapping.h |  20 +-
 arch/arm/mm/dma-mapping.c  |  22 +-
 arch/arm/xen/mm.c  |   4 +-
 arch/arm64/include/asm/device.h|   1 -
 arch/arm64/include/asm/dma-mapping.h   |  12 +-
 arch/arm64/mm/dma-mapping.c|  14 +-
 arch/avr32/include/asm/dma-mapping.h   |   4 +-
 arch/avr32/mm/dma-coherent.c   |   2 +-
 arch/blackfin/include/asm/dma-mapping.h|   4 +-
 arch/blackfin/kernel/dma-mapping.c |   2 +-
 arch/c6x/include/asm/dma-mapping.h |   4 +-
 arch/c6x/kernel/dma.c  |   2 +-
 arch/cris/arch-v32/drivers/pci/dma.c   |   2 +-
 arch/cris/include/asm/dma-mapping.h|   6 +-
 arch/frv/include/asm/dma-mapping.h |   4 +-
 arch/frv/mb93090-mb00/pci-dma-nommu.c  |   2 +-
 arch/frv/mb93090-mb00/pci-dma.c|   2 +-
 arch/h8300/include/asm/dma-mapping.h   |   4 +-
 arch/h8300/kernel/dma.c|   2 +-
 arch/hexagon/include/asm/dma-mapping.h |   7 +-
 arch/hexagon/kernel/dma.c  |   4 +-
 arch/ia64/hp/common/hwsw_iommu.c   |   4 +-
 arch/ia64/hp/common/sba_iommu.c|   4 +-
 arch/ia64/include/asm/dma-mapping.h|   7 +-
 arch/ia64/include/asm/machvec.h|   4 +-
 arch/ia64/kernel/dma-mapping.c |   4 +-
 arch/ia64/kernel/pci-dma.c |  10 +-
 arch/ia64/kernel/pci-swiotlb.c |   2 +-
 arch/m32r/Kconfig  |   1 +
 arch/m32r/include/asm/device.h |   1 -
 arch/m32r/include/asm/dma-mapping.h|   4 +-
 arch/m68k/include/asm/dma-mapping.h|   4 +-
 arch/m68k/kernel/dma.c |   2 +-
 arch/metag/include/asm/dma-mapping.h 

[PATCH v2 22/26] nvme-rdma: Inline ib_dma_map_*() functions

2017-01-12 Thread Bart Van Assche
Signed-off-by: Bart Van Assche 
Reviewed-by: Christoph Hellwig 
Reviewed-by: Sagi Grimberg 
Cc: Keith Busch 
---
 drivers/nvme/host/rdma.c   | 35 +++
 drivers/nvme/target/rdma.c | 32 
 2 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 208b6a08781c..877ff1982f38 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -207,7 +207,7 @@ static inline size_t nvme_rdma_inline_data_size(struct 
nvme_rdma_queue *queue)
 static void nvme_rdma_free_qe(struct ib_device *ibdev, struct nvme_rdma_qe *qe,
size_t capsule_size, enum dma_data_direction dir)
 {
-   ib_dma_unmap_single(ibdev, qe->dma, capsule_size, dir);
+   dma_unmap_single(ibdev->dma_device, qe->dma, capsule_size, dir);
kfree(qe->data);
 }
 
@@ -218,8 +218,9 @@ static int nvme_rdma_alloc_qe(struct ib_device *ibdev, 
struct nvme_rdma_qe *qe,
if (!qe->data)
return -ENOMEM;
 
-   qe->dma = ib_dma_map_single(ibdev, qe->data, capsule_size, dir);
-   if (ib_dma_mapping_error(ibdev, qe->dma)) {
+   qe->dma = dma_map_single(ibdev->dma_device, qe->data, capsule_size,
+dir);
+   if (dma_mapping_error(ibdev->dma_device, qe->dma)) {
kfree(qe->data);
return -ENOMEM;
}
@@ -895,9 +896,8 @@ static void nvme_rdma_unmap_data(struct nvme_rdma_queue 
*queue,
}
}
 
-   ib_dma_unmap_sg(ibdev, req->sg_table.sgl,
-   req->nents, rq_data_dir(rq) ==
-   WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+   dma_unmap_sg(ibdev->dma_device, req->sg_table.sgl, req->nents,
+   rq_data_dir(rq) == WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
nvme_cleanup_cmd(rq);
sg_free_table_chained(&req->sg_table, true);
@@ -1008,7 +1008,7 @@ static int nvme_rdma_map_data(struct nvme_rdma_queue 
*queue,
 
req->nents = blk_rq_map_sg(rq->q, rq, req->sg_table.sgl);
 
-   count = ib_dma_map_sg(ibdev, req->sg_table.sgl, req->nents,
+   count = dma_map_sg(ibdev->dma_device, req->sg_table.sgl, req->nents,
rq_data_dir(rq) == WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
if (unlikely(count <= 0)) {
sg_free_table_chained(&req->sg_table, true);
@@ -1135,7 +1135,8 @@ static void nvme_rdma_submit_async_event(struct nvme_ctrl 
*arg, int aer_idx)
if (WARN_ON_ONCE(aer_idx != 0))
return;
 
-   ib_dma_sync_single_for_cpu(dev, sqe->dma, sizeof(*cmd), DMA_TO_DEVICE);
+   dma_sync_single_for_cpu(dev->dma_device, sqe->dma, sizeof(*cmd),
+   DMA_TO_DEVICE);
 
memset(cmd, 0, sizeof(*cmd));
cmd->common.opcode = nvme_admin_async_event;
@@ -1143,8 +1144,8 @@ static void nvme_rdma_submit_async_event(struct nvme_ctrl 
*arg, int aer_idx)
cmd->common.flags |= NVME_CMD_SGL_METABUF;
nvme_rdma_set_sg_null(cmd);
 
-   ib_dma_sync_single_for_device(dev, sqe->dma, sizeof(*cmd),
-   DMA_TO_DEVICE);
+   dma_sync_single_for_device(dev->dma_device, sqe->dma, sizeof(*cmd),
+  DMA_TO_DEVICE);
 
ret = nvme_rdma_post_send(queue, sqe, &sge, 1, NULL, false);
WARN_ON_ONCE(ret);
@@ -1194,7 +1195,8 @@ static int __nvme_rdma_recv_done(struct ib_cq *cq, struct 
ib_wc *wc, int tag)
return 0;
}
 
-   ib_dma_sync_single_for_cpu(ibdev, qe->dma, len, DMA_FROM_DEVICE);
+   dma_sync_single_for_cpu(ibdev->dma_device, qe->dma, len,
+   DMA_FROM_DEVICE);
/*
 * AEN requests are special as they don't time out and can
 * survive any kind of queue freeze and often don't respond to
@@ -1207,7 +1209,8 @@ static int __nvme_rdma_recv_done(struct ib_cq *cq, struct 
ib_wc *wc, int tag)
&cqe->result);
else
ret = nvme_rdma_process_nvme_rsp(queue, cqe, wc, tag);
-   ib_dma_sync_single_for_device(ibdev, qe->dma, len, DMA_FROM_DEVICE);
+   dma_sync_single_for_device(ibdev->dma_device, qe->dma, len,
+  DMA_FROM_DEVICE);
 
nvme_rdma_post_recv(queue, qe);
return ret;
@@ -1455,8 +1458,8 @@ static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,
return BLK_MQ_RQ_QUEUE_BUSY;
 
dev = queue->device->dev;
-   ib_dma_sync_single_for_cpu(dev, sqe->dma,
-   sizeof(struct nvme_command), DMA_TO_DEVICE);
+   dma_sync_single_for_cpu(dev->dma_device, sqe->dma,
+   sizeof(struct nvme_command), DMA_TO_DEVICE);
 
ret = nvme_setup_cmd(ns, rq, c);
if (ret != BLK_MQ_RQ_QUEUE_OK)
@@ -1473,8 +1476,8 @@ static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,
goto err;
}
 
- 

[PATCH v2 15/26] IB/mlx5: Inline ib_dma_map_*() functions

2017-01-12 Thread Bart Van Assche
Signed-off-by: Bart Van Assche 
Reviewed-by: Christoph Hellwig 
Reviewed-by: Sagi Grimberg 
Acked-by: Leon Romanovsky 
---
 drivers/infiniband/hw/mlx5/mr.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 00175191fdc6..4d3daef6d859 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -1865,9 +1865,9 @@ int mlx5_ib_map_mr_sg(struct ib_mr *ibmr, struct 
scatterlist *sg, int sg_nents,
 
mr->ndescs = 0;
 
-   ib_dma_sync_single_for_cpu(ibmr->device, mr->desc_map,
-  mr->desc_size * mr->max_descs,
-  DMA_TO_DEVICE);
+   dma_sync_single_for_cpu(ibmr->device->dma_device, mr->desc_map,
+   mr->desc_size * mr->max_descs,
+   DMA_TO_DEVICE);
 
if (mr->access_mode == MLX5_MKC_ACCESS_MODE_KLMS)
n = mlx5_ib_sg_to_klms(mr, sg, sg_nents, sg_offset);
@@ -1875,9 +1875,9 @@ int mlx5_ib_map_mr_sg(struct ib_mr *ibmr, struct 
scatterlist *sg, int sg_nents,
n = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset,
mlx5_set_page);
 
-   ib_dma_sync_single_for_device(ibmr->device, mr->desc_map,
- mr->desc_size * mr->max_descs,
- DMA_TO_DEVICE);
+   dma_sync_single_for_device(ibmr->device->dma_device, mr->desc_map,
+  mr->desc_size * mr->max_descs,
+  DMA_TO_DEVICE);
 
return n;
 }
-- 
2.11.0



[PATCH v2 18/26] IB/isert: Inline ib_dma_map_*() functions

2017-01-12 Thread Bart Van Assche
Signed-off-by: Bart Van Assche 
Reviewed-by: Christoph Hellwig 
Reviewed-by: Sagi Grimberg 
---
 drivers/infiniband/ulp/isert/ib_isert.c | 120 +---
 1 file changed, 63 insertions(+), 57 deletions(-)

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c 
b/drivers/infiniband/ulp/isert/ib_isert.c
index 314e95516068..ca919d472bd5 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -189,9 +189,10 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn)
rx_desc = isert_conn->rx_descs;
 
for (i = 0; i < ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++)  {
-   dma_addr = ib_dma_map_single(ib_dev, (void *)rx_desc,
-   ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
-   if (ib_dma_mapping_error(ib_dev, dma_addr))
+   dma_addr = dma_map_single(ib_dev->dma_device, rx_desc,
+ ISER_RX_PAYLOAD_SIZE,
+ DMA_FROM_DEVICE);
+   if (dma_mapping_error(ib_dev->dma_device, dma_addr))
goto dma_map_fail;
 
rx_desc->dma_addr = dma_addr;
@@ -208,8 +209,8 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn)
 dma_map_fail:
rx_desc = isert_conn->rx_descs;
for (j = 0; j < i; j++, rx_desc++) {
-   ib_dma_unmap_single(ib_dev, rx_desc->dma_addr,
-   ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+   dma_unmap_single(ib_dev->dma_device, rx_desc->dma_addr,
+ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
}
kfree(isert_conn->rx_descs);
isert_conn->rx_descs = NULL;
@@ -229,8 +230,8 @@ isert_free_rx_descriptors(struct isert_conn *isert_conn)
 
rx_desc = isert_conn->rx_descs;
for (i = 0; i < ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++)  {
-   ib_dma_unmap_single(ib_dev, rx_desc->dma_addr,
-   ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+   dma_unmap_single(ib_dev->dma_device, rx_desc->dma_addr,
+ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
}
 
kfree(isert_conn->rx_descs);
@@ -410,13 +411,12 @@ isert_free_login_buf(struct isert_conn *isert_conn)
 {
struct ib_device *ib_dev = isert_conn->device->ib_device;
 
-   ib_dma_unmap_single(ib_dev, isert_conn->login_rsp_dma,
-   ISER_RX_PAYLOAD_SIZE, DMA_TO_DEVICE);
+   dma_unmap_single(ib_dev->dma_device, isert_conn->login_rsp_dma,
+ISER_RX_PAYLOAD_SIZE, DMA_TO_DEVICE);
kfree(isert_conn->login_rsp_buf);
 
-   ib_dma_unmap_single(ib_dev, isert_conn->login_req_dma,
-   ISER_RX_PAYLOAD_SIZE,
-   DMA_FROM_DEVICE);
+   dma_unmap_single(ib_dev->dma_device, isert_conn->login_req_dma,
+ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
kfree(isert_conn->login_req_buf);
 }
 
@@ -431,10 +431,11 @@ isert_alloc_login_buf(struct isert_conn *isert_conn,
if (!isert_conn->login_req_buf)
return -ENOMEM;
 
-   isert_conn->login_req_dma = ib_dma_map_single(ib_dev,
-   isert_conn->login_req_buf,
-   ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
-   ret = ib_dma_mapping_error(ib_dev, isert_conn->login_req_dma);
+   isert_conn->login_req_dma = dma_map_single(ib_dev->dma_device,
+  isert_conn->login_req_buf,
+  ISER_RX_PAYLOAD_SIZE,
+  DMA_FROM_DEVICE);
+   ret = dma_mapping_error(ib_dev->dma_device, isert_conn->login_req_dma);
if (ret) {
isert_err("login_req_dma mapping error: %d\n", ret);
isert_conn->login_req_dma = 0;
@@ -447,10 +448,11 @@ isert_alloc_login_buf(struct isert_conn *isert_conn,
goto out_unmap_login_req_buf;
}
 
-   isert_conn->login_rsp_dma = ib_dma_map_single(ib_dev,
-   isert_conn->login_rsp_buf,
-   ISER_RX_PAYLOAD_SIZE, DMA_TO_DEVICE);
-   ret = ib_dma_mapping_error(ib_dev, isert_conn->login_rsp_dma);
+   isert_conn->login_rsp_dma = dma_map_single(ib_dev->dma_device,
+  isert_conn->login_rsp_buf,
+  ISER_RX_PAYLOAD_SIZE,
+  DMA_TO_DEVICE);
+   ret = dma_mapping_error(ib_dev->dma_device, isert_conn->login_rsp_dma);
if (ret) {
isert_err("login_rsp_dma mapping error: %d\n", ret);
isert_conn->login_rsp_dma = 0;
@@ -462,8 +464,8 @@ isert_alloc_login_buf(struct isert_conn *isert_conn,
 out_free_login_rsp_bu

[PATCH v2 23/26] net/9p: Inline ib_dma_map_*() functions

2017-01-12 Thread Bart Van Assche
Signed-off-by: Bart Van Assche 
Reviewed-by: Christoph Hellwig 
Reviewed-by: Sagi Grimberg 
Cc: Eric Van Hensbergen 
---
 net/9p/trans_rdma.c | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
index 553ed4ecb6a0..b49d5998289e 100644
--- a/net/9p/trans_rdma.c
+++ b/net/9p/trans_rdma.c
@@ -294,8 +294,8 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc)
int16_t tag;
 
req = NULL;
-   ib_dma_unmap_single(rdma->cm_id->device, c->busa, client->msize,
-DMA_FROM_DEVICE);
+   dma_unmap_single(rdma->cm_id->device->dma_device, c->busa,
+client->msize, DMA_FROM_DEVICE);
 
if (wc->status != IB_WC_SUCCESS)
goto err_out;
@@ -339,9 +339,8 @@ send_done(struct ib_cq *cq, struct ib_wc *wc)
struct p9_rdma_context *c =
container_of(wc->wr_cqe, struct p9_rdma_context, cqe);
 
-   ib_dma_unmap_single(rdma->cm_id->device,
-   c->busa, c->req->tc->size,
-   DMA_TO_DEVICE);
+   dma_unmap_single(rdma->cm_id->device->dma_device, c->busa,
+c->req->tc->size, DMA_TO_DEVICE);
up(&rdma->sq_sem);
kfree(c);
 }
@@ -379,10 +378,9 @@ post_recv(struct p9_client *client, struct p9_rdma_context 
*c)
struct ib_recv_wr wr, *bad_wr;
struct ib_sge sge;
 
-   c->busa = ib_dma_map_single(rdma->cm_id->device,
-   c->rc->sdata, client->msize,
-   DMA_FROM_DEVICE);
-   if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
+   c->busa = dma_map_single(rdma->cm_id->device->dma_device, c->rc->sdata,
+client->msize, DMA_FROM_DEVICE);
+   if (dma_mapping_error(rdma->cm_id->device->dma_device, c->busa))
goto error;
 
c->cqe.done = recv_done;
@@ -469,10 +467,10 @@ static int rdma_request(struct p9_client *client, struct 
p9_req_t *req)
}
c->req = req;
 
-   c->busa = ib_dma_map_single(rdma->cm_id->device,
-   c->req->tc->sdata, c->req->tc->size,
-   DMA_TO_DEVICE);
-   if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) {
+   c->busa = dma_map_single(rdma->cm_id->device->dma_device,
+c->req->tc->sdata, c->req->tc->size,
+DMA_TO_DEVICE);
+   if (dma_mapping_error(rdma->cm_id->device->dma_device, c->busa)) {
err = -EIO;
goto send_error;
}
-- 
2.11.0



<    3   4   5   6   7   8   9   10   >