Re: [PATCH] [media] omap3isp: don't call of_node_put

2016-09-28 Thread H. Nikolaus Schaller
ping ping.

> Am 19.09.2016 um 11:55 schrieb H. Nikolaus Schaller :
> 
> ping.
> 
>> Am 08.09.2016 um 17:48 schrieb H. Nikolaus Schaller :
>> 
>> of_node_put() has already been called inside of_graph_get_next_endpoint().
>> 
>> Otherwise we may get warnings like
>> 
>> [   10.118286] omap3isp 480bc000.isp: parsing endpoint 
>> /ocp/isp@480bc000/ports/port@0/endpoint, interface 0
>> [   10.118499] ERROR: Bad of_node_put() on 
>> /ocp/isp@480bc000/ports/port@0/endpoint
>> [   10.118499] CPU: 0 PID: 968 Comm: udevd Not tainted 4.7.0-rc4-letux+ #376
>> [   10.118530] Hardware name: Generic OMAP36xx (Flattened Device Tree)
>> [   10.118560] [] (unwind_backtrace) from [] 
>> (show_stack+0x10/0x14)
>> [   10.118591] [] (show_stack) from [] 
>> (dump_stack+0x98/0xd0)
>> [   10.118591] [] (dump_stack) from [] 
>> (kobject_release+0x60/0x74)
>> [   10.118621] [] (kobject_release) from [] 
>> (__of_get_next_child+0x40/0x48)
>> [   10.118652] [] (__of_get_next_child) from [] 
>> (of_get_next_child+0x28/0x44)
>> [   10.118652] [] (of_get_next_child) from [] 
>> (of_graph_get_next_endpoint+0xe4/0x124)
>> [   10.118804] [] (of_graph_get_next_endpoint) from [] 
>> (isp_probe+0xdc/0xd80 [omap3_isp])
>> [   10.118896] [] (isp_probe [omap3_isp]) from [] 
>> (platform_drv_probe+0x50/0xa0)
>> [   10.118927] [] (platform_drv_probe) from [] 
>> (driver_probe_device+0x134/0x29c)
>> [   10.118957] [] (driver_probe_device) from [] 
>> (__driver_attach+0x88/0xac)
>> [   10.118957] [] (__driver_attach) from [] 
>> (bus_for_each_dev+0x6c/0x90)
>> [   10.118957] [] (bus_for_each_dev) from [] 
>> (bus_add_driver+0xcc/0x1e8)
>> [   10.118988] [] (bus_add_driver) from [] 
>> (driver_register+0xac/0xf4)
>> [   10.118988] [] (driver_register) from [] 
>> (do_one_initcall+0xac/0x154)
>> [   10.119018] [] (do_one_initcall) from [] 
>> (do_init_module+0x58/0x39c)
>> [   10.119049] [] (do_init_module) from [] 
>> (load_module+0xe5c/0x1004)
>> [   10.119049] [] (load_module) from [] 
>> (SyS_finit_module+0x88/0x90)
>> [   10.119079] [] (SyS_finit_module) from [] 
>> (ret_fast_syscall+0x0/0x1c)
>> 
>> Signed-off-by: H. Nikolaus Schaller 
>> ---
>> drivers/media/platform/omap3isp/isp.c | 3 +--
>> 1 file changed, 1 insertion(+), 2 deletions(-)
>> 
>> diff --git a/drivers/media/platform/omap3isp/isp.c 
>> b/drivers/media/platform/omap3isp/isp.c
>> index 5d54e2c..6e2624e 100644
>> --- a/drivers/media/platform/omap3isp/isp.c
>> +++ b/drivers/media/platform/omap3isp/isp.c
>> @@ -2114,7 +2114,6 @@ static int isp_of_parse_nodes(struct device *dev,
>> 
>>  isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL);
>>  if (!isd) {
>> -of_node_put(node);
>>  return -ENOMEM;
>>  }
>> 
>> @@ -2126,7 +2125,7 @@ static int isp_of_parse_nodes(struct device *dev,
>>  }
>> 
>>  isd->asd.match.of.node = of_graph_get_remote_port_parent(node);
>> -of_node_put(node);
>> +
>>  if (!isd->asd.match.of.node) {
>>  dev_warn(dev, "bad remote port parent\n");
>>  return -EINVAL;
>> -- 
>> 2.7.3
>> 
> 



Re: [PATCH v4 0/5] Functional dependencies between devices

2016-09-28 Thread Marek Szyprowski

Hi Rafael,

On 2016-09-29 02:24, Rafael J. Wysocki wrote:

Hi Everyone,

On Thursday, September 08, 2016 11:25:44 PM Rafael J. Wysocki wrote:

Hi Everyone,

This is a refresh of the functional dependencies series that I posted last
year and which has picked up by Marek quite recently.  For reference,
appended is my introductory message sent previously (which may be
slightly outdated now).

As last time, the first patch rearranges the code around
__device_release_driver() a bit to prepare it for the next one (it
actually hasn't changed AFAICS).

The second patch introduces the actual device links mechanics, but without
system suspend/resume and runtime PM support which are added by the
subsequent patches.

Some bugs found by Marek during his work on these patches should be fixed
here.  In particular, the endless recursion in device_reorder_to_tail()
which simply was broken before.

There are two additional patches to address the issue with runtime PM
support
that occured when runtime PM was disabled for some suppliers due to a PM
sleep transition in progress.  Those patches simply make runtime PM
helpers
return 0 in that case which may be controversial, so please let me know if
there are concerns about those.

The way device_link_add() works is a bit different, as it takes an
additional
status argument now.  That makes it possible to create a link in any
state,
with extra care of course, and should address the problem pointed to by
Lukas
during the previous discussion.

Also some comments from Tomeu have been addressed.

An update here.

The first patch hasn't changed, so I'm resending it.

The majority of changes in the other patches are in order to address Lukas'
comments.

First off, I added a DEVICE_LINK_STATELESS flag that will prevent the driver
core from trying to maintain device links having it set.

Also, the DEVICE_LINK_PERSISTENT flag was dropped (as link "persistence" is
the default behavior now) and there's a new one, DEVICE_LINK_AUTOREMOVE,
that will cause the driver core to remove the link on the consumer driver
unbind.

Moreover, the code checks attempts to create a link between a parent and a
child device now and actively prevents that from happening.

The changelog of the second patch has been updated as requested by Ulf.

The third patch was updated to fix a bug related to the (previously missing)
clearing of power.direct_complete for supplier devices having consumers that
don't use direct_complete.

The next two (runtime PM) patches turned out to be unnecessary, so I've
dropped them.

The runtime PM patch [4/5] was reorganized somewhat to reduce the
indentation
level in there, but the code flow introduced by it is essentially the same
and the last patch was simply rebased on top of the new series.

Time for another update. :-)

Fewer changes this time, mostly to address issues found by Lukas and Marek.

The most significant one is to make device_link_add() cope with the case when
the consumer device has not been registered yet when it is called.  The
supplier device still is required to be registered and the function will return
NULL if that is not the case.

Another significant change is in patch [4/5] that now makes the core apply
pm_runtime_get_sync()/pm_runtime_put() to supplier devices around the probing
of a consumer one (in analogy with the parent).


Thanks for the update! Updated version fixes all the remaining issues.

Tested-by: Marek Szyprowski 

Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland



Re: [PATCH 4/5] ACPI / property: Allow holes in reference properties

2016-09-28 Thread Mika Westerberg
On Wed, Sep 28, 2016 at 11:36:10PM +0200, Rafael J. Wysocki wrote:
> On Fri, Sep 23, 2016 at 4:57 PM, Mika Westerberg
>  wrote:
> > DT allows holes or empty phandles for references. This is used for example
> > in SPI subsystem where some chip selects are native and others are regular
> > GPIOs. In ACPI _DSD we currently do not support this but instead the
> > preceding reference "consumes" all following integer arguments.
> >
> > For example we would like to support something like the below ASL fragment
> > for SPI:
> >
> >   Package () {
> >   "cs-gpios",
> >   Package () {
> >   ^GPIO, 19, 0, 0, // GPIO CS0
> >   0,   // Native CS
> >   ^GPIO, 20, 0, 0, // GPIO CS1
> >   }
> >   }
> >
> > The zero in the middle means "no entry" or NULL reference. To support this
> > we add a new function acpi_node_get_property_reference_fixed_args() that
> > takes number of expected arguments as parameter. Function returns -ENOENT
> > if the corresponding index resolves to the "no entry" reference.
> >
> > Signed-off-by: Mika Westerberg 
> > ---
> >  drivers/acpi/property.c | 116 
> > +++-
> >  include/linux/acpi.h|   3 ++
> >  2 files changed, 89 insertions(+), 30 deletions(-)
> >
> > diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> > index f2fd3fee588a..b255c4442a05 100644
> > --- a/drivers/acpi/property.c
> > +++ b/drivers/acpi/property.c
> > @@ -472,6 +472,7 @@ static int acpi_data_get_property_array(struct 
> > acpi_device_data *data,
> >   * @data: ACPI device data object containing the property
> >   * @propname: Name of the property
> >   * @index: Index of the reference to return
> > + * @num_args: Maximum number of arguments after each reference
> >   * @args: Location to store the returned reference with optional arguments
> >   *
> >   * Find property with @name, verifify that it is a package containing at 
> > least
> > @@ -485,8 +486,8 @@ static int acpi_data_get_property_array(struct 
> > acpi_device_data *data,
> >   * Return: %0 on success, negative error code on failure.
> >   */
> >  static int acpi_data_get_property_reference(struct acpi_device_data *data,
> > -   const char *propname, size_t 
> > index,
> > -   struct acpi_reference_args 
> > *args)
> > +   const char *propname, size_t index, size_t num_args,
> > +   struct acpi_reference_args *args)
> >  {
> > const union acpi_object *element, *end;
> > const union acpi_object *obj;
> > @@ -532,41 +533,52 @@ static int acpi_data_get_property_reference(struct 
> > acpi_device_data *data,
> > while (element < end) {
> > u32 nargs, i;
> >
> > -   if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
> > -   return -EPROTO;
> > -
> > -   ret = acpi_bus_get_device(element->reference.handle, 
> > &device);
> > -   if (ret)
> > -   return -ENODEV;
> > -
> > -   element++;
> > -   nargs = 0;
> > -
> > -   /* assume following integer elements are all args */
> > -   for (i = 0; element + i < end; i++) {
> > -   int type = element[i].type;
> > +   if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
> > +   ret = acpi_bus_get_device(element->reference.handle,
> > + &device);
> > +   if (ret)
> > +   return -ENODEV;
> > +
> > +   nargs = 0;
> > +   element++;
> > +
> > +   /* assume following integer elements are all args */
> > +   for (i = 0; element + i < end && i < num_args; i++) 
> > {
> > +   int type = element[i].type;
> > +
> > +   if (type == ACPI_TYPE_INTEGER)
> > +   nargs++;
> > +   else if (type == ACPI_TYPE_LOCAL_REFERENCE)
> > +   break;
> > +   else
> > +   return -EPROTO;
> > +   }
> >
> > -   if (type == ACPI_TYPE_INTEGER)
> > -   nargs++;
> > -   else if (type == ACPI_TYPE_LOCAL_REFERENCE)
> > -   break;
> > -   else
> > +   if (nargs > MAX_ACPI_REFERENCE_ARGS)
> > return -EPROTO;
> > -   }
> >
> > -   if (idx++ == index) {
> > -   args->adev = device;
> > -   args->nargs = nargs;
> > -   for (i = 0; i < nargs; i++)
> > -   args->args[i] = element[i].integer.

Re: [PATCH] pinctrl: freescale: avoid overwriting pin config when freeing GPIO

2016-09-28 Thread Viresh Kumar
On 28-09-16, 15:07, Vladimir Zapolskiy wrote:
> I would expect that the change below improves the situation, but I didn't
> perform any tests and here the core change is governed by the accepted
> i.MX i2c bus driver specific changes, thus conceptually it may be incorrect:
> 
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index da3a02ef4a31..3a4f59c3c3e6 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -697,9 +697,6 @@ static int i2c_generic_recovery(struct i2c_adapter *adap)
>   struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
>   int i = 0, val = 1, ret = 0;
> - if (bri->prepare_recovery)
> - bri->prepare_recovery(adap);
> -
>   bri->set_scl(adap, val);
>   ndelay(RECOVERY_NDELAY);
> @@ -725,22 +722,34 @@ static int i2c_generic_recovery(struct i2c_adapter 
> *adap)
>   ndelay(RECOVERY_NDELAY);
>   }
> - if (bri->unprepare_recovery)
> - bri->unprepare_recovery(adap);
> -
>   return ret;
>  }
>  int i2c_generic_scl_recovery(struct i2c_adapter *adap)
>  {
> - return i2c_generic_recovery(adap);
> + struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
> + int ret;
> +
> + if (bri->prepare_recovery)
> + bri->prepare_recovery(adap);
> +
> + ret = i2c_generic_recovery(adap);
> +
> + if (bri->unprepare_recovery)
> + bri->unprepare_recovery(adap);
> +
> + return ret;
>  }
>  EXPORT_SYMBOL_GPL(i2c_generic_scl_recovery);
>  int i2c_generic_gpio_recovery(struct i2c_adapter *adap)
>  {
> + struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
>   int ret;
> + if (bri->prepare_recovery)
> + bri->prepare_recovery(adap);
> +
>   ret = i2c_get_gpios_for_recovery(adap);
>   if (ret)
>   return ret;
> @@ -748,6 +757,9 @@ int i2c_generic_gpio_recovery(struct i2c_adapter *adap)
>   ret = i2c_generic_recovery(adap);
>   i2c_put_gpios_for_recovery(adap);
> + if (bri->unprepare_recovery)
> + bri->unprepare_recovery(adap);
> +
>   return ret;
>  }
>  EXPORT_SYMBOL_GPL(i2c_generic_gpio_recovery);

That looks to like a hack made just to make things work on one platform.

I would rather wait for an answer to my query first, which I asked in a separate
email.
 
-- 
viresh


Re: [PATCH 5/8] pinctrl: aspeed: Enable capture of off-SCU pinmux state

2016-09-28 Thread Joel Stanley
On Wed, Sep 28, 2016 at 12:20 AM, Andrew Jeffery  wrote:
> The System Control Unit IP in the Aspeed SoCs is typically where the
> pinmux configuration is found.
>
> But not always.
>
> On the AST2400 and AST2500 a number of pins depend on state in one of
> the SIO, LPC or GFX IP blocks, so add support to at least capture what
> that state is. The pinctrl engine for the Aspeed SoCs doesn't try to
> inspect or modify the state of the off-SCU IP blocks. Instead, it logs
> the state requirement with the expectation that the platform
> designer/maintainer arranges for the appropriate configuration to be
> applied through the associated drivers.

This is unfortunate.

This patch kicks the can down the road, but doesn't solve the problem
for a user who wants to configure some functionality that depends on
the non-SCU bits. Because of this I'm not sure if we want to put it in
the tree.

However, I'm not sure what a proper solution would look like. Perhaps
Linus can point out another SoC that has a similar problem?

Cheers,

Joel

>
> The IP block of interest is encoded in the reg member of struct
> aspeed_sig_desc. For compatibility with the existing code, the SCU is
> defined to have an IP value of 0.
>
> Signed-off-by: Andrew Jeffery 
> ---
>  drivers/pinctrl/aspeed/pinctrl-aspeed.c | 53 +++---
>  drivers/pinctrl/aspeed/pinctrl-aspeed.h | 16 +++-
>  2 files changed, 61 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c 
> b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> index 49aeba912531..21ef195d586f 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> @@ -14,6 +14,8 @@
>  #include "../core.h"
>  #include "pinctrl-aspeed.h"
>
> +const char *const aspeed_pinmux_ips[] = { "SCU", "SIO", "GFX", "LPC" };
> +
>  int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
>  {
> struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
> @@ -78,7 +80,9 @@ int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
>  static inline void aspeed_sig_desc_print_val(
> const struct aspeed_sig_desc *desc, bool enable, u32 rv)
>  {
> -   pr_debug("SCU%x[0x%08x]=0x%x, got 0x%x from 0x%08x\n", desc->reg,
> +   pr_debug("Want %s%lX[0x%08X]=0x%X, got 0x%X from 0x%08X\n",
> +   aspeed_pinmux_ips[SIG_DESC_IP_FROM_REG(desc->reg)],
> +   SIG_DESC_OFFSET_FROM_REG(desc->reg),
> desc->mask, enable ? desc->enable : desc->disable,
> (rv & desc->mask) >> __ffs(desc->mask), rv);
>  }
> @@ -105,6 +109,8 @@ static bool aspeed_sig_desc_eval(const struct 
> aspeed_sig_desc *desc,
> unsigned int raw;
> u32 want;
>
> +   WARN_ON(SIG_DESC_IP_FROM_REG(desc->reg) != ASPEED_IP_SCU);
> +
> if (regmap_read(map, desc->reg, &raw) < 0)
> return false;
>
> @@ -142,9 +148,19 @@ static bool aspeed_sig_expr_eval(const struct 
> aspeed_sig_expr *expr,
>
> for (i = 0; i < expr->ndescs; i++) {
> const struct aspeed_sig_desc *desc = &expr->descs[i];
> +   size_t ip = SIG_DESC_IP_FROM_REG(desc->reg);
> +
> +   if (ip == ASPEED_IP_SCU) {
> +   if (!aspeed_sig_desc_eval(desc, enabled, map))
> +   return false;
> +   } else {
> +   size_t offset = SIG_DESC_OFFSET_FROM_REG(desc->reg);
> +   const char *ip_name = aspeed_pinmux_ips[ip];
> +
> +   pr_debug("Ignoring configuration of field 
> %s%X[0x%08X]\n",
> +ip_name, offset, desc->mask);
> +   }
>
> -   if (!aspeed_sig_desc_eval(desc, enabled, map))
> -   return false;
> }
>
> return true;
> @@ -170,7 +186,14 @@ static bool aspeed_sig_expr_set(const struct 
> aspeed_sig_expr *expr,
> for (i = 0; i < expr->ndescs; i++) {
> bool ret;
> const struct aspeed_sig_desc *desc = &expr->descs[i];
> +
> +   size_t offset = SIG_DESC_OFFSET_FROM_REG(desc->reg);
> +   size_t ip = SIG_DESC_IP_FROM_REG(desc->reg);
> +   bool is_scu = (ip == ASPEED_IP_SCU);
> +   const char *ip_name = aspeed_pinmux_ips[ip];
> +
> u32 pattern = enable ? desc->enable : desc->disable;
> +   u32 val = (pattern << __ffs(desc->mask));
>
> /*
>  * Strap registers are configured in hardware or by early-boot
> @@ -179,11 +202,27 @@ static bool aspeed_sig_expr_set(const struct 
> aspeed_sig_expr *expr,
>  * deconfigured and is the reason we re-evaluate after writing
>  * all descriptor bits.
>  */
> -   if (desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2)
> +   if (is_scu && (offset == HW_STRAP1 || offse

Re: NMI for ARC

2016-09-28 Thread Peter Zijlstra
On Wed, Sep 28, 2016 at 06:20:29PM -0700, Vineet Gupta wrote:
> On 09/28/2016 03:26 PM, Andy Lutomirski wrote:
> >> Right, so what I think Vineet is asking is if we need to disable NMIs as
> >> > well, we cannot on x86 disable NMIs so no.
> >> >
> > The same argument works here, too: an NMI won't set TIF_NEED_RESCHED
> > without sending an IPI, so we can't miss a wakeup.
> 
> But what exact wakeup miss are we taking about here. If intr were NOT 
> disabled,
> how could this happen. Just trying to understand the need for "irqs-disabled" 
> in
> resume_{user,kernel}_*
> 
> The intr disabled before reg file restore makes complete sense though.


userirq nmi

|
|
`-> .
|
|
|
`-> .
|
|
. <-'
. <-'
|
|

So what Andy is saying is that NMI context never sets TIF_NEED_RESCHED,
this means that return from NMI never needs to check for preemption
etc..

Now your return from IRQ obviously should, the normal way. If the IRQ
return gets interrupted by the NMI nothing special should occur. The
return from NMI should simply resume the return from IRQ.

So I'm a little confused by your timer interrupt example, it _should_ do
the preemption, the nested interrupt (NMI) will return to the regular
interrupt which should resume its normal return preemption or not.




[PATCH -v4 5/9] mm, THP, swap: Support to clear SWAP_HAS_CACHE for huge page

2016-09-28 Thread Huang, Ying
From: Huang Ying 

__swapcache_free() is added to support to clear the SWAP_HAS_CACHE flag
for the huge page.  This will free the specified swap cluster now.
Because now this function will be called only in the error path to free
the swap cluster just allocated.  So the corresponding swap_map[i] ==
SWAP_HAS_CACHE, that is, the swap count is 0.  This makes the
implementation simpler than that of the ordinary swap entry.

This will be used for delaying splitting THP (Transparent Huge Page)
during swapping out.  Where for one THP to swap out, we will allocate a
swap cluster, add the THP into the swap cache, then split the THP.  If
anything fails after allocating the swap cluster and before splitting
the THP successfully, the swapcache_free_trans_huge() will be used to
free the swap space allocated.

Cc: Andrea Arcangeli 
Cc: Kirill A. Shutemov 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Minchan Kim 
Cc: Rik van Riel 
Signed-off-by: "Huang, Ying" 
---
 include/linux/swap.h |  9 +++--
 mm/swapfile.c| 33 +++--
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index b83d36d..e303ad9 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -408,7 +408,7 @@ extern void swap_shmem_alloc(swp_entry_t);
 extern int swap_duplicate(swp_entry_t);
 extern int swapcache_prepare(swp_entry_t);
 extern void swap_free(swp_entry_t);
-extern void swapcache_free(swp_entry_t);
+extern void __swapcache_free(swp_entry_t, bool);
 extern int free_swap_and_cache(swp_entry_t);
 extern int swap_type_of(dev_t, sector_t, struct block_device **);
 extern unsigned int count_swap_pages(int, int);
@@ -480,7 +480,7 @@ static inline void swap_free(swp_entry_t swp)
 {
 }
 
-static inline void swapcache_free(swp_entry_t swp)
+static inline void __swapcache_free(swp_entry_t swp, bool huge)
 {
 }
 
@@ -551,6 +551,11 @@ static inline swp_entry_t get_huge_swap_page(void)
 
 #endif /* CONFIG_SWAP */
 
+static inline void swapcache_free(swp_entry_t entry)
+{
+   __swapcache_free(entry, false);
+}
+
 #ifdef CONFIG_MEMCG
 static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
 {
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 8224150..126c789 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -732,6 +732,27 @@ static void swap_free_huge_cluster(struct swap_info_struct 
*si,
__swap_entry_free(si, offset, true);
 }
 
+/*
+ * Caller should hold si->lock.
+ */
+static void swapcache_free_trans_huge(struct swap_info_struct *si,
+ swp_entry_t entry)
+{
+   unsigned long offset = swp_offset(entry);
+   unsigned long idx = offset / SWAPFILE_CLUSTER;
+   unsigned char *map;
+   unsigned int i;
+
+   map = si->swap_map + offset;
+   for (i = 0; i < SWAPFILE_CLUSTER; i++) {
+   VM_BUG_ON(map[i] != SWAP_HAS_CACHE);
+   map[i] &= ~SWAP_HAS_CACHE;
+   }
+   /* Cluster size is same as huge page size */
+   mem_cgroup_uncharge_swap(entry, HPAGE_PMD_NR);
+   swap_free_huge_cluster(si, idx);
+}
+
 static unsigned long swap_alloc_huge_cluster(struct swap_info_struct *si)
 {
unsigned long idx;
@@ -758,6 +779,11 @@ static inline unsigned long swap_alloc_huge_cluster(struct 
swap_info_struct *si)
 {
return 0;
 }
+
+static inline void swapcache_free_trans_huge(struct swap_info_struct *si,
+swp_entry_t entry)
+{
+}
 #endif
 
 swp_entry_t __get_swap_page(bool huge)
@@ -949,13 +975,16 @@ void swap_free(swp_entry_t entry)
 /*
  * Called after dropping swapcache to decrease refcnt to swap entries.
  */
-void swapcache_free(swp_entry_t entry)
+void __swapcache_free(swp_entry_t entry, bool huge)
 {
struct swap_info_struct *p;
 
p = swap_info_get(entry);
if (p) {
-   swap_entry_free(p, entry, SWAP_HAS_CACHE);
+   if (unlikely(huge))
+   swapcache_free_trans_huge(p, entry);
+   else
+   swap_entry_free(p, entry, SWAP_HAS_CACHE);
spin_unlock(&p->lock);
}
 }
-- 
2.9.3



[PATCH -v4 9/9] mm, THP, swap: Delay splitting THP during swap out

2016-09-28 Thread Huang, Ying
From: Huang Ying 

In this patch, splitting huge page is delayed from almost the first step
of swapping out to after allocating the swap space for the
THP (Transparent Huge Page) and adding the THP into the swap cache.
This will reduce lock acquiring/releasing for the locks used for the
swap cache management.

This is the first step for the THP swap support.  The plan is to delay
splitting the THP step by step and avoid splitting the THP finally.

The advantages of the THP swap support include:

- Batch the swap operations for the THP to reduce lock
  acquiring/releasing, including allocating/freeing the swap space,
  adding/deleting to/from the swap cache, and writing/reading the swap
  space, etc.  This will help to improve the THP swap performance.

- The THP swap space read/write will be 2M sequential IO.  It is
  particularly helpful for the swap read, which usually are 4k random
  IO.  This will help to improve the THP swap performance too.

- It will help the memory fragmentation, especially when the THP is
  heavily used by the applications.  The 2M continuous pages will be
  free up after the THP swapping out.

With the patchset, the swap out throughput improved 12.1% (from 1.12GB/s
to 1.25GB/s) in the vm-scalability swap-w-seq test case with 16
processes.  The test is done on a Xeon E5 v3 system.  The RAM simulated
PMEM (persistent memory) device is used as the swap device.  To test
sequential swapping out, the test case uses 16 processes sequentially
allocate and write to the anonymous pages until the RAM and part of the
swap device is used up.

The detailed compare result is as follow,

base base+patchset
 --
 %stddev %change %stddev
 \  |\
   1118821 ±  0% +12.1%1254241 ±  1%  vmstat.swap.so
   2460636 ±  1% +10.6%2720983 ±  1%  vm-scalability.throughput
308.79 ±  1%  -7.9% 284.53 ±  1%  vm-scalability.time.elapsed_time
  1639 ±  4%+232.3%   5446 ±  1%  meminfo.SwapCached
  0.70 ±  3%  +8.7%   0.77 ±  5%  perf-stat.ipc
  9.82 ±  8% -31.6%   6.72 ±  2%  
perf-profile.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list

Signed-off-by: "Huang, Ying" 
---
 mm/swap_state.c | 65 ++---
 1 file changed, 62 insertions(+), 3 deletions(-)

diff --git a/mm/swap_state.c b/mm/swap_state.c
index 3115762..b338523 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -175,12 +176,53 @@ void __delete_from_swap_cache(struct page *page)
ADD_CACHE_INFO(del_total, nr);
 }
 
+#ifdef CONFIG_THP_SWAP_CLUSTER
+int add_to_swap_trans_huge(struct page *page, struct list_head *list)
+{
+   swp_entry_t entry;
+   int ret = 0;
+
+   /* cannot split, which may be needed during swap in, skip it */
+   if (!can_split_huge_page(page))
+   return -EBUSY;
+   /* fallback to split huge page firstly if no PMD map */
+   if (!compound_mapcount(page))
+   return 0;
+   entry = get_huge_swap_page();
+   if (!entry.val)
+   return 0;
+   if (mem_cgroup_try_charge_swap(page, entry, HPAGE_PMD_NR)) {
+   __swapcache_free(entry, true);
+   return -EOVERFLOW;
+   }
+   ret = add_to_swap_cache(page, entry,
+   __GFP_HIGH | __GFP_NOMEMALLOC|__GFP_NOWARN);
+   /* -ENOMEM radix-tree allocation failure */
+   if (ret) {
+   __swapcache_free(entry, true);
+   return 0;
+   }
+   ret = split_huge_page_to_list(page, list);
+   if (ret) {
+   delete_from_swap_cache(page);
+   return -EBUSY;
+   }
+   return 1;
+}
+#else
+static inline int add_to_swap_trans_huge(struct page *page,
+struct list_head *list)
+{
+   return 0;
+}
+#endif
+
 /**
  * add_to_swap - allocate swap space for a page
  * @page: page we want to move to swap
  *
  * Allocate swap space for the page and add the page to the
- * swap cache.  Caller needs to hold the page lock. 
+ * swap cache.  Caller needs to hold the page lock.
  */
 int add_to_swap(struct page *page, struct list_head *list)
 {
@@ -190,6 +232,18 @@ int add_to_swap(struct page *page, struct list_head *list)
VM_BUG_ON_PAGE(!PageLocked(page), page);
VM_BUG_ON_PAGE(!PageUptodate(page), page);
 
+   if (unlikely(PageTransHuge(page))) {
+   err = add_to_swap_trans_huge(page, list);
+   switch (err) {
+   case 1:
+   return 1;
+   case 0:
+   /* fallback to split firstly if return 0 */
+   break;
+   default:
+   return 0;
+   }
+   }
entry = get_swa

[PATCH -v4 7/9] mm, THP: Add can_split_huge_page()

2016-09-28 Thread Huang, Ying
From: Huang Ying 

Separates checking whether we can split the huge page from
split_huge_page_to_list() into a function.  This will help to check that
before splitting the THP (Transparent Huge Page) really.

This will be used for delaying splitting THP during swapping out.  Where
for a THP, we will allocate a swap cluster, add the THP into the swap
cache, then split the THP.  To avoid the unnecessary operations for the
un-splittable THP, we will check that firstly.

There is no functionality change in this patch.

Cc: Andrea Arcangeli 
Cc: Kirill A. Shutemov 
Cc: Ebru Akagunduz 
Signed-off-by: "Huang, Ying" 
---
 include/linux/huge_mm.h |  7 +++
 mm/huge_memory.c| 13 -
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 9b9f65d..14ffa3f 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -94,6 +94,7 @@ extern unsigned long thp_get_unmapped_area(struct file *filp,
 extern void prep_transhuge_page(struct page *page);
 extern void free_transhuge_page(struct page *page);
 
+bool can_split_huge_page(struct page *page);
 int split_huge_page_to_list(struct page *page, struct list_head *list);
 static inline int split_huge_page(struct page *page)
 {
@@ -176,6 +177,12 @@ static inline void prep_transhuge_page(struct page *page) 
{}
 
 #define thp_get_unmapped_area  NULL
 
+static inline bool
+can_split_huge_page(struct page *page)
+{
+   BUILD_BUG();
+   return false;
+}
 static inline int
 split_huge_page_to_list(struct page *page, struct list_head *list)
 {
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 1d558fc..c856a7c 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2016,6 +2016,17 @@ int page_trans_huge_mapcount(struct page *page, int 
*total_mapcount)
return ret;
 }
 
+/* Racy check whether the huge page can be split */
+bool can_split_huge_page(struct page *page)
+{
+   int extra_pins = 0;
+
+   /* Additional pins from radix tree */
+   if (!PageAnon(page))
+   extra_pins = HPAGE_PMD_NR;
+   return total_mapcount(page) == page_count(page) - extra_pins - 1;
+}
+
 /*
  * This function splits huge page into normal pages. @page can point to any
  * subpage of huge page to split. Split doesn't change the position of @page.
@@ -2086,7 +2097,7 @@ int split_huge_page_to_list(struct page *page, struct 
list_head *list)
 * Racy check if we can split the page, before freeze_page() will
 * split PMDs
 */
-   if (total_mapcount(head) != page_count(head) - extra_pins - 1) {
+   if (!can_split_huge_page(head)) {
ret = -EBUSY;
goto out_unlock;
}
-- 
2.9.3



[PATCH] Subject: [PATCH -v4] THP swap: Delay splitting THP during swapping out

2016-09-28 Thread Huang, Ying
From: Huang Ying 

Johannes suggested me to use two big patches instead 9 patches.  And he
feels that is easier for him to review.  I am not sure whether this is
desirable for other reviewers too.  So I sent out both versions for
review.  If this version is preferable for more reviewers, I will take
this way.  Otherwise, I will still use the traditional 9 patches version
as main version and use this version for review by some reviewers.

Because of that, I didn't separate can_split_huge_page() etc. code into
a separate patch as Johannes suggested for now.  And the patch
description should be improved if big patches are chosen finally.

This patchset is to optimize the performance of Transparent Huge Page
(THP) swap.

Hi, Andrew, could you help me to check whether the overall design is
reasonable?

Hi, Hugh, Shaohua, Minchan and Rik, could you help me to review the
swap part of the patchset?  Especially [01/10], [04/10], [05/10],
[06/10], [07/10], [10/10].

Hi, Andrea and Kirill, could you help me to review the THP part of the
patchset?  Especially [02/10], [03/10], [09/10] and [10/10].

Hi, Johannes, Michal and Vladimir, I am not very confident about the
memory cgroup part, especially [02/10] and [03/10].  Could you help me
to review it?

And for all, Any comment is welcome!

Recently, the performance of the storage devices improved so fast that
we cannot saturate the disk bandwidth when do page swap out even on a
high-end server machine.  Because the performance of the storage
device improved faster than that of CPU.  And it seems that the trend
will not change in the near future.  On the other hand, the THP
becomes more and more popular because of increased memory size.  So it
becomes necessary to optimize THP swap performance.

The advantages of the THP swap support include:

- Batch the swap operations for the THP to reduce lock
  acquiring/releasing, including allocating/freeing the swap space,
  adding/deleting to/from the swap cache, and writing/reading the swap
  space, etc.  This will help improve the performance of the THP swap.

- The THP swap space read/write will be 2M sequential IO.  It is
  particularly helpful for the swap read, which are usually 4k random
  IO.  This will improve the performance of the THP swap too.

- It will help the memory fragmentation, especially when the THP is
  heavily used by the applications.  The 2M continuous pages will be
  free up after THP swapping out.

- It will improve the THP utilization on the system with the swap
  turned on.  Because the speed for khugepaged to collapse the normal
  pages into the THP is quite slow.  After the THP is split during the
  swapping out, it will take quite long time for the normal pages to
  collapse back into the THP after being swapped in.  The high THP
  utilization helps the efficiency of the page based memory management
  too.

This patchset is based on 9/20 head of mmotm/master.

This patchset is the first step for the THP swap support.  The plan is
to delay splitting THP step by step, finally avoid splitting THP
during the THP swapping out and swap out/in the THP as a whole.

As the first step, in this patchset, the splitting huge page is
delayed from almost the first step of swapping out to after allocating
the swap space for the THP and adding the THP into the swap cache.
This will reduce lock acquiring/releasing for the locks used for the
swap cache management.

With the patchset, the swap out throughput improves 12.1% (from about
1.12GB/s to about 1.25GB/s) in the vm-scalability swap-w-seq test case
with 16 processes.  The test is done on a Xeon E5 v3 system.  The swap
device used is a RAM simulated PMEM (persistent memory) device.  To
test the sequential swapping out, the test case uses 16 processes,
which sequentially allocate and write to the anonymous pages until the
RAM and part of the swap device is used up.

The detailed compare result is as follow,

base base+patchset
 --
 %stddev %change %stddev
 \  |\
   1118821 ±  0% +12.1%1254241 ±  1%  vmstat.swap.so
   2460636 ±  1% +10.6%2720983 ±  1%  vm-scalability.throughput
308.79 ±  1%  -7.9% 284.53 ±  1%  vm-scalability.time.elapsed_time
  1639 ±  4%+232.3%   5446 ±  1%  meminfo.SwapCached
  0.70 ±  3%  +8.7%   0.77 ±  5%  perf-stat.ipc
  9.82 ±  8% -31.6%   6.72 ±  2%  
perf-profile.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list

>From the swap out throughput number, we can find, even tested on a RAM
simulated PMEM (Persistent Memory) device, the swap out throughput can
reach only about 1.1GB/s.  While, in the file IO test, the sequential
write throughput of an Intel P3700 SSD can reach about 1.8GB/s
steadily.  And according the following URL,

https://www-ssl.intel.com/content/www/us/en/solid-state-drives/intel-ssd-dc-family-for-pcie.html

[PATCH -v4 3/9] mm, THP, swap: Add swap cluster allocate/free functions

2016-09-28 Thread Huang, Ying
From: Huang Ying 

The swap cluster allocation/free functions are added based on the
existing swap cluster management mechanism for SSD.  These functions
don't work for the rotating hard disks because the existing swap cluster
management mechanism doesn't work for them.  The hard disks support may
be added if someone really need it.  But that needn't be included in
this patchset.

This will be used for the THP (Transparent Huge Page) swap support.
Where one swap cluster will hold the contents of each THP swapped out.

Cc: Andrea Arcangeli 
Cc: Kirill A. Shutemov 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Minchan Kim 
Cc: Rik van Riel 
Signed-off-by: "Huang, Ying" 
---
 mm/swapfile.c | 203 +-
 1 file changed, 146 insertions(+), 57 deletions(-)

diff --git a/mm/swapfile.c b/mm/swapfile.c
index f3fc83f..3643049 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -326,6 +326,14 @@ static void swap_cluster_schedule_discard(struct 
swap_info_struct *si,
schedule_work(&si->discard_work);
 }
 
+static void __free_cluster(struct swap_info_struct *si, unsigned long idx)
+{
+   struct swap_cluster_info *ci = si->cluster_info;
+
+   cluster_set_flag(ci + idx, CLUSTER_FLAG_FREE);
+   cluster_list_add_tail(&si->free_clusters, ci, idx);
+}
+
 /*
  * Doing discard actually. After a cluster discard is finished, the cluster
  * will be added to free cluster list. caller should hold si->lock.
@@ -345,8 +353,7 @@ static void swap_do_scheduled_discard(struct 
swap_info_struct *si)
SWAPFILE_CLUSTER);
 
spin_lock(&si->lock);
-   cluster_set_flag(&info[idx], CLUSTER_FLAG_FREE);
-   cluster_list_add_tail(&si->free_clusters, info, idx);
+   __free_cluster(si, idx);
memset(si->swap_map + idx * SWAPFILE_CLUSTER,
0, SWAPFILE_CLUSTER);
}
@@ -363,6 +370,34 @@ static void swap_discard_work(struct work_struct *work)
spin_unlock(&si->lock);
 }
 
+static void alloc_cluster(struct swap_info_struct *si, unsigned long idx)
+{
+   struct swap_cluster_info *ci = si->cluster_info;
+
+   VM_BUG_ON(cluster_list_first(&si->free_clusters) != idx);
+   cluster_list_del_first(&si->free_clusters, ci);
+   cluster_set_count_flag(ci + idx, 0, 0);
+}
+
+static void free_cluster(struct swap_info_struct *si, unsigned long idx)
+{
+   struct swap_cluster_info *ci = si->cluster_info + idx;
+
+   VM_BUG_ON(cluster_count(ci) != 0);
+   /*
+* If the swap is discardable, prepare discard the cluster
+* instead of free it immediately. The cluster will be freed
+* after discard.
+*/
+   if ((si->flags & (SWP_WRITEOK | SWP_PAGE_DISCARD)) ==
+   (SWP_WRITEOK | SWP_PAGE_DISCARD)) {
+   swap_cluster_schedule_discard(si, idx);
+   return;
+   }
+
+   __free_cluster(si, idx);
+}
+
 /*
  * The cluster corresponding to page_nr will be used. The cluster will be
  * removed from free cluster list and its usage counter will be increased.
@@ -374,11 +409,8 @@ static void inc_cluster_info_page(struct swap_info_struct 
*p,
 
if (!cluster_info)
return;
-   if (cluster_is_free(&cluster_info[idx])) {
-   VM_BUG_ON(cluster_list_first(&p->free_clusters) != idx);
-   cluster_list_del_first(&p->free_clusters, cluster_info);
-   cluster_set_count_flag(&cluster_info[idx], 0, 0);
-   }
+   if (cluster_is_free(&cluster_info[idx]))
+   alloc_cluster(p, idx);
 
VM_BUG_ON(cluster_count(&cluster_info[idx]) >= SWAPFILE_CLUSTER);
cluster_set_count(&cluster_info[idx],
@@ -402,21 +434,8 @@ static void dec_cluster_info_page(struct swap_info_struct 
*p,
cluster_set_count(&cluster_info[idx],
cluster_count(&cluster_info[idx]) - 1);
 
-   if (cluster_count(&cluster_info[idx]) == 0) {
-   /*
-* If the swap is discardable, prepare discard the cluster
-* instead of free it immediately. The cluster will be freed
-* after discard.
-*/
-   if ((p->flags & (SWP_WRITEOK | SWP_PAGE_DISCARD)) ==
-(SWP_WRITEOK | SWP_PAGE_DISCARD)) {
-   swap_cluster_schedule_discard(p, idx);
-   return;
-   }
-
-   cluster_set_flag(&cluster_info[idx], CLUSTER_FLAG_FREE);
-   cluster_list_add_tail(&p->free_clusters, cluster_info, idx);
-   }
+   if (cluster_count(&cluster_info[idx]) == 0)
+   free_cluster(p, idx);
 }
 
 /*
@@ -497,6 +516,69 @@ static void scan_swap_map_try_ssd_cluster(struct 
swap_info_struct *si,
*scan_base = tmp;
 }
 
+#ifdef CONFIG_THP_SWAP_CLUSTER
+static inline unsigned int huge_cluster_nr_entries(bool huge)
+{
+   return huge ? SWAPFILE_CLUSTER 

[PATCH -v4 1/9] mm, swap: Make swap cluster size same of THP size on x86_64

2016-09-28 Thread Huang, Ying
From: Huang Ying 

In this patch, the size of the swap cluster is changed to that of the
THP (Transparent Huge Page) on x86_64 architecture (512).  This is for
the THP swap support on x86_64.  Where one swap cluster will be used to
hold the contents of each THP swapped out.  And some information of the
swapped out THP (such as compound map count) will be recorded in the
swap_cluster_info data structure.

For other architectures which want THP swap support,
ARCH_USES_THP_SWAP_CLUSTER need to be selected in the Kconfig file for
the architecture.

In effect, this will enlarge swap cluster size by 2 times on x86_64.
Which may make it harder to find a free cluster when the swap space
becomes fragmented.  So that, this may reduce the continuous swap space
allocation and sequential write in theory.  The performance test in 0day
shows no regressions caused by this.

Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Minchan Kim 
Cc: Rik van Riel 
Suggested-by: Andrew Morton 
Signed-off-by: "Huang, Ying" 
---
 arch/x86/Kconfig |  1 +
 mm/Kconfig   | 13 +
 mm/swapfile.c|  4 
 3 files changed, 18 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 68a166d..0a29bcc 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -164,6 +164,7 @@ config X86
select HAVE_STACK_VALIDATIONif X86_64
select ARCH_USES_HIGH_VMA_FLAGS if 
X86_INTEL_MEMORY_PROTECTION_KEYS
select ARCH_HAS_PKEYS   if 
X86_INTEL_MEMORY_PROTECTION_KEYS
+   select ARCH_USES_THP_SWAP_CLUSTER   if X86_64
 
 config INSTRUCTION_DECODER
def_bool y
diff --git a/mm/Kconfig b/mm/Kconfig
index be0ee11..2da8128 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -503,6 +503,19 @@ config FRONTSWAP
 
  If unsure, say Y to enable frontswap.
 
+config ARCH_USES_THP_SWAP_CLUSTER
+   bool
+   default n
+
+config THP_SWAP_CLUSTER
+   bool
+   depends on SWAP && TRANSPARENT_HUGEPAGE && ARCH_USES_THP_SWAP_CLUSTER
+   default y
+   help
+ Use one swap cluster to hold the contents of the THP
+ (Transparent Huge Page) swapped out.  The size of the swap
+ cluster will be same as that of THP.
+
 config CMA
bool "Contiguous Memory Allocator"
depends on HAVE_MEMBLOCK && MMU
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 2210de2..18e247b 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -196,7 +196,11 @@ static void discard_swap_cluster(struct swap_info_struct 
*si,
}
 }
 
+#ifdef CONFIG_THP_SWAP_CLUSTER
+#define SWAPFILE_CLUSTER   HPAGE_PMD_NR
+#else
 #define SWAPFILE_CLUSTER   256
+#endif
 #define LATENCY_LIMIT  256
 
 static inline void cluster_set_flag(struct swap_cluster_info *info,
-- 
2.9.3



[PATCH -v4 4/9] mm, THP, swap: Add get_huge_swap_page()

2016-09-28 Thread Huang, Ying
From: Huang Ying 

A variation of get_swap_page(), get_huge_swap_page(), is added to
allocate a swap cluster (HPAGE_PMD_NR swap slots) based on the swap
cluster allocation function.  A fair simple algorithm is used, that is,
only the first swap device in priority list will be tried to allocate
the swap cluster.  The function will fail if the trying is not
successful, and the caller will fallback to allocate a single swap slot
instead.  This works good enough for normal cases.

This will be used for the THP (Transparent Huge Page) swap support.
Where get_huge_swap_page() will be used to allocate one swap cluster for
each THP swapped out.

Because of the algorithm adopted, if the difference of the number of the
free swap clusters among multiple swap devices is significant, it is
possible that some THPs are split earlier than necessary.  For example,
this could be caused by big size difference among multiple swap devices.

Cc: Andrea Arcangeli 
Cc: Kirill A. Shutemov 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Minchan Kim 
Cc: Rik van Riel 
Signed-off-by: "Huang, Ying" 
---
 include/linux/swap.h | 24 +++-
 mm/swapfile.c| 18 --
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 4650963..b83d36d 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -401,7 +401,7 @@ static inline long get_nr_swap_pages(void)
 }
 
 extern void si_swapinfo(struct sysinfo *);
-extern swp_entry_t get_swap_page(void);
+extern swp_entry_t __get_swap_page(bool huge);
 extern swp_entry_t get_swap_page_of_type(int);
 extern int add_swap_count_continuation(swp_entry_t, gfp_t);
 extern void swap_shmem_alloc(swp_entry_t);
@@ -421,6 +421,23 @@ extern bool reuse_swap_page(struct page *, int *);
 extern int try_to_free_swap(struct page *);
 struct backing_dev_info;
 
+static inline swp_entry_t get_swap_page(void)
+{
+   return __get_swap_page(false);
+}
+
+#ifdef CONFIG_THP_SWAP_CLUSTER
+static inline swp_entry_t get_huge_swap_page(void)
+{
+   return __get_swap_page(true);
+}
+#else
+static inline swp_entry_t get_huge_swap_page(void)
+{
+   return (swp_entry_t) {0};
+}
+#endif
+
 #else /* CONFIG_SWAP */
 
 #define swap_address_space(entry)  (NULL)
@@ -527,6 +544,11 @@ static inline swp_entry_t get_swap_page(void)
return entry;
 }
 
+static inline swp_entry_t get_huge_swap_page(void)
+{
+   return (swp_entry_t) {0};
+}
+
 #endif /* CONFIG_SWAP */
 
 #ifdef CONFIG_MEMCG
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 3643049..8224150 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -760,14 +760,15 @@ static inline unsigned long 
swap_alloc_huge_cluster(struct swap_info_struct *si)
 }
 #endif
 
-swp_entry_t get_swap_page(void)
+swp_entry_t __get_swap_page(bool huge)
 {
struct swap_info_struct *si, *next;
pgoff_t offset;
+   int nr_pages = huge_cluster_nr_entries(huge);
 
-   if (atomic_long_read(&nr_swap_pages) <= 0)
+   if (atomic_long_read(&nr_swap_pages) < nr_pages)
goto noswap;
-   atomic_long_dec(&nr_swap_pages);
+   atomic_long_sub(nr_pages, &nr_swap_pages);
 
spin_lock(&swap_avail_lock);
 
@@ -795,10 +796,15 @@ swp_entry_t get_swap_page(void)
}
 
/* This is called for allocating swap entry for cache */
-   offset = scan_swap_map(si, SWAP_HAS_CACHE);
+   if (likely(nr_pages == 1))
+   offset = scan_swap_map(si, SWAP_HAS_CACHE);
+   else
+   offset = swap_alloc_huge_cluster(si);
spin_unlock(&si->lock);
if (offset)
return swp_entry(si->type, offset);
+   else if (unlikely(nr_pages != 1))
+   goto fail_alloc;
pr_debug("scan_swap_map of si %d failed to find offset\n",
   si->type);
spin_lock(&swap_avail_lock);
@@ -818,8 +824,8 @@ swp_entry_t get_swap_page(void)
}
 
spin_unlock(&swap_avail_lock);
-
-   atomic_long_inc(&nr_swap_pages);
+fail_alloc:
+   atomic_long_add(nr_pages, &nr_swap_pages);
 noswap:
return (swp_entry_t) {0};
 }
-- 
2.9.3



[PATCH -v4 2/9] mm, memcg: Support to charge/uncharge multiple swap entries

2016-09-28 Thread Huang, Ying
From: Huang Ying 

This patch make it possible to charge or uncharge a set of continuous
swap entries in the swap cgroup.  The number of swap entries is
specified via an added parameter.

This will be used for the THP (Transparent Huge Page) swap support.
Where a swap cluster backing a THP may be allocated and freed as a
whole.  So a set of (HPAGE_PMD_NR) continuous swap entries backing one
THP need to be charged or uncharged together.  This will batch the
cgroup operations for the THP swap too.

Cc: Andrea Arcangeli 
Cc: Kirill A. Shutemov 
Cc: Vladimir Davydov 
Cc: Johannes Weiner 
Cc: Michal Hocko 
Cc: Tejun Heo 
Cc: cgro...@vger.kernel.org
Signed-off-by: "Huang, Ying" 
---
 include/linux/swap.h| 12 ++
 include/linux/swap_cgroup.h |  6 +++--
 mm/memcontrol.c | 55 +
 mm/shmem.c  |  2 +-
 mm/swap_cgroup.c| 40 -
 mm/swap_state.c |  2 +-
 mm/swapfile.c   |  2 +-
 7 files changed, 76 insertions(+), 43 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 7e553e1..4650963 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -552,8 +552,10 @@ static inline int mem_cgroup_swappiness(struct mem_cgroup 
*mem)
 
 #ifdef CONFIG_MEMCG_SWAP
 extern void mem_cgroup_swapout(struct page *page, swp_entry_t entry);
-extern int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry);
-extern void mem_cgroup_uncharge_swap(swp_entry_t entry);
+extern int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry,
+ unsigned int nr_entries);
+extern void mem_cgroup_uncharge_swap(swp_entry_t entry,
+unsigned int nr_entries);
 extern long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg);
 extern bool mem_cgroup_swap_full(struct page *page);
 #else
@@ -562,12 +564,14 @@ static inline void mem_cgroup_swapout(struct page *page, 
swp_entry_t entry)
 }
 
 static inline int mem_cgroup_try_charge_swap(struct page *page,
-swp_entry_t entry)
+swp_entry_t entry,
+unsigned int nr_entries)
 {
return 0;
 }
 
-static inline void mem_cgroup_uncharge_swap(swp_entry_t entry)
+static inline void mem_cgroup_uncharge_swap(swp_entry_t entry,
+   unsigned int nr_entries)
 {
 }
 
diff --git a/include/linux/swap_cgroup.h b/include/linux/swap_cgroup.h
index 145306b..b2b8ec7 100644
--- a/include/linux/swap_cgroup.h
+++ b/include/linux/swap_cgroup.h
@@ -7,7 +7,8 @@
 
 extern unsigned short swap_cgroup_cmpxchg(swp_entry_t ent,
unsigned short old, unsigned short new);
-extern unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id);
+extern unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id,
+unsigned int nr_ents);
 extern unsigned short lookup_swap_cgroup_id(swp_entry_t ent);
 extern int swap_cgroup_swapon(int type, unsigned long max_pages);
 extern void swap_cgroup_swapoff(int type);
@@ -15,7 +16,8 @@ extern void swap_cgroup_swapoff(int type);
 #else
 
 static inline
-unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id)
+unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id,
+ unsigned int nr_ents)
 {
return 0;
 }
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index ae052b5..581f705 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2383,10 +2383,9 @@ void mem_cgroup_split_huge_fixup(struct page *head)
 
 #ifdef CONFIG_MEMCG_SWAP
 static void mem_cgroup_swap_statistics(struct mem_cgroup *memcg,
-bool charge)
+  int nr_entries)
 {
-   int val = (charge) ? 1 : -1;
-   this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_SWAP], val);
+   this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_SWAP], nr_entries);
 }
 
 /**
@@ -2412,8 +2411,8 @@ static int mem_cgroup_move_swap_account(swp_entry_t entry,
new_id = mem_cgroup_id(to);
 
if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) {
-   mem_cgroup_swap_statistics(from, false);
-   mem_cgroup_swap_statistics(to, true);
+   mem_cgroup_swap_statistics(from, -1);
+   mem_cgroup_swap_statistics(to, 1);
return 0;
}
return -EINVAL;
@@ -5433,7 +5432,7 @@ void mem_cgroup_commit_charge(struct page *page, struct 
mem_cgroup *memcg,
 * let's not wait for it.  The page already received a
 * memory+swap charge, drop the swap entry duplicate.
 */
-   mem_cgroup_uncharge_swap(entry);
+   mem_cgroup_uncharge_swap(entry, nr_pages);
}
 

[PATCH -v4 8/9] mm, THP, swap: Support to split THP in swap cache

2016-09-28 Thread Huang, Ying
From: Huang Ying 

This patch enhanced the split_huge_page_to_list() to work properly for
the THP (Transparent Huge Page) in the swap cache during swapping out.

This is used for delaying splitting the THP during swapping out.  Where
for a THP to be swapped out, we will allocate a swap cluster, add the
THP into the swap cache, then split the THP.  The page lock will be held
during this process.  So in the code path other than swapping out, if
the THP need to be split, the PageSwapCache(THP) will be always false.

Cc: Andrea Arcangeli 
Cc: Kirill A. Shutemov 
Cc: Ebru Akagunduz 
Signed-off-by: "Huang, Ying" 
---
 mm/huge_memory.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index c856a7c..c58e032 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1834,7 +1834,7 @@ static void __split_huge_page_tail(struct page *head, int 
tail,
 * atomic_set() here would be safe on all archs (and not only on x86),
 * it's safer to use atomic_inc()/atomic_add().
 */
-   if (PageAnon(head)) {
+   if (PageAnon(head) && !PageSwapCache(head)) {
page_ref_inc(page_tail);
} else {
/* Additional pin to radix tree */
@@ -1845,6 +1845,7 @@ static void __split_huge_page_tail(struct page *head, int 
tail,
page_tail->flags |= (head->flags &
((1L << PG_referenced) |
 (1L << PG_swapbacked) |
+(1L << PG_swapcache) |
 (1L << PG_mlocked) |
 (1L << PG_uptodate) |
 (1L << PG_active) |
@@ -1907,7 +1908,11 @@ static void __split_huge_page(struct page *page, struct 
list_head *list,
ClearPageCompound(head);
/* See comment in __split_huge_page_tail() */
if (PageAnon(head)) {
-   page_ref_inc(head);
+   /* Additional pin to radix tree of swap cache */
+   if (PageSwapCache(head))
+   page_ref_add(head, 2);
+   else
+   page_ref_inc(head);
} else {
/* Additional pin to radix tree */
page_ref_add(head, 2);
@@ -2019,10 +2024,12 @@ int page_trans_huge_mapcount(struct page *page, int 
*total_mapcount)
 /* Racy check whether the huge page can be split */
 bool can_split_huge_page(struct page *page)
 {
-   int extra_pins = 0;
+   int extra_pins;
 
/* Additional pins from radix tree */
-   if (!PageAnon(page))
+   if (PageAnon(page))
+   extra_pins = PageSwapCache(page) ? HPAGE_PMD_NR : 0;
+   else
extra_pins = HPAGE_PMD_NR;
return total_mapcount(page) == page_count(page) - extra_pins - 1;
 }
@@ -2075,7 +2082,7 @@ int split_huge_page_to_list(struct page *page, struct 
list_head *list)
ret = -EBUSY;
goto out;
}
-   extra_pins = 0;
+   extra_pins = PageSwapCache(head) ? HPAGE_PMD_NR : 0;
mapping = NULL;
anon_vma_lock_write(anon_vma);
} else {
-- 
2.9.3



[PATCH -v4 6/9] mm, THP, swap: Support to add/delete THP to/from swap cache

2016-09-28 Thread Huang, Ying
From: Huang Ying 

With this patch, a THP (Transparent Huge Page) can be added/deleted
to/from the swap cache as a set of (HPAGE_PMD_NR) sub-pages.

This will be used for the THP (Transparent Huge Page) swap support.
Where one THP may be added/delted to/from the swap cache.  This will
batch the swap cache operations to reduce the lock acquire/release times
for the THP swap too.

Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Minchan Kim 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: Kirill A. Shutemov 
Signed-off-by: "Huang, Ying" 
---
 include/linux/page-flags.h |  2 +-
 mm/swap_state.c| 58 --
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 74e4dda..f5bcbea 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -314,7 +314,7 @@ PAGEFLAG_FALSE(HighMem)
 #endif
 
 #ifdef CONFIG_SWAP
-PAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND)
+PAGEFLAG(SwapCache, swapcache, PF_NO_TAIL)
 #else
 PAGEFLAG_FALSE(SwapCache)
 #endif
diff --git a/mm/swap_state.c b/mm/swap_state.c
index d3f047b..3115762 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -43,6 +43,7 @@ struct address_space swapper_spaces[MAX_SWAPFILES] = {
 };
 
 #define INC_CACHE_INFO(x)  do { swap_cache_info.x++; } while (0)
+#define ADD_CACHE_INFO(x, nr)  do { swap_cache_info.x += (nr); } while (0)
 
 static struct {
unsigned long add_total;
@@ -80,25 +81,33 @@ void show_swap_cache_info(void)
  */
 int __add_to_swap_cache(struct page *page, swp_entry_t entry)
 {
-   int error;
+   int error, i, nr = hpage_nr_pages(page);
struct address_space *address_space;
+   struct page *cur_page;
+   swp_entry_t cur_entry;
 
VM_BUG_ON_PAGE(!PageLocked(page), page);
VM_BUG_ON_PAGE(PageSwapCache(page), page);
VM_BUG_ON_PAGE(!PageSwapBacked(page), page);
 
-   get_page(page);
+   page_ref_add(page, nr);
SetPageSwapCache(page);
-   set_page_private(page, entry.val);
 
address_space = swap_address_space(entry);
+   cur_page = page;
+   cur_entry.val = entry.val;
spin_lock_irq(&address_space->tree_lock);
-   error = radix_tree_insert(&address_space->page_tree,
- swp_offset(entry), page);
+   for (i = 0; i < nr; i++, cur_page++, cur_entry.val++) {
+   set_page_private(cur_page, cur_entry.val);
+   error = radix_tree_insert(&address_space->page_tree,
+ swp_offset(cur_entry), cur_page);
+   if (unlikely(error))
+   break;
+   }
if (likely(!error)) {
-   address_space->nrpages++;
-   __inc_node_page_state(page, NR_FILE_PAGES);
-   INC_CACHE_INFO(add_total);
+   address_space->nrpages += nr;
+   __mod_node_page_state(page_pgdat(page), NR_FILE_PAGES, nr);
+   ADD_CACHE_INFO(add_total, nr);
}
spin_unlock_irq(&address_space->tree_lock);
 
@@ -109,9 +118,16 @@ int __add_to_swap_cache(struct page *page, swp_entry_t 
entry)
 * So add_to_swap_cache() doesn't returns -EEXIST.
 */
VM_BUG_ON(error == -EEXIST);
-   set_page_private(page, 0UL);
ClearPageSwapCache(page);
-   put_page(page);
+   set_page_private(cur_page, 0UL);
+   while (i--) {
+   cur_page--;
+   cur_entry.val--;
+   set_page_private(cur_page, 0UL);
+   radix_tree_delete(&address_space->page_tree,
+ swp_offset(cur_entry));
+   }
+   page_ref_sub(page, nr);
}
 
return error;
@@ -122,7 +138,7 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, 
gfp_t gfp_mask)
 {
int error;
 
-   error = radix_tree_maybe_preload(gfp_mask);
+   error = radix_tree_maybe_preload_order(gfp_mask, compound_order(page));
if (!error) {
error = __add_to_swap_cache(page, entry);
radix_tree_preload_end();
@@ -138,6 +154,7 @@ void __delete_from_swap_cache(struct page *page)
 {
swp_entry_t entry;
struct address_space *address_space;
+   int i, nr = hpage_nr_pages(page);
 
VM_BUG_ON_PAGE(!PageLocked(page), page);
VM_BUG_ON_PAGE(!PageSwapCache(page), page);
@@ -145,12 +162,17 @@ void __delete_from_swap_cache(struct page *page)
 
entry.val = page_private(page);
address_space = swap_address_space(entry);
-   radix_tree_delete(&address_space->page_tree, swp_offset(entry));
-   set_page_private(page, 0);
ClearPageSwapCache(page);
-   address_space->nrpages--;
-   __dec_node_page_state(page, NR_FILE_PAGES);
-   INC_CACHE_INFO(del_total);
+   for (i = 0; i < nr; i++, entry

[PATCH -v4 00/10] THP swap: Delay splitting THP during swapping out

2016-09-28 Thread Huang, Ying
From: Huang Ying 

This patchset is to optimize the performance of Transparent Huge Page
(THP) swap.

Hi, Andrew, could you help me to check whether the overall design is
reasonable?

Hi, Hugh, Shaohua, Minchan and Rik, could you help me to review the
swap part of the patchset?  Especially [01/10], [04/10], [05/10],
[06/10], [07/10], [10/10].

Hi, Andrea and Kirill, could you help me to review the THP part of the
patchset?  Especially [02/10], [03/10], [09/10] and [10/10].

Hi, Johannes, Michal and Vladimir, I am not very confident about the
memory cgroup part, especially [02/10] and [03/10].  Could you help me
to review it?

And for all, Any comment is welcome!


Recently, the performance of the storage devices improved so fast that
we cannot saturate the disk bandwidth when do page swap out even on a
high-end server machine.  Because the performance of the storage
device improved faster than that of CPU.  And it seems that the trend
will not change in the near future.  On the other hand, the THP
becomes more and more popular because of increased memory size.  So it
becomes necessary to optimize THP swap performance.

The advantages of the THP swap support include:

- Batch the swap operations for the THP to reduce lock
  acquiring/releasing, including allocating/freeing the swap space,
  adding/deleting to/from the swap cache, and writing/reading the swap
  space, etc.  This will help improve the performance of the THP swap.

- The THP swap space read/write will be 2M sequential IO.  It is
  particularly helpful for the swap read, which are usually 4k random
  IO.  This will improve the performance of the THP swap too.

- It will help the memory fragmentation, especially when the THP is
  heavily used by the applications.  The 2M continuous pages will be
  free up after THP swapping out.

- It will improve the THP utilization on the system with the swap
  turned on.  Because the speed for khugepaged to collapse the normal
  pages into the THP is quite slow.  After the THP is split during the
  swapping out, it will take quite long time for the normal pages to
  collapse back into the THP after being swapped in.  The high THP
  utilization helps the efficiency of the page based memory management
  too.


This patchset is based on 9/20 head of mmotm/master.

This patchset is the first step for the THP swap support.  The plan is
to delay splitting THP step by step, finally avoid splitting THP
during the THP swapping out and swap out/in the THP as a whole.

As the first step, in this patchset, the splitting huge page is
delayed from almost the first step of swapping out to after allocating
the swap space for the THP and adding the THP into the swap cache.
This will reduce lock acquiring/releasing for the locks used for the
swap cache management.

With the patchset, the swap out throughput improves 12.1% (from about
1.12GB/s to about 1.25GB/s) in the vm-scalability swap-w-seq test case
with 16 processes.  The test is done on a Xeon E5 v3 system.  The swap
device used is a RAM simulated PMEM (persistent memory) device.  To
test the sequential swapping out, the test case uses 16 processes,
which sequentially allocate and write to the anonymous pages until the
RAM and part of the swap device is used up.

The detailed compare result is as follow,

base base+patchset
 -- 
 %stddev %change %stddev
 \  |\  
   1118821 ±  0% +12.1%1254241 ±  1%  vmstat.swap.so
   2460636 ±  1% +10.6%2720983 ±  1%  vm-scalability.throughput
308.79 ±  1%  -7.9% 284.53 ±  1%  vm-scalability.time.elapsed_time
  1639 ±  4%+232.3%   5446 ±  1%  meminfo.SwapCached
  0.70 ±  3%  +8.7%   0.77 ±  5%  perf-stat.ipc
  9.82 ±  8% -31.6%   6.72 ±  2%  
perf-profile.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list


>From the swap out throughput number, we can find, even tested on a RAM
simulated PMEM (Persistent Memory) device, the swap out throughput can
reach only about 1.1GB/s.  While, in the file IO test, the sequential
write throughput of an Intel P3700 SSD can reach about 1.8GB/s
steadily.  And according the following URL,

https://www-ssl.intel.com/content/www/us/en/solid-state-drives/intel-ssd-dc-family-for-pcie.html

The sequential write throughput of Intel P3608 SSD can reach about
3.0GB/s, while the random read IOPS can reach about 850k.  It is clear
that the bottleneck has moved from the disk to the kernel swap
component itself.

The improved storage device performance should have made the swap
becomes a better feature than before with better performance.  But
because of the issues of kernel swap component itself, the swap
performance is still kept at the low level.  That prevents the swap
feature to be used by more users.  And this in turn causes few kernel
developers think it is necessary to optimize kernel swap compon

linux-next: Tree for Sep 29

2016-09-28 Thread Stephen Rothwell
Hi all,

Changes since 20160928:

The xtensa tree gained a conflict against Linus' tree.

The tip tree gained a conflict against the vfs tree and a build failure
due to an interaction with the pm tree for which I added a merge fix
patch.

Non-merge commits (relative to Linus' tree): 13043
 9796 files changed, 537508 insertions(+), 295801 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc and an allmodconfig (with
CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a
native build of tools/perf. After the final fixups (if any), I do an
x86_64 modules_install followed by builds for x86_64 allnoconfig,
powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig
(this fails its final link) and pseries_le_defconfig and i386, sparc
and sparc64 defconfig.

Below is a summary of the state of the merge.

I am currently merging 243 trees (counting Linus' and 34 trees of patches
pending for Linus' tree).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (ae6dd8d61913 Merge tag 'for-linus-20160928' of 
git://git.infradead.org/linux-mtd)
Merging fixes/master (d3396e1e4ec4 Merge tag 'fixes-for-linus' of 
git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc)
Merging kbuild-current/rc-fixes (d3e2773c4ede builddeb: Skip gcc-plugins when 
not configured)
Merging arc-current/for-curr (3eab887a5542 Linux 4.8-rc4)
Merging arm-current/fixes (1a57c286d8ce ARM: pxa/lubbock: add pcmcia clock)
Merging m68k-current/for-linus (6bd80f372371 m68k/defconfig: Update defconfigs 
for v4.7-rc2)
Merging metag-fixes/fixes (97b1d23f7bcb metag: Drop show_mem() from mem_init())
Merging powerpc-fixes/fixes (b79331a5eb9f powerpc/powernv/pci: Fix m64 checks 
for SR-IOV and window alignment)
Merging sparc/master (ebb99a4c12e4 sparc64: Fix irq stack bootmem allocation.)
Merging net/master (7b8147aae741 Merge branch 'act_ife-fixes')
Merging ipsec/master (b1f2beb87bb0 Merge tag 'media/v4.8-7' of 
git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media)
Merging netfilter/master (440f895aa97f drivers: net: phy: xgene: Fix 'remove' 
function)
Merging ipvs/master (ea43f860d984 Merge branch 'ethoc-fixes')
Merging wireless-drivers/master (db64c5fa590b Merge tag 
'iwlwifi-for-kalle-2016-09-15' of 
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes)
Merging mac80211/master (7ac327318e09 Merge tag 'mac80211-for-davem-2016-09-16' 
of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211)
Merging sound-current/for-linus (0eec880966e7 ALSA: hda - Add the top speaker 
pin config for HP Spectre x360)
Merging pci-current/for-linus (035ee288ae7a PCI: Fix bridge_d3 update on device 
removal)
Merging driver-core.current/driver-core-linus (c6935931c189 Linux 4.8-rc5)
Merging tty.current/tty-linus (c6935931c189 Linux 4.8-rc5)
Merging usb.current/usb-linus (3be7988674ab Linux 4.8-rc7)
Merging usb-gadget-fixes/fixes (d8a4100ddc75 usb: gadget: udc: atmel: fix 
endpoint name)
Merging usb-serial-fixes/usb-linus (f190fd92458d USB: serial: simple: add 
support for another Infineon flashloader)
Merging usb-chipidea-fixes/ci-for-usb-stable (6f3c4fb6d05e usb: chipidea: udc: 
fix NULL ptr dereference in isr_setup_status_phase)
Merging staging.current/staging-linus (9395452b4aab Linux 4.8-rc6)
Merging char-misc.current/char-misc-linus (c6935931c189 Linux 4.8-rc5)
Merging input-current/for-linus (9fb6de1b0bf4 Input: joydev - recognize devices 
with Z axis as joysticks)
Merging crypto-current/master (0cf43f509f72 crypto: rsa-pkcs1pad - Handle 
leading zero for decryption)
Merging ide/master (797cee982eef Merge branch 'stable-4.8' of 
git://git.infradead.org/users/pcmoore/audit)
Merging rr-fixes/fixes (8244062ef1e5 modules: fix longstanding /proc/kallsyms 
vs module 

Re: [PATCH] MAINTAINERS: update entry for atmel_serial driver

2016-09-28 Thread Greg Kroah-Hartman
On Wed, Sep 28, 2016 at 05:47:35PM +0200, Nicolas Ferre wrote:
> Change maintainer for the serial driver found on most of the
> Microchip / Atmel MPUs and take advantage of the move to rename
> and reorder the entry.
> I'm happy that Richard is taking over the maintenance of this
> driver.
> 
> Signed-off-by: Nicolas Ferre 
> Acked-by: Richard Genoud 
> ---
>  MAINTAINERS | 11 ++-
>  1 file changed, 6 insertions(+), 5 deletions(-)

This doesn't apply to my tty-next tree at all, what did you make it
against?

thanks,

greg k-h


Re: [PATCH v2 2/3] mm: add LSM hook for writes to readonly memory

2016-09-28 Thread Ingo Molnar

* Jann Horn  wrote:

> +/*
> + * subject_cred must be the subjective credentials using which access is
> + * requested.
> + * object_cred must be the objective credentials of the target task at the 
> time
> + * the mm_struct was acquired.
> + * Both of these may be NULL if FOLL_FORCE is unset or FOLL_WRITE is unset.

Hm, I have trouble parsing the first sentence.

> - return __get_user_pages_locked(current, current->mm, start, nr_pages,
> -write, force, pages, vmas, NULL, false,
> -FOLL_TOUCH);
> + return __get_user_pages_locked(current, current->mm, current_cred(),
> +current_real_cred(), start,
> +nr_pages, write, force, pages, vmas,
> +NULL, false, FOLL_TOUCH);

So the parameter passing was disgustig before, and now it became super 
disgusing! 

Would it improve the code if we added a friendly helper structure (or two if 
that's better) to clean up all the interactions within these various functions?

Thanks,

Ingo


Re: [PATCH v2 3/3] selinux: require EXECMEM for forced ptrace poke

2016-09-28 Thread Ingo Molnar

* Jann Horn  wrote:

> +{
> + /* Permitting a write to readonly memory is fine - making the readonly
> +  * memory executable afterwards would require EXECMOD permission because
> +  * anon_vma would be non-NULL.
> +  */

Minor stylistic nit: please fix this comment to be visually symmetric. (There's 
another one introduced by one of your other patches.)

Thanks,

Ingo


Re: [PATCH] MAINTAINERS: update entry for atmel_serial driver

2016-09-28 Thread Richard Genoud
2016-09-28 18:04 GMT+02:00 Joe Perches :
> On Wed, 2016-09-28 at 17:47 +0200, Nicolas Ferre wrote:
>> Change maintainer for the serial driver found on most of the
>> Microchip / Atmel MPUs and take advantage of the move to rename
>> and reorder the entry.
> []
>> diff --git a/MAINTAINERS b/MAINTAINERS
> []
>> +MICROCHIP / ATMEL AT91 / AT32 SERIAL DRIVER
>> +M:   Richard Genoud 
>> +S:   Maintained
>> +F:   drivers/tty/serial/atmel_serial.c
>> +F:   include/linux/atmel_serial.h
>
> Thanks Richard.
>
> include/linux is pretty cluttered with random files.
>
> atmel_serial.h is #include exactly once.
>
> Please move it out of include/linux and into
> drivers/tty/serial/ one day.
No problem, I'll add that to my TBD list !

Richard.


Re: [PATCH v4 0/3] mm/hugetlb: memory offline issues with hugepages

2016-09-28 Thread Naoya Horiguchi
On Mon, Sep 26, 2016 at 07:28:08PM +0200, Gerald Schaefer wrote:
> This addresses several issues with hugepages and memory offline. While
> the first patch fixes a panic, and is therefore rather important, the
> last patch is just a performance optimization.
> 
> The second patch fixes a theoretical issue with reserved hugepages,
> while still leaving some ugly usability issue, see description.
> 
> Changes in v4:
> - Add check for free vs. reserved hugepages
> - Revalidate checks in dissolve_free_huge_page() after taking the lock
> - Split up into 3 patches
> 
> Changes in v3:
> - Add Fixes: c8721bbb
> - Add Cc: stable
> - Elaborate on losing the gigantic page vs. failing memory offline
> - Move page_count() check out of dissolve_free_huge_page()
> 
> Changes in v2:
> - Update comment in dissolve_free_huge_pages()
> - Change locking in dissolve_free_huge_page()
> 
> Gerald Schaefer (3):
>   mm/hugetlb: fix memory offline with hugepage size > memory block size
>   mm/hugetlb: check for reserved hugepages during memory offline
>   mm/hugetlb: improve locking in dissolve_free_huge_pages()
> 
>  include/linux/hugetlb.h |  6 +++---
>  mm/hugetlb.c| 47 +++
>  mm/memory_hotplug.c |  4 +++-
>  3 files changed, 41 insertions(+), 16 deletions(-)

I'm happy with these patches fixing/improving hugetlb offline code,
thank you very much, Gerald and reviewers/testers!

For patchset ...

Acked-by: Naoya Horiguchi 


Re: [PATCH] gpio: pca953x: add a comment explaining the need for a lockdep subclass

2016-09-28 Thread Wolfram Sang
On Mon, Sep 26, 2016 at 12:00:30PM +0200, Wolfram Sang wrote:
> On Mon, Sep 26, 2016 at 11:54:15AM +0200, Bartosz Golaszewski wrote:
> > This is a follow-up to commit 559b46990e76 ("gpio: pca953x: fix an
> > incorrect lockdep warning"). The reason for calling
> > lockdep_set_subclass() in pca953x_probe() is not explained in
> > the code.
> > 
> > Add a comment describing the problem, partial solution and required
> > future extensions.
> > 
> > Signed-off-by: Bartosz Golaszewski 
> 
> Acked-by: Wolfram Sang 
> 
> Linus, because of dependencies, I should probably pick it up?

Linus, ping!



signature.asc
Description: PGP signature


Re: Regression in mobility grouping?

2016-09-28 Thread Joonsoo Kim
On Wed, Sep 28, 2016 at 10:25:40PM -0400, Johannes Weiner wrote:
> On Wed, Sep 28, 2016 at 11:39:25AM -0400, Johannes Weiner wrote:
> > On Wed, Sep 28, 2016 at 11:00:15AM +0200, Vlastimil Babka wrote:
> > > I guess testing revert of 9c0415e could give us some idea. Commit
> > > 3a1086f shouldn't result in pageblock marking differences and as I said
> > > above, 99592d5 should be just restoring to what 3.10 did.
> > 
> > I can give this a shot, but note that this commit makes only unmovable
> > stealing more aggressive. We see reclaimable blocks up as well.
> 
> Quick update, I reverted back to stealing eagerly only on behalf of
> MIGRATE_RECLAIMABLE allocations in a 4.6 kernel:

Hello, Johannes.

I think that it would be better to check 3.10 with above patches.
Fragmentation depends on not only policy itself but also
allocation/free pattern. There might be a large probability that
allocation/free pattern is changed in this large kernel version
difference.

> 
> static bool can_steal_fallback(unsigned int order, int start_mt)
> {
> if (order >= pageblock_order / 2 ||
> start_mt == MIGRATE_RECLAIMABLE ||
> page_group_by_mobility_disabled)
> return true;
> 
> return false;
> }
> 
> Yet, I still see UNMOVABLE growing to the thousands within minutes,
> whereas 3.10 didn't reach those numbers even after days of uptime.
> 
> Okay, that wasn't it. However, there is something fishy going on,
> because I see extfrag traces like these:
> 
> -0 [006] d.s.  1110.217281: mm_page_alloc_extfrag: 
> page=ea0064142000 pfn=26235008 alloc_order=3 fallback_order=3 
> pageblock_order=9 alloc_migratetype=0 fallback_migratetype=2 fragmenting=1 
> change_ownership=1
> 
> enum {
> MIGRATE_UNMOVABLE,
> MIGRATE_MOVABLE,
> MIGRATE_RECLAIMABLE,
> MIGRATE_PCPTYPES,   /* the number of types on the pcp lists */
> MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES,
>   ...
> };
> 
> This is an UNMOVABLE order-3 allocation falling back to RECLAIMABLE.
> According to can_steal_fallback(), this allocation shouldn't steal the
> pageblock, yet change_ownership=1 indicates the block is UNMOVABLE.
> 
> Who converted it? I wonder if there is a bug in ownership management,
> and there was an UNMOVABLE block on the RECLAIMABLE freelist from the
> beginning. AFAICS we never validate list/mt consistency anywhere.

According to my code review, it would be possible. When stealing
happens, we moved those buddy pages to current requested migratetype
buddy list. If the other migratetype allocation request comes and
stealing from the buddy list of previous requested migratetype
happens, change_ownership will show '1' even if there is no ownership
changing.

Thanks.


Re: [PATCH 2/2] drm/mediatek: clear IRQ status before enable OVL interrupt

2016-09-28 Thread CK Hu
Acked-by: CK Hu 

On Thu, 2016-09-29 at 11:29 +0800, Bibby Hsieh wrote:
> To make sure that the first vblank IRQ after enabling
> vblank isn't too short or immediate, we have to clear
> the IRQ status before enable OVL interrupt.
> 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c |1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 019b7ca..f75c5b5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -80,6 +80,7 @@ static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
>ddp_comp);
>  
>   priv->crtc = crtc;
> + writel(0x0, comp->regs + DISP_REG_OVL_INTSTA);
>   writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
>  }
>  




Re: [PATCH v3 2/7] i2c: bcm2835: Protect against unexpected TXW/RXR interrupts

2016-09-28 Thread Stefan Wahren

> Noralf Trønnes  hat am 29. September 2016 um 00:22
> geschrieben:
> 
> 
> 
> Den 29.09.2016 00:00, skrev Eric Anholt:
> > Noralf Trønnes  writes:
> >
> >> If an unexpected TXW or RXR interrupt occurs (msg_buf_remaining == 0),
> >> the driver has no way to fill/drain the FIFO to stop the interrupts.
> >> In this case the controller has to be disabled and the transfer
> >> completed to avoid hang.
> >>
> >> (CLKT | ERR) and DONE interrupts are completed in their own paths, and
> >> the controller is disabled in the transfer function after completion.
> >> Unite the code paths and do disabling inside the interrupt routine.
> >>
> >> Clear interrupt status bits in the united completion path instead of
> >> trying to do it on every interrupt which isn't necessary.
> >> Only CLKT, ERR and DONE can be cleared that way.
> >>
> >> Add the status value to the error value in case of TXW/RXR errors to
> >> distinguish them from the other S_LEN error.
> > I was surprised that not writing the TXW/RXR bits on handling their
> > interrupts was OK, given that we were doing so before, but it's a level
> > interrupt and those bits are basically ignored on write.
> >
> > This patch and 3, 4, and 6 are:
> >
> > Reviewed-by: Eric Anholt 
> >
> > Patch 5 is:
> >
> > Acked-by: Eric Anholt 
> >
> > Note for future debug: The I2C_C_CLEAR on errors will take some time to
> > resolve -- if you were in non-idle state and I2C_C_READ, it sets an
> > abort_rx flag and runs through the state machine to send a NACK and a
> > STOP, I think.  Since we're setting CLEAR without I2CEN, that NACK will
> > be hanging around queued up for next time we start the engine.
> 
> Maybe you're able to explain the issues I had with reset:
> https://github.com/raspberrypi/linux/issues/1653
> 
> Should we put your note into the commit message?
> It will most likely be lost if it just stays in this email.

I prefer to have this kind of information as a code comment.

> 
> Noralf.
> 
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Re: [PATCH 1/2] drm/mediatek: set vblank_disable_allowed to true

2016-09-28 Thread CK Hu
Acked-by: CK Hu 

On Thu, 2016-09-29 at 11:29 +0800, Bibby Hsieh wrote:
> MTK DRM driver didn't set the vblank_disable_allowed to
> true, it cause that the irq_handler is called every
> 16.6 ms (every vblank) when the display didn't be updated.
> 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index eebb7d8..941ec5f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -200,6 +200,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>   if (ret < 0)
>   goto err_component_unbind;
>  
> + drm->vblank_disable_allowed = true;
>   drm_kms_helper_poll_init(drm);
>   drm_mode_config_reset(drm);
>  




[PATCH kernel v2] PCI: Enable access to custom VPD for Chelsio devices (cxgb3)

2016-09-28 Thread Alexey Kardashevskiy
There is at least one Chelsio 10Gb card which uses VPD area to store
some custom blocks (example below). However pci_vpd_size() returns
the length of the first block only assuming that there can be only
one VPD "End Tag" and VFIO blocks access beyond that offset
(since 4e1a63555) which leads to the situation when the guest "cxgb3"
driver fails to probe the device. The host system does not have this
problem as the drives accesses the config space directly without
pci_read_vpd()/...

This adds a quirk to override the VPD size to a bigger value.
The maximum size is taken from EEPROMSIZE in
drivers/net/ethernet/chelsio/cxgb3/common.h. We do not read the tag
as the cxgb3 driver does as the driver supports writing to EEPROM/VPD
and when it writes, it only checks for 8192 bytes boundary. The quirk
is registerted for all devices supported by the cxgb3 driver.

This adds a quirk to the PCI layer (not to the cxgb3 driver) as
the cxgb3 driver itself accesses VPD directly and the problem only exists
with the vfio-pci driver (when cxgb3 is not running on the host and
may not be even loaded) which blocks accesses beyond the first block
of VPD data. However vfio-pci itself does not have quirks mechanism so
we add it to PCI.

Tested on:
Ethernet controller [0200]: Chelsio Communications Inc T310 10GbE Single Port 
Adapter [1425:0030]

This is its VPD:
 Large item 42 bytes; name 0x2 Identifier String
b'10 Gigabit Ethernet-SR PCI Express Adapter'
#00 [EC] len=7: b'D76809 '
#0a [FN] len=7: b'46K7897'
#14 [PN] len=7: b'46K7897'
#1e [MN] len=4: b'1037'
#25 [FC] len=4: b'5769'
#2c [SN] len=12: b'YL102035603V'
#3b [NA] len=12: b'00145E992ED1'

0c00 Large item 16 bytes; name 0x2 Identifier String
b'S310E-SR-X  '
0c13 Large item 234 bytes; name 0x10
#00 [PN] len=16: b'TBD '
#13 [EC] len=16: b'110107730D2 '
#26 [SN] len=16: b'97YL102035603V  '
#39 [NA] len=12: b'00145E992ED1'
#48 [V0] len=6: b'175000'
#51 [V1] len=6: b'26'
#5a [V2] len=6: b'26'
#63 [V3] len=6: b'2000  '
#6c [V4] len=2: b'1 '
#71 [V5] len=6: b'c2'
#7a [V6] len=6: b'0 '
#83 [V7] len=2: b'1 '
#88 [V8] len=2: b'0 '
#8d [V9] len=2: b'0 '
#92 [VA] len=2: b'0 '
#97 [RV] len=80: 
b's\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'...
0d00 Large item 252 bytes; name 0x11
#00 [VC] len=16: b'122310_1222 dp  '
#13 [VD] len=16: b'610-0001-00 H1\x00\x00'
#26 [VE] len=16: b'122310_1353 fp  '
#39 [VF] len=16: b'610-0001-00 H1\x00\x00'
#4c [RW] len=173: 
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'...
0dff Small item 0 bytes; name 0xf End Tag

Signed-off-by: Alexey Kardashevskiy 
---
Changes:
v2:
* used pci_set_vpd_size() helper
* added explicit list of IDs from cxgb3 driver
* added a note in the commit log why the quirk is not in cxgb3
---
 drivers/pci/quirks.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 44e0ff3..b22fce5 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3243,6 +3243,28 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
quirk_thunderbolt_hotplug_msi);
 
+static void quirk_chelsio_extend_vpd(struct pci_dev *dev)
+{
+   if (!dev->vpd)
+   return;
+
+   pci_set_vpd_size(dev, max_t(unsigned int, dev->vpd->len, 8192));
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x20, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x21, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x22, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x23, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x24, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x25, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x26, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x30, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x31, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x32, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x35, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x36, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x37, quirk_chelsio_extend_vpd);
+
 #ifdef CONFIG_ACPI
 /*
  * Apple: Shutdown Cactus Ridge Thunderbolt controller.
-- 
2.5.0.rc3



[PATCH v3 2/3] ARM: dts: omap5 uevm: add LEDs

2016-09-28 Thread H. Nikolaus Schaller
Signed-off-by: H. Nikolaus Schaller 
---
 arch/arm/boot/dts/omap5-uevm.dts | 60 
 1 file changed, 60 insertions(+)

diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts
index be659e8..31ce4f8 100644
--- a/arch/arm/boot/dts/omap5-uevm.dts
+++ b/arch/arm/boot/dts/omap5-uevm.dts
@@ -17,6 +17,66 @@
device_type = "memory";
reg = <0x8000 0x7F00>; /* 2032 MB */
};
+
+   evm_leds {
+   compatible = "gpio-leds";
+
+   led1 {
+   label = "omap5:red:led";
+   gpios = <&gpio9 17 GPIO_ACTIVE_HIGH>;
+   linux,default-trigger = "mmc0";
+   default-state = "off";
+   };
+
+   led2 {
+   label = "omap5:green:led";
+   gpios = <&gpio9 18 GPIO_ACTIVE_HIGH>;
+   linux,default-trigger = "mmc1";
+   default-state = "off";
+   };
+
+   led3 {
+   label = "omap5:blue:led";
+   gpios = <&gpio9 19 GPIO_ACTIVE_HIGH>;
+   linux,default-trigger = "mmc2";
+   default-state = "off";
+   };
+
+   led4 {
+   label = "omap5:green:led1";
+   gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>;
+   linux,default-trigger = "heartbeat";
+   default-state = "off";
+   };
+
+   led5 {
+   label = "omap5:green:led2";
+   gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>;
+   linux,default-trigger = "default-on";
+   default-state = "off";
+   };
+
+   led6 {
+   label = "omap5:green:led3";
+   gpios = <&gpio9 4 GPIO_ACTIVE_HIGH>;
+   linux,default-trigger = "heartbeat";
+   default-state = "off";
+   };
+
+   led7 {
+   label = "omap5:green:led4";
+   gpios = <&gpio9 5 GPIO_ACTIVE_HIGH>;
+   linux,default-trigger = "default-on";
+   default-state = "off";
+   };
+
+   led8 {
+   label = "omap5:green:led5";
+   gpios = <&gpio9 6 GPIO_ACTIVE_HIGH>;
+   linux,default-trigger = "heartbeat";
+   default-state = "off";
+   };
+   };
 };
 
 &hdmi {
-- 
2.7.3



[PATCH v3 3/3] ARM: dts: omap5 uevm: add USR1 button

2016-09-28 Thread H. Nikolaus Schaller
Signed-off-by: H. Nikolaus Schaller 
---
 arch/arm/boot/dts/omap5-uevm.dts | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts
index 31ce4f8..0f50baf 100644
--- a/arch/arm/boot/dts/omap5-uevm.dts
+++ b/arch/arm/boot/dts/omap5-uevm.dts
@@ -18,6 +18,25 @@
reg = <0x8000 0x7F00>; /* 2032 MB */
};
 
+   evm_keys {
+   compatible = "gpio-keys";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&evm_keys_pins>;
+
+   #address-cells = <7>;
+   #size-cells = <0>;
+
+   btn1 {
+   label = "BTN1";
+   linux,code = <169>;
+   gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;/* gpio3_83 */
+   gpio-key,wakeup;
+   autorepeat;
+   debounce_interval = <50>;
+   };
+   };
+
evm_leds {
compatible = "gpio-leds";
 
@@ -105,6 +124,12 @@
 };
 
 &omap5_pmx_core {
+   evm_keys_pins: pinmux_evm_keys_gpio_pins {
+   pinctrl-single,pins = <
+   OMAP5_IOPAD(0x0b6, PIN_INPUT | MUX_MODE6)   /* 
gpio3_83 */
+   >;
+   };
+
i2c5_pins: pinmux_i2c5_pins {
pinctrl-single,pins = <
OMAP5_IOPAD(0x1c6, PIN_INPUT | MUX_MODE0)   
/* i2c5_scl */
-- 
2.7.3



[PATCH v3 1/3] ARM: dts: omap5 uevm: add EEPROM

2016-09-28 Thread H. Nikolaus Schaller
Signed-off-by: H. Nikolaus Schaller 
---
 arch/arm/boot/dts/omap5-uevm.dts | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts
index 36ff7c3..be659e8 100644
--- a/arch/arm/boot/dts/omap5-uevm.dts
+++ b/arch/arm/boot/dts/omap5-uevm.dts
@@ -23,6 +23,13 @@
vdda-supply = <&ldo4_reg>;
 };
 
+&i2c1 {
+   eeprom@50 {
+   compatible = "atmel,24c02";
+   reg = <0x50>;
+   };
+};
+
 &i2c5 {
pinctrl-names = "default";
pinctrl-0 = <&i2c5_pins>;
-- 
2.7.3



[PATCH v3 0/3] ARM: dts: omap5 uevm: add LEDs, USR1 button and EEPROM

2016-09-28 Thread H. Nikolaus Schaller
Changes V3:
* remove unit addresses from LEDs [Rob Herring]

2016-09-28 20:08:23: Changes V2:
* fixed subject of patches to correctly tell that it is for omap5 evm
* changed default triggers a little to create a nicer default pattern

2016-09-27 07:26:14: These patches configure
* the EEPROM
* the LEDs (with some default triggers)
* the USR1 gpio button
for the OMAP5 UEVM board.

H. Nikolaus Schaller (3):
  ARM: dts: omap5 uevm: add EEPROM
  ARM: dts: omap5 uevm: add LEDs
  ARM: dts: omap5 uevm: add USR1 button

 arch/arm/boot/dts/omap5-uevm.dts | 92 
 1 file changed, 92 insertions(+)

-- 
2.7.3



Re: [PATCH 2/3] DT: EVM: add LEDs

2016-09-28 Thread H. Nikolaus Schaller

> Am 29.09.2016 um 07:14 schrieb Rob Herring :
> 
> On Tue, Sep 27, 2016 at 12:26 AM, H. Nikolaus Schaller
>  wrote:
> 
> The subject gives no indication this is for OMAP. Please follow
> standard patterns.
> 
>> Signed-off-by: H. Nikolaus Schaller 
>> ---
>> arch/arm/boot/dts/omap5-uevm.dts | 60 
>> 
>> 1 file changed, 60 insertions(+)
>> 
>> diff --git a/arch/arm/boot/dts/omap5-uevm.dts 
>> b/arch/arm/boot/dts/omap5-uevm.dts
>> index be659e8..19f5f0a 100644
>> --- a/arch/arm/boot/dts/omap5-uevm.dts
>> +++ b/arch/arm/boot/dts/omap5-uevm.dts
>> @@ -17,6 +17,66 @@
>>device_type = "memory";
>>reg = <0x8000 0x7F00>; /* 2032 MB */
>>};
>> +
>> +   evm_leds {
>> +   compatible = "gpio-leds";
>> +
>> +   led@1 {
> 
> Drop the unit address. There's no reg property.

This needs to be fixed. Goes to v3.

BR and thanks,
Nikolaus

> 
>> +   label = "omap5:red:led";
>> +   gpios = <&gpio9 17 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "mmc0";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@2 {
>> +   label = "omap5:green:led";
>> +   gpios = <&gpio9 18 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "mmc1";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@3 {
>> +   label = "omap5:blue:led";
>> +   gpios = <&gpio9 19 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "mmc2";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@4 {
>> +   label = "omap5:green:led1";
>> +   gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "default-on";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@5 {
>> +   label = "omap5:green:led2";
>> +   gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "default-on";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@6 {
>> +   label = "omap5:green:led3";
>> +   gpios = <&gpio9 4 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "heartbeat";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@7 {
>> +   label = "omap5:green:led4";
>> +   gpios = <&gpio9 5 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "heartbeat";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@8 {
>> +   label = "omap5:green:led5";
>> +   gpios = <&gpio9 6 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "heartbeat";
>> +   default-state = "off";
>> +   };
>> +   };
>> };
>> 
>> &hdmi {
>> --
>> 2.7.3
>> 
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html



Re: [PATCH 17/26] intel_telemetry_debugfs: constify local structures

2016-09-28 Thread Julia Lawall


On Wed, 28 Sep 2016, Darren Hart wrote:

> On Sun, Sep 11, 2016 at 03:05:59PM +0200, Julia Lawall wrote:
>
> Hi Julia,
>
> > For structure types defined in the same file or local header files, find
> > top-level static structure declarations that have the following
> > properties:
> > 1. Never reassigned.
> > 2. Address never taken
>
> Hrm. telem_apl_debugfs_conf is passed to the TELEM_DEBUGFS_CPU macro as the
> second argument "data":
>
> #define TELEM_DEBUGFS_CPU(model, data) \
>   { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&data}
>
> And the address is taken, and later assigned to the debugfs_conf pointer.
>
> The usage still seems OK, but did I misunderstand the conditions?

OK, this is definitely a weakness of the script and my methodology for
checking the results.  There was already a case of a cast that I have
fixed up my script for, but this one is worse because it's under a macro.
I can look into whether the cast can be changed to add a const, but for
the time being, I think you should just drop this patch.

Thanks for the careful review.

julia

>
>
> > 3. Not passed to a top-level macro call
> > 4. No pointer or array-typed field passed to a function or stored in a
> > variable.
> > Declare structures having all of these properties as const.
> >
> > Done using Coccinelle.
> > Based on a suggestion by Joe Perches .
>
> > Signed-off-by: Julia Lawall 
> >
> > ---
> > The semantic patch seems too long for a commit log, but is in the cover
> > letter.
> >
> >  drivers/platform/x86/intel_telemetry_debugfs.c |2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c 
> > b/drivers/platform/x86/intel_telemetry_debugfs.c
> > index ef29f18..d0761f3 100644
> > --- a/drivers/platform/x86/intel_telemetry_debugfs.c
> > +++ b/drivers/platform/x86/intel_telemetry_debugfs.c
> > @@ -297,7 +297,7 @@ struct telemetry_debugfs_conf {
> >
> >  static struct telemetry_debugfs_conf *debugfs_conf;
> >
> > -static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
> > +static const struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
> > .pss_idle_data = telem_apl_pss_idle_data,
> > .pcs_idle_blkd_data = telem_apl_pcs_idle_blkd_data,
> > .pcs_s0ix_blkd_data = telem_apl_pcs_s0ix_blkd_data,
> >
> >
>
> --
> Darren Hart
> Intel Open Source Technology Center
> --
> To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


Re: [PATCH 2/3] DT: EVM: add LEDs

2016-09-28 Thread H. Nikolaus Schaller

> Am 29.09.2016 um 07:14 schrieb Rob Herring :
> 
> On Tue, Sep 27, 2016 at 12:26 AM, H. Nikolaus Schaller
>  wrote:
> 
> The subject gives no indication this is for OMAP. Please follow
> standard patterns.

Already fixed. Please see v2.

> 
>> Signed-off-by: H. Nikolaus Schaller 
>> ---
>> arch/arm/boot/dts/omap5-uevm.dts | 60 
>> 
>> 1 file changed, 60 insertions(+)
>> 
>> diff --git a/arch/arm/boot/dts/omap5-uevm.dts 
>> b/arch/arm/boot/dts/omap5-uevm.dts
>> index be659e8..19f5f0a 100644
>> --- a/arch/arm/boot/dts/omap5-uevm.dts
>> +++ b/arch/arm/boot/dts/omap5-uevm.dts
>> @@ -17,6 +17,66 @@
>>device_type = "memory";
>>reg = <0x8000 0x7F00>; /* 2032 MB */
>>};
>> +
>> +   evm_leds {
>> +   compatible = "gpio-leds";
>> +
>> +   led@1 {
> 
> Drop the unit address. There's no reg property.
> 
>> +   label = "omap5:red:led";
>> +   gpios = <&gpio9 17 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "mmc0";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@2 {
>> +   label = "omap5:green:led";
>> +   gpios = <&gpio9 18 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "mmc1";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@3 {
>> +   label = "omap5:blue:led";
>> +   gpios = <&gpio9 19 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "mmc2";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@4 {
>> +   label = "omap5:green:led1";
>> +   gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "default-on";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@5 {
>> +   label = "omap5:green:led2";
>> +   gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "default-on";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@6 {
>> +   label = "omap5:green:led3";
>> +   gpios = <&gpio9 4 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "heartbeat";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@7 {
>> +   label = "omap5:green:led4";
>> +   gpios = <&gpio9 5 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "heartbeat";
>> +   default-state = "off";
>> +   };
>> +
>> +   led@8 {
>> +   label = "omap5:green:led5";
>> +   gpios = <&gpio9 6 GPIO_ACTIVE_HIGH>;
>> +   linux,default-trigger = "heartbeat";
>> +   default-state = "off";
>> +   };
>> +   };
>> };
>> 
>> &hdmi {
>> --
>> 2.7.3
>> 
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html



Re: [PATCH 2/3] DT: EVM: add LEDs

2016-09-28 Thread Rob Herring
On Tue, Sep 27, 2016 at 12:26 AM, H. Nikolaus Schaller
 wrote:

The subject gives no indication this is for OMAP. Please follow
standard patterns.

> Signed-off-by: H. Nikolaus Schaller 
> ---
>  arch/arm/boot/dts/omap5-uevm.dts | 60 
> 
>  1 file changed, 60 insertions(+)
>
> diff --git a/arch/arm/boot/dts/omap5-uevm.dts 
> b/arch/arm/boot/dts/omap5-uevm.dts
> index be659e8..19f5f0a 100644
> --- a/arch/arm/boot/dts/omap5-uevm.dts
> +++ b/arch/arm/boot/dts/omap5-uevm.dts
> @@ -17,6 +17,66 @@
> device_type = "memory";
> reg = <0x8000 0x7F00>; /* 2032 MB */
> };
> +
> +   evm_leds {
> +   compatible = "gpio-leds";
> +
> +   led@1 {

Drop the unit address. There's no reg property.

> +   label = "omap5:red:led";
> +   gpios = <&gpio9 17 GPIO_ACTIVE_HIGH>;
> +   linux,default-trigger = "mmc0";
> +   default-state = "off";
> +   };
> +
> +   led@2 {
> +   label = "omap5:green:led";
> +   gpios = <&gpio9 18 GPIO_ACTIVE_HIGH>;
> +   linux,default-trigger = "mmc1";
> +   default-state = "off";
> +   };
> +
> +   led@3 {
> +   label = "omap5:blue:led";
> +   gpios = <&gpio9 19 GPIO_ACTIVE_HIGH>;
> +   linux,default-trigger = "mmc2";
> +   default-state = "off";
> +   };
> +
> +   led@4 {
> +   label = "omap5:green:led1";
> +   gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>;
> +   linux,default-trigger = "default-on";
> +   default-state = "off";
> +   };
> +
> +   led@5 {
> +   label = "omap5:green:led2";
> +   gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>;
> +   linux,default-trigger = "default-on";
> +   default-state = "off";
> +   };
> +
> +   led@6 {
> +   label = "omap5:green:led3";
> +   gpios = <&gpio9 4 GPIO_ACTIVE_HIGH>;
> +   linux,default-trigger = "heartbeat";
> +   default-state = "off";
> +   };
> +
> +   led@7 {
> +   label = "omap5:green:led4";
> +   gpios = <&gpio9 5 GPIO_ACTIVE_HIGH>;
> +   linux,default-trigger = "heartbeat";
> +   default-state = "off";
> +   };
> +
> +   led@8 {
> +   label = "omap5:green:led5";
> +   gpios = <&gpio9 6 GPIO_ACTIVE_HIGH>;
> +   linux,default-trigger = "heartbeat";
> +   default-state = "off";
> +   };
> +   };
>  };
>
>  &hdmi {
> --
> 2.7.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH][v3] mfd: intel-lpss: Avoid resuming runtime-suspended lpss unnecessarily

2016-09-28 Thread Chen Yu
We have report that the intel_lpss_prepare() takes too much time during
suspend, and this is because we first resume the devices from runtime
suspend by resume_lpss_device(), to make sure they are in proper state
before system suspend, which takes 100ms for each LPSS devices(PCI power
state from D3_cold to D0). And since resume_lpss_device() resumes the
devices synchronously, we might get huge latency if we have many
LPSS devices.

So first try is to use pm_request_resume() instead, to make the runtime
resume process asynchronously. Unfortunately the asynchronous runtime
resume relies on pm_wq, which is freezed at early stage. So we choose
another method, that is to avoid resuming runtime-suspended devices,
if they are already runtime suspended. This is safe because for LPSS
driver, the runtime suspend and system suspend are of the same
hook - i.e., intel_lpss_suspend(). And moreover, this device is
neither runtime wakeup source nor system wakeup source.

Suggested-by: Rafael J. Wysocki 
Acked-by: Mika Westerberg 
Reviewed-by: Andy Shevchenko 
Cc: Andy Shevchenko 
Cc: Mika Westerberg 
Cc: Rafael J. Wysocki 
Cc: Lee Jones 
Signed-off-by: Chen Yu 
---
 drivers/mfd/intel-lpss.c | 9 +
 include/linux/pm.h   | 7 +++
 2 files changed, 16 insertions(+)

diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
index 41b1138..2583db8 100644
--- a/drivers/mfd/intel-lpss.c
+++ b/drivers/mfd/intel-lpss.c
@@ -485,6 +485,15 @@ static int resume_lpss_device(struct device *dev, void 
*data)
 int intel_lpss_prepare(struct device *dev)
 {
/*
+* This is safe because:
+* 1. The runtime suspend and system suspend
+* are of the same hook.
+* 2. This device is neither runtime wakeup source
+* nor system wakeup source.
+*/
+   if (pm_runtime_status_suspended(dev))
+   return DPM_DIRECT_COMPLETE;
+   /*
 * Resume both child devices before entering system sleep. This
 * ensures that they are in proper state before they get suspended.
 */
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 06eb353..4a788b4 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -786,4 +786,11 @@ enum dpm_order {
DPM_ORDER_DEV_LAST,
 };
 
+/*
+ * Return this from system suspend/hibernation ->prepare() callback to
+ * request the core to leave the device runtime-suspended during system
+ * suspend if possible.
+ */
+#define DPM_DIRECT_COMPLETE 1
+
 #endif /* _LINUX_PM_H */
-- 
2.7.4



Re: [PATCH][v2] mfd: intel-lpss: Avoid resuming runtime-suspended lpss unnecessarily

2016-09-28 Thread Chen Yu
On Wed, Sep 28, 2016 at 11:48:40PM +0200, Rafael J. Wysocki wrote:
> On Wed, Sep 28, 2016 at 6:29 PM, Chen Yu  wrote:
> > We have report that the intel_lpss_prepare() takes too much time during
> > suspend, and this is because we first resume the devices from runtime
> > suspend by resume_lpss_device(), to make sure they are in proper state
> > before system suspend, which takes 100ms for each LPSS devices(PCI power
> > state from D3_cold to D0). And since resume_lpss_device() resumes the
> > devices synchronously, we might get huge latency if we have many
> > LPSS devices.
> >
> > So first try is to use pm_request_resume() instead, to make the runtime
> > resume process asynchronously. Unfortunately the asynchronous runtime
> > resume relies on pm_wq, which is freezed at early stage. So we choose
> > another method, that is to avoid resuming runtime-suspended devices,
> > if they are already runtime suspended. This is safe because for LPSS
> > driver, the runtime suspend and system suspend are of the same
> > hook - i.e., intel_lpss_suspend(). And moreover, this device is
> > neither runtime wakeup source nor system wakeup source.
> >
> > Suggested-by: Rafael J. Wysocki 
> > Acked-by: Mika Westerberg 
> > Reviewed-by: Andy Shevchenko 
> > Cc: Andy Shevchenko 
> > Cc: Mika Westerberg 
> > Cc: Rafael J. Wysocki 
> > Cc: Lee Jones 
> > Signed-off-by: Chen Yu 
> > ---
> >  drivers/mfd/intel-lpss.c | 9 +
> >  include/linux/pm.h   | 3 +++
> >  2 files changed, 12 insertions(+)
> >
> > diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
> > index 41b1138..2583db8 100644
> > --- a/drivers/mfd/intel-lpss.c
> > +++ b/drivers/mfd/intel-lpss.c
> > @@ -485,6 +485,15 @@ static int resume_lpss_device(struct device *dev, void 
> > *data)
> >  int intel_lpss_prepare(struct device *dev)
> >  {
> > /*
> > +* This is safe because:
> > +* 1. The runtime suspend and system suspend
> > +* are of the same hook.
> > +* 2. This device is neither runtime wakeup source
> > +* nor system wakeup source.
> > +*/
> > +   if (pm_runtime_status_suspended(dev))
> > +   return DPM_DIRECT_COMPLETE;
> > +   /*
> >  * Resume both child devices before entering system sleep. This
> >  * ensures that they are in proper state before they get suspended.
> >  */
> > diff --git a/include/linux/pm.h b/include/linux/pm.h
> > index 06eb353..5606ad9 100644
> > --- a/include/linux/pm.h
> > +++ b/include/linux/pm.h
> > @@ -786,4 +786,7 @@ enum dpm_order {
> > DPM_ORDER_DEV_LAST,
> >  };
> >
> > +/* The device is OK to remain runtime-suspended during suspend.*/
> 
> /*
>  * Return this from system suspend/hibernation ->prepare() callback to
> request the
>  * core to leave the device runtime-suspended during system suspend if 
> possible.
>  */
>
I've taken this comment in a new version, thanks! 
> > +#define DPM_DIRECT_COMPLETE 1
> > +
> >  #endif /* _LINUX_PM_H */
> > --
> 
> But it is fine by me overall.
> 
> Thanks,
> Rafael


[PATCH v2 net-next] mlx5: Add ndo_poll_controller() implementation

2016-09-28 Thread Calvin Owens
This implements ndo_poll_controller in net_device_ops callbacks for mlx5,
which is necessary to use netconsole with this driver.

Acked-By: Saeed Mahameed 
Signed-off-by: Calvin Owens 
---
Changes in v2:
* Only iterate channels to avoid redundant napi_schedule() calls

drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c 
b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index b58cfe3..7eaf380 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3188,6 +3188,20 @@ static int mlx5e_xdp(struct net_device *dev, struct 
netdev_xdp *xdp)
}
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/* Fake "interrupt" called by netpoll (eg netconsole) to send skbs without
+ * reenabling interrupts.
+ */
+static void mlx5e_netpoll(struct net_device *dev)
+{
+   struct mlx5e_priv *priv = netdev_priv(dev);
+   int i;
+
+   for (i = 0; i < priv->params.num_channels; i++)
+   napi_schedule(&priv->channel[i]->napi);
+}
+#endif
+
 static const struct net_device_ops mlx5e_netdev_ops_basic = {
.ndo_open= mlx5e_open,
.ndo_stop= mlx5e_close,
@@ -3208,6 +3222,9 @@ static const struct net_device_ops mlx5e_netdev_ops_basic 
= {
 #endif
.ndo_tx_timeout  = mlx5e_tx_timeout,
.ndo_xdp = mlx5e_xdp,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+   .ndo_poll_controller = mlx5e_netpoll,
+#endif
 };
 
 static const struct net_device_ops mlx5e_netdev_ops_sriov = {
@@ -3240,6 +3257,9 @@ static const struct net_device_ops mlx5e_netdev_ops_sriov 
= {
.ndo_get_vf_stats= mlx5e_get_vf_stats,
.ndo_tx_timeout  = mlx5e_tx_timeout,
.ndo_xdp = mlx5e_xdp,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+   .ndo_poll_controller = mlx5e_netpoll,
+#endif
 };
 
 static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
-- 
2.9.3



Re: [PATCH v19 05/12] fpga-mgr: add fpga image information struct

2016-09-28 Thread Alan Tull
On Wed, Sep 28, 2016 at 6:41 PM, Moritz Fischer
 wrote:
Hi Moritz,

> Hi Alan,
>
> generally ok with the change.

Cool!

>
> On Wed, Sep 28, 2016 at 11:21 AM, Alan Tull  
> wrote:
>
>> -int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf,
>> - size_t count)
>> +int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info 
>> *info,
>> + const char *buf, size_t count)
>
> Doesn't this break the both socfpga and zynq if [6/12] and [7/12] are
> not part of this commit?
> i.e shouldn't 5,6 and 7 be a single commit?

Yeah, squashing those would improve bisectability.

Alan
aka atull

>
> Cheers,
> Moritz


Re: [PATCH] drm/mediatek: fix a typo

2016-09-28 Thread CK Hu
Acked-by: CK Hu 

On Thu, 2016-09-29 at 11:22 +0800, Bibby Hsieh wrote:
> Fix the typo: OD_RELAYMODE->OD_CFG
> 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index df33b3c..aa5f20f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -123,7 +123,7 @@ static void mtk_od_config(struct mtk_ddp_comp *comp, 
> unsigned int w,
> unsigned int bpc)
>  {
>   writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
> - writel(OD_RELAYMODE, comp->regs + OD_RELAYMODE);
> + writel(OD_RELAYMODE, comp->regs + OD_CFG);
>   mtk_dither_set(comp, bpc, DISP_OD_CFG);
>  }
>  




[PATCH] jiffies: add time comparison functions for 64 bit jiffies

2016-09-28 Thread Jason A. Donenfeld
Though the time_before and time_after family of functions were nicely
extended to support jiffies64, so that the interface would be
consistent, it was forgotten to also extend the before/after jiffies
functions to support jiffies64. This commit brings the interface to
parity between jiffies and jiffies64, which is quite convenient.

Signed-off-by: Jason A. Donenfeld 
---
 include/linux/jiffies.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 5fdc553..589d14e 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -150,15 +150,19 @@ static inline u64 get_jiffies_64(void)
 
 /* time_is_before_jiffies(a) return true if a is before jiffies */
 #define time_is_before_jiffies(a) time_after(jiffies, a)
+#define time_is_before_jiffies64(a) time_after64(get_jiffies_64(), a)
 
 /* time_is_after_jiffies(a) return true if a is after jiffies */
 #define time_is_after_jiffies(a) time_before(jiffies, a)
+#define time_is_after_jiffies64(a) time_before64(get_jiffies_64(), a)
 
 /* time_is_before_eq_jiffies(a) return true if a is before or equal to 
jiffies*/
 #define time_is_before_eq_jiffies(a) time_after_eq(jiffies, a)
+#define time_is_before_eq_jiffies64(a) time_after_eq64(get_jiffies_64(), a)
 
 /* time_is_after_eq_jiffies(a) return true if a is after or equal to jiffies*/
 #define time_is_after_eq_jiffies(a) time_before_eq(jiffies, a)
+#define time_is_after_eq_jiffies64(a) time_before_eq64(get_jiffies_64(), a)
 
 /*
  * Have the 32 bit jiffies value wrap 5 minutes after boot
-- 
2.10.0



[PATCH 0/2] fix issue: vblank interrupts are never disabled

2016-09-28 Thread Bibby Hsieh
Clean the interrupt status before enable interrupt
and set the vblank_disable_allowed to fix the issue.

Bibby Hsieh (2):
  drm/mediatek: set vblank_disable_allowed to true
  drm/mediatek: clear IRQ status before enable OVL interrupt

 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |1 +
 2 files changed, 2 insertions(+)

-- 
1.7.9.5



[PATCH 1/2] drm/mediatek: set vblank_disable_allowed to true

2016-09-28 Thread Bibby Hsieh
MTK DRM driver didn't set the vblank_disable_allowed to
true, it cause that the irq_handler is called every
16.6 ms (every vblank) when the display didn't be updated.

Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index eebb7d8..941ec5f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -200,6 +200,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
if (ret < 0)
goto err_component_unbind;
 
+   drm->vblank_disable_allowed = true;
drm_kms_helper_poll_init(drm);
drm_mode_config_reset(drm);
 
-- 
1.7.9.5



[PATCH 2/2] drm/mediatek: clear IRQ status before enable OVL interrupt

2016-09-28 Thread Bibby Hsieh
To make sure that the first vblank IRQ after enabling
vblank isn't too short or immediate, we have to clear
the IRQ status before enable OVL interrupt.

Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 019b7ca..f75c5b5 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -80,6 +80,7 @@ static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
 ddp_comp);
 
priv->crtc = crtc;
+   writel(0x0, comp->regs + DISP_REG_OVL_INTSTA);
writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
 }
 
-- 
1.7.9.5



[PATCH] drm/mediatek: fix a typo

2016-09-28 Thread Bibby Hsieh
Fix the typo: OD_RELAYMODE->OD_CFG

Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index df33b3c..aa5f20f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -123,7 +123,7 @@ static void mtk_od_config(struct mtk_ddp_comp *comp, 
unsigned int w,
  unsigned int bpc)
 {
writel(w << 16 | h, comp->regs + DISP_OD_SIZE);
-   writel(OD_RELAYMODE, comp->regs + OD_RELAYMODE);
+   writel(OD_RELAYMODE, comp->regs + OD_CFG);
mtk_dither_set(comp, bpc, DISP_OD_CFG);
 }
 
-- 
1.7.9.5



linux-next: build failure after merge of the tip tree

2016-09-28 Thread Stephen Rothwell
Hi all,

After merging the tip tree, today's linux-next build (x86_64 allmodconfig)
failed like this:

arch/x86/power/hibernate_64.c: In function 'hibernation_e820_save':
arch/x86/power/hibernate_64.c:236:15: error: passing argument 1 of 
'get_e820_md5' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
  get_e820_md5(&e820_saved, buf);
   ^
arch/x86/power/hibernate_64.c:203:12: note: expected 'struct e820map *' but 
argument is of type 'struct e820map **'
 static int get_e820_md5(struct e820map *map, void *buf)
^
arch/x86/power/hibernate_64.c: In function 'hibernation_e820_mismatch':
arch/x86/power/hibernate_64.c:249:21: error: passing argument 1 of 
'get_e820_md5' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
  ret = get_e820_md5(&e820_saved, result);
 ^
arch/x86/power/hibernate_64.c:203:12: note: expected 'struct e820map *' but 
argument is of type 'struct e820map **'
 static int get_e820_md5(struct e820map *map, void *buf)
^

Caused by commit

  475339684ef1 ("x86/e820: Prepare e280 code for switch to dynamic storage")

interacting with commit

  6f95ad2b6162 ("PM / hibernate: Verify e820 memory map by MD5 digest")

from the pm tree.

I have applied the following merge fix patch:

From: Stephen Rothwell 
Date: Thu, 29 Sep 2016 13:13:45 +1000
Subject: [PATCH] pm/hibernate: merge fix for type of e820_saved changing

Signed-off-by: Stephen Rothwell 
---
 arch/x86/power/hibernate_64.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
index 72f2c9531b03..904048f7a9c9 100644
--- a/arch/x86/power/hibernate_64.c
+++ b/arch/x86/power/hibernate_64.c
@@ -233,7 +233,7 @@ static int get_e820_md5(struct e820map *map, void *buf)
 
 static void hibernation_e820_save(void *buf)
 {
-   get_e820_md5(&e820_saved, buf);
+   get_e820_md5(e820_saved, buf);
 }
 
 static bool hibernation_e820_mismatch(void *buf)
@@ -246,7 +246,7 @@ static bool hibernation_e820_mismatch(void *buf)
if (!memcmp(result, buf, MD5_DIGEST_SIZE))
return false;
 
-   ret = get_e820_md5(&e820_saved, result);
+   ret = get_e820_md5(e820_saved, result);
if (ret)
return true;
 
-- 
2.8.1

-- 
Cheers,
Stephen Rothwell


Re: [PATCH 2/3] zram: support page-based parallel write

2016-09-28 Thread Sergey Senozhatsky
Hello Minchan,

On (09/22/16 15:42), Minchan Kim wrote:
> zram supports stream-based parallel compression. IOW, it can support
> parallel compression on SMP system only if each cpus has streams.
> For example, assuming 4 CPU system, there are 4 sources for compressing
> in system and each source must be located in each CPUs for full
> parallel compression.
> 
> So, if there is *one* stream in the system, it cannot be compressed
> in parallel although the system supports multiple CPUs. This patch
> aims to overcome such weakness.
> 
> The idea is to use multiple background threads to compress pages
> in idle CPU and foreground just queues BIOs without interrupting
> while other CPUs consumes pages in BIO to compress.
> It means zram begins to support asynchronous writeback to increase
> write bandwidth.
> 
> 1) test cp A to B as an example of single stream compression and
> enhanced 36%.
> 
> x86_64, 4 CPU
> Copy kernel source to zram
> old: 3.4s, new: 2.2s
> 
> 2) test per-process reclaim to swap: 524M
> x86_64, 4 CPU:
> old: 1.2s new: 0.3s
> 
> 3) FIO benchamrk
> random read was worse so it supports only write at the moment.
> Later, We might revisit asynchronous read.


sorry for long reply.

frankly speaking, sorry, I'm very skeptical about the patch set.

from your tests it seems that only a tiny corner case can gain some
extra performance: when we have SMP system with multiple CPUs, but
*guaranteed* only one process doing *only* one type of requests.
as soon as this process starts to do things simultaneously (like
mixed READ-WRITE) _or_ there are several processes: we are done. and
for that tiny corner case we are about to add a complex logic and a
big pile of code. I'm quite sure I'll never enable CONFIG_ZRAM_ASYNC_IO.
why would you enable it? I mean what setups you are looking at that will
benefit? hosting a CVS repository? :) just kidding.

are there any block devices being specifically optimized for a "one
process doing one OP" cases?

my tests show a dramatic performance drop down with NEW zram.
even "one" process case (one fio job) is almost x3 slower.
somtimes WRITE test case even go from MB/s to KB/s

WRITE:  3181.4MB/s→  948111KB/s


I've attached the .config


ENV
===

  x86_64 SMP (4 CPUs), "bare zram" 2g, lzo, static compression buffer.


TEST COMMAND


  ZRAM_SIZE=2G ZRAM_COMP_ALG=lzo LOG_SUFFIX={NEW, OLD} FIO_LOOPS=2 
./zram-fio-test.sh


EXECUTED TESTS
==

 - [seq-read]
 - [rand-read]
 - [seq-write]
 - [rand-write]
 - [mixed-seq]
 - [mixed-rand]


RESULTS
===

# ./fio-perf-o-meter.sh test-fio-zram-OLD test-fio-zram-NEW
Processing test-fio-zram-OLD
Processing test-fio-zram-NEW


OLD  NEW

#jobs1  
READ:   2345.1MB/s   2373.2MB/s
READ:   1948.2MB/s   1987.7MB/s
WRITE:  1292.7MB/s   275277KB/s
WRITE:  1047.5MB/s   257140KB/s
READ:   429530KB/s   175450KB/s
WRITE:  429840KB/s   175576KB/s
READ:   414074KB/s   164091KB/s
WRITE:  414402KB/s   164221KB/s
#jobs2  
READ:   4484.7MB/s   4532.7MB/s
READ:   3705.7MB/s   3744.6MB/s
WRITE:  2170.7MB/s   492404KB/s
WRITE:  1864.4MB/s   470723KB/s
READ:   829949KB/s   340146KB/s
WRITE:  830065KB/s   340194KB/s
READ:   805639KB/s   336380KB/s
WRITE:  807140KB/s   337006KB/s
#jobs3  
READ:   5920.1MB/s   6025.6MB/s
READ:   4845.5MB/s   5037.5MB/s
WRITE:  2956.3MB/s   777683KB/s
WRITE:  2525.7MB/s   727868KB/s
READ:   1083.6MB/s   507481KB/s
WRITE:  1085.1MB/s   508634KB/s
READ:   1114.2MB/s   493014KB/s
WRITE:  1114.7MB/s   492849KB/s
#jobs4  
READ:   7819.3MB/s   7897.2MB/s
READ:   6445.4MB/s   6604.7MB/s
WRITE:  3737.3MB/s   1002.6MB/s
WRITE:  3232.5MB/s   974777KB/s
READ:   1447.1MB/s   592012KB/s
WRITE:  1448.5MB/s   592205KB/s
READ:   1427.5MB/s   569307KB/s
WRITE:  1428.1MB/s   569881KB/s
#jobs5  
READ:   7201.2MB/s   7560.1MB/s
READ:   5710.4MB/s   6078.4MB/s
WRITE:  3635.1MB/s   989502KB/s
WRITE:  3131.6MB/s   949969KB/s
READ:   1428.4MB/s   650856KB/s
WRITE:  1429.7MB/s   651182KB/s
READ:   1413.9MB/s   644587KB/s
WRITE:  1412.6MB/s   644328KB/s
#jobs6  
READ:   7252.5MB/s   7248.2MB/s
READ:   6150.2MB/s   6396.7MB/s
WRITE:  3583.3MB/s   954890KB/s
WRITE:  2994.2MB/s   921172KB/s
READ:   1444.6MB/s   76863

Re: [PATCH 08/16] md/bitmap: Rename a jump label in location_store()

2016-09-28 Thread Guoqing Jiang



On 09/28/2016 03:55 PM, Jes Sorensen wrote:

SF Markus Elfring  writes:

From: Markus Elfring 
Date: Tue, 27 Sep 2016 15:46:22 +0200

Adjust jump labels according to the current Linux coding style convention.

Signed-off-by: Markus Elfring 
---
  drivers/md/bitmap.c | 18 +-
  1 file changed, 9 insertions(+), 9 deletions(-)

Sorry but this patch is just plain ridiculous. It does not improve the
code in any shape or form.

'out' as a label is perfectly legitimate and just as good as 'unlock'.


Agree, I also curious which document recorded the coding style convention.

Thanks,
Guoqing



[PATCH v5 2/3] drm/mediatek: enhance the HDMI driving current

2016-09-28 Thread Bibby Hsieh
From: Junzhi Zhao 

In order to improve 4K resolution performance,
we have to enhance the HDMI driving current
when clock rate is greater than 165MHz.

Signed-off-by: Junzhi Zhao 
Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c |   42 +---
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c 
b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
index 8a24754..51cb9cf 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
@@ -265,6 +265,9 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, 
unsigned long rate,
struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
unsigned int pre_div;
unsigned int div;
+   unsigned int pre_ibias;
+   unsigned int hdmi_ibias;
+   unsigned int imp_en;
 
dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__,
rate, parent_rate);
@@ -298,18 +301,31 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, 
unsigned long rate,
  (0x1 << PLL_BR_SHIFT),
  RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC |
  RG_HDMITX_PLL_BR);
-   mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_PRD_IMP_EN);
+   if (rate < 16500) {
+   mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
+   RG_HDMITX_PRD_IMP_EN);
+   pre_ibias = 0x3;
+   imp_en = 0x0;
+   hdmi_ibias = hdmi_phy->ibias;
+   } else {
+   mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
+ RG_HDMITX_PRD_IMP_EN);
+   pre_ibias = 0x6;
+   imp_en = 0xf;
+   hdmi_ibias = hdmi_phy->ibias_up;
+   }
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4,
- (0x3 << PRD_IBIAS_CLK_SHIFT) |
- (0x3 << PRD_IBIAS_D2_SHIFT) |
- (0x3 << PRD_IBIAS_D1_SHIFT) |
- (0x3 << PRD_IBIAS_D0_SHIFT),
+ (pre_ibias << PRD_IBIAS_CLK_SHIFT) |
+ (pre_ibias << PRD_IBIAS_D2_SHIFT) |
+ (pre_ibias << PRD_IBIAS_D1_SHIFT) |
+ (pre_ibias << PRD_IBIAS_D0_SHIFT),
  RG_HDMITX_PRD_IBIAS_CLK |
  RG_HDMITX_PRD_IBIAS_D2 |
  RG_HDMITX_PRD_IBIAS_D1 |
  RG_HDMITX_PRD_IBIAS_D0);
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3,
- (0x0 << DRV_IMP_EN_SHIFT), RG_HDMITX_DRV_IMP_EN);
+ (imp_en << DRV_IMP_EN_SHIFT),
+ RG_HDMITX_DRV_IMP_EN);
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6,
  (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) |
  (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
@@ -318,12 +334,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, 
unsigned long rate,
  RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 |
  RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0);
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5,
- (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) |
- (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) |
- (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) |
- (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT),
- RG_HDMITX_DRV_IBIAS_CLK | RG_HDMITX_DRV_IBIAS_D2 |
- RG_HDMITX_DRV_IBIAS_D1 | RG_HDMITX_DRV_IBIAS_D0);
+ (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) |
+ (hdmi_ibias << DRV_IBIAS_D2_SHIFT) |
+ (hdmi_ibias << DRV_IBIAS_D1_SHIFT) |
+ (hdmi_ibias << DRV_IBIAS_D0_SHIFT),
+ RG_HDMITX_DRV_IBIAS_CLK |
+ RG_HDMITX_DRV_IBIAS_D2 |
+ RG_HDMITX_DRV_IBIAS_D1 |
+ RG_HDMITX_DRV_IBIAS_D0);
return 0;
 }
 
-- 
1.7.9.5



[PATCH v5 3/3] drm/mediatek: modify the factor to make the pll_rate set in the 1G-2G range

2016-09-28 Thread Bibby Hsieh
From: Junzhi Zhao 

Currently, the code sets the "pll" to the desired multiple
of the pixel clock manully(4*3m 8*3,etc).  The valid range
of the pll is 1G-2G, however, when the pixel clock is bigger
than 167MHz,  the "pll" will be set to a invalid value( > 2G),
then the "pll" will be 2GHz, thus the pixel clock will be in
correct. Change the factor to make the "pll" be set in the
(1G, 2G) range.

Signed-off-by: Junzhi Zhao 
Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_dpi.c |9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 0186e50..90fb831 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -432,11 +432,16 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
unsigned long pll_rate;
unsigned int factor;
 
+   /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
pix_rate = 1000UL * mode->clock;
-   if (mode->clock <= 74000)
+   if (mode->clock <= 27000)
+   factor = 16 * 3;
+   else if (mode->clock <= 84000)
factor = 8 * 3;
-   else
+   else if (mode->clock <= 167000)
factor = 4 * 3;
+   else
+   factor = 2 * 3;
pll_rate = pix_rate * factor;
 
dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
-- 
1.7.9.5



[PATCH v5 0/3] MT8173 HDMI 4K support

2016-09-28 Thread Bibby Hsieh
This is MT8173 HDMI 4K support PATCH v5, based on 4.8-rc1.

In order to support HDMI 4K on MT8173,
we have to make some modifications.
1) Make sure that mtk_hdmi_send_infoframe is sent successfully.
2) Enhance the HDMI driving current to improve performance.
3) Make sure that pixel clock is 297MHz when resolution is 4K.

Changes since v4:
 - Update commit message and patch title.

Changes since v3:
 - Rebase to 4.8-rc1.
 - The valid range of tvdpll is 1G to 2G Hz, so, we Change the
   if statement of mode->clock to fit that and add a comment.

Changes since v2:
 - Remove the change about preparation for MT2701 support.

Changes since v1:
 - According to the suggestion from philipp, We use the new
   dpi0_sel rate set method.
 - calls clk_set_rate to set the dpi0_sel according to the
   pixel clock.
 - Remove the direct access to all the intermediate clock part.
 - Remove the intermediate tvdpll_d* clocks in dts.
 - According to suggestion from CK, we rename the clock parse
   function and remove it from mtk_dpi_conf struct.
 - Merges the hdmi Pll set rate for pixel clock greater than
   165MHz and smaller parts.

The PATCH depends on the following patch:
https://patchwork.kernel.org/patch/9262575/
(arm64: dts: mt8173: add mmsel clocks for 4K support)

Junzhi Zhao (3):
  drm/mediatek: do mtk_hdmi_send_infoframe after HDMI clock enable
  drm/mediatek: enhance the HDMI driving current
  drm/mediatek: modify the factor to make the pll_rate set in the 1G-2G
range

 drivers/gpu/drm/mediatek/mtk_dpi.c |9 +++--
 drivers/gpu/drm/mediatek/mtk_hdmi.c|   17 ++
 drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c |   42 +---
 3 files changed, 48 insertions(+), 20 deletions(-)

-- 
1.7.9.5



[PATCH v5 1/3] drm/mediatek: do mtk_hdmi_send_infoframe after HDMI clock enable

2016-09-28 Thread Bibby Hsieh
From: Junzhi Zhao 

The mtk_hdmi_send_infoframe have to
be run after PLL and PIXEL clock of HDMI enable.
Make sure that HDMI inforframes can be sent
successfully.

Signed-off-by: Junzhi Zhao 
Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c |   17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c 
b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 334562d..875b045 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1133,12 +1133,6 @@ static int mtk_hdmi_output_set_display_mode(struct 
mtk_hdmi *hdmi,
phy_power_on(hdmi->phy);
mtk_hdmi_aud_output_config(hdmi, mode);
 
-   mtk_hdmi_setup_audio_infoframe(hdmi);
-   mtk_hdmi_setup_avi_infoframe(hdmi, mode);
-   mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI");
-   if (mode->flags & DRM_MODE_FLAG_3D_MASK)
-   mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode);
-
mtk_hdmi_hw_vid_black(hdmi, false);
mtk_hdmi_hw_aud_unmute(hdmi);
mtk_hdmi_hw_send_av_unmute(hdmi);
@@ -1401,6 +1395,16 @@ static void mtk_hdmi_bridge_pre_enable(struct drm_bridge 
*bridge)
hdmi->powered = true;
 }
 
+static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi,
+   struct drm_display_mode *mode)
+{
+   mtk_hdmi_setup_audio_infoframe(hdmi);
+   mtk_hdmi_setup_avi_infoframe(hdmi, mode);
+   mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI");
+   if (mode->flags & DRM_MODE_FLAG_3D_MASK)
+   mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode);
+}
+
 static void mtk_hdmi_bridge_enable(struct drm_bridge *bridge)
 {
struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
@@ -1409,6 +1413,7 @@ static void mtk_hdmi_bridge_enable(struct drm_bridge 
*bridge)
clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]);
clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]);
phy_power_on(hdmi->phy);
+   mtk_hdmi_send_infoframe(hdmi, &hdmi->mode);
 
hdmi->enabled = true;
 }
-- 
1.7.9.5



linux-next: manual merge of the tip tree with the vfs tree

2016-09-28 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the tip tree got a conflict in:

  arch/x86/mm/fault.c

between commit:

  df720ac12fc7 ("exceptions: detritus removal")

from the vfs tree and commit:

  744c193eb9a2 ("x86: Migrate exception table users off module.h and onto 
extable.h")

from the tip tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc arch/x86/mm/fault.c
index c0413d5541af,4dc13340653e..
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@@ -5,7 -5,7 +5,7 @@@
   */
  #include   /* test_thread_flag(), ...  */
  #include  /* oops_begin/end, ...  */
- #include  /* search_exception_tables  */
 -#include /* search_exception_table   */
++#include /* search_exception_tables  */
  #include /* max_low_pfn  */
  #include /* NOKPROBE_SYMBOL, ... */
  #include   /* kmmio_handler, ...   */


tracing: add #undef to fix compile error

2016-09-28 Thread Rik van Riel
There are several trace include files that define TRACE_INCLUDE_FILE.

Include several of them in the same .c file (as I currently have in
some code I am working on), and the compile will blow up with a
"warning: "TRACE_INCLUDE_FILE" redefined #define TRACE_INCLUDE_FILE syscalls"

Every other include file in include/trace/events/ avoids that issue
by having a #undef TRACE_INCLUDE_FILE before the #define; syscalls.h
should have one, too.

Signed-off-by: Rik van Riel 
---
 include/trace/events/syscalls.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/trace/events/syscalls.h b/include/trace/events/syscalls.h
index 14e49c798135..b35533b94277 100644
--- a/include/trace/events/syscalls.h
+++ b/include/trace/events/syscalls.h
@@ -1,5 +1,6 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM raw_syscalls
+#undef TRACE_INCLUDE_FILE
 #define TRACE_INCLUDE_FILE syscalls
 
 #if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)


Re: [PATCH 2/2] drm/vc4: Add support for interlaced modes on HDMI.

2016-09-28 Thread Eric Anholt
Mark yao  writes:

> On 2016年09月29日 10:20, Eric Anholt wrote:
>> We just needed to initialize a few more fields.
>>
>> Signed-off-by: Eric Anholt 
>> ---
>>   drivers/gpu/drm/vc4/vc4_crtc.c | 17 ++---
>>   drivers/gpu/drm/vc4/vc4_hdmi.c | 12 
>>   drivers/gpu/drm/vc4/vc4_regs.h |  3 +++
>>   3 files changed, 25 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
>> index 8fc2b731b59a..d575f8aa3273 100644
>> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
>> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
>> @@ -428,13 +428,24 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc 
>> *crtc)
>> VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
>>   PV_VERTB_VFP) |
>> VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
>> +
>> +/* We set up first field even mode for HDMI.  VEC's
>> + * NTSC mode would want first field odd instead, once
>> + * we support it (to do so, set ODD_FIRST and put the
>> + * delay in VSYNCD_EVEN instead).
>> + */
>> +CRTC_WRITE(PV_V_CONTROL,
>> +   PV_VCONTROL_CONTINUOUS |
>> +   PV_VCONTROL_INTERLACE |
>> +   VC4_SET_FIELD(mode->htotal / 2,
>> + PV_VCONTROL_ODD_DELAY));
>> +CRTC_WRITE(PV_VSYNCD_EVEN, 0);
>> +} else {
>> +CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
>>  }
>>   
>>  CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
>>   
>> -CRTC_WRITE(PV_V_CONTROL,
>> -   PV_VCONTROL_CONTINUOUS |
>> -   (interlace ? PV_VCONTROL_INTERLACE : 0));
>>   
>>  CRTC_WRITE(PV_CONTROL,
>> VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
>> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
>> index 5770d6704f4b..6095e48fcf46 100644
>> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
>> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
>> @@ -246,7 +246,7 @@ static struct drm_connector 
>> *vc4_hdmi_connector_init(struct drm_device *dev,
>>  connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
>>   DRM_CONNECTOR_POLL_DISCONNECT);
>>   
>> -connector->interlace_allowed = 0;
>> +connector->interlace_allowed = true;
>>  connector->doublescan_allowed = 0;
>>   
>>  drm_mode_connector_attach_encoder(connector, encoder);
>> @@ -278,8 +278,8 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder 
>> *encoder,
>>  bool debug_dump_regs = false;
>>  bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
>>  bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
>> -u32 vactive = (mode->vdisplay >>
>> -   ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
>> +bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
>> +u32 vactive = mode->vdisplay >> interlaced;
>
> How about use mode->crtc_vdisplay:
>
> see this:
> drm_mode_set_crtcinfo()
>
>  if (p->flags & DRM_MODE_FLAG_INTERLACE) {
>  if (adjust_flags & CRTC_INTERLACE_HALVE_V) {
>  p->crtc_vdisplay /= 2;
>  p->crtc_vsync_start /= 2;
>  p->crtc_vsync_end /= 2;
>  p->crtc_vtotal /= 2;
>  }
>  }

That would require setting up the adjust_flags, and I thought in the DRM
we were trying to move away from using it.  Also it would be pretty
strange to use just this one field from crtc_*.



signature.asc
Description: PGP signature


RE: [PATCH 3/3] KVM: x86: do not scan IRR twice on APICv vmentry

2016-09-28 Thread Wu, Feng


> -Original Message-
> From: Paolo Bonzini [mailto:paolo.bonz...@gmail.com] On Behalf Of Paolo
> Bonzini
> Sent: Wednesday, September 28, 2016 5:20 AM
> To: linux-kernel@vger.kernel.org; k...@vger.kernel.org
> Cc: yang.zhang...@gmail.com; Wu, Feng ;
> m...@redhat.com; rkrc...@redhat.com
> Subject: [PATCH 3/3] KVM: x86: do not scan IRR twice on APICv vmentry
> 
> Calling apic_find_highest_irr results in IRR being scanned twice,
> once in vmx_sync_pir_from_irr and once in apic_search_irr.  Change
> vcpu_enter_guest to use sync_pir_from_irr (with a new argument to
> trigger the RVI write), and let sync_pir_from_irr get the new RVI
> directly from kvm_apic_update_irr.
> 
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Feng Wu 

Thanks,
Feng

> ---
>  arch/x86/include/asm/kvm_host.h |  2 +-
>  arch/x86/kvm/lapic.c| 25 -
>  arch/x86/kvm/lapic.h|  4 ++--
>  arch/x86/kvm/svm.c  |  2 +-
>  arch/x86/kvm/vmx.c  | 25 ++---
>  arch/x86/kvm/x86.c  |  7 +++
>  6 files changed, 37 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h
> b/arch/x86/include/asm/kvm_host.h
> index 4b20f7304b9c..f73eea243567 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -941,7 +941,7 @@ struct kvm_x86_ops {
>   void (*set_virtual_x2apic_mode)(struct kvm_vcpu *vcpu, bool set);
>   void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
>   void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
> - void (*sync_pir_to_irr)(struct kvm_vcpu *vcpu);
> + void (*sync_pir_to_irr)(struct kvm_vcpu *vcpu, bool sync_rvi);
>   int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
>   int (*get_tdp_level)(void);
>   u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index be8b7ad56dd1..85b79b90e3d0 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -317,7 +317,7 @@ static int find_highest_vector(void *bitmap)
>vec >= 0; vec -= APIC_VECTORS_PER_REG) {
>   reg = bitmap + REG_POS(vec);
>   if (*reg)
> - return fls(*reg) - 1 + vec;
> + return __fls(*reg) + vec;
>   }
> 
>   return -1;
> @@ -337,25 +337,32 @@ static u8 count_vectors(void *bitmap)
>   return count;
>  }
> 
> -void __kvm_apic_update_irr(u32 *pir, void *regs)
> +int __kvm_apic_update_irr(u32 *pir, void *regs)
>  {
> - u32 i, pir_val;
> + u32 i, vec;
> + u32 pir_val, irr_val;
> + int max_irr = -1;
> 
> - for (i = 0; i <= 7; i++) {
> + for (i = vec = 0; i <= 7; i++, vec += 32) {
>   pir_val = READ_ONCE(pir[i]);
> + irr_val = *((u32 *)(regs + APIC_IRR + i * 0x10));
>   if (pir_val) {
> - pir_val = xchg(&pir[i], 0);
> - *((u32 *)(regs + APIC_IRR + i * 0x10)) |= pir_val;
> + irr_val |= xchg(&pir[i], 0);
> + *((u32 *)(regs + APIC_IRR + i * 0x10)) = irr_val;
>   }
> + if (irr_val)
> + max_irr = __fls(irr_val) + vec;
>   }
> +
> + return max_irr;
>  }
>  EXPORT_SYMBOL_GPL(__kvm_apic_update_irr);
> 
> -void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir)
> +int kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir)
>  {
>   struct kvm_lapic *apic = vcpu->arch.apic;
> 
> - __kvm_apic_update_irr(pir, apic->regs);
> + return __kvm_apic_update_irr(pir, apic->regs);
>  }
>  EXPORT_SYMBOL_GPL(kvm_apic_update_irr);
> 
> @@ -376,7 +383,7 @@ static inline int apic_find_highest_irr(struct kvm_lapic
> *apic)
>   return -1;
> 
>   if (apic->vcpu->arch.apicv_active)
> - kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
> + kvm_x86_ops->sync_pir_to_irr(apic->vcpu, false);
>   result = apic_search_irr(apic);
>   ASSERT(result == -1 || result >= 16);
> 
> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> index f60d01c29d51..fc72828c3782 100644
> --- a/arch/x86/kvm/lapic.h
> +++ b/arch/x86/kvm/lapic.h
> @@ -70,8 +70,8 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset,
> int len,
>  bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
>  int short_hand, unsigned int dest, int dest_mode);
> 
> -void __kvm_apic_update_irr(u32 *pir, void *regs);
> -void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
> +int __kvm_apic_update_irr(u32 *pir, void *regs);
> +int kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
>  int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
>struct dest_map *dest_map);
>  int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type);
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 9b4221471e3d..60e53fa2b554 1

Re: [PATCH net v2] L2TP:Adjust intf MTU,factor underlay L3,overlay L2

2016-09-28 Thread R. Parameswaran


Hi David,

Please see inline:

On Wed, 28 Sep 2016, David Miller wrote:

> From: "R. Parameswaran" 
> Date: Tue, 27 Sep 2016 12:17:21 -0700 (PDT)
> 
> > Later, in vxlan_dev_configure(), called from vxlan_dev_create(), it gets 
> > adjusted to account for the headers:
> > 
> > vxlan_dev_configure():
> > ...
> >  if (!conf->mtu)
> > dev->mtu = lowerdev->mtu - (use_ipv6 ? 
> > VXLAN6_HEADROOM : VXLAN_HEADROOM);
> > 
> > 
> > where VXLAN_HEADROOM is defined as follows: 
> > 
> > /* IP header + UDP + VXLAN + Ethernet header */
> > #define VXLAN_HEADROOM (20 + 8 + 8 + 14)
> > /* IPv6 header + UDP + VXLAN + Ethernet header */
> > #define VXLAN6_HEADROOM (40 + 8 + 8 + 14)
> 
> Right but I don't see it going through the effort to make use of the
> PMTU like you are.
> 
> I have another strong concern related to this.  There seems to be no
> mechanism used to propagate any PMTU events into the device's MTU.
> 
> Because if there is a limiting nexthop in the route to the other end
> of the UDP tunnel, you won't learn the PMTU until you (or some other
> entity on the machine) actually starts sending traffic to the tunnel's
> endpoint.
> 
> If the PMTU events aren't propagated into the tunnel's MTU or similar
> I think this is an ad-hoc solution.
> 
> I would suggest that you either:
> 
> 1) Do what VXLAN appears to do an ignore the PMTu
> 

I'd like to point out one difference with VXLAN - in VXLAN, the 
local physical interface is directly specified at the time of 
creation of the tunnel, and the data structure seems to have the ifindex 
of the local interface with which it is able to directly pull up the 
underlay interface device. Whereas in L2TP, we only have the IP
address of the remote tunnel end-point and thus only the socket and the 
dst from which we need to derive this. 

Also, dst_mtu references dst->ops->mtu, which if I followed the pointer
chain correctly, will dereference to ipv4_mtu() (for the IPv4 case, as
an example). The code in ipv4_mtu looks like the following:

ipv4_mtu():

unsigned int mtu = rt->rt_pmtu;

if (!mtu || time_after_eq(jiffies, rt->dst.expires))
mtu = dst_metric_raw(dst, RTAX_MTU);

if (mtu)
return mtu;

mtu = dst->dev->mtu;

if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
if (rt->rt_uses_gateway && mtu > 576)
mtu = 576;
}

return min_t(unsigned int, mtu, IP_MAX_MTU);

The code above does not depend on PMTU to be working. If no PMTU 
discovered MTU exists, it eventually falls back to the local 
underlay device MTU - and this is the mode in which I tested the fix - PMTU 
was off in my testbed, but it was picking up the local device MTU correctly.

Basically, this looks better than the VXLAN handling as far as I can 
tell - at least it will pick up the existing discovered PMTU on a best 
effort basis, while falling back to the underlay device if all else fails. 

I agree that something like 2. below would be needed in the long run (it 
will need some effort and redesign -e.g. how do I lookup the parent tunnel 
from the socket when receiving a PMTU update, existing pointer chain runs 
from tunnel to socket).  

But since the existing (Ethernet over L2TP) MTU derivation is incorrect, I am 
hoping this may be acceptable as an interim solution. 

thanks,

Ramkumar


> 2) Add code to handle PMTU events that land on the UDP tunnel
>socket.
> 
> Thanks.
> 


Re: Runtime failure running sh:qemu in -next due to 'sh: fix copy_from_user()'

2016-09-28 Thread Rob Landley
On 09/18/2016 10:17 AM, Rich Felker wrote:
> On Sat, Sep 17, 2016 at 11:40:28PM -0500, Rob Landley wrote:
>>
>>
>> On 09/16/2016 09:23 PM, Guenter Roeck wrote:
>>> On 09/16/2016 04:32 PM, Rich Felker wrote:
> 4.6.3 from kernel.org.

 That is utterly ancient and probaby very buggy. I would recommend 5.x+
 or at the very least 4.7 or 4.8.

>>> Unfortunately that is the latest one available from kernel.org :-(.
>>> I'll try to build one myself.
>>
>> Rich, you really, really need to get an actual release version of
>> https://github.com/richfelker/musl-cross-make posted.
> 
> What do you mean? Binaries? There are release tags, though it would
> probably be a good time to make another one.
> 
> But this project (musl-cross-make) is not needed for building kernels
> -- stock gcc, any modern-ish version, should work fine. The canonical
> way (from prior to my involvement) to build sh* kernels is to use a
> gcc that supports any ISA level, and this can be done without multilib
> libgcc since the kernel provides its own libgcc replacement functions.

The above was an example of somebody using a broken toolchain because
there isn't a known-good reference toolchain for the architecture, which
the kernel maintainer is known to regression test against. Having such a
thing might help people distinguish "bug in kernel" from "bug in gcc".

> Rich

Rob


Re: [PATCH 2/2] drm/vc4: Add support for interlaced modes on HDMI.

2016-09-28 Thread Mark yao

On 2016年09月29日 10:20, Eric Anholt wrote:

We just needed to initialize a few more fields.

Signed-off-by: Eric Anholt 
---
  drivers/gpu/drm/vc4/vc4_crtc.c | 17 ++---
  drivers/gpu/drm/vc4/vc4_hdmi.c | 12 
  drivers/gpu/drm/vc4/vc4_regs.h |  3 +++
  3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 8fc2b731b59a..d575f8aa3273 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -428,13 +428,24 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
   VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
 PV_VERTB_VFP) |
   VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
+
+   /* We set up first field even mode for HDMI.  VEC's
+* NTSC mode would want first field odd instead, once
+* we support it (to do so, set ODD_FIRST and put the
+* delay in VSYNCD_EVEN instead).
+*/
+   CRTC_WRITE(PV_V_CONTROL,
+  PV_VCONTROL_CONTINUOUS |
+  PV_VCONTROL_INTERLACE |
+  VC4_SET_FIELD(mode->htotal / 2,
+PV_VCONTROL_ODD_DELAY));
+   CRTC_WRITE(PV_VSYNCD_EVEN, 0);
+   } else {
+   CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
}
  
  	CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
  
-	CRTC_WRITE(PV_V_CONTROL,

-  PV_VCONTROL_CONTINUOUS |
-  (interlace ? PV_VCONTROL_INTERLACE : 0));
  
  	CRTC_WRITE(PV_CONTROL,

   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 5770d6704f4b..6095e48fcf46 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -246,7 +246,7 @@ static struct drm_connector *vc4_hdmi_connector_init(struct 
drm_device *dev,
connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
 DRM_CONNECTOR_POLL_DISCONNECT);
  
-	connector->interlace_allowed = 0;

+   connector->interlace_allowed = true;
connector->doublescan_allowed = 0;
  
  	drm_mode_connector_attach_encoder(connector, encoder);

@@ -278,8 +278,8 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder 
*encoder,
bool debug_dump_regs = false;
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
-   u32 vactive = (mode->vdisplay >>
-  ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
+   bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
+   u32 vactive = mode->vdisplay >> interlaced;


How about use mode->crtc_vdisplay:

see this:
drm_mode_set_crtcinfo()

if (p->flags & DRM_MODE_FLAG_INTERLACE) {
if (adjust_flags & CRTC_INTERLACE_HALVE_V) {
p->crtc_vdisplay /= 2;
p->crtc_vsync_start /= 2;
p->crtc_vsync_end /= 2;
p->crtc_vtotal /= 2;
}
}

Thanks


u32 verta = (VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
   VC4_HDMI_VERTA_VSP) |
 VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
@@ -288,6 +288,10 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder 
*encoder,
u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
 VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
   VC4_HDMI_VERTB_VBP));
+   u32 vertb_even = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
+ VC4_SET_FIELD(mode->vtotal - mode->vsync_end -
+   interlaced,
+   VC4_HDMI_VERTB_VBP));
  
  	if (debug_dump_regs) {

DRM_INFO("HDMI regs before:\n");
@@ -319,7 +323,7 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder 
*encoder,
HDMI_WRITE(VC4_HDMI_VERTA0, verta);
HDMI_WRITE(VC4_HDMI_VERTA1, verta);
  
-	HDMI_WRITE(VC4_HDMI_VERTB0, vertb);

+   HDMI_WRITE(VC4_HDMI_VERTB0, vertb_even);
HDMI_WRITE(VC4_HDMI_VERTB1, vertb);
  
  	HD_WRITE(VC4_HD_VID_CTL,

diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 160942a9180e..fec7b5ef058b 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -183,6 +183,9 @@
  # define PV_CONTROL_ENBIT(0)
  
  #define PV_V_CONTROL0x04

+# define PV_VCONTROL_ODD_DELAY_MASKVC4_MASK(22, 6)
+# define PV_VCONTROL_ODD_DELAY_SHIFT   6
+# define PV_VCONTROL_ODD_FIRST BIT(5)
  # define PV_VCONTROL_INTERLACEBIT(4)
  # define PV_VCONTROL_CONTINUOUS   BIT(1)
  # define PV_VCONTROL_VIDENBIT(0)



--
M

Re: [PATCH] perf sched: kill time stamp discrepancy between script and latency

2016-09-28 Thread Joonwoo Park



On 09/28/2016 07:25 PM, Joonwoo Park wrote:

Perf sched latency is handy to find out the maximum sched latency and
the time stamp of the event.  After running sched latency, if a found
latency looks suspicious it's quite reasonable to run perf script
subsequently and search with the time stamp given by perf sched latency
to continue further debugging.  However, at present, it's possible the
time stamp given by perf sched latency cannot be found in the trace
output by perf script because perf sched latency converts the event
time from ns to ms as double float and prints it with printf which
does banker's rounding as opposed to perf script doesn't.

  For example:

   0x750ff0 [0x80]: event: 9
   
   2 1858303049520 0x750ff0 [0x80]: PERF_RECORD_SAMPLE(IP, 0x1): 15281/15281: 
0x8162a63a period: 1 addr: 0
... thread: hackbench:15281
   

$ perf sched -i perf.data latency | grep hackbench
  hackbench:(401)   +   3539.283 ms |23347 | avg:7.286 ms | 
max:  829.998 ms | max at:   1858.303050 s

$ perf script -i perf.data | grep "1858\.303050"

$ perf script -i perf.data | grep "1858\.303049"
  hackbench 15281 [002]  1858.303049:   sched:sched_switch: 
prev_comm=hackbench prev_pid=15281 prev_prio=120 prev_state=D ==> 
next_comm=hackbench next_pid=15603 next_prio=120

Fix perf latency to print out time stamp without rounding to avoid such
discrepancy.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexander Shishkin 
Cc: Steven Rostedt 
Cc: Namhyung Kim 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joonwoo Park 
---

I was tempted to get rid of all u64 to double casting in the function
output_lat_thread but didn't because there is no data loss as of
today.  Double float gives at least 15 significant decimal digits
precision while the function requires only 14 significant digits precision.

$ python -c "print(len(str(int(0x / 1e6"
14

 tools/lib/traceevent/event-parse.h |  1 +
 tools/perf/builtin-sched.c | 12 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h 
b/tools/lib/traceevent/event-parse.h
index 9ffde37..f42703c 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -174,6 +174,7 @@ struct pevent_plugin_option {

 #define NSECS_PER_SEC  10ULL
 #define NSECS_PER_USEC 1000ULL
+#define MSECS_PER_SEC  1000ULL

 enum format_flags {
FIELD_IS_ARRAY  = 1,
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index afa0576..e5cf51a 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1190,6 +1190,7 @@ static void output_lat_thread(struct perf_sched *sched, 
struct work_atoms *work_
int i;
int ret;
u64 avg;
+   u64 max_lat_at_sec, max_lat_at_msec;

if (!work_list->nb_atoms)
return;
@@ -1212,11 +1213,18 @@ static void output_lat_thread(struct perf_sched *sched, 
struct work_atoms *work_

avg = work_list->total_lat / work_list->nb_atoms;

-   printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: 
%13.6f s\n",
+   /*
+* Avoid round up with printf to prevent event time discrepency


s/discrepency/discrepancy/
I will fix this typo after gathering review comments.

Thanks,
Joonwoo


+* between sched script and latency.
+*/
+   max_lat_at_sec = work_list->max_lat_at / NSECS_PER_SEC;
+   max_lat_at_msec = (work_list->max_lat_at -
+  max_lat_at_sec * NSECS_PER_SEC) / MSECS_PER_SEC;
+   printf("+%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: 
%6lu.%06lu s\n",
  (double)work_list->total_runtime / 1e6,
 work_list->nb_atoms, (double)avg / 1e6,
 (double)work_list->max_lat / 1e6,
-(double)work_list->max_lat_at / 1e9);
+max_lat_at_sec, max_lat_at_msec);
 }

 static int pid_cmp(struct work_atoms *l, struct work_atoms *r)



[PATCH] perf sched: kill time stamp discrepancy between script and latency

2016-09-28 Thread Joonwoo Park
Perf sched latency is handy to find out the maximum sched latency and
the time stamp of the event.  After running sched latency, if a found
latency looks suspicious it's quite reasonable to run perf script
subsequently and search with the time stamp given by perf sched latency
to continue further debugging.  However, at present, it's possible the
time stamp given by perf sched latency cannot be found in the trace
output by perf script because perf sched latency converts the event
time from ns to ms as double float and prints it with printf which
does banker's rounding as opposed to perf script doesn't.

  For example:

   0x750ff0 [0x80]: event: 9
   
   2 1858303049520 0x750ff0 [0x80]: PERF_RECORD_SAMPLE(IP, 0x1): 15281/15281: 
0x8162a63a period: 1 addr: 0
... thread: hackbench:15281
   

$ perf sched -i perf.data latency | grep hackbench
  hackbench:(401)   +   3539.283 ms |23347 | avg:7.286 ms | 
max:  829.998 ms | max at:   1858.303050 s

$ perf script -i perf.data | grep "1858\.303050"

$ perf script -i perf.data | grep "1858\.303049"
  hackbench 15281 [002]  1858.303049:   sched:sched_switch: 
prev_comm=hackbench prev_pid=15281 prev_prio=120 prev_state=D ==> 
next_comm=hackbench next_pid=15603 next_prio=120

Fix perf latency to print out time stamp without rounding to avoid such
discrepancy.

Cc: Peter Zijlstra 
Cc: Ingo Molnar 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexander Shishkin 
Cc: Steven Rostedt 
Cc: Namhyung Kim 
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joonwoo Park 
---

I was tempted to get rid of all u64 to double casting in the function
output_lat_thread but didn't because there is no data loss as of
today.  Double float gives at least 15 significant decimal digits
precision while the function requires only 14 significant digits precision.

$ python -c "print(len(str(int(0x / 1e6"
14

 tools/lib/traceevent/event-parse.h |  1 +
 tools/perf/builtin-sched.c | 12 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h 
b/tools/lib/traceevent/event-parse.h
index 9ffde37..f42703c 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -174,6 +174,7 @@ struct pevent_plugin_option {
 
 #define NSECS_PER_SEC  10ULL
 #define NSECS_PER_USEC 1000ULL
+#define MSECS_PER_SEC  1000ULL
 
 enum format_flags {
FIELD_IS_ARRAY  = 1,
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index afa0576..e5cf51a 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1190,6 +1190,7 @@ static void output_lat_thread(struct perf_sched *sched, 
struct work_atoms *work_
int i;
int ret;
u64 avg;
+   u64 max_lat_at_sec, max_lat_at_msec;
 
if (!work_list->nb_atoms)
return;
@@ -1212,11 +1213,18 @@ static void output_lat_thread(struct perf_sched *sched, 
struct work_atoms *work_
 
avg = work_list->total_lat / work_list->nb_atoms;
 
-   printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max 
at: %13.6f s\n",
+   /*
+* Avoid round up with printf to prevent event time discrepency
+* between sched script and latency.
+*/
+   max_lat_at_sec = work_list->max_lat_at / NSECS_PER_SEC;
+   max_lat_at_msec = (work_list->max_lat_at -
+  max_lat_at_sec * NSECS_PER_SEC) / MSECS_PER_SEC;
+   printf("+%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max 
at: %6lu.%06lu s\n",
  (double)work_list->total_runtime / 1e6,
 work_list->nb_atoms, (double)avg / 1e6,
 (double)work_list->max_lat / 1e6,
-(double)work_list->max_lat_at / 1e9);
+max_lat_at_sec, max_lat_at_msec);
 }
 
 static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



Re: Regression in 4.8 - CPU speed set very low

2016-09-28 Thread Larry Finger

On 09/27/2016 09:51 AM, Lennart Sorensen wrote:

On Mon, Sep 26, 2016 at 04:28:29PM -0500, Larry Finger wrote:

Mostly I use a KDE applet named "System load" and look at the "average
clock", but the same info is also available in /proc/cpuinfo as "cpu MHz".
When the bug triggers, the system gets very slow, and the cpu fan stops even
though the cpu is still busy.

Commit f7816ad, which had run for 7 days without showing the bug, failed
after about 2 hours today. All my testing since Sept. 9 has been wasted. Oh
well, that's the way it goes!


Is it possible there is no bug and instead you have a hardware problem?

What I am thinking:

CPU fan stops, then CPU gets busy, CPU overheats, thermal throtling
kicks in to protect CPU and it gets VERY slow.

So maybe you have a bad CPU fan that is getting stuck.  Perhaps even if
you have a motherboard that varies the CPU fan depending on need and the
fan doesn't like the lowest speed and sometimes gets stuck when asked
to go slow.

Of course if the CPU fan is the problem that could explain why it takes
varying amounts of time to see the problem.

I suggest checking what the cpu temperature sensors are showing next
time it gets slow.


By the time it gets slow, the CPU's cool, and one cannot see the temp just 
before that event happened.


The reason I suspect a bug is that it fails with 4.8-rcX, but not with 4.7. Of 
course, it could be something subtle that slightly changes the heat load, which 
causes the CPU temp to be a little higher so that the effect is triggered.


I am reasonably confident that it is not a hardware problem, but we may have to 
wait until 4.8 is released and gets wider usage. If no one else reports a 
problem, then I am certainly wrong.


Larry






Re: [PATCH] netfilter: bridge: clarify bridge/netfilter message

2016-09-28 Thread Florian Westphal
Stefan Agner  wrote:
> When using bridge without bridge netfilter enabled the message
> displayed is rather confusing and leads to belive that a deprecated
> feature is in use. Use IS_MODULE to be explicit that the message only
> affects users which use bridge netfilter as module and reword the
> message.

Acked-by: Florian Westphal 



Re: Regression in mobility grouping?

2016-09-28 Thread Johannes Weiner
On Wed, Sep 28, 2016 at 11:39:25AM -0400, Johannes Weiner wrote:
> On Wed, Sep 28, 2016 at 11:00:15AM +0200, Vlastimil Babka wrote:
> > I guess testing revert of 9c0415e could give us some idea. Commit
> > 3a1086f shouldn't result in pageblock marking differences and as I said
> > above, 99592d5 should be just restoring to what 3.10 did.
> 
> I can give this a shot, but note that this commit makes only unmovable
> stealing more aggressive. We see reclaimable blocks up as well.

Quick update, I reverted back to stealing eagerly only on behalf of
MIGRATE_RECLAIMABLE allocations in a 4.6 kernel:

static bool can_steal_fallback(unsigned int order, int start_mt)
{
if (order >= pageblock_order / 2 ||
start_mt == MIGRATE_RECLAIMABLE ||
page_group_by_mobility_disabled)
return true;

return false;
}

Yet, I still see UNMOVABLE growing to the thousands within minutes,
whereas 3.10 didn't reach those numbers even after days of uptime.

Okay, that wasn't it. However, there is something fishy going on,
because I see extfrag traces like these:

-0 [006] d.s.  1110.217281: mm_page_alloc_extfrag: 
page=ea0064142000 pfn=26235008 alloc_order=3 fallback_order=3 
pageblock_order=9 alloc_migratetype=0 fallback_migratetype=2 fragmenting=1 
change_ownership=1

enum {
MIGRATE_UNMOVABLE,
MIGRATE_MOVABLE,
MIGRATE_RECLAIMABLE,
MIGRATE_PCPTYPES,   /* the number of types on the pcp lists */
MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES,
...
};

This is an UNMOVABLE order-3 allocation falling back to RECLAIMABLE.
According to can_steal_fallback(), this allocation shouldn't steal the
pageblock, yet change_ownership=1 indicates the block is UNMOVABLE.

Who converted it? I wonder if there is a bug in ownership management,
and there was an UNMOVABLE block on the RECLAIMABLE freelist from the
beginning. AFAICS we never validate list/mt consistency anywhere.

I'll continue looking tomorrow.


[PATCH] clk: bcm2835: Clamp the PLL's requested rate to the hardware limits.

2016-09-28 Thread Eric Anholt
Fixes setting low-resolution video modes on HDMI.  Now the PLLH_PIX
divider adjusts itself until the PLLH is within bounds.

Signed-off-by: Eric Anholt 
---
 drivers/clk/bcm/clk-bcm2835.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 7a7970865c2d..fedc88908e61 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -499,8 +499,13 @@ static long bcm2835_pll_rate_from_divisors(unsigned long 
parent_rate,
 static long bcm2835_pll_round_rate(struct clk_hw *hw, unsigned long rate,
   unsigned long *parent_rate)
 {
+   struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+   const struct bcm2835_pll_data *data = pll->data;
u32 ndiv, fdiv;
 
+   rate = max(data->min_rate, rate);
+   rate = min(data->max_rate, rate);
+
bcm2835_pll_choose_ndiv_and_fdiv(rate, *parent_rate, &ndiv, &fdiv);
 
return bcm2835_pll_rate_from_divisors(*parent_rate, ndiv, fdiv, 1);
@@ -605,13 +610,6 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
u32 ana[4];
int i;
 
-   if (rate < data->min_rate || rate > data->max_rate) {
-   dev_err(cprman->dev, "%s: rate out of spec: %lu vs (%lu, 
%lu)\n",
-   clk_hw_get_name(hw), rate,
-   data->min_rate, data->max_rate);
-   return -EINVAL;
-   }
-
if (rate > data->max_fb_rate) {
use_fb_prediv = true;
rate /= 2;
-- 
2.9.3



Re: Regression in 4.8 - CPU speed set very low

2016-09-28 Thread Larry Finger

On 09/27/2016 06:46 AM, Rafael J. Wysocki wrote:

On Tue, Sep 27, 2016 at 10:48 AM, Larry Finger
 wrote:

On 09/26/2016 10:12 PM, Doug Smythies wrote:


On 2016.09.26 18:31 Srinivas Pandruvada wrote:


On Mon, 2016-09-26 at 19:48 -0500, Larry Finger wrote:


On 09/26/2016 07:21 PM, Rafael J. Wysocki wrote:


On Tue, Sep 27, 2016 at 1:53 AM, Larry Finger wrote:
But for both we need a reproducer anyway.


I do not have a reliable reproducer. The condition has always
happened when
running a high-compute job such as a 'make -j8' on the kernel, or
building the
RPM for openSUSE's implementation of VirtualBox. The latter is what
I'm using
for most of my testing.



Run some CPU stressor and get all your CPU's going at 100% load.
And watch your core temperatures while you do so.



for i in 1 2 3 4; do while : ; do : ; done & done

triggered the fault in a few minutes.






It also would be good to rule out the thermal throttling (as per
the Srinivas' comments).



It is almost certainly thermal throttling, or similar causing
Clock modulation, of it seems 50%.



While the infinite loops were running, the temps were:

finger@linux-1t8h:~/rtlwifi_new> sensors
coretemp-isa-
Adapter: ISA adapter
Physical id 0:  +83.0°C  (high = +84.0°C, crit = +100.0°C)
Core 0: +83.0°C  (high = +84.0°C, crit = +100.0°C)
Core 1: +74.0°C  (high = +84.0°C, crit = +100.0°C)


It looks like the trip point (high) temperature was exceeded causing
thermal throttling to kick in.


After the fault occurs, I get

finger@linux-1t8h:~/rtlwifi_new> sensors
coretemp-isa-
Adapter: ISA adapter
Physical id 0:  +44.0°C  (high = +84.0°C, crit = +100.0°C)
Core 0: +43.0°C  (high = +84.0°C, crit = +100.0°C)
Core 1: +41.0°C  (high = +84.0°C, crit = +100.0°C)


So after that it stays at 400 MHz forever, right?



For now, please tell me what's in
/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq


80


Your effective freq is lower than 800MHz. One of the possible reason is
thermal throttling.

What distro you are using?



And what make and model of LapTop?



Toshiba Tecra A50-A with CPU Model: 6.60.3 "Intel(R) Core(TM) i7-4600M CPU @
2.90GHz. That is a dual-core unit with hyperthreading.

@Rafael: As I write this, the system has been running the infinite loop test
for almost 5 hours with kernel 4.7. I will leave that running while I'm
gone, but I am certain that it is OK.


OK, and what temperatures do you see while doing this?


finger@linux-1t8h:~/linux-2.6> sensors
coretemp-isa-
Adapter: ISA adapter
Physical id 0:  +90.0°C  (high = +84.0°C, crit = +100.0°C)
Core 0: +90.0°C  (high = +84.0°C, crit = +100.0°C)
Core 1: +78.0°C  (high = +84.0°C, crit = +100.0°C)

Once again, the CPU temp is greater than the "high" value; however, the clock 
rate continues to hold near 3600 MHz.


My laptop was inadvertently put to sleep while I was gone. I forgot to leave a 
note for my wife and she quieted the noisy cpu fan. :)


Larry




[PATCH 1/2] drm/vc4: Increase timeout for HDMI_SCHEDULER_CONTROL changes.

2016-09-28 Thread Eric Anholt
Fixes occasional debug spew at boot when connected directly through
HDMI, and probably confusing the HDMI state machine when we go trying
to poke registers for the enable sequence too soon.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 4452f3631cac..5770d6704f4b 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -369,7 +369,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
*encoder)
   VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
 
ret = wait_for(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
-  VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1);
+  VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1000);
WARN_ONCE(ret, "Timeout waiting for "
  "VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
} else {
@@ -381,7 +381,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
*encoder)
   ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
 
ret = wait_for(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
-VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1);
+VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1000);
WARN_ONCE(ret, "Timeout waiting for "
  "!VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
}
-- 
2.9.3



[PATCH 2/2] drm/vc4: Add support for interlaced modes on HDMI.

2016-09-28 Thread Eric Anholt
We just needed to initialize a few more fields.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 17 ++---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 12 
 drivers/gpu/drm/vc4/vc4_regs.h |  3 +++
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 8fc2b731b59a..d575f8aa3273 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -428,13 +428,24 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
   VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
 PV_VERTB_VFP) |
   VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
+
+   /* We set up first field even mode for HDMI.  VEC's
+* NTSC mode would want first field odd instead, once
+* we support it (to do so, set ODD_FIRST and put the
+* delay in VSYNCD_EVEN instead).
+*/
+   CRTC_WRITE(PV_V_CONTROL,
+  PV_VCONTROL_CONTINUOUS |
+  PV_VCONTROL_INTERLACE |
+  VC4_SET_FIELD(mode->htotal / 2,
+PV_VCONTROL_ODD_DELAY));
+   CRTC_WRITE(PV_VSYNCD_EVEN, 0);
+   } else {
+   CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
}
 
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
 
-   CRTC_WRITE(PV_V_CONTROL,
-  PV_VCONTROL_CONTINUOUS |
-  (interlace ? PV_VCONTROL_INTERLACE : 0));
 
CRTC_WRITE(PV_CONTROL,
   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 5770d6704f4b..6095e48fcf46 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -246,7 +246,7 @@ static struct drm_connector *vc4_hdmi_connector_init(struct 
drm_device *dev,
connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
 DRM_CONNECTOR_POLL_DISCONNECT);
 
-   connector->interlace_allowed = 0;
+   connector->interlace_allowed = true;
connector->doublescan_allowed = 0;
 
drm_mode_connector_attach_encoder(connector, encoder);
@@ -278,8 +278,8 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder 
*encoder,
bool debug_dump_regs = false;
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
-   u32 vactive = (mode->vdisplay >>
-  ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
+   bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
+   u32 vactive = mode->vdisplay >> interlaced;
u32 verta = (VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
   VC4_HDMI_VERTA_VSP) |
 VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
@@ -288,6 +288,10 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder 
*encoder,
u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
 VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
   VC4_HDMI_VERTB_VBP));
+   u32 vertb_even = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
+ VC4_SET_FIELD(mode->vtotal - mode->vsync_end -
+   interlaced,
+   VC4_HDMI_VERTB_VBP));
 
if (debug_dump_regs) {
DRM_INFO("HDMI regs before:\n");
@@ -319,7 +323,7 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder 
*encoder,
HDMI_WRITE(VC4_HDMI_VERTA0, verta);
HDMI_WRITE(VC4_HDMI_VERTA1, verta);
 
-   HDMI_WRITE(VC4_HDMI_VERTB0, vertb);
+   HDMI_WRITE(VC4_HDMI_VERTB0, vertb_even);
HDMI_WRITE(VC4_HDMI_VERTB1, vertb);
 
HD_WRITE(VC4_HD_VID_CTL,
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 160942a9180e..fec7b5ef058b 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -183,6 +183,9 @@
 # define PV_CONTROL_EN BIT(0)
 
 #define PV_V_CONTROL   0x04
+# define PV_VCONTROL_ODD_DELAY_MASKVC4_MASK(22, 6)
+# define PV_VCONTROL_ODD_DELAY_SHIFT   6
+# define PV_VCONTROL_ODD_FIRST BIT(5)
 # define PV_VCONTROL_INTERLACE BIT(4)
 # define PV_VCONTROL_CONTINUOUSBIT(1)
 # define PV_VCONTROL_VIDEN BIT(0)
-- 
2.9.3



[PATCH V4 06/10] dmaengine: qcom_hidma: make error and success path common

2016-09-28 Thread Sinan Kaya
Remove code duplication by feeding the error code from outside
into successful data transfer handler.

Signed-off-by: Sinan Kaya 
---
 drivers/dma/qcom/hidma_ll.c | 34 ++
 1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/drivers/dma/qcom/hidma_ll.c b/drivers/dma/qcom/hidma_ll.c
index 29fef4f..c911ca2 100644
--- a/drivers/dma/qcom/hidma_ll.c
+++ b/drivers/dma/qcom/hidma_ll.c
@@ -241,11 +241,11 @@ static int hidma_post_completed(struct hidma_lldev 
*lldev, int tre_iterator,
  * Return a positive number if there are pending TREs or EVREs.
  * Return 0 if there is nothing to consume or no pending TREs/EVREs found.
  */
-static int hidma_handle_tre_completion(struct hidma_lldev *lldev)
+static int hidma_handle_tre_completion(struct hidma_lldev *lldev, u8 err_info,
+  u8 err_code)
 {
u32 evre_ring_size = lldev->evre_ring_size;
u32 tre_ring_size = lldev->tre_ring_size;
-   u32 err_info, err_code, evre_write_off;
u32 tre_iterator, evre_iterator;
u32 num_completed = 0;
 
@@ -268,10 +268,13 @@ static int hidma_handle_tre_completion(struct hidma_lldev 
*lldev)
u32 cfg;
 
cfg = current_evre[HIDMA_EVRE_CFG_IDX];
-   err_info = cfg >> HIDMA_EVRE_ERRINFO_BIT_POS;
-   err_info &= HIDMA_EVRE_ERRINFO_MASK;
-   err_code =
-   (cfg >> HIDMA_EVRE_CODE_BIT_POS) & HIDMA_EVRE_CODE_MASK;
+   if (!err_info) {
+   err_info = cfg >> HIDMA_EVRE_ERRINFO_BIT_POS;
+   err_info &= HIDMA_EVRE_ERRINFO_MASK;
+   }
+   if (!err_code)
+   err_code = (cfg >> HIDMA_EVRE_CODE_BIT_POS) &
+   HIDMA_EVRE_CODE_MASK;
 
if (hidma_post_completed(lldev, tre_iterator, err_info,
 err_code))
@@ -314,27 +317,10 @@ static int hidma_handle_tre_completion(struct hidma_lldev 
*lldev)
 void hidma_cleanup_pending_tre(struct hidma_lldev *lldev, u8 err_info,
   u8 err_code)
 {
-   u32 tre_iterator;
-   u32 tre_ring_size = lldev->tre_ring_size;
-   int num_completed = 0;
-   u32 tre_read_off;
-
-   tre_iterator = lldev->tre_processed_off;
while (atomic_read(&lldev->pending_tre_count)) {
-   if (hidma_post_completed(lldev, tre_iterator, err_info,
-err_code))
+   if (hidma_handle_tre_completion(lldev, err_info, err_code))
break;
-   HIDMA_INCREMENT_ITERATOR(tre_iterator, HIDMA_TRE_SIZE,
-tre_ring_size);
-   num_completed++;
}
-   tre_read_off = (lldev->tre_processed_off +
-   HIDMA_TRE_SIZE * num_completed);
-
-   tre_read_off = tre_read_off % tre_ring_size;
-
-   /* record the last processed tre offset */
-   lldev->tre_processed_off = tre_read_off;
 }
 
 static int hidma_ll_reset(struct hidma_lldev *lldev)
-- 
1.9.1



[PATCH V4 07/10] dmaengine: qcom_hidma: bring out interrupt cause

2016-09-28 Thread Sinan Kaya
Bring out the interrupt cause to the top level so that MSI interrupts
can be hooked at a later stage.

Signed-off-by: Sinan Kaya 
---
 drivers/dma/qcom/hidma_ll.c | 72 +
 1 file changed, 34 insertions(+), 38 deletions(-)

diff --git a/drivers/dma/qcom/hidma_ll.c b/drivers/dma/qcom/hidma_ll.c
index c911ca2..088935f 100644
--- a/drivers/dma/qcom/hidma_ll.c
+++ b/drivers/dma/qcom/hidma_ll.c
@@ -397,12 +397,24 @@ static int hidma_ll_reset(struct hidma_lldev *lldev)
  * requests traditionally to the destination, this concept does not apply
  * here for this HW.
  */
-irqreturn_t hidma_ll_inthandler(int chirq, void *arg)
+static void hidma_ll_int_handler_internal(struct hidma_lldev *lldev, int cause)
 {
-   struct hidma_lldev *lldev = arg;
-   u32 status;
-   u32 enable;
-   u32 cause;
+   if (cause & HIDMA_ERR_INT_MASK) {
+   dev_err(lldev->dev, "error 0x%x, disabling...\n",
+   cause);
+
+   /* Clear out pending interrupts */
+   writel(cause, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
+
+   /* No further submissions. */
+   hidma_ll_disable(lldev);
+
+   /* Driver completes the txn and intimates the client.*/
+   hidma_cleanup_pending_tre(lldev, 0xFF,
+ HIDMA_EVRE_STATUS_ERROR);
+
+   return;
+   }
 
/*
 * Fine tuned for this HW...
@@ -412,45 +424,29 @@ irqreturn_t hidma_ll_inthandler(int chirq, void *arg)
 * interrupt delivery guarantees. Do not copy this code blindly and
 * expect that to work.
 */
-   status = readl_relaxed(lldev->evca + HIDMA_EVCA_IRQ_STAT_REG);
-   enable = readl_relaxed(lldev->evca + HIDMA_EVCA_IRQ_EN_REG);
-   cause = status & enable;
-
-   while (cause) {
-   if (cause & HIDMA_ERR_INT_MASK) {
-   dev_err(lldev->dev, "error 0x%x, disabling...\n",
-   cause);
-
-   /* Clear out pending interrupts */
-   writel(cause, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
-
-   /* No further submissions. */
-   hidma_ll_disable(lldev);
-
-   /* Driver completes the txn and intimates the client.*/
-   hidma_cleanup_pending_tre(lldev, 0xFF,
- HIDMA_EVRE_STATUS_ERROR);
-   goto out;
-   }
-
+   while (atomic_read(&lldev->pending_tre_count)) {
/*
 * Try to consume as many EVREs as possible.
 */
-   hidma_handle_tre_completion(lldev);
+   if (hidma_handle_tre_completion(lldev, 0, 0))
+   break;
+   }
 
-   /* We consumed TREs or there are pending TREs or EVREs. */
-   writel_relaxed(cause, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
+   /* We consumed TREs or there are pending TREs or EVREs. */
+   writel_relaxed(cause, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
+}
 
-   /*
-* Another interrupt might have arrived while we are
-* processing this one. Read the new cause.
-*/
-   status = readl_relaxed(lldev->evca + HIDMA_EVCA_IRQ_STAT_REG);
-   enable = readl_relaxed(lldev->evca + HIDMA_EVCA_IRQ_EN_REG);
-   cause = status & enable;
-   }
+irqreturn_t hidma_ll_inthandler(int chirq, void *arg)
+{
+   struct hidma_lldev *lldev = arg;
+   u32 status;
+   u32 enable;
+   u32 cause;
 
-out:
+   status = readl_relaxed(lldev->evca + HIDMA_EVCA_IRQ_STAT_REG);
+   enable = readl_relaxed(lldev->evca + HIDMA_EVCA_IRQ_EN_REG);
+   cause = status & enable;
+   hidma_ll_int_handler_internal(lldev, cause);
return IRQ_HANDLED;
 }
 
-- 
1.9.1



[PATCH V4 08/10] dmaengine: qcom_hidma: add a common API to setup the interrupt

2016-09-28 Thread Sinan Kaya
Introducing the hidma_ll_setup_irq function to set up the interrupt
type externally from the OS interface.

Signed-off-by: Sinan Kaya 
---
 drivers/dma/qcom/hidma.h|  2 ++
 drivers/dma/qcom/hidma_ll.c | 27 +++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/qcom/hidma.h b/drivers/dma/qcom/hidma.h
index 3f2ddd4..181f7e0 100644
--- a/drivers/dma/qcom/hidma.h
+++ b/drivers/dma/qcom/hidma.h
@@ -46,6 +46,7 @@ struct hidma_tre {
 };
 
 struct hidma_lldev {
+   bool msi_support;   /* flag indicating MSI support*/
bool initialized;   /* initialized flag   */
u8 trch_state;  /* trch_state of the device   */
u8 evch_state;  /* evch_state of the device   */
@@ -145,6 +146,7 @@ int hidma_ll_disable(struct hidma_lldev *lldev);
 int hidma_ll_enable(struct hidma_lldev *llhndl);
 void hidma_ll_set_transfer_params(struct hidma_lldev *llhndl, u32 tre_ch,
dma_addr_t src, dma_addr_t dest, u32 len, u32 flags);
+void hidma_ll_setup_irq(struct hidma_lldev *lldev, bool msi);
 int hidma_ll_setup(struct hidma_lldev *lldev);
 struct hidma_lldev *hidma_ll_init(struct device *dev, u32 max_channels,
void __iomem *trca, void __iomem *evca,
diff --git a/drivers/dma/qcom/hidma_ll.c b/drivers/dma/qcom/hidma_ll.c
index 088935f..f0630e0 100644
--- a/drivers/dma/qcom/hidma_ll.c
+++ b/drivers/dma/qcom/hidma_ll.c
@@ -672,17 +672,36 @@ int hidma_ll_setup(struct hidma_lldev *lldev)
writel(HIDMA_EVRE_SIZE * nr_tres,
lldev->evca + HIDMA_EVCA_RING_LEN_REG);
 
-   /* support IRQ only for now */
+   /* configure interrupts */
+   hidma_ll_setup_irq(lldev, lldev->msi_support);
+
+   rc = hidma_ll_enable(lldev);
+   if (rc)
+   return rc;
+
+   return rc;
+}
+
+void hidma_ll_setup_irq(struct hidma_lldev *lldev, bool msi)
+{
+   u32 val;
+
+   lldev->msi_support = msi;
+
+   /* disable interrupts again after reset */
+   writel(0, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
+   writel(0, lldev->evca + HIDMA_EVCA_IRQ_EN_REG);
+
+   /* support IRQ by default */
val = readl(lldev->evca + HIDMA_EVCA_INTCTRL_REG);
val &= ~0xF;
-   val |= 0x1;
+   if (!lldev->msi_support)
+   val = val | 0x1;
writel(val, lldev->evca + HIDMA_EVCA_INTCTRL_REG);
 
/* clear all pending interrupts and enable them */
writel(ENABLE_IRQS, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
writel(ENABLE_IRQS, lldev->evca + HIDMA_EVCA_IRQ_EN_REG);
-
-   return hidma_ll_enable(lldev);
 }
 
 struct hidma_lldev *hidma_ll_init(struct device *dev, u32 nr_tres,
-- 
1.9.1



[PATCH V4 09/10] dmaengine: qcom_hidma: protect common data structures

2016-09-28 Thread Sinan Kaya
When MSI interrupts are supported, error and the transfer interrupt can
come from multiple processor contexts.

Each error interrupt is an MSI interrupt. If the channel is disabled by
the first error interrupt, the remaining error interrupts will gracefully
return in the interrupt handler.

If an error is observed while servicing the completions in success case,
the posting of the completions will be aborted as soon as channel disabled
state is observed. The error interrupt handler will take it from there and
finish the remaining completions. We don't want to create multiple success
and error messages to be delivered to the client in mixed order.

Also got rid of hidma_post_completed method and moved the locks inside
hidma_ll_int_handler_internal function. Rearranged the assignments so that
variables are updated only when a lock is held.

Signed-off-by: Sinan Kaya 
---
 drivers/dma/qcom/hidma_ll.c | 142 ++--
 1 file changed, 58 insertions(+), 84 deletions(-)

diff --git a/drivers/dma/qcom/hidma_ll.c b/drivers/dma/qcom/hidma_ll.c
index f0630e0..386a64c 100644
--- a/drivers/dma/qcom/hidma_ll.c
+++ b/drivers/dma/qcom/hidma_ll.c
@@ -198,18 +198,50 @@ static void hidma_ll_tre_complete(unsigned long arg)
}
 }
 
-static int hidma_post_completed(struct hidma_lldev *lldev, int tre_iterator,
-   u8 err_info, u8 err_code)
+/*
+ * Called to handle the interrupt for the channel.
+ * Return a positive number if TRE or EVRE were consumed on this run.
+ * Return a positive number if there are pending TREs or EVREs.
+ * Return 0 if there is nothing to consume or no pending TREs/EVREs found.
+ */
+static int hidma_handle_tre_completion(struct hidma_lldev *lldev, u8 err_info,
+  u8 err_code)
 {
+   u32 *current_evre;
struct hidma_tre *tre;
unsigned long flags;
+   u32 evre_write_off;
+   u32 cfg;
+   u32 offset;
+
+   evre_write_off = readl_relaxed(lldev->evca + HIDMA_EVCA_WRITE_PTR_REG);
+   if ((evre_write_off > lldev->evre_ring_size) ||
+   (evre_write_off % HIDMA_EVRE_SIZE)) {
+   dev_err(lldev->dev, "HW reports invalid EVRE write offset\n");
+   return -EINVAL;
+   }
 
spin_lock_irqsave(&lldev->lock, flags);
-   tre = lldev->pending_tre_list[tre_iterator / HIDMA_TRE_SIZE];
+   if (lldev->evre_processed_off == evre_write_off) {
+   spin_unlock_irqrestore(&lldev->lock, flags);
+   return 0;
+   }
+   current_evre = lldev->evre_ring + lldev->evre_processed_off;
+   cfg = current_evre[HIDMA_EVRE_CFG_IDX];
+   if (!err_info) {
+   err_info = cfg >> HIDMA_EVRE_ERRINFO_BIT_POS;
+   err_info &= HIDMA_EVRE_ERRINFO_MASK;
+   }
+   if (!err_code)
+   err_code = (cfg >> HIDMA_EVRE_CODE_BIT_POS) &
+   HIDMA_EVRE_CODE_MASK;
+
+   offset = lldev->tre_processed_off;
+   tre = lldev->pending_tre_list[offset / HIDMA_TRE_SIZE];
if (!tre) {
spin_unlock_irqrestore(&lldev->lock, flags);
dev_warn(lldev->dev, "tre_index [%d] and tre out of sync\n",
-tre_iterator / HIDMA_TRE_SIZE);
+lldev->tre_processed_off / HIDMA_TRE_SIZE);
return -EINVAL;
}
lldev->pending_tre_list[tre->tre_index] = NULL;
@@ -223,6 +255,14 @@ static int hidma_post_completed(struct hidma_lldev *lldev, 
int tre_iterator,
atomic_set(&lldev->pending_tre_count, 0);
}
 
+
+   HIDMA_INCREMENT_ITERATOR(lldev->tre_processed_off, HIDMA_TRE_SIZE,
+lldev->tre_ring_size);
+   HIDMA_INCREMENT_ITERATOR(lldev->evre_processed_off, HIDMA_EVRE_SIZE,
+lldev->evre_ring_size);
+
+   writel(lldev->evre_processed_off,
+   lldev->evca + HIDMA_EVCA_DOORBELL_REG);
spin_unlock_irqrestore(&lldev->lock, flags);
 
tre->err_info = err_info;
@@ -232,86 +272,7 @@ static int hidma_post_completed(struct hidma_lldev *lldev, 
int tre_iterator,
kfifo_put(&lldev->handoff_fifo, tre);
tasklet_schedule(&lldev->task);
 
-   return 0;
-}
-
-/*
- * Called to handle the interrupt for the channel.
- * Return a positive number if TRE or EVRE were consumed on this run.
- * Return a positive number if there are pending TREs or EVREs.
- * Return 0 if there is nothing to consume or no pending TREs/EVREs found.
- */
-static int hidma_handle_tre_completion(struct hidma_lldev *lldev, u8 err_info,
-  u8 err_code)
-{
-   u32 evre_ring_size = lldev->evre_ring_size;
-   u32 tre_ring_size = lldev->tre_ring_size;
-   u32 tre_iterator, evre_iterator;
-   u32 num_completed = 0;
-
-   evre_write_off = readl_relaxed(lldev->evca + HIDMA_EVCA_WRITE_PTR_REG);
-   tre_iterator 

[PATCH V4 10/10] dmaengine: qcom_hidma: add MSI support for interrupts

2016-09-28 Thread Sinan Kaya
The interrupts can now be delivered as platform MSI interrupts
on newer platforms. The code looks for a new OF and ACPI strings
in order to enable the functionality.

Signed-off-by: Sinan Kaya 
---
 drivers/dma/qcom/hidma.c| 129 ++--
 drivers/dma/qcom/hidma.h|   2 +
 drivers/dma/qcom/hidma_ll.c |   8 +++
 3 files changed, 134 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index e244e10..f4fe4ee 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -56,6 +56,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "../dmaengine.h"
 #include "hidma.h"
@@ -70,6 +71,7 @@
 #define HIDMA_ERR_INFO_SW  0xFF
 #define HIDMA_ERR_CODE_UNEXPECTED_TERMINATE0x0
 #define HIDMA_NR_DEFAULT_DESC  10
+#define HIDMA_MSI_INTS 11
 
 static inline struct hidma_dev *to_hidma_dev(struct dma_device *dmadev)
 {
@@ -553,6 +555,15 @@ static irqreturn_t hidma_chirq_handler(int chirq, void 
*arg)
return hidma_ll_inthandler(chirq, lldev);
 }
 
+static irqreturn_t hidma_chirq_handler_msi(int chirq, void *arg)
+{
+   struct hidma_lldev **lldevp = arg;
+   struct hidma_dev *dmadev = to_hidma_dev_from_lldev(lldevp);
+
+   return hidma_ll_inthandler_msi(chirq, *lldevp,
+  1 << (chirq - dmadev->msi_virqbase));
+}
+
 static ssize_t hidma_show_values(struct device *dev,
 struct device_attribute *attr, char *buf)
 {
@@ -590,6 +601,99 @@ static int hidma_create_sysfs_entry(struct hidma_dev *dev, 
char *name,
return device_create_file(dev->ddev.dev, attrs);
 }
 
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+static void hidma_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
+{
+   struct device *dev = msi_desc_to_dev(desc);
+   struct hidma_dev *dmadev = dev_get_drvdata(dev);
+
+   if (!desc->platform.msi_index) {
+   writel(msg->address_lo, dmadev->dev_evca + 0x118);
+   writel(msg->address_hi, dmadev->dev_evca + 0x11C);
+   writel(msg->data, dmadev->dev_evca + 0x120);
+   }
+}
+
+static void hidma_free_msis(void *data)
+{
+   struct device *dev = data;
+
+   platform_msi_domain_free_irqs(dev);
+}
+#endif
+
+static int hidma_request_msi(struct hidma_dev *dmadev,
+struct platform_device *pdev)
+{
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+   int rc;
+   struct msi_desc *desc;
+   struct msi_desc *failed_desc = NULL;
+
+   rc = platform_msi_domain_alloc_irqs(&pdev->dev, HIDMA_MSI_INTS,
+   hidma_write_msi_msg);
+   if (rc)
+   return rc;
+
+   for_each_msi_entry(desc, &pdev->dev) {
+   if (!desc->platform.msi_index)
+   dmadev->msi_virqbase = desc->irq;
+
+   rc = devm_request_irq(&pdev->dev, desc->irq,
+  hidma_chirq_handler_msi,
+  0, "qcom-hidma-msi",
+  &dmadev->lldev);
+   if (rc) {
+   failed_desc = desc;
+   break;
+   }
+   }
+
+   if (rc) {
+   /* free allocated MSI interrupts above */
+   for_each_msi_entry(desc, &pdev->dev) {
+   if (desc == failed_desc)
+   break;
+   devm_free_irq(&pdev->dev, desc->irq,
+ &dmadev->lldev);
+   }
+   } else {
+   /* Add callback to free MSIs on teardown */
+   devm_add_action(&pdev->dev, hidma_free_msis,
+   &pdev->dev);
+   hidma_ll_setup_irq(dmadev->lldev, true);
+
+   }
+   if (rc)
+   dev_warn(&pdev->dev,
+"failed to request MSI irq, falling back to wired 
IRQ\n");
+   return rc;
+#else
+   return -EINVAL;
+#endif
+}
+
+static bool hidma_msi_capable(struct device *dev)
+{
+   struct acpi_device *adev = ACPI_COMPANION(dev);
+   const char *of_compat;
+   int ret = -EINVAL;
+
+   if (!adev || acpi_disabled) {
+   ret = device_property_read_string(dev, "compatible",
+ &of_compat);
+   if (ret)
+   return false;
+
+   ret = strcmp(of_compat, "qcom,hidma-1.1");
+   } else {
+#ifdef CONFIG_ACPI
+   ret = strcmp(acpi_device_hid(adev), "QCOM8062");
+#endif
+   }
+   return ret == 0;
+}
+
 static int hidma_probe(struct platform_device *pdev)
 {
struct hidma_dev *dmadev;
@@ -599,6 +703,7 @@ static int hidma_probe(struct platform_device *pdev)
void __iomem *evca;
void __iomem *trca;
int rc;
+   bool msi;
 
pm_runtime_set_a

[PATCH V4 04/10] dmaengine: qcom_hidma: configure DMA and MSI for OF

2016-09-28 Thread Sinan Kaya
Configure the DMA bindings for the device tree based firmware.

Signed-off-by: Sinan Kaya 
---
 drivers/dma/qcom/hidma_mgmt.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/qcom/hidma_mgmt.c b/drivers/dma/qcom/hidma_mgmt.c
index 82f36e4..e8f6b84 100644
--- a/drivers/dma/qcom/hidma_mgmt.c
+++ b/drivers/dma/qcom/hidma_mgmt.c
@@ -375,8 +375,11 @@ static int __init hidma_mgmt_of_populate_channels(struct 
device_node *np)
ret = PTR_ERR(new_pdev);
goto out;
}
+   of_node_get(child);
+   new_pdev->dev.of_node = child;
of_dma_configure(&new_pdev->dev, child);
-
+   of_msi_configure(&new_pdev->dev, child);
+   of_node_put(child);
kfree(res);
res = NULL;
}
-- 
1.9.1



[PATCH V4 05/10] dmaengine: qcom_hidma: make pending_tre_count atomic

2016-09-28 Thread Sinan Kaya
Getting ready for the MSI interrupts. The pending_tre_count is used
in the interrupt handler to make sure all outstanding requests are
serviced.

Making it atomic so that it can be updated from multiple contexts.

Signed-off-by: Sinan Kaya 
---
 drivers/dma/qcom/hidma.h |  2 +-
 drivers/dma/qcom/hidma_dbg.c |  3 ++-
 drivers/dma/qcom/hidma_ll.c  | 13 ++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/dma/qcom/hidma.h b/drivers/dma/qcom/hidma.h
index e52e207..3f2ddd4 100644
--- a/drivers/dma/qcom/hidma.h
+++ b/drivers/dma/qcom/hidma.h
@@ -58,7 +58,7 @@ struct hidma_lldev {
void __iomem *evca; /* Event Channel address  */
struct hidma_tre
**pending_tre_list; /* Pointers to pending TREs   */
-   s32 pending_tre_count;  /* Number of TREs pending */
+   atomic_t pending_tre_count; /* Number of TREs pending */
 
void *tre_ring; /* TRE ring   */
dma_addr_t tre_dma; /* TRE ring to be shared with HW  */
diff --git a/drivers/dma/qcom/hidma_dbg.c b/drivers/dma/qcom/hidma_dbg.c
index fa827e5..87db285 100644
--- a/drivers/dma/qcom/hidma_dbg.c
+++ b/drivers/dma/qcom/hidma_dbg.c
@@ -74,7 +74,8 @@ static void hidma_ll_devstats(struct seq_file *s, void 
*llhndl)
seq_printf(s, "tre_ring_handle=%pap\n", &lldev->tre_dma);
seq_printf(s, "tre_ring_size = 0x%x\n", lldev->tre_ring_size);
seq_printf(s, "tre_processed_off = 0x%x\n", lldev->tre_processed_off);
-   seq_printf(s, "pending_tre_count=%d\n", lldev->pending_tre_count);
+   seq_printf(s, "pending_tre_count=%d\n",
+   atomic_read(&lldev->pending_tre_count));
seq_printf(s, "evca=%p\n", lldev->evca);
seq_printf(s, "evre_ring=%p\n", lldev->evre_ring);
seq_printf(s, "evre_ring_handle=%pap\n", &lldev->evre_dma);
diff --git a/drivers/dma/qcom/hidma_ll.c b/drivers/dma/qcom/hidma_ll.c
index 3224f24..29fef4f 100644
--- a/drivers/dma/qcom/hidma_ll.c
+++ b/drivers/dma/qcom/hidma_ll.c
@@ -218,10 +218,9 @@ static int hidma_post_completed(struct hidma_lldev *lldev, 
int tre_iterator,
 * Keep track of pending TREs that SW is expecting to receive
 * from HW. We got one now. Decrement our counter.
 */
-   lldev->pending_tre_count--;
-   if (lldev->pending_tre_count < 0) {
+   if (atomic_dec_return(&lldev->pending_tre_count) < 0) {
dev_warn(lldev->dev, "tre count mismatch on completion");
-   lldev->pending_tre_count = 0;
+   atomic_set(&lldev->pending_tre_count, 0);
}
 
spin_unlock_irqrestore(&lldev->lock, flags);
@@ -321,7 +320,7 @@ void hidma_cleanup_pending_tre(struct hidma_lldev *lldev, 
u8 err_info,
u32 tre_read_off;
 
tre_iterator = lldev->tre_processed_off;
-   while (lldev->pending_tre_count) {
+   while (atomic_read(&lldev->pending_tre_count)) {
if (hidma_post_completed(lldev, tre_iterator, err_info,
 err_code))
break;
@@ -548,7 +547,7 @@ void hidma_ll_queue_request(struct hidma_lldev *lldev, u32 
tre_ch)
tre->err_code = 0;
tre->err_info = 0;
tre->queued = 1;
-   lldev->pending_tre_count++;
+   atomic_inc(&lldev->pending_tre_count);
lldev->tre_write_offset = (lldev->tre_write_offset + HIDMA_TRE_SIZE)
% lldev->tre_ring_size;
spin_unlock_irqrestore(&lldev->lock, flags);
@@ -654,7 +653,7 @@ int hidma_ll_setup(struct hidma_lldev *lldev)
u32 val;
u32 nr_tres = lldev->nr_tres;
 
-   lldev->pending_tre_count = 0;
+   atomic_set(&lldev->pending_tre_count, 0);
lldev->tre_processed_off = 0;
lldev->evre_processed_off = 0;
lldev->tre_write_offset = 0;
@@ -816,7 +815,7 @@ int hidma_ll_uninit(struct hidma_lldev *lldev)
tasklet_kill(&lldev->task);
memset(lldev->trepool, 0, required_bytes);
lldev->trepool = NULL;
-   lldev->pending_tre_count = 0;
+   atomic_set(&lldev->pending_tre_count, 0);
lldev->tre_write_offset = 0;
 
rc = hidma_ll_reset(lldev);
-- 
1.9.1



[PATCH V4 03/10] of: irq: make of_msi_configure accessible from modules

2016-09-28 Thread Sinan Kaya
The of_msi_configure routine is only accessible by the built-in
kernel drivers. Export this function so that modules can use it
too.

This function is useful for configuring MSI on child device tree
nodes on hierarchical objects.

Acked-by: Rob Herring 
Signed-off-by: Sinan Kaya 
---
 drivers/of/irq.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index a2e68f7..20c09e0 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -767,3 +767,4 @@ void of_msi_configure(struct device *dev, struct 
device_node *np)
dev_set_msi_domain(dev,
   of_msi_get_domain(dev, np, DOMAIN_BUS_PLATFORM_MSI));
 }
+EXPORT_SYMBOL_GPL(of_msi_configure);
-- 
1.9.1



[PATCH V4 02/10] Documentation: DT: qcom_hidma: correct spelling mistakes

2016-09-28 Thread Sinan Kaya
Fix the spelling mistakes and extra and statements in the sentences.

Acked-by: Rob Herring 
Signed-off-by: Sinan Kaya 
---
 Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt 
b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
index 2c5e4b8..55492c2 100644
--- a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
+++ b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
@@ -5,13 +5,13 @@ memcpy and memset capabilities. It has been designed for 
virtualized
 environments.
 
 Each HIDMA HW instance consists of multiple DMA channels. These channels
-share the same bandwidth. The bandwidth utilization can be parititioned
+share the same bandwidth. The bandwidth utilization can be partitioned
 among channels based on the priority and weight assignments.
 
 There are only two priority levels and 15 weigh assignments possible.
 
 Other parameters here determine how much of the system bus this HIDMA
-instance can use like maximum read/write request and and number of bytes to
+instance can use like maximum read/write request and number of bytes to
 read/write in a single burst.
 
 Main node required properties:
-- 
1.9.1



[PATCH V4 01/10] Documentation: DT: qcom_hidma: update binding for MSI

2016-09-28 Thread Sinan Kaya
Adding a new binding for qcom,hidma-1.1 to distinguish HW supporting
MSI interrupts from the older revision.

Signed-off-by: Sinan Kaya 
---
 Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt 
b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
index fd5618b..2c5e4b8 100644
--- a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
+++ b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
@@ -47,12 +47,18 @@ When the OS is not in control of the management interface 
(i.e. it's a guest),
 the channel nodes appear on their own, not under a management node.
 
 Required properties:
-- compatible: must contain "qcom,hidma-1.0"
+- compatible: must contain "qcom,hidma-1.0" for initial HW or "qcom,hidma-1.1"
+for MSI capable HW.
 - reg: Addresses for the transfer and event channel
 - interrupts: Should contain the event interrupt
 - desc-count: Number of asynchronous requests this channel can handle
 - iommus: required a iommu node
 
+Optional properties for MSI:
+- msi-parent : See the generic MSI binding described in
+ devicetree/bindings/interrupt-controller/msi.txt for a description of the
+ msi-parent property.
+
 Example:
 
 Hypervisor OS configuration:
-- 
1.9.1



[PATCH] include/linux/property.h: fix typo/compile error

2016-09-28 Thread John Youn
This fixes commit d76eebfa175e ("include/linux/property.h: fix build
issues with gcc-4.4.4").

With that commit we get the following compile error when using the
PROPERTY_ENTRY_INTEGER_ARRAY macro.

../include/linux/property.h:201:39: error: ‘u32_data’ undeclared (first
 use in this function)
  PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u32, _val_)
   ^
../include/linux/property.h:193:17: note: in definition of macro
 ‘PROPERTY_ENTRY_INTEGER_ARRAY’
  { .pointer = { _type_##_data = _val_ } },  \
 ^

This needs a '.' to reference the union member. It seems this was just
overlooked here since it is done correctly in similar constructs in
other parts of the original commit.

This fix is in preparation of upcoming commits that will use this macro.

Fixes: commit d76eebfa175e ("include/linux/property.h: fix build issues with 
gcc-4.4.4")
Signed-off-by: John Youn 
---
 include/linux/property.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/property.h b/include/linux/property.h
index 3a2f9ae..856e50b 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -190,7 +190,7 @@ struct property_entry {
.length = ARRAY_SIZE(_val_) * sizeof(_type_),   \
.is_array = true,   \
.is_string = false, \
-   { .pointer = { _type_##_data = _val_ } },   \
+   { .pointer = { ._type_##_data = _val_ } },  \
 }
 
 #define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_) \
-- 
2.10.0



Re: [PATCH 2/2] Input: add motion-tracking ABS_* bits and docs

2016-09-28 Thread Roderick Colenbrander
On Wed, Sep 28, 2016 at 10:39 AM, Dmitry Torokhov
 wrote:
>
> On Tue, Sep 27, 2016 at 4:38 PM, Roderick Colenbrander
>  wrote:
> > From: Roderick Colenbrander 
> >
> > This patch introduces new axes for acceleration and angular velocity.
> > David Herrmann's work served as a base, but we extended the specification
> > with various changes inspired by real devices and challenges we see
> > when doing motion tracking.
> >
> > - Changed unit of acceleration to G instead of m/s^2. We felt that m/s^2
> >   is not the appropriate unit to return, because accelerometers are most
> >   often calibrated based on gravity. They return values in multiples of
> >   G and since we don't know the device location on earth, we should not
> >   blindly multiply by '9.8' for accuracy reasons. Such conversion is left
> >   to userspace.
> > - Resolution field is used for acceleration and gyro to report precision.
> >   The previous spec, specified to map 1 unit to e.g. 0.001 deg/s or 0.001 
> > m/s^2.
> >   This is of course simpler for applications, but unit definition is a bit
> >   arbitrary. Previous axes definitions used the resolution field, which
> >   felt more consistent.
> > - Added section on timestamps, which are important for accurate motion
> >   tracking purposes. The use of MSC_TIMESTAMP was recommended in this
> >   situation to get access to the hardware timestamp if available.
> > - Changed motion axes to be defined as a right-handed coordinate system.
> >   Due to this change the gyro vectors are now defined as counter-clockwise.
> >   The overall changes makes the definitions consistent with computer 
> > graphics.
> >
> > [PATCH 4/4] Input: add motion-tracking ABS_* bits and docs
> > David Herrmann 
> > Tue Dec 17 07:48:54 PST 2013
> >
> > Motion sensors are getting quite common in mobile devices. To avoid
> > returning accelerometer data via ABS_X/Y/Z and irritating the Xorg
> > mouse-driver, this adds separate ABS_* bits for that.
>
> We have IIO for motions sensors that are not strictly human input
> devices; I believe there is also IIO->input bridge where generic IIO
> sensors could be mapped to input device if they are supposed to be
> used as such in given product.
>

If we decide to move forward in the direction proposed by this patch,
the spec could be updated
to limit the scope a bit or to make it wider.


> >
> > This is needed if gaming devices want to report their normal data plus
> > accelerometer/gyro data. Usually, ABS_X/Y are already used by analog
> > sticks, so need separate definitions, anyway.
>
> I am not sure if this direction is sustainable. We can't keep adding
> more and more ABS axes every time we add another control to something
> that is basically a composite device. What if you add another stick?
> Magnetometer? Some other sensor?
>
> I think the only reasonable way it to come up with a notion of
> "composite" input device consisting of several event nodes and have
> userspace "assemble" it all together.
>

In our case we are interested in the motion functionality for some devices
with drivers already in the kernel, which we want to extend over time with
improved capabilities.

I understand your concerns about the scalability of ABS axes in general.
If someone were to come up with some crazy flight simulator joystick with many
weird axes, do you then add an ABS_X2, ABS_X3 etcetera? Similar what if
a controller for whatever reasons shipped with multiple gyroscopes,
accelerometers,
magnetic sensor, heartrate sensors etcetera?

A composite device would on the other hand be more of a pain for the different
userland APIs ranging from libinput, SDL2, Android and other embedded
platforms. It
would be quite an extensive change. How would they even do the
stitching? You could
handle this through sysfs (not my favorite way) or maybe have a notion
of a 'master'
device being the current event node and some way to enumerate 'sensor'
nodes or something.

It ultimate won't be my call, but I find it hard to say whether such a
potential big overhaul
is warranted at this point.

Thanks,
Roderick


> >
> > Signed-off-by: David Herrmann 
> > Signed-off-by: Roderick Colenbrander 
> > ---
> >  Documentation/input/gamepad.txt |   9 +-
> >  Documentation/input/motion-tracking.txt | 176 
> > 
> >  include/uapi/linux/input-event-codes.h  |   7 ++
> >  3 files changed, 190 insertions(+), 2 deletions(-)
> >  create mode 100644 Documentation/input/motion-tracking.txt
> >
> > diff --git a/Documentation/input/gamepad.txt 
> > b/Documentation/input/gamepad.txt
> > index 3f6d8a5..ed13782 100644
> > --- a/Documentation/input/gamepad.txt
> > +++ b/Documentation/input/gamepad.txt
> > @@ -57,6 +57,9 @@ Most gamepads have the following features:
> >- Rumble
> >  Many devices provide force-feedback features. But are mostly just
> >  simple rumble motors.
> > +  - Motion-tracking
> > +Gamepads may include motion-tracking sensors like accelerometers and
> > +   

Re: [PATCH] x86/entry/64: Fix context tracking state warning when load_gs_index fails

2016-09-28 Thread Wanpeng Li
Sorry for the ping, hope it can catch the upcoming merge window. :)
2016-09-26 19:49 GMT+08:00 Wanpeng Li :
> From: Wanpeng Li 
>
>  WARNING: CPU: 0 PID: 3331 at arch/x86/entry/common.c:45 
> enter_from_user_mode+0x32/0x50
>  CPU: 0 PID: 3331 Comm: ldt_gdt_64 Not tainted 4.8.0-rc7+ #13
>  Call Trace:
>   dump_stack+0x99/0xd0
>   __warn+0xd1/0xf0
>   warn_slowpath_null+0x1d/0x20
>   enter_from_user_mode+0x32/0x50
>   error_entry+0x6d/0xc0
>   ? general_protection+0x12/0x30
>   ? native_load_gs_index+0xd/0x20
>   ? do_set_thread_area+0x19c/0x1f0
>   SyS_set_thread_area+0x24/0x30
>   do_int80_syscall_32+0x7c/0x220
>   entry_INT80_compat+0x38/0x50
>
> This can be reproduced by running the GS testcase of ldt_gdt test unit in
> selftests.
>
> do_int80_syscall_32() will call enter_form_user_mode() to convert context
> tracking state from user state to kernel state. The load_gs_index can fail
> with user gsbase, gsbase will be fixed up and proceed if this happen.
> However, enter_from_user_mode() will be called again in the fixed up path
> though it is context tracking kernel state currently.
>
> This patch fix it by just fixing up gsbase and telling lockdep that IRQs
> are off once load_gs_index failed with user gsbase.
>
> Cc: Thomas Gleixner 
> Cc: Ingo Molnar 
> Cc: "H. Peter Anvin" 
> Cc: Andy Lutomirski 
> Cc: Borislav Petkov 
> Signed-off-by: Wanpeng Li 
> ---
>  arch/x86/entry/entry_64.S | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> index d172c61..dc1ec23 100644
> --- a/arch/x86/entry/entry_64.S
> +++ b/arch/x86/entry/entry_64.S
> @@ -1045,7 +1045,9 @@ ENTRY(error_entry)
>  * gsbase and proceed.  We'll fix up the exception and land in
>  * .Lgs_change's error handler with kernel gsbase.
>  */
> -   jmp .Lerror_entry_from_usermode_swapgs
> +   SWAPGS
> +   TRACE_IRQS_OFF
> +   ret
>
>  .Lbstep_iret:
> /* Fix truncated RIP */
> --
> 1.9.1
>


RE: [PATCH RFT] platform/x86: intel_pmc_ipc: Convert to use platform_device_register_full

2016-09-28 Thread Zha, Qipeng
It's good to me, thanks.

>+LKML
>
>Axel, please always include LKML on any patch.
>
>Qipeng, any concerns?

On Sat, Sep 24, 2016 at 11:54:08AM +0800, Axel Lin wrote:
> Use platform_device_register_full() instead of open-coded.
> 
> Signed-off-by: Axel Lin 
> ---
>  drivers/platform/x86/intel_pmc_ipc.c | 110 
> +++
>  1 file changed, 33 insertions(+), 77 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel_pmc_ipc.c 
> b/drivers/platform/x86/intel_pmc_ipc.c
> index b86e1bc..665a9a1 100644
> --- a/drivers/platform/x86/intel_pmc_ipc.c
> +++ b/drivers/platform/x86/intel_pmc_ipc.c
> @@ -522,48 +522,36 @@ static struct resource telemetry_res[] = {  
> static int ipc_create_punit_device(void)  {
>   struct platform_device *pdev;
> - int ret;
> -
> - pdev = platform_device_alloc(PUNIT_DEVICE_NAME, -1);
> - if (!pdev) {
> - dev_err(ipcdev.dev, "Failed to alloc punit platform device\n");
> - return -ENOMEM;
> - }
> -
> - pdev->dev.parent = ipcdev.dev;
> - ret = platform_device_add_resources(pdev, punit_res_array,
> - ARRAY_SIZE(punit_res_array));
> - if (ret) {
> - dev_err(ipcdev.dev, "Failed to add platform punit resources\n");
> - goto err;
> - }
> + const struct platform_device_info pdevinfo = {
> + .parent = ipcdev.dev,
> + .name = PUNIT_DEVICE_NAME,
> + .id = -1,
> + .res = punit_res_array,
> + .num_res = ARRAY_SIZE(punit_res_array),
> + };
> +
> + pdev = platform_device_register_full(&pdevinfo);
> + if (IS_ERR(pdev))
> + return PTR_ERR(pdev);
>  
> - ret = platform_device_add(pdev);
> - if (ret) {
> - dev_err(ipcdev.dev, "Failed to add punit platform device\n");
> - goto err;
> - }
>   ipcdev.punit_dev = pdev;
>  
>   return 0;
> -err:
> - platform_device_put(pdev);
> - return ret;
>  }
>  
>  static int ipc_create_tco_device(void)  {
>   struct platform_device *pdev;
>   struct resource *res;
> - int ret;
> -
> - pdev = platform_device_alloc(TCO_DEVICE_NAME, -1);
> - if (!pdev) {
> - dev_err(ipcdev.dev, "Failed to alloc tco platform device\n");
> - return -ENOMEM;
> - }
> -
> - pdev->dev.parent = ipcdev.dev;
> + const struct platform_device_info pdevinfo = {
> + .parent = ipcdev.dev,
> + .name = TCO_DEVICE_NAME,
> + .id = -1,
> + .res = tco_res,
> + .num_res = ARRAY_SIZE(tco_res),
> + .data = &tco_info,
> + .size_data = sizeof(tco_info),
> + };
>  
>   res = tco_res + TCO_RESOURCE_ACPI_IO;
>   res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET; @@ -577,45 
> +565,26 @@ static int ipc_create_tco_device(void)
>   res->start = ipcdev.gcr_base + TCO_PMC_OFFSET;
>   res->end = res->start + TCO_PMC_SIZE - 1;
>  
> - ret = platform_device_add_resources(pdev, tco_res, ARRAY_SIZE(tco_res));
> - if (ret) {
> - dev_err(ipcdev.dev, "Failed to add tco platform resources\n");
> - goto err;
> - }
> -
> - ret = platform_device_add_data(pdev, &tco_info, sizeof(tco_info));
> - if (ret) {
> - dev_err(ipcdev.dev, "Failed to add tco platform data\n");
> - goto err;
> - }
> + pdev = platform_device_register_full(&pdevinfo);
> + if (IS_ERR(pdev))
> + return PTR_ERR(pdev);
>  
> - ret = platform_device_add(pdev);
> - if (ret) {
> - dev_err(ipcdev.dev, "Failed to add tco platform device\n");
> - goto err;
> - }
>   ipcdev.tco_dev = pdev;
>  
>   return 0;
> -err:
> - platform_device_put(pdev);
> - return ret;
>  }
>  
>  static int ipc_create_telemetry_device(void)  {
>   struct platform_device *pdev;
>   struct resource *res;
> - int ret;
> -
> - pdev = platform_device_alloc(TELEMETRY_DEVICE_NAME, -1);
> - if (!pdev) {
> - dev_err(ipcdev.dev,
> - "Failed to allocate telemetry platform device\n");
> - return -ENOMEM;
> - }
> -
> - pdev->dev.parent = ipcdev.dev;
> + const struct platform_device_info pdevinfo = {
> + .parent = ipcdev.dev,
> + .name = TELEMETRY_DEVICE_NAME,
> + .id = -1,
> + .res = telemetry_res,
> + .num_res = ARRAY_SIZE(telemetry_res),
> + };
>  
>   res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM;
>   res->start = ipcdev.telem_punit_ssram_base; @@ -625,26 +594,13 @@ 
> static int ipc_create_telemetry_device(void)
>   res->start = ipcdev.telem_pmc_ssram_base;
>   res->end = res->start + ipcdev.telem_pmc_ssram_size - 1;
>  
> - ret = platform_device_add_resources(pdev, telemetry_res,
> - ARRAY_SIZE(t

[PATCH] video: console: bitblit: fixed an indentation coding style issue

2016-09-28 Thread Nahom
Fixed a coding style issue.
Signed-off-by: Nahom 
---
 drivers/video/console/bitblit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index dbfe4ee..4e7d0e3 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -256,7 +256,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info 
*info, int mode,
y += softback_lines;
}
 
-   c = scr_readw((u16 *) vc->vc_pos);
+   c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
 
-- 
2.7.4



Re: [PATCH v6 1/4] mfd: mxs-lradc: Add support for mxs-lradc MFD

2016-09-28 Thread Stefan Wahren
Hi Lee,

> Lee Jones  hat am 28. September 2016 um 03:05
> geschrieben:
> 
> 
> On Sat, 17 Sep 2016, Ksenija Stanojevic wrote:
> 
> > +
> > +static int mxs_lradc_probe(struct platform_device *pdev)
> > +{
> > +   const struct of_device_id *of_id;
> > +   struct device *dev = &pdev->dev;
> > +   struct device_node *node = dev->of_node;
> > +   struct mxs_lradc *lradc;
> > +   struct mfd_cell *cells = NULL;
> > +   int ret = 0;
> > +   u32 ts_wires = 0;
> > +
> > +   lradc = devm_kzalloc(&pdev->dev, sizeof(*lradc), GFP_KERNEL);
> > +   if (!lradc)
> > +   return -ENOMEM;
> > +
> > +   of_id = of_match_device(mxs_lradc_dt_ids, &pdev->dev);
> > +   lradc->soc = (enum mxs_lradc_id)of_id->data;
> > +
> > +   lradc->clk = devm_clk_get(&pdev->dev, NULL);
> > +   if (IS_ERR(lradc->clk)) {
> > +   dev_err(dev, "Failed to get the delay unit clock\n");
> > +   return PTR_ERR(lradc->clk);
> > +   }
> > +
> > +   ret = clk_prepare_enable(lradc->clk);
> > +   if (ret) {
> > +   dev_err(dev, "Failed to enable the delay unit clock\n");
> > +   return ret;
> > +   }
> > +
> > +   ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
> 
> Have you moved the documentation into devicetree/bindings/mfd?
> 

i hope it's okay if i answer. The binding has moved to
devicetree/binding/iio/adc/ [1]

Should it move completely to mfd or split too?

I'm asking myself how we keep DT ABI in the latter case.

[1] -
http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/iio/adc/mxs-lradc.txt

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


Zprava pro vas!!

2016-09-28 Thread K May



Ahoj.

Dobry vecer a jak se mas? Jen rychly jedno, je tu oficialni prilezitosti 
bych chtel diskutovat s vami soukrome.

 
Ocenil bych vasi rychlou reakci tady na mem osobnim soukromeho e-mailu 
nize pro dalsí komunikaci.


S pratelským pozdravem,
Paní Ko May Leung
email: kmayln...@gmail.com
Místopredseda, Managing Director
a výkonný reditel Chong Hing Bank Limited


[RESEND][PATCH] [media] atmel-isc: start dma in some scenario

2016-09-28 Thread Songjun Wu
If a new vb buf is added to vb queue, the queue is
empty and steaming, dma should be started.

Signed-off-by: Songjun Wu 
---

 drivers/media/platform/atmel/atmel-isc.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index ccfe13b..ff403d5 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -617,7 +617,14 @@ static void isc_buffer_queue(struct vb2_buffer *vb)
unsigned long flags;
 
spin_lock_irqsave(&isc->dma_queue_lock, flags);
-   list_add_tail(&buf->list, &isc->dma_queue);
+   if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
+   vb2_is_streaming(vb->vb2_queue)) {
+   isc->cur_frm = buf;
+   isc_start_dma(isc->regmap, isc->cur_frm,
+   isc->current_fmt->reg_dctrl_dview);
+   } else {
+   list_add_tail(&buf->list, &isc->dma_queue);
+   }
spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
 }
 
-- 
2.7.4



Re: NMI for ARC

2016-09-28 Thread Vineet Gupta
On 09/28/2016 03:26 PM, Andy Lutomirski wrote:
>> Right, so what I think Vineet is asking is if we need to disable NMIs as
>> > well, we cannot on x86 disable NMIs so no.
>> >
> The same argument works here, too: an NMI won't set TIF_NEED_RESCHED
> without sending an IPI, so we can't miss a wakeup.

But what exact wakeup miss are we taking about here. If intr were NOT disabled,
how could this happen. Just trying to understand the need for "irqs-disabled" in
resume_{user,kernel}_*

The intr disabled before reg file restore makes complete sense though.



Re: linux-next: manual merge of the netfilter-next tree with the net tree

2016-09-28 Thread Stephen Rothwell
Hi all,

On Tue, 13 Sep 2016 10:12:50 +1000 Stephen Rothwell  
wrote:
>
> Today's linux-next merge of the netfilter-next tree got a conflict in:
> 
>   net/netfilter/nf_tables_netdev.c
> 
> between commit:
> 
>   c73c24849011 ("netfilter: nf_tables_netdev: remove redundant ip_hdr 
> assignment")
> 
> from the net tree and commit:
> 
>   ddc8b6027ad0 ("netfilter: introduce nft_set_pktinfo_{ipv4, 
> ipv6}_validate()")
> 
> from the netfilter-next tree.
> 
> I fixed it up (I used the latter version of this file and applied the
> patch below) and can carry the fix as necessary. This is now fixed as
> far as linux-next is concerned, but any non trivial conflicts should be
> mentioned to your upstream maintainer when your tree is submitted for
> merging.  You may also want to consider cooperating with the maintainer
> of the conflicting tree to minimise any particularly complex conflicts.
> 
> From: Stephen Rothwell 
> Date: Tue, 13 Sep 2016 10:08:58 +1000
> Subject: [PATCH] netfilter: merge fixup for "nf_tables_netdev: remove
>  redundant ip_hdr assignment"
> 
> Signed-off-by: Stephen Rothwell 
> ---
>  include/net/netfilter/nf_tables_ipv4.h | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/include/net/netfilter/nf_tables_ipv4.h 
> b/include/net/netfilter/nf_tables_ipv4.h
> index 968f00b82fb5..25e33aee91e7 100644
> --- a/include/net/netfilter/nf_tables_ipv4.h
> +++ b/include/net/netfilter/nf_tables_ipv4.h
> @@ -33,7 +33,6 @@ __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
>   if (!iph)
>   return -1;
>  
> - iph = ip_hdr(skb);
>   if (iph->ihl < 5 || iph->version != 4)
>   return -1;
>  
> -- 
> 2.8.1

The above merge fix patch is now needed when the net-next tree is
merged with Linus' tree.

-- 
Cheers,
Stephen Rothwell


Re: [PATCH RFT] platform/x86: intel_pmc_ipc: Convert to use platform_device_register_full

2016-09-28 Thread Darren Hart
On Thu, Sep 29, 2016 at 08:59:55AM +0800, Axel Lin wrote:
> 2016-09-29 7:36 GMT+08:00 Darren Hart :
> > +LKML
> >
> > Axel, please always include LKML on any patch.
> 
> I thought  +LKML is optional if you already have a dedicated
> platform-driver-x86 maillist.

Nope, LKML is never optional. All patches to the Linux Kernel must include LKML.


-- 
Darren Hart
Intel Open Source Technology Center


Re: [PATCH RFT] platform/x86: intel_pmc_ipc: Convert to use platform_device_register_full

2016-09-28 Thread Axel Lin
2016-09-29 7:36 GMT+08:00 Darren Hart :
> +LKML
>
> Axel, please always include LKML on any patch.

I thought  +LKML is optional if you already have a dedicated
platform-driver-x86 maillist.


Re: [PATCH v2 7/8] media: vidc: add Makefiles and Kconfig files

2016-09-28 Thread Stanimir Varbanov
Hi Hans,

On 09/19/2016 01:35 PM, Hans Verkuil wrote:
> On 09/07/2016 01:37 PM, Stanimir Varbanov wrote:
>> Makefile and Kconfig files to build the video codec driver.
>>
>> Signed-off-by: Stanimir Varbanov 
>> ---
>>  drivers/media/platform/qcom/Kconfig   |  8 
>>  drivers/media/platform/qcom/Makefile  |  6 ++
>>  drivers/media/platform/qcom/vidc/Makefile | 15 +++
>>  3 files changed, 29 insertions(+)
>>  create mode 100644 drivers/media/platform/qcom/Kconfig
>>  create mode 100644 drivers/media/platform/qcom/Makefile
>>  create mode 100644 drivers/media/platform/qcom/vidc/Makefile
>>
>> diff --git a/drivers/media/platform/qcom/Kconfig 
>> b/drivers/media/platform/qcom/Kconfig
>> new file mode 100644
>> index ..4bad5c0f68e4
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/Kconfig
>> @@ -0,0 +1,8 @@
>> +comment "Qualcomm V4L2 drivers"
>> +
>> +menuconfig QCOM_VIDC
>> +tristate "Qualcomm V4L2 encoder/decoder driver"
>> +depends on ARCH_QCOM && VIDEO_V4L2
>> +depends on IOMMU_DMA
>> +depends on QCOM_VENUS_PIL
>> +select VIDEOBUF2_DMA_SG
> 
> If at all possible, please depend on COMPILE_TEST as well!

OK, I will add it.

> 
> Also missing: a patch adding an entry to the MAINTAINERS file.

I will add such a patch in next submission.

-- 
regards,
Stan


Re: [PATCH 2/8] pinctrl: aspeed-g5: Fix names of GPID2 pins

2016-09-28 Thread Joel Stanley
On Wed, Sep 28, 2016 at 12:20 AM, Andrew Jeffery  wrote:
> Fixes simple typos in the initial commit. There is no behavioural
> change.
>
> Fixes: 56e57cb6c07f (pinctrl: Add pinctrl-aspeed-g5 driver)
> Reported-by: Xo Wang 
> Signed-off-by: Andrew Jeffery 

Reviewed-by: Joel Stanley 

> ---
>  drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c 
> b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> index e1ab864e1a7f..14639834a5eb 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> @@ -151,21 +151,21 @@ FUNC_GROUP_DECL(GPID0, F19, E21);
>
>  #define GPID2_DESC  SIG_DESC_SET(SCU8C, 9)
>
> -#define D20 26
> +#define F20 26
>  SIG_EXPR_LIST_DECL_SINGLE(SD2DAT0, SD2, SD2_DESC);
>  SIG_EXPR_DECL(GPID2IN, GPID2, GPID2_DESC);
>  SIG_EXPR_DECL(GPID2IN, GPID, GPID_DESC);
>  SIG_EXPR_LIST_DECL_DUAL(GPID2IN, GPID2, GPID);
> -MS_PIN_DECL(D20, GPIOD2, SD2DAT0, GPID2IN);
> +MS_PIN_DECL(F20, GPIOD2, SD2DAT0, GPID2IN);
>
> -#define D21 27
> +#define D20 27
>  SIG_EXPR_LIST_DECL_SINGLE(SD2DAT1, SD2, SD2_DESC);
>  SIG_EXPR_DECL(GPID2OUT, GPID2, GPID2_DESC);
>  SIG_EXPR_DECL(GPID2OUT, GPID, GPID_DESC);
>  SIG_EXPR_LIST_DECL_DUAL(GPID2OUT, GPID2, GPID);
> -MS_PIN_DECL(D21, GPIOD3, SD2DAT1, GPID2OUT);
> +MS_PIN_DECL(D20, GPIOD3, SD2DAT1, GPID2OUT);
>
> -FUNC_GROUP_DECL(GPID2, D20, D21);
> +FUNC_GROUP_DECL(GPID2, F20, D20);
>
>  #define GPIE_DESC  SIG_DESC_SET(HW_STRAP1, 21)
>  #define GPIE0_DESC SIG_DESC_SET(SCU8C, 12)
> @@ -614,7 +614,6 @@ static struct pinctrl_pin_desc 
> aspeed_g5_pins[ASPEED_G5_NR_PINS] = {
> ASPEED_PINCTRL_PIN(D10),
> ASPEED_PINCTRL_PIN(D2),
> ASPEED_PINCTRL_PIN(D20),
> -   ASPEED_PINCTRL_PIN(D21),
> ASPEED_PINCTRL_PIN(D4),
> ASPEED_PINCTRL_PIN(D5),
> ASPEED_PINCTRL_PIN(D6),
> @@ -630,6 +629,7 @@ static struct pinctrl_pin_desc 
> aspeed_g5_pins[ASPEED_G5_NR_PINS] = {
> ASPEED_PINCTRL_PIN(E7),
> ASPEED_PINCTRL_PIN(E9),
> ASPEED_PINCTRL_PIN(F19),
> +   ASPEED_PINCTRL_PIN(F20),
> ASPEED_PINCTRL_PIN(F9),
> ASPEED_PINCTRL_PIN(H20),
> ASPEED_PINCTRL_PIN(L1),
> --
> git-series 0.8.10


Re: [PATCH 4/8] pinctrl: aspeed-g5: Fix pin association of SPI1 function

2016-09-28 Thread Joel Stanley
On Wed, Sep 28, 2016 at 12:20 AM, Andrew Jeffery  wrote:
> The SPI1 function was associated with the wrong pins: The functions that
> those pins provide is either an SPI debug or passthrough function
> coupled to SPI1. Make the SPI1 mux function configure the relevant pins
> and associate new SPI1DEBUG and SPI1PASSTHRU functions with the pins
> that were already defined.
>
> The notation used in the datasheet's multi-function pin table for the SoC is
> often creative: in this case the SYS* signals are enabled by a single bit,
> which is nothing unusual on its own, but in this case the bit was also
> participating in a multi-bit bitfield and therefore represented multiple
> functions. This fact was overlooked in the original patch.
>
> Fixes: 56e57cb6c07f (pinctrl: Add pinctrl-aspeed-g5 driver)
> Signed-off-by: Andrew Jeffery 

Reviewed-by: Joel Stanley 

> ---
>  Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt |  4 +-
>  drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c   | 86 ++-
>  2 files changed, 81 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt 
> b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> index 5e60ad18f147..2ad18c4ea55c 100644
> --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> @@ -43,7 +43,9 @@ aspeed,ast2500-pinctrl, aspeed,g5-pinctrl:
>
>  GPID0 GPID2 GPIE0 I2C10 I2C11 I2C12 I2C13 I2C14 I2C3 I2C4 I2C5 I2C6 I2C7 I2C8
>  I2C9 MAC1LINK MDIO1 MDIO2 OSCCLK PEWAKE PWM0 PWM1 PWM2 PWM3 PWM4 PWM5 PWM6 
> PWM7
> -RGMII1 RGMII2 RMII1 RMII2 SD1 SPI1 TIMER4 TIMER5 TIMER6 TIMER7 TIMER8
> +RGMII1 RGMII2 RMII1 RMII2 SD1 SPI1 SPI1DEBUG SPI1PASSTHRU TIMER4 TIMER5 
> TIMER6
> +TIMER7 TIMER8 VGABIOSROM
> +
>
>  Examples:
>
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c 
> b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> index 235d929e74fd..c8c72e8259d3 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> @@ -186,24 +186,84 @@ MS_PIN_DECL(C20, GPIOE1, NDCD3, GPIE0OUT);
>
>  FUNC_GROUP_DECL(GPIE0, B20, C20);
>
> -#define SPI1_DESC  SIG_DESC_SET(HW_STRAP1, 13)
> +#define SPI1_DESC  { HW_STRAP1, GENMASK(13, 12), 1, 0 }
> +#define SPI1DEBUG_DESC { HW_STRAP1, GENMASK(13, 12), 2, 0 }
> +#define SPI1PASSTHRU_DESC  { HW_STRAP1, GENMASK(13, 12), 3, 0 }
> +
>  #define C18 64
> -SIG_EXPR_LIST_DECL_SINGLE(SYSCS, SPI1, COND1, SPI1_DESC);
> +SIG_EXPR_DECL(SYSCS, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> +SIG_EXPR_DECL(SYSCS, SPI1PASSTHRU, COND1, SPI1PASSTHRU_DESC);
> +SIG_EXPR_LIST_DECL_DUAL(SYSCS, SPI1DEBUG, SPI1PASSTHRU);
>  SS_PIN_DECL(C18, GPIOI0, SYSCS);
>
>  #define E15 65
> -SIG_EXPR_LIST_DECL_SINGLE(SYSCK, SPI1, COND1, SPI1_DESC);
> +SIG_EXPR_DECL(SYSCK, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> +SIG_EXPR_DECL(SYSCK, SPI1PASSTHRU, COND1, SPI1PASSTHRU_DESC);
> +SIG_EXPR_LIST_DECL_DUAL(SYSCK, SPI1DEBUG, SPI1PASSTHRU);
>  SS_PIN_DECL(E15, GPIOI1, SYSCK);
>
> -#define A14 66
> -SIG_EXPR_LIST_DECL_SINGLE(SYSMOSI, SPI1, COND1, SPI1_DESC);
> -SS_PIN_DECL(A14, GPIOI2, SYSMOSI);
> +#define B16 66
> +SIG_EXPR_DECL(SYSMOSI, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> +SIG_EXPR_DECL(SYSMOSI, SPI1PASSTHRU, COND1, SPI1PASSTHRU_DESC);
> +SIG_EXPR_LIST_DECL_DUAL(SYSMOSI, SPI1DEBUG, SPI1PASSTHRU);
> +SS_PIN_DECL(B16, GPIOI2, SYSMOSI);
>
>  #define C16 67
> -SIG_EXPR_LIST_DECL_SINGLE(SYSMISO, SPI1, COND1, SPI1_DESC);
> +SIG_EXPR_DECL(SYSMISO, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> +SIG_EXPR_DECL(SYSMISO, SPI1PASSTHRU, COND1, SPI1PASSTHRU_DESC);
> +SIG_EXPR_LIST_DECL_DUAL(SYSMISO, SPI1DEBUG, SPI1PASSTHRU);
>  SS_PIN_DECL(C16, GPIOI3, SYSMISO);
>
> -FUNC_GROUP_DECL(SPI1, C18, E15, A14, C16);
> +#define VB_DESCSIG_DESC_SET(HW_STRAP1, 5)
> +
> +#define B15 68
> +SIG_EXPR_DECL(SPI1CS0, SPI1, COND1, SPI1_DESC);
> +SIG_EXPR_DECL(SPI1CS0, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> +SIG_EXPR_DECL(SPI1CS0, SPI1PASSTHRU, COND1, SPI1PASSTHRU_DESC);
> +SIG_EXPR_LIST_DECL(SPI1CS0, SIG_EXPR_PTR(SPI1CS0, SPI1),
> +   SIG_EXPR_PTR(SPI1CS0, SPI1DEBUG),
> +   SIG_EXPR_PTR(SPI1CS0, SPI1PASSTHRU));
> +SIG_EXPR_LIST_DECL_SINGLE(VBCS, VGABIOSROM, COND1, VB_DESC);
> +MS_PIN_DECL(B15, GPIOI4, SPI1CS0, VBCS);
> +
> +#define C15 69
> +SIG_EXPR_DECL(SPI1CK, SPI1, COND1, SPI1_DESC);
> +SIG_EXPR_DECL(SPI1CK, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> +SIG_EXPR_DECL(SPI1CK, SPI1PASSTHRU, COND1, SPI1PASSTHRU_DESC);
> +SIG_EXPR_LIST_DECL(SPI1CK, SIG_EXPR_PTR(SPI1CK, SPI1),
> +   SIG_EXPR_PTR(SPI1CK, SPI1DEBUG),
> +   SIG_EXPR_PTR(SPI1CK, SPI1PASSTHRU));
> +SIG_EXPR_LIST_DECL_SINGLE(VBCK, VGABIOSROM, COND1, VB_DESC);
> +MS_PIN_DECL(C15, GPIOI5, SPI1CK, VBCK);
> +
> +#define A14 70
> +SIG_EXPR_DECL(SPI1MOSI, SPI1, COND1, SPI1_DESC);
> +SIG_EXPR_DECL(SPI1MOSI, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> +SIG_EXPR_DECL(SPI1MO

Re: [PATCH 7/8] pinctrl: aspeed-g4: Add mux configuration for all pins

2016-09-28 Thread Joel Stanley
On Wed, Sep 28, 2016 at 12:20 AM, Andrew Jeffery  wrote:
> The patch introducing the g4 pinctrl driver implemented a smattering of
> pins to flesh out the implementation of the core and provide bare-bones
> support for some OpenPOWER platforms. Now, update the bindings document
> to reflect the complete functionality and implement the necessary pin
> configuration tables in the driver.
>
> Cc: Timothy Pearson 
> Signed-off-by: Andrew Jeffery 

Acked-by: Joel Stanley 


Re: [PATCH 8/8] pinctrl: aspeed-g5: Add mux configuration for all pins

2016-09-28 Thread Joel Stanley
On Wed, Sep 28, 2016 at 12:20 AM, Andrew Jeffery  wrote:
> The patch introducing the g5 pinctrl driver implemented a smattering of
> pins to flesh out the implementation of the core and provide bare-bones
> support for some OpenPOWER platforms and the AST2500 evaluation board.
> Now, update the bindings document to reflect the complete functionality
> and implement the necessary pin configuration tables in the driver.
>
> Signed-off-by: Andrew Jeffery 

Acked-by: Joel Stanley 

> ---
>  Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt |   17 +-
>  drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c   | 1476 ++-
>  drivers/pinctrl/aspeed/pinctrl-aspeed.h  |1 +-
>  3 files changed, 1487 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt 
> b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> index 0defef01ff83..67e133ba3113 100644
> --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> @@ -46,10 +46,19 @@ VGAVS VPI18 VPI24 VPI30 VPO12 VPO24 WDTRST1 WDTRST2
>
>  aspeed,ast2500-pinctrl, aspeed,g5-pinctrl:
>
> -GPID0 GPID2 GPIE0 I2C10 I2C11 I2C12 I2C13 I2C14 I2C3 I2C4 I2C5 I2C6 I2C7 I2C8
> -I2C9 MAC1LINK MDIO1 MDIO2 OSCCLK PEWAKE PWM0 PWM1 PWM2 PWM3 PWM4 PWM5 PWM6 
> PWM7
> -RGMII1 RGMII2 RMII1 RMII2 SD1 SPI1 SPI1DEBUG SPI1PASSTHRU TIMER4 TIMER5 
> TIMER6
> -TIMER7 TIMER8 VGABIOSROM
> +ACPI ADC0 ADC1 ADC10 ADC11 ADC12 ADC13 ADC14 ADC15 ADC2 ADC3 ADC4 ADC5 ADC6
> +ADC7 ADC8 ADC9 BMCINT DDCCLK DDCDAT ESPI FWSPICS1 FWSPICS2 GPID0 GPID2 GPID4
> +GPID6 GPIE0 GPIE2 GPIE4 GPIE6 I2C10 I2C11 I2C12 I2C13 I2C14 I2C3 I2C4 I2C5 
> I2C6
> +I2C7 I2C8 I2C9 LAD0 LAD1 LAD2 LAD3 LCLK LFRAME LPCHC LPCPD LPCPLUS LPCPME
> +LPCRST LPCSMI LSIRQ MAC1LINK MAC2LINK MDIO1 MDIO2 NCTS1 NCTS2 NCTS3 NCTS4 
> NDCD1
> +NDCD2 NDCD3 NDCD4 NDSR1 NDSR2 NDSR3 NDSR4 NDTR1 NDTR2 NDTR3 NDTR4 NRI1 NRI2
> +NRI3 NRI4 NRTS1 NRTS2 NRTS3 NRTS4 OSCCLK PEWAKE PNOR PWM0 PWM1 PWM2 PWM3 PWM4
> +PWM5 PWM6 PWM7 RGMII1 RGMII2 RMII1 RMII2 RXD1 RXD2 RXD3 RXD4 SALT1 SALT10
> +SALT11 SALT12 SALT13 SALT14 SALT2 SALT3 SALT4 SALT5 SALT6 SALT7 SALT8 SALT9
> +SCL1 SCL2 SD1 SD2 SDA1 SDA2 SGPS1 SGPS2 SIOONCTRL SIOPBI SIOPBO SIOPWREQ
> +SIOPWRGD SIOS3 SIOS5 SIOSCI SPI1 SPI1CS1 SPI1DEBUG SPI1PASSTHRU SPI2CK 
> SPI2CS0
> +SPI2CS1 SPI2MISO SPI2MOSI TIMER3 TIMER4 TIMER5 TIMER6 TIMER7 TIMER8 TXD1 TXD2
> +TXD3 TXD4 UART6 USBCKI VGABIOSROM VGAHS VGAVS VPI24 VPO WDTRST1 WDTRST2
>
>
>  Examples:
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c 
> b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> index c8c72e8259d3..481e836d12e5 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> @@ -24,14 +24,27 @@
>  #include "../pinctrl-utils.h"
>  #include "pinctrl-aspeed.h"
>
> -#define ASPEED_G5_NR_PINS 228
> +#define ASPEED_G5_NR_PINS 232
>
>  #define COND1  SIG_DESC_BIT(SCU90, 6, 0)
>  #define COND2  { SCU94, GENMASK(1, 0), 0, 0 }
>
> +#define LHCR0  SIG_DESC_TO_REG(ASPEED_IP_LPC, 0xA0)
> +#define GFX064 SIG_DESC_TO_REG(ASPEED_IP_GFX, 0x64)
> +
>  #define B14 0
>  SSSF_PIN_DECL(B14, GPIOA0, MAC1LINK, SIG_DESC_SET(SCU80, 0));
>
> +#define D14 1
> +SSSF_PIN_DECL(D14, GPIOA1, MAC2LINK, SIG_DESC_SET(SCU80, 1));
> +
> +#define D13 2
> +SIG_EXPR_LIST_DECL_SINGLE(SPI1CS1, SPI1CS1, SIG_DESC_SET(SCU80, 15));
> +SIG_EXPR_LIST_DECL_SINGLE(TIMER3, TIMER3, SIG_DESC_SET(SCU80, 2));
> +MS_PIN_DECL(D13, GPIOA2, SPI1CS1, TIMER3);
> +FUNC_GROUP_DECL(SPI1CS1, D13);
> +FUNC_GROUP_DECL(TIMER3, D13);
> +
>  #define E13 3
>  SSSF_PIN_DECL(E13, GPIOA3, TIMER4, SIG_DESC_SET(SCU80, 3));
>
> @@ -71,6 +84,32 @@ FUNC_GROUP_DECL(TIMER8, B13);
>
>  FUNC_GROUP_DECL(MDIO2, C13, B13);
>
> +#define K19 8
> +GPIO_PIN_DECL(K19, GPIOB0);
> +
> +#define L19 9
> +GPIO_PIN_DECL(L19, GPIOB1);
> +
> +#define L18 10
> +GPIO_PIN_DECL(L18, GPIOB2);
> +
> +#define K18 11
> +GPIO_PIN_DECL(K18, GPIOB3);
> +
> +#define J20 12
> +SSSF_PIN_DECL(J20, GPIOB4, USBCKI, SIG_DESC_SET(HW_STRAP1, 23));
> +
> +#define H21 13
> +#define H21_DESC   SIG_DESC_SET(SCU80, 13)
> +SIG_EXPR_LIST_DECL_SINGLE(LPCPD, LPCPD, H21_DESC, SIG_DESC_BIT(SIORD30, 1, 
> 0));
> +SIG_EXPR_LIST_DECL_SINGLE(LPCSMI, LPCSMI, H21_DESC, SIG_DESC_SET(SIORD30, 
> 1));
> +MS_PIN_DECL(H21, GPIOB5, LPCPD, LPCSMI);
> +FUNC_GROUP_DECL(LPCPD, H21);
> +FUNC_GROUP_DECL(LPCSMI, H21);
> +
> +#define H22 14
> +SSSF_PIN_DECL(H22, GPIOB6, LPCPME, SIG_DESC_SET(SCU80, 14));
> +
>  #define H20 15
>  GPIO_PIN_DECL(H20, GPIOB7);
>
> @@ -167,7 +206,44 @@ MS_PIN_DECL(D20, GPIOD3, SD2DAT1, GPID2OUT);
>
>  FUNC_GROUP_DECL(GPID2, F20, D20);
>
> -#define GPIE_DESC  SIG_DESC_SET(HW_STRAP1, 21)
> +#define GPID4_DESC  SIG_DESC_SET(SCU8C, 10)
> +
> +#define D21 28
> +SIG_EXPR_LIST_DECL_SINGLE(SD2DAT2, SD2, SD2_DESC);
> +SIG_EXPR_DECL(GPID4IN, GPID4, GPID4_DESC);
> +SIG_EXPR_DECL(GPID4IN, GPID, GPID_DESC);
> +SI

Re: [PATCH 3/8] pinctrl: aspeed-g5: Fix GPIOE1 typo

2016-09-28 Thread Joel Stanley
On Wed, Sep 28, 2016 at 12:20 AM, Andrew Jeffery  wrote:
> This prevented C20 from successfully being muxed as GPIO.
>
> Fixes: 56e57cb6c07f (pinctrl: Add pinctrl-aspeed-g5 driver)
> Signed-off-by: Andrew Jeffery 

Reviewed-by: Joel Stanley 

> ---
>  drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c 
> b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> index 14639834a5eb..235d929e74fd 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> @@ -182,7 +182,7 @@ SIG_EXPR_LIST_DECL_SINGLE(NDCD3, NDCD3, 
> SIG_DESC_SET(SCU80, 17));
>  SIG_EXPR_DECL(GPIE0OUT, GPIE0, GPIE0_DESC);
>  SIG_EXPR_DECL(GPIE0OUT, GPIE, GPIE_DESC);
>  SIG_EXPR_LIST_DECL_DUAL(GPIE0OUT, GPIE0, GPIE);
> -MS_PIN_DECL(C20, GPIE0, NDCD3, GPIE0OUT);
> +MS_PIN_DECL(C20, GPIOE1, NDCD3, GPIE0OUT);
>
>  FUNC_GROUP_DECL(GPIE0, B20, C20);
>
> --
> git-series 0.8.10


Re: [PATCH 1/8] pinctrl: aspeed: "Not enabled" is a significant mux state

2016-09-28 Thread Joel Stanley
On Wed, Sep 28, 2016 at 12:20 AM, Andrew Jeffery  wrote:
> Consider a scenario with one pin P that has two signals A and B, where A
> is defined to be higher priority than B: That is, if the mux IP is in a
> state that would consider both A and B to be active on P, then A will be
> the active signal.
>
> To instead configure B as the active signal we must configure the mux so
> that A is inactive. The mux state for signals can be described by
> logical operations on one or more bits from one or more registers (a
> "signal expression"), which in some cases leads to aliased mux states for
> a particular signal. Further, signals described by multi-bit bitfields
> often do not only need to record the states that would make them active
> (the "enable" expressions), but also the states that makes them inactive
> (the "disable" expressions). All of this combined leads to four possible
> states for a signal:
>
>  1. A signal is active with respect to an "enable" expression
>  2. A signal is not active with respect to an "enable" expression
>  3. A signal is inactive with respect to a "disable" expression
>  4. A signal is not inactive with respect to a "disable" expression
>
> In the case of P, if we are looking to activate B without explicitly
> having configured A it's enough to consider A inactive if all of A's
> "enable" signal expressions evaluate to "not active". If any evaluate to
> "active" then the corresponding "disable" states must be applied so it
> becomes inactive.
>
> For example, on the AST2400 the pins composing GPIO bank H provide
> signals ROMD8 through ROMD15 (high priority) and those for UART6 (low
> priority). The mux states for ROMD8 through ROMD15 are aliased, i.e.
> there are two mux states that result in the respective signals being
> configured:
>
>  A. SCU90[6]=1
>  B. Strap[4,1:0]=100
>
> Further, the second mux state is a 3-bit bitfield that explicitly
> defines the enabled state but the disabled state is implicit, i.e. if
> Strap[4,1:0] is not exactly "100" then ROMD8 through ROMD15 are not
> considered active. This requires the mux function evaluation logic to
> use approach 2. above, however the existing code was using approach 3.
> The problem was brought to light on the Palmetto machines where the
> strap register value is 0x120ce416, and prevented GPIO requests in bank
> H from succeeding despite the hardware being in a position to allow
> them.
>
> Fixes: 318398c09a8d ("pinctrl: Add core pinctrl support for Aspeed SoCs")
> Signed-off-by: Andrew Jeffery 

That's a decent commit message.

Reviewed-by: Joel Stanley 

> ---
>  drivers/pinctrl/aspeed/pinctrl-aspeed.c | 12 +++-
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c 
> b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> index 0391f9f13f3e..49aeba912531 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> @@ -166,13 +166,9 @@ static bool aspeed_sig_expr_set(const struct 
> aspeed_sig_expr *expr,
> bool enable, struct regmap *map)
>  {
> int i;
> -   bool ret;
> -
> -   ret = aspeed_sig_expr_eval(expr, enable, map);
> -   if (ret)
> -   return ret;
>
> for (i = 0; i < expr->ndescs; i++) {
> +   bool ret;
> const struct aspeed_sig_desc *desc = &expr->descs[i];
> u32 pattern = enable ? desc->enable : desc->disable;
>
> @@ -199,12 +195,18 @@ static bool aspeed_sig_expr_set(const struct 
> aspeed_sig_expr *expr,
>  static bool aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr,
>struct regmap *map)
>  {
> +   if (aspeed_sig_expr_eval(expr, true, map))
> +   return true;
> +
> return aspeed_sig_expr_set(expr, true, map);
>  }
>
>  static bool aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr,
> struct regmap *map)
>  {
> +   if (!aspeed_sig_expr_eval(expr, true, map))
> +   return true;
> +
> return aspeed_sig_expr_set(expr, false, map);
>  }
>
> --
> git-series 0.8.10


Re: [PATCH v2 4/8] media: vidc: encoder: add video encoder files

2016-09-28 Thread Stanimir Varbanov
Hi Hans,

On 09/19/2016 01:15 PM, Hans Verkuil wrote:
> Many of my review comments for the decoder apply to the encoder as well,
> so I won't repeat those.

Sure, will address them too.

> 
> On 09/07/2016 01:37 PM, Stanimir Varbanov wrote:
>> This adds encoder part of the driver plus encoder controls.
>>
>> Signed-off-by: Stanimir Varbanov 
>> ---
>>  drivers/media/platform/qcom/vidc/venc.c   | 1252 
>> +
>>  drivers/media/platform/qcom/vidc/venc.h   |   29 +
>>  drivers/media/platform/qcom/vidc/venc_ctrls.c |  396 
>>  drivers/media/platform/qcom/vidc/venc_ctrls.h |   23 +
>>  4 files changed, 1700 insertions(+)
>>  create mode 100644 drivers/media/platform/qcom/vidc/venc.c
>>  create mode 100644 drivers/media/platform/qcom/vidc/venc.h
>>  create mode 100644 drivers/media/platform/qcom/vidc/venc_ctrls.c
>>  create mode 100644 drivers/media/platform/qcom/vidc/venc_ctrls.h
>>
>> diff --git a/drivers/media/platform/qcom/vidc/venc.c 
>> b/drivers/media/platform/qcom/vidc/venc.c
>> new file mode 100644
>> index ..3b65f851a807
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/vidc/venc.c
>> @@ -0,0 +1,1252 @@
> 
> 
> 
>> +static int venc_s_selection(struct file *file, void *fh,
>> +struct v4l2_selection *s)
>> +{
>> +return -EINVAL;
>> +}
> 
> Huh? Either remove this, or implement this correctly.

OK, I cannot remember why I keep it this way, might be v4l2-compliance

> 
> 
> 
>> +static int venc_subscribe_event(struct v4l2_fh *fh,
>> +const struct  v4l2_event_subscription *sub)
>> +{
>> +switch (sub->type) {
>> +case V4L2_EVENT_EOS:
>> +return v4l2_event_subscribe(fh, sub, 2, NULL);
>> +case V4L2_EVENT_SOURCE_CHANGE:
>> +return v4l2_src_change_event_subscribe(fh, sub);
> 
> These two events aren't used in this driver AFAICT, so this can be dropped.
> 
> Since that leaves just V4L2_EVENT_CTRL this function can be replaced by
> v4l2_ctrl_subscribe_event().

sure I can remove it.

-- 
regards,
Stan


  1   2   3   4   5   6   7   8   9   10   >