Re: [tip:x86/urgent 3/3] arch/x86/kernel/apic/apic.c:1182:6: warning: the address of 'x2apic_enabled' will always evaluate as 'true'

2019-08-26 Thread Bandan Das
Thomas Gleixner  writes:

> On Tue, 27 Aug 2019, Bandan Das wrote:
>> kbuild test robot  writes:
>> 
>> > tree:   
>> > https://kernel.googlesource.com/pub/scm/linux/kernel/git/tip/tip.git 
>> > x86/urgent
>> > head:   cfa16294b1c5b320c0a0e1cac37c784b92366c87
>> > commit: cfa16294b1c5b320c0a0e1cac37c784b92366c87 [3/3] x86/apic: Include 
>> > the LDR when clearing out APIC registers
>> > config: i386-defconfig (attached as .config)
>> > compiler: gcc-7 (Debian 7.4.0-10) 7.4.0
>> > reproduce:
>> > git checkout cfa16294b1c5b320c0a0e1cac37c784b92366c87
>> > # save the attached .config to linux build tree
>> > make ARCH=i386 
>> >
>> > If you fix the issue, kindly add following tag
>> > Reported-by: kbuild test robot 
>> >
>> > All warnings (new ones prefixed by >>):
>> >
>> >arch/x86/kernel/apic/apic.c: In function 'clear_local_APIC':
>> >>> arch/x86/kernel/apic/apic.c:1182:6: warning: the address of 
>> >>> 'x2apic_enabled' will always evaluate as 'true' [-Waddress]
>> >  if (!x2apic_enabled) {
>> >  ^
>> Thomas, I apologize for the typo here. This is the x2apic_enabled() function.
>> Should I respin ?
>
>   
> https://lkml.kernel.org/r/156684295076.23440.2192639697586451635.tip-bot2@tip-bot2
>
> You have that mail in your inbox ..

Ah, thanks!


Re: [RESEND PATCH v3 10/20] mtd: spi-nor: Rework the SPI NOR lock/unlock logic

2019-08-26 Thread Tudor.Ambarus


On 08/27/2019 09:36 AM, Vignesh Raghavendra wrote:
>> +nor->flags = SNOR_F_HAS_LOCK;
> This is okay for now. But Perhaps its safer to do:
> 
>   nor->flags |= SNOR_F_HAS_LOCK;
> 
> so that we don't override flags if set earlier than
> spi_nor_manufacturer_init_params(). I see that patch 20/20 does indeed
> present one such case wrt atmel/Xilinix flashes IIUC

yep, you're right, I'll update as you suggested.

Thanks!


[PATCH 1/2] gpio: gpio-pca953x.c: Correct type of reg_direction

2019-08-26 Thread David Jander
The type of reg_direction needs to match the type of the regmap, which is
u8.

Signed-off-by: David Jander 
---
 drivers/gpio/gpio-pca953x.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 378b206d2dc9..30072a570bc2 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -604,7 +604,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
u8 new_irqs;
int level, i;
u8 invert_irq_mask[MAX_BANK];
-   int reg_direction[MAX_BANK];
+   u8 reg_direction[MAX_BANK];
 
regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
 NBANK(chip));
@@ -679,7 +679,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, 
u8 *pending)
bool pending_seen = false;
bool trigger_seen = false;
u8 trigger[MAX_BANK];
-   int reg_direction[MAX_BANK];
+   u8 reg_direction[MAX_BANK];
int ret, i;
 
if (chip->driver_data & PCA_PCAL) {
@@ -768,7 +768,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
 {
struct i2c_client *client = chip->client;
struct irq_chip *irq_chip = &chip->irq_chip;
-   int reg_direction[MAX_BANK];
+   u8 reg_direction[MAX_BANK];
int ret, i;
 
if (!client->irq)
-- 
2.19.1



[PATCH 2/2] gpio: pca953x.c: Use pca953x_read_regs instead of regmap_bulk_read

2019-08-26 Thread David Jander
The register number needs to be translated for chips with more than 8
ports. This patch fixes a bug causing all chips with more than 8 GPIO pins
to not work correctly.

Signed-off-by: David Jander 
---
 drivers/gpio/gpio-pca953x.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 30072a570bc2..48fea4c68e8d 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -606,8 +606,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
u8 invert_irq_mask[MAX_BANK];
u8 reg_direction[MAX_BANK];
 
-   regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
-NBANK(chip));
+   pca953x_read_regs(chip, chip->regs->direction, reg_direction);
 
if (chip->driver_data & PCA_PCAL) {
/* Enable latch on interrupt-enabled inputs */
@@ -710,8 +709,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, 
u8 *pending)
return false;
 
/* Remove output pins from the equation */
-   regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
-NBANK(chip));
+   pca953x_read_regs(chip, chip->regs->direction, reg_direction);
for (i = 0; i < NBANK(chip); i++)
cur_stat[i] &= reg_direction[i];
 
@@ -789,8 +787,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
 * interrupt.  We have to rely on the previous read for
 * this purpose.
 */
-   regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
-NBANK(chip));
+   pca953x_read_regs(chip, chip->regs->direction, reg_direction);
for (i = 0; i < NBANK(chip); i++)
chip->irq_stat[i] &= reg_direction[i];
mutex_init(&chip->irq_lock);
-- 
2.19.1



Re: [PATCH v5 2/4] iio: imu: st_lsm6sdx: move register definitions to sensor_settings struct

2019-08-26 Thread Martin Kepplinger
On 21.08.19 15:25, Martin Kepplinger wrote:
> Move some register definitions to the per-device array of struct
> st_lsm6dsx_sensor_settings in order to simplify adding new sensor
> devices to the driver.
> 
> Also, remove completely unused register definitions.
> 
> Signed-off-by: Martin Kepplinger 
> Acked-by: Lorenzo Bianconi 
> ---
>  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h  |  6 
>  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 31 ++--
>  2 files changed, 28 insertions(+), 9 deletions(-)
> 

I just notices the commit message header typo "st_lsm6sdx" should be
"st_lsm6dsx" of course. If you can still rebase/force-push to testing,
would you be able to fix that? If it's too far out there already, so be
it :) sorry for the typo, and thanks for adding "-imu" yourself where
applicable.

thanks,

  martin


Re: [tip:x86/urgent 3/3] arch/x86/kernel/apic/apic.c:1182:6: warning: the address of 'x2apic_enabled' will always evaluate as 'true'

2019-08-26 Thread Thomas Gleixner
On Tue, 27 Aug 2019, Bandan Das wrote:
> kbuild test robot  writes:
> 
> > tree:   
> > https://kernel.googlesource.com/pub/scm/linux/kernel/git/tip/tip.git 
> > x86/urgent
> > head:   cfa16294b1c5b320c0a0e1cac37c784b92366c87
> > commit: cfa16294b1c5b320c0a0e1cac37c784b92366c87 [3/3] x86/apic: Include 
> > the LDR when clearing out APIC registers
> > config: i386-defconfig (attached as .config)
> > compiler: gcc-7 (Debian 7.4.0-10) 7.4.0
> > reproduce:
> > git checkout cfa16294b1c5b320c0a0e1cac37c784b92366c87
> > # save the attached .config to linux build tree
> > make ARCH=i386 
> >
> > If you fix the issue, kindly add following tag
> > Reported-by: kbuild test robot 
> >
> > All warnings (new ones prefixed by >>):
> >
> >arch/x86/kernel/apic/apic.c: In function 'clear_local_APIC':
> >>> arch/x86/kernel/apic/apic.c:1182:6: warning: the address of 
> >>> 'x2apic_enabled' will always evaluate as 'true' [-Waddress]
> >  if (!x2apic_enabled) {
> >  ^
> Thomas, I apologize for the typo here. This is the x2apic_enabled() function.
> Should I respin ?

  
https://lkml.kernel.org/r/156684295076.23440.2192639697586451635.tip-bot2@tip-bot2

You have that mail in your inbox ..


[PATCH] pci: get pm runtime ref before resetting bus

2019-08-26 Thread Xiongfeng Wang
When I inject a PCIE Fatal error into a mellanox netdevice, 'dmesg' shows
the device is recovered successfully, but 'lspci' didn't show the
device. I checked the configuration space of the slot where the netdevice
is inserted and found out the bit 'PCI_BRIDGE_CTL_BUS_RESET' is set.
Later, I found out it is because this bit is saved in
'saved_config_space' of 'struct pci_dev' when 'pci_pm_runtime_suspend()'
is called. And 'PCI_BRIDGE_CTL_BUS_RESET' is set every time we restore
the configuration sapce.

This patch use 'pm_runtime_get' to avoid saving the configuration space
of the bridge when the bus is being reset.

Signed-off-by: Xiongfeng Wang 
---
 drivers/pci/pci.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9cae66c..0079f0a 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4546,6 +4546,9 @@ void pci_reset_secondary_bus(struct pci_dev *dev)
 {
u16 ctrl;
 
+   /* avoid wrongly saving 'PCI_BRIDGE_CTL_BUS_RESET' */
+   pm_runtime_get(&dev->dev);
+
pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl);
ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
@@ -4567,6 +4570,8 @@ void pci_reset_secondary_bus(struct pci_dev *dev)
 * but we don't make use of them yet.
 */
ssleep(1);
+
+   pm_runtime_put(&dev->dev);
 }
 
 void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
-- 
1.7.12.4



Re: [tip:x86/urgent 3/3] arch/x86/kernel/apic/apic.c:1182:6: warning: the address of 'x2apic_enabled' will always evaluate as 'true'

2019-08-26 Thread Bandan Das
kbuild test robot  writes:

> tree:   https://kernel.googlesource.com/pub/scm/linux/kernel/git/tip/tip.git 
> x86/urgent
> head:   cfa16294b1c5b320c0a0e1cac37c784b92366c87
> commit: cfa16294b1c5b320c0a0e1cac37c784b92366c87 [3/3] x86/apic: Include the 
> LDR when clearing out APIC registers
> config: i386-defconfig (attached as .config)
> compiler: gcc-7 (Debian 7.4.0-10) 7.4.0
> reproduce:
> git checkout cfa16294b1c5b320c0a0e1cac37c784b92366c87
> # save the attached .config to linux build tree
> make ARCH=i386 
>
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot 
>
> All warnings (new ones prefixed by >>):
>
>arch/x86/kernel/apic/apic.c: In function 'clear_local_APIC':
>>> arch/x86/kernel/apic/apic.c:1182:6: warning: the address of 
>>> 'x2apic_enabled' will always evaluate as 'true' [-Waddress]
>  if (!x2apic_enabled) {
>  ^
Thomas, I apologize for the typo here. This is the x2apic_enabled() function.
Should I respin ?

>
> vim +1182 arch/x86/kernel/apic/apic.c
>
>   1142
>   1143/*
>   1144 * Local APIC start and shutdown
>   1145 */
>   1146
>   1147/**
>   1148 * clear_local_APIC - shutdown the local APIC
>   1149 *
>   1150 * This is called, when a CPU is disabled and before rebooting, 
> so the state of
>   1151 * the local APIC has no dangling leftovers. Also used to 
> cleanout any BIOS
>   1152 * leftovers during boot.
>   1153 */
>   1154void clear_local_APIC(void)
>   1155{
>   1156int maxlvt;
>   1157u32 v;
>   1158
>   1159/* APIC hasn't been mapped yet */
>   1160if (!x2apic_mode && !apic_phys)
>   1161return;
>   1162
>   1163maxlvt = lapic_get_maxlvt();
>   1164/*
>   1165 * Masking an LVT entry can trigger a local APIC error
>   1166 * if the vector is zero. Mask LVTERR first to prevent 
> this.
>   1167 */
>   1168if (maxlvt >= 3) {
>   1169v = ERROR_APIC_VECTOR; /* any non-zero vector 
> will do */
>   1170apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
>   1171}
>   1172/*
>   1173 * Careful: we have to set masks only first to deassert
>   1174 * any level-triggered sources.
>   1175 */
>   1176v = apic_read(APIC_LVTT);
>   1177apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
>   1178v = apic_read(APIC_LVT0);
>   1179apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
>   1180v = apic_read(APIC_LVT1);
>   1181apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
>> 1182 if (!x2apic_enabled) {
>   1183v = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
>   1184apic_write(APIC_LDR, v);
>   1185}
>   1186if (maxlvt >= 4) {
>   1187v = apic_read(APIC_LVTPC);
>   1188apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
>   1189}
>   1190
>   1191/* lets not touch this if we didn't frob it */
>   1192#ifdef CONFIG_X86_THERMAL_VECTOR
>   1193if (maxlvt >= 5) {
>   1194v = apic_read(APIC_LVTTHMR);
>   1195apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
>   1196}
>   1197#endif
>   1198#ifdef CONFIG_X86_MCE_INTEL
>   1199if (maxlvt >= 6) {
>   1200v = apic_read(APIC_LVTCMCI);
>   1201if (!(v & APIC_LVT_MASKED))
>   1202apic_write(APIC_LVTCMCI, v | 
> APIC_LVT_MASKED);
>   1203}
>   1204#endif
>   1205
>   1206/*
>   1207 * Clean APIC state for other OSs:
>   1208 */
>   1209apic_write(APIC_LVTT, APIC_LVT_MASKED);
>   1210apic_write(APIC_LVT0, APIC_LVT_MASKED);
>   1211apic_write(APIC_LVT1, APIC_LVT_MASKED);
>   1212if (maxlvt >= 3)
>   1213apic_write(APIC_LVTERR, APIC_LVT_MASKED);
>   1214if (maxlvt >= 4)
>   1215apic_write(APIC_LVTPC, APIC_LVT_MASKED);
>   1216
>   1217/* Integrated APIC (!82489DX) ? */
>   1218if (lapic_is_integrated()) {
>   1219if (maxlvt > 3)
>   1220/* Clear ESR due to Pentium errata 3AP 
> and 11AP */
>   1221apic_write(APIC_ESR, 0);
>   1222apic_read(APIC_ESR);
>   1223}
>   1224 

Re: [PATCH] powerpc: Perform a bounds check in arch_add_memory

2019-08-26 Thread Alastair D'Silva
On Tue, 2019-08-27 at 08:28 +0200, Michal Hocko wrote:
> On Tue 27-08-19 15:20:46, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> > 
> > It is possible for firmware to allocate memory ranges outside
> > the range of physical memory that we support (MAX_PHYSMEM_BITS).
> 
> Doesn't that count as a FW bug? Do you have any evidence of that in
> the
> field? Just wondering...
> 

Not outside our lab, but OpenCAPI attached LPC memory is assigned
addresses based on the slot/NPU it is connected to. These addresses
prior to:
4ffe713b7587 ("powerpc/mm: Increase the max addressable memory to 2PB")
were inaccessible and resulted in bogus sections - see our discussion
on 'mm: Trigger bug on if a section is not found in __section_nr'.
Doing this check here was your suggestion :)

It's entirely possible that a similar problem will occur in the future,
and it's cheap to guard against, which is why I've added this.

-- 
Alastair D'Silva
Open Source Developer
Linux Technology Centre, IBM Australia
mob: 0423 762 819



[PATCH v2] kbuild: change *FLAGS_.o to take the path relative to $(obj)

2019-08-26 Thread Masahiro Yamada
Kbuild provides per-file compiler flag addition/removal:

  CFLAGS_.o
  CFLAGS_REMOVE_.o
  AFLAGS_.o
  AFLAGS_REMOVE_.o
  CPPFLAGS_.lds
  HOSTCFLAGS_.o
  HOSTCXXFLAGS_.o

The  is the filename of the target with its directory and
suffix stripped.

This syntax comes into a trouble when two files with the same name
appear in one Makefile, for example:

  obj-y += foo.o
  obj-y += dir/foo.o
  CFLAGS_foo.o := 

Here, the  applies to both foo.o and dir/foo.o

The real world problem is:

  scripts/kconfig/util.c
  scripts/kconfig/lxdialog/util.c

Both files are compiled into scripts/kconfig/mconf, but only the
latter should be given with additional flags for ncurses.

It is more sensible to use the relative path to the Makefile, like this:

  obj-y += foo.o
  CFLAGS_foo.o := 
  obj-y += dir/foo.o
  CFLAGS_dir/foo.o := 

The $* variable is replaced with the stem ('%') part in a pattern rule.
In other words, this only works for pattern rules.

Signed-off-by: Masahiro Yamada 
Acked-by: Marc Zyngier 
---

Changes in v2:
  - Fix build errors for gpu drivers

 arch/arm/kvm/Makefile |  5 ++--
 arch/x86/entry/vdso/Makefile  |  3 +-
 drivers/gpu/drm/amd/display/dc/calcs/Makefile |  6 ++--
 drivers/gpu/drm/amd/display/dc/dcn20/Makefile |  2 +-
 drivers/gpu/drm/amd/display/dc/dml/Makefile   | 17 +--
 drivers/gpu/drm/amd/display/dc/dsc/Makefile   |  7 ++---
 drivers/gpu/drm/i915/Makefile |  2 +-
 scripts/Makefile.host | 30 +--
 scripts/Makefile.lib  | 10 +++
 scripts/kconfig/Makefile  |  8 ++---
 10 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index 531e59f5be9c..b76b75bd9e00 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -8,13 +8,14 @@ ifeq ($(plus_virt),+virt)
plus_virt_def := -DREQUIRES_VIRT=1
 endif
 
+KVM := ../../../virt/kvm
+
 ccflags-y += -I $(srctree)/$(src) -I $(srctree)/virt/kvm/arm/vgic
-CFLAGS_arm.o := $(plus_virt_def)
+CFLAGS_$(KVM)/arm/arm.o := $(plus_virt_def)
 
 AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt)
 AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt)
 
-KVM := ../../../virt/kvm
 kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o 
$(KVM)/vfio.o
 
 obj-$(CONFIG_KVM_ARM_HOST) += hyp/
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index 8df549138193..0f2154106d01 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -89,6 +89,7 @@ $(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) 
$(RETPOLINE_CFLAGS
 #
 CFLAGS_REMOVE_vdso-note.o = -pg
 CFLAGS_REMOVE_vclock_gettime.o = -pg
+CFLAGS_REMOVE_vdso32/vclock_gettime.o = -pg
 CFLAGS_REMOVE_vgetcpu.o = -pg
 CFLAGS_REMOVE_vvar.o = -pg
 
@@ -128,7 +129,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
 $(obj)/vdsox32.so.dbg: $(obj)/vdsox32.lds $(vobjx32s) FORCE
$(call if_changed,vdso_and_check)
 
-CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
+CPPFLAGS_vdso32/vdso32.lds = $(CPPFLAGS_vdso.lds)
 VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -soname linux-gate.so.1
 
 targets += vdso32/vdso32.lds
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile 
b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
index 95f332ee3e7e..d930df63772c 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
@@ -32,9 +32,9 @@ endif
 
 calcs_ccflags := -mhard-float -msse $(cc_stack_align)
 
-CFLAGS_dcn_calcs.o := $(calcs_ccflags)
-CFLAGS_dcn_calc_auto.o := $(calcs_ccflags)
-CFLAGS_dcn_calc_math.o := $(calcs_ccflags) -Wno-tautological-compare
+CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calcs.o := $(calcs_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calc_auto.o := $(calcs_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calc_math.o := $(calcs_ccflags) 
-Wno-tautological-compare
 
 BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
index e9721a906592..83635ad9124e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
@@ -16,7 +16,7 @@ else ifneq ($(call cc-option, -mstack-alignment=16),)
cc_stack_align := -mstack-alignment=16
 endif
 
-CFLAGS_dcn20_resource.o := -mhard-float -msse $(cc_stack_align)
+CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -msse 
$(cc_stack_align)
 
 AMD_DAL_DCN20 = $(addprefix $(AMDDALPATH)/dc/dcn20/,$(DCN20))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile 
b/drivers/gpu/drm/amd/display/dc/dml/Makefile
index 0bb7a20675c4..83792e2c0f0e 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -32,19 +32,16 @@ endif
 
 dml_ccflags := -mhard-float -msse $(cc_stack_align)
 
-CFLAGS_display_mode_lib.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(d

Re: [RESEND PATCH v3 10/20] mtd: spi-nor: Rework the SPI NOR lock/unlock logic

2019-08-26 Thread Vignesh Raghavendra



On 26/08/19 5:38 PM, tudor.amba...@microchip.com wrote:
> From: Boris Brezillon 
> 
> Add the SNOR_F_HAS_LOCK flag and set it when SPI_NOR_HAS_LOCK is set
> in the flash_info entry or when it's a Micron or ST flash.
> 
> Move the locking hooks in a separate struct so that we have just
> one field to update when we change the locking implementation.
> 
> Signed-off-by: Boris Brezillon 
> [tudor.amba...@microchip.com: use ->default_init() hook, introduce
> spi_nor_late_init_params(), set ops in nor->params]
> Signed-off-by: Tudor Ambarus 
> ---
> v3: no changes, clear_sr_bp() is handled in the last patch of the
> series.
> 

Reviewed-by: Vignesh Raghavendra 

One suggestion below:


>  drivers/mtd/spi-nor/spi-nor.c | 50 
> ---
>  include/linux/mtd/spi-nor.h   | 23 ++--
>  2 files changed, 53 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 235e82a121a1..3f997797fa9d 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1598,6 +1598,12 @@ static int stm_is_locked(struct spi_nor *nor, loff_t 
> ofs, uint64_t len)
>   return stm_is_locked_sr(nor, ofs, len, status);
>  }
>  
> +static const struct spi_nor_locking_ops stm_locking_ops = {
> + .lock = stm_lock,
> + .unlock = stm_unlock,
> + .is_locked = stm_is_locked,
> +};
> +
>  static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>  {
>   struct spi_nor *nor = mtd_to_spi_nor(mtd);
> @@ -1607,7 +1613,7 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t 
> ofs, uint64_t len)
>   if (ret)
>   return ret;
>  
> - ret = nor->flash_lock(nor, ofs, len);
> + ret = nor->params.locking_ops->lock(nor, ofs, len);
>  
>   spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
>   return ret;
> @@ -1622,7 +1628,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t 
> ofs, uint64_t len)
>   if (ret)
>   return ret;
>  
> - ret = nor->flash_unlock(nor, ofs, len);
> + ret = nor->params.locking_ops->unlock(nor, ofs, len);
>  
>   spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
>   return ret;
> @@ -1637,7 +1643,7 @@ static int spi_nor_is_locked(struct mtd_info *mtd, 
> loff_t ofs, uint64_t len)
>   if (ret)
>   return ret;
>  
> - ret = nor->flash_is_locked(nor, ofs, len);
> + ret = nor->params.locking_ops->is_locked(nor, ofs, len);
>  
>   spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
>   return ret;
> @@ -4148,6 +4154,7 @@ static void macronix_set_default_init(struct spi_nor 
> *nor)
>  
>  static void st_micron_set_default_init(struct spi_nor *nor)
>  {
> + nor->flags = SNOR_F_HAS_LOCK;

This is okay for now. But Perhaps its safer to do:

nor->flags |= SNOR_F_HAS_LOCK;

so that we don't override flags if set earlier than
spi_nor_manufacturer_init_params(). I see that patch 20/20 does indeed
present one such case wrt atmel/Xilinix flashes IIUC

Regards
Vignesh

>   nor->params.quad_enable = NULL;
>   nor->params.set_4byte = st_micron_set_4byte;
>  }
> @@ -4292,6 +4299,23 @@ static void spi_nor_info_init_params(struct spi_nor 
> *nor)
>  }
>  
>  /**
> + * spi_nor_late_init_params() - Late initialization of default flash 
> parameters.
> + * @nor: pointer to a 'struct spi_nor'
> + *
> + * Used to set default flash parameters and settings when the 
> ->default_init()
> + * hook or the SFDP parser let voids.
> + */
> +static void spi_nor_late_init_params(struct spi_nor *nor)
> +{
> + /*
> +  * NOR protection support. When locking_ops are not provided, we pick
> +  * the default ones.
> +  */
> + if (nor->flags & SNOR_F_HAS_LOCK && !nor->params.locking_ops)
> + nor->params.locking_ops = &stm_locking_ops;
> +}
> +
> +/**
>   * spi_nor_init_params() - Initialize the flash's parameters and settings.
>   * @nor: pointer to a 'struct spi-nor'.
>   *
> @@ -4316,6 +4340,10 @@ static void spi_nor_info_init_params(struct spi_nor 
> *nor)
>   *Please not that there is a ->post_bfpt() fixup hook that can overwrite 
> the
>   *flash parameters and settings imediately after parsing the Basic Flash
>   *Parameter Table.
> + *
> + * 4/ Late default flash parameters initialization, used when the
> + * ->default_init() hook or the SFDP parser do not set specific params.
> + *   spi_nor_late_init_params()
>   */
>  static void spi_nor_init_params(struct spi_nor *nor)
>  {
> @@ -4326,6 +4354,8 @@ static void spi_nor_init_params(struct spi_nor *nor)
>   if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&
>   !(nor->info->flags & SPI_NOR_SKIP_SFDP))
>   spi_nor_sfdp_init_params(nor);
> +
> + spi_nor_late_init_params(nor);
>  }
>  
>  static int spi_nor_select_read(struct spi_nor *nor,
> @@ -4707,6 +4737,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>   if

Re: Linux-next-20190823: x86_64/i386: prot_hsymlinks.c:325: Failed to run cmd: useradd hsym

2019-08-26 Thread Naresh Kamboju
On Tue, 27 Aug 2019 at 04:42, Jan Stancek  wrote:
>
>
> - Original Message -
> > On Mon, 2019-08-26 at 10:38 -0400, Jan Stancek wrote:
>
> No change with that patch,

Same for me.

> but following one fixes it for me:

Works for me.
Thanks for the fix patch.

>
> diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
> index 20b3717cd7ca..56cefa0ab804 100644
> --- a/fs/nfs/pagelist.c
> +++ b/fs/nfs/pagelist.c
> @@ -590,7 +590,7 @@ static void nfs_pgio_rpcsetup(struct nfs_pgio_header *hdr,
> }
>
> hdr->res.fattr   = &hdr->fattr;
> -   hdr->res.count   = 0;
> +   hdr->res.count   = count;
> hdr->res.eof = 0;
> hdr->res.verf= &hdr->verf;
> nfs_fattr_init(&hdr->fattr);
>
> which is functionally revert of "NFS: Fix initialisation of I/O result struct 
> in nfs_pgio_rpcsetup".
>
> This hunk caught my eye, could res.eof == 0 explain those I/O errors?
> /* Emulate the eof flag, which isn't normally needed in NFSv2
>  * as it is guaranteed to always return the file attributes
>  */
> if (hdr->args.offset + hdr->res.count >= hdr->res.fattr->size)
> hdr->res.eof = 1;


- Naresh


[PATCH v2 48/49] Input: atmel_mxt_ts: Implement synchronization during various operation

2019-08-26 Thread Jiada Wang
From: Sanjeev Chugh 

There could be scope of race conditions when sysfs is being handled
and at the same time, device removal is occurring. For example,
we don't want the device removal to begin if the Atmel device
cfg update is going on or firmware update is going on. In such
cases, wait for device update to be completed before the removal
continues.

Thread  Thread 2:
=   =
mxt_update_fw_store()   mxt_remove()
mutex_lock(&data->lock) ...
mxt_initialize()//Tries to acquire lock
  request_firmware_nowait() mutex_lock(&data->lock)
... ==>waits for lock()
... .
... .
mutex_unlock(&data->lock)   .
//Gets lock and proceeds
mxt_free_input_device();
...
mutex_unlock(&data->lock)
//Frees atmel driver data
kfree(data)

If the request_firmware_nowait() completes after the driver removal,
and callback is triggered. But kernel crashes since the module is
already removed.

This commit adds state machine to serialize such scenarios.

Signed-off-by: Sanjeev Chugh 
Signed-off-by: Bhuvanesh Surachari 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 222 ---
 1 file changed, 196 insertions(+), 26 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 63ff8a211a90..a461220cd336 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -224,6 +224,7 @@ enum t100_type {
 #define MXT_POWERON_DELAY  150 /* msec */
 #define MXT_BOOTLOADER_WAIT36E5/* 1 minute */
 #define MXT_WATCHDOG_TIMEOUT   1000/* msec */
+#define MXT_CONFIG_TIMEOUT 1000/* msec */
 
 /* Command to unlock bootloader */
 #define MXT_UNLOCK_CMD_MSB 0xaa
@@ -247,6 +248,20 @@ enum t100_type {
 
 #define DEBUG_MSG_MAX  200
 
+enum device_state {
+   MXT_STATE_READY,
+   MXT_STATE_UPDATING_CONFIG,
+   MXT_STATE_UPDATING_CONFIG_ASYNC,
+   MXT_STATE_START,
+   MXT_STATE_STOP,
+   MXT_STATE_GOING_AWAY
+};
+
+enum mxt_cmd {
+   UPDATE_CFG,
+   UPDATE_FW
+};
+
 struct mxt_info {
u8 family_id;
u8 variant_id;
@@ -426,11 +441,15 @@ struct mxt_data {
/* Indicates whether device is in suspend */
bool suspended;
 
-   /* Indicates whether device is updating configuration */
-   bool updating_config;
+   struct mutex lock;
 
unsigned int mtu;
bool t25_status;
+
+   /* State handling for probe/remove, open/close and config update */
+   enum device_state e_state;
+
+   struct completion update_cfg_completion;
 };
 
 struct mxt_vb2_buffer {
@@ -1654,6 +1673,7 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
struct mxt_data *data = dev_id;
int ret;
 
+   mutex_lock(&data->lock);
data->mxt_status.intp_triggered = true;
 
if (data->in_bootloader) {
@@ -1681,6 +1701,8 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 
 exit:
data->mxt_status.intp_triggered = false;
+   mutex_unlock(&data->lock);
+
return ret;
 }
 
@@ -2261,6 +2283,8 @@ static void mxt_free_object_table(struct mxt_data *data)
video_unregister_device(&data->dbg.vdev);
v4l2_device_unregister(&data->dbg.v4l2);
 #endif
+   mutex_lock(&data->lock);
+
data->object_table = NULL;
kfree(data->info);
data->info = NULL;
@@ -2290,6 +2314,8 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T100_reportid_min = 0;
data->T100_reportid_max = 0;
data->max_reportid = 0;
+
+   mutex_unlock(&data->lock);
 }
 
 static int mxt_parse_object_table(struct mxt_data *data,
@@ -2971,8 +2997,15 @@ static int mxt_configure_objects(struct mxt_data *data,
 
 static void mxt_config_cb(const struct firmware *cfg, void *ctx)
 {
+   struct mxt_data *data = ctx;
+
mxt_configure_objects(ctx, cfg);
release_firmware(cfg);
+   complete(&data->update_cfg_completion);
+   mutex_lock(&data->lock);
+   if (data->e_state != MXT_STATE_GOING_AWAY)
+   data->e_state = MXT_STATE_READY;
+   mutex_unlock(&data->lock);
 }
 
 static int mxt_bootloader_status(struct mxt_data *data)
@@ -3085,6 +3118,15 @@ static int mxt_initialize(struct mxt_data *data)
goto err_free_sysfs;
 
if (data->cfg_name) {
+   

[PATCH v2 49/49] Input: atmel_mxt_ts - Fix compilation warning

2019-08-26 Thread Jiada Wang
fix "make W=1" compilation warnings from Atmel driver
as per the compilation logs.

Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index a461220cd336..115c94d3f0d4 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2046,7 +2046,7 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data, 
struct mxt_cfg *cfg)
 
byte_offset = reg + i - cfg->start_ofs;
 
-   if (byte_offset >= 0 && byte_offset < cfg->mem_size) {
+   if (byte_offset < cfg->mem_size) {
*(cfg->mem + byte_offset) = val;
} else {
dev_err(dev, "Bad object: reg:%d, T%d, 
ofs=%d\n",
-- 
2.19.2



[PATCH v2 43/49] Input: Atmel: handle ReportID "0x00" while processing T5 messages

2019-08-26 Thread Jiada Wang
From: Deepak Das 

ReportID "0x00" is reserved by Atmel and should not be used by any
Atmel touch controller.

reportID is the first byte retrieved from T5 message payload.
Currently Atmel driver continues to process the T5 messages even if
the reportID "0x00" is returned by Touch Controller.

This commit modifies Atmel touch driver to return -EINVAL if ReportID
"0x00" is received while processing T5 messages.

Signed-off-by: Deepak Das 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 41d92d765aa2..b6f50fee3695 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -76,6 +76,7 @@
 #define MXT_PROCI_TOUCHSEQUENCELOGGER  93
 #define MXT_TOUCH_MULTITOUCHSCREEN_T100 100
 #define MXT_PROCI_ACTIVESTYLUS_T107107
+#define MXT_RPTID_RESERVED 0
 
 /* MXT_GEN_MESSAGE_T5 object */
 #define MXT_RPTID_NOMSG0xff
@@ -1381,6 +1382,11 @@ static int mxt_proc_message(struct mxt_data *data, u8 
*message)
u8 report_id = message[0];
bool dump = data->debug_enabled;
 
+   if (report_id == MXT_RPTID_RESERVED) {
+   dev_err(&data->client->dev,
+   "Received Reserved ReportID 0x00\n");
+   return -EINVAL;
+   }
if (report_id == MXT_RPTID_NOMSG)
return 0;
 
@@ -1451,6 +1457,8 @@ static int mxt_read_and_process_messages(struct mxt_data 
*data, u8 count)
ret = mxt_proc_message(data,
data->msg_buf + data->T5_msg_size * i);
 
+   if (ret < 0)
+   return ret;
if (ret == 1)
num_valid++;
}
-- 
2.19.2



[PATCH v2 44/49] Input: Atmel: use T44 object to process T5 messages

2019-08-26 Thread Jiada Wang
From: Deepak Das 

T44 object returns the count of valid T5 messages in the buffer. According
to atmel, this count should be the main criteria to read the number of T5
messages.

Following is the statement from atmel confirming the same :-
"For the readout of messages we recommend to stop after the last message
is read out from the buffer. One way to identify the amount of new messages
is to read T44. The other way is to monitor the /CHG line which indicates
independent of mode 0 or mode 1 if there are still data in the buffer.
0xFF indicates that there is no message pending anymore, but it is not
recommended to use this as the main criteria to control the
data transfer."

This commit modifies the logic to readout the T5 messages on the basis
of T44 object.

Signed-off-by: Deepak Das 
Signed-off-by: Sanjeev Chugh 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 55 +++-
 1 file changed, 35 insertions(+), 20 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index b6f50fee3695..58e54eb45cf0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1486,7 +1486,7 @@ static u8 mxt_max_msg_read_count(struct mxt_data *data, 
u8 max_T5_msg_count)
return min(T5_msg_count_limit, max_T5_msg_count);
 }
 
-static irqreturn_t mxt_process_messages_t44(struct mxt_data *data)
+static int mxt_process_messages_t44(struct mxt_data *data)
 {
struct device *dev = &data->client->dev;
int ret;
@@ -1499,7 +1499,7 @@ static irqreturn_t mxt_process_messages_t44(struct 
mxt_data *data)
data->T5_msg_size + 1, data->msg_buf);
if (ret) {
dev_err(dev, "Failed to read T44 and T5 (%d)\n", ret);
-   return IRQ_NONE;
+   return ret;
}
 
T5_msg_count = data->msg_buf[0];
@@ -1509,7 +1509,7 @@ static irqreturn_t mxt_process_messages_t44(struct 
mxt_data *data)
 * Mode 0. It results in unnecessary I2C operations but it is benign.
 */
if (!T5_msg_count)
-   return IRQ_NONE;
+   return processed_valid;
 
if (T5_msg_count > data->max_reportid) {
dev_warn(dev, "T44 count %d exceeded max report id\n",
@@ -1521,12 +1521,14 @@ static irqreturn_t mxt_process_messages_t44(struct 
mxt_data *data)
ret = mxt_proc_message(data, data->msg_buf + 1);
if (ret < 0) {
dev_warn(dev, "Unexpected invalid message\n");
-   return IRQ_NONE;
+   return ret;
}
 
total_pending = T5_msg_count - 1;
-   if (!total_pending)
+   if (!total_pending) {
+   processed_valid = 1;
goto end;
+   }
 
/* Process remaining messages if necessary */
T5_msg_count = mxt_max_msg_read_count(data, total_pending);
@@ -1550,7 +1552,7 @@ static irqreturn_t mxt_process_messages_t44(struct 
mxt_data *data)
data->update_input = false;
}
 
-   return IRQ_HANDLED;
+   return processed_valid;
 }
 
 static int mxt_process_messages_until_invalid(struct mxt_data *data)
@@ -1580,7 +1582,7 @@ static int mxt_process_messages_until_invalid(struct 
mxt_data *data)
return -EBUSY;
 }
 
-static irqreturn_t mxt_process_messages(struct mxt_data *data)
+static int mxt_process_messages(struct mxt_data *data)
 {
int total_handled, num_handled;
u8 count = data->last_message_count;
@@ -1591,7 +1593,7 @@ static irqreturn_t mxt_process_messages(struct mxt_data 
*data)
/* include final invalid message */
total_handled = mxt_read_and_process_messages(data, count + 1);
if (total_handled < 0)
-   return IRQ_NONE;
+   return total_handled;
/* if there were invalid messages, then we are done */
else if (total_handled <= count)
goto update_count;
@@ -1600,7 +1602,7 @@ static irqreturn_t mxt_process_messages(struct mxt_data 
*data)
do {
num_handled = mxt_read_and_process_messages(data, 2);
if (num_handled < 0)
-   return IRQ_NONE;
+   return num_handled;
 
total_handled += num_handled;
 
@@ -1616,12 +1618,13 @@ static irqreturn_t mxt_process_messages(struct mxt_data 
*data)
data->update_input = false;
}
 
-   return IRQ_HANDLED;
+   return total_handled;
 }
 
 static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 {
struct mxt_data *data = dev_id;
+   int ret;
 
if (data->in_bootloader) {
complete(&data->chg_completion);
@@ -1629,17 +1632,22 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
if (data->flash && &data->flash->work)
cancel_delayed_work_sync(&data->flash->work);
 
-   return IRQ_R

[PATCH v2 41/49] Input: Atmel: improve error handling in mxt_update_cfg()

2019-08-26 Thread Jiada Wang
From: Deepak Das 

mxt_update_cfg() failed to propagate the error
code from mxt_init_t7_power_cfg() so return the error code.

Signed-off-by: Deepak Das 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 59533753a431..716b91e6fd66 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2183,7 +2183,9 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
dev_info(dev, "Config successfully updated\n");
 
/* T7 config may have changed */
-   mxt_init_t7_power_cfg(data);
+   ret = mxt_init_t7_power_cfg(data);
+   if (ret)
+   dev_warn(dev, "Power Config failed to update\n");
 
 release_mem:
kfree(cfg.mem);
-- 
2.19.2



[PATCH v2 46/49] input: touchscreen: atmel_mxt_ts: Added sysfs entry for touchscreen status

2019-08-26 Thread Jiada Wang
From: Naveen Chakka 

To know the current communication status of the touch controller during
runtime, sysfs interface is added

sysfs interface: /sys/class/i2c-dev/i2c-*/device/*/touch_dev_stat
Executing the above sysfs interface provides two output values

1)Status of the touch device
value 0 represents device is inactive
value 1 represents device is active
2)Error counter
value represents the number of times device in inactive since last read

Signed-off-by: Naveen Chakka 
Signed-off-by: Sanjeev Chugh 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 109 +--
 1 file changed, 102 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 1187e21a67e4..5a112dfe30e4 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -222,6 +223,7 @@ enum t100_type {
 #define MXT_CHG_DELAY  100 /* msec */
 #define MXT_POWERON_DELAY  150 /* msec */
 #define MXT_BOOTLOADER_WAIT36E5/* 1 minute */
+#define MXT_WATCHDOG_TIMEOUT   1000/* msec */
 
 /* Command to unlock bootloader */
 #define MXT_UNLOCK_CMD_MSB 0xaa
@@ -317,6 +319,12 @@ struct mxt_flash {
struct delayed_work work;
 };
 
+struct mxt_statusinfo {
+   bool dev_status;
+   bool intp_triggered;
+   u32 error_count;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -372,6 +380,9 @@ struct mxt_data {
const char *pcfg_name;
const char *input_name;
struct mxt_flash *flash;
+   struct work_struct watchdog_work;
+   struct timer_list watchdog_timer;
+   struct mxt_statusinfo mxt_status;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -1621,11 +1632,30 @@ static int mxt_process_messages(struct mxt_data *data)
return total_handled;
 }
 
+static void mxt_start_wd_timer(struct mxt_data *data)
+{
+   mod_timer(&data->watchdog_timer, jiffies +
+   msecs_to_jiffies(MXT_WATCHDOG_TIMEOUT));
+}
+
+static void mxt_stop_wd_timer(struct mxt_data *data)
+{
+   /*
+* Ensure we wait until the watchdog timer
+* running on a different CPU finishes
+*/
+   del_timer_sync(&data->watchdog_timer);
+   cancel_work_sync(&data->watchdog_work);
+   del_timer_sync(&data->watchdog_timer);
+}
+
 static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 {
struct mxt_data *data = dev_id;
int ret;
 
+   data->mxt_status.intp_triggered = true;
+
if (data->in_bootloader) {
complete(&data->chg_completion);
 
@@ -1633,21 +1663,25 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
cancel_delayed_work_sync(&data->flash->work);
 
ret = mxt_check_bootloader(data);
-   return IRQ_RETVAL(ret);
+   ret = IRQ_RETVAL(ret);
+   goto exit;
}
 
-   if (!data->object_table)
-   return IRQ_HANDLED;
+   if (!data->object_table) {
+   ret = IRQ_HANDLED;
+   goto exit;
+   }
 
if (data->T44_address)
ret = mxt_process_messages_t44(data);
else
ret = mxt_process_messages(data);
 
-   if (ret <= 0)
-   return IRQ_NONE;
-   else
-   return IRQ_HANDLED;
+   ret = (ret <= 0) ? IRQ_NONE : IRQ_HANDLED;
+
+exit:
+   data->mxt_status.intp_triggered = false;
+   return ret;
 }
 
 static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset,
@@ -2967,6 +3001,36 @@ static int mxt_bootloader_status(struct mxt_data *data)
return 0;
 }
 
+static void mxt_watchdog_timer(struct timer_list *t)
+{
+   struct mxt_data *data = from_timer(data, t, watchdog_timer);
+
+   if (!work_pending(&data->watchdog_work)) {
+   if (!data->mxt_status.intp_triggered)
+   schedule_work(&data->watchdog_work);
+   }
+
+   mxt_start_wd_timer(data);
+}
+
+static void mxt_watchdog_work(struct work_struct *work)
+{
+   struct mxt_data *data =
+   container_of(work, struct mxt_data, watchdog_work);
+   u16 info_buf;
+   int ret = 0;
+   u8 size = 2;
+
+   ret = __mxt_read_reg(data->client, 0, size, &info_buf);
+
+   if (ret) {
+   data->mxt_status.error_count++;
+   data->mxt_status.dev_status = false;
+   } else {
+   data->mxt_status.dev_status = true;
+   }
+}
+
 static int mxt_initialize(struct mxt_data *data)
 {
struct i2c_client *client = data->client;
@@ -3944,6 +4008,22 @@ static const struct attribute_group mxt_fw_attr_group = {
.attrs = mxt_fw_attrs,
 };
 
+static ssize_t m

[PATCH v2 45/49] Input: atmel_mxt_ts: use gpiod_set_value_cansleep for reset pin

2019-08-26 Thread Jiada Wang
From: Balasubramani Vivekanandan 

In case of remote display, touch controller will be also remote.
In such cases, the reset pin of the touch controller will be
controlled through bridging ICs like Deserilizer and Serializer.
Therefore accessing the gpio pins require transactions with the
external IC. Using the function gpiod_set_value will print a
warning like below

WARNING: CPU: 0 PID: 576 at drivers/gpio/gpiolib.c:1441 
gpiod_set_value+0x34/0x60()
CPU: 0 PID: 576 Comm: modprobe Not tainted 3.14.79-08377-g84ea22f-dirty #4
Backtrace:
[<80011c58>] (dump_backtrace) from [<80011e60>] (show_stack+0x18/0x1c)
[<80011e48>] (show_stack) from [<8052d7ac>] (dump_stack+0x7c/0x9c)
[<8052d730>] (dump_stack) from [<800241bc>] (warn_slowpath_common+0x74/0x9c)
[<80024148>] (warn_slowpath_common) from [<80024288>] 
(warn_slowpath_null+0x24/0x2c)
[<80024264>] (warn_slowpath_null) from [<8029e070>] (gpiod_set_value+0x34/0x60)
[<8029e03c>] (gpiod_set_value) from [<7f492e98>] (mxt_probe+0x1e0/0x718 
[atmel_mxt_ts])
[<7f492cb8>] (mxt_probe [atmel_mxt_ts]) from [<803c4d34>] 
(i2c_device_probe+0xcc/0xec)
[<803c4c68>] (i2c_device_probe) from [<803252a0>] 
(driver_probe_device+0xc0/0x200)

Signed-off-by: Balasubramani Vivekanandan 

Signed-off-by: Vladimir Zapolskiy 
Signed-off-by: Sanjeev Chugh 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 58e54eb45cf0..1187e21a67e4 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2487,7 +2487,7 @@ static void mxt_regulator_enable(struct mxt_data *data)
if (!data->reg_vdd || !data->reg_avdd)
return;
 
-   gpiod_set_value(data->reset_gpio, 0);
+   gpiod_set_value_cansleep(data->reset_gpio, 0);
 
error = regulator_enable(data->reg_vdd);
if (error)
@@ -2505,7 +2505,7 @@ static void mxt_regulator_enable(struct mxt_data *data)
 * voltage
 */
msleep(MXT_REGULATOR_DELAY);
-   gpiod_set_value(data->reset_gpio, 1);
+   gpiod_set_value_cansleep(data->reset_gpio, 1);
msleep(MXT_CHG_DELAY);
 
 retry_wait:
@@ -4311,7 +4311,7 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
disable_irq(data->irq);
} else if (data->reset_gpio) {
msleep(MXT_RESET_GPIO_TIME);
-   gpiod_set_value(data->reset_gpio, 1);
+   gpiod_set_value_cansleep(data->reset_gpio, 1);
msleep(MXT_RESET_INVALID_CHG);
} else {
dev_dbg(&client->dev,
-- 
2.19.2



[PATCH v2 47/49] input: atmel_mxt_ts: added sysfs interface to update atmel T38 data

2019-08-26 Thread Jiada Wang
From: Naveen Chakka 

Atmel touch controller contains T38 object where a user can store its own
data of length 64 bytes. T38 data will not be part of checksum
calculation on executing T6 BACKUP command.

format used to update the T38 data is given below:

  

offset: offset address of the data to be written in the t38 object
(in decimal)

length: length of the data to be written into the t38 object(in decimal)

data: actual data bytes to be written into the t38 object
  (values should be in hex)

Ex:
1. 0 2 10 20
updates first two bytes of the t38 data with values 10 and 20

2. 19 6 10 2f 30 4a 50 60
updates 6 bytes of t38 data from the index 19-24 with hex values

Signed-off-by: Naveen Chakka 
Signed-off-by: Sanjeev Chugh 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 102 +++
 1 file changed, 102 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5a112dfe30e4..63ff8a211a90 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -4024,6 +4024,106 @@ static ssize_t mxt_touch_device_status(struct device 
*dev, struct
return ret;
 }
 
+static ssize_t mxt_t38_data_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   struct mxt_data *data = dev_get_drvdata(dev);
+   struct mxt_object *object;
+   size_t count = 0, size;
+   u8 i, *t38_buf;
+
+   if (!data->object_table)
+   return -ENXIO;
+
+   object = mxt_get_object(data, MXT_SPT_USERDATA_T38);
+   size = mxt_obj_size(object);
+
+   /* Pre-allocate buffer large enough to hold max size of t38 object.*/
+   t38_buf = kmalloc(size, GFP_KERNEL);
+   if (!t38_buf)
+   return -ENOMEM;
+
+   count = __mxt_read_reg(data->client, object->start_address,
+  size, t38_buf);
+   if (count)
+   goto end;
+
+   for (i = 0; i < size; i++)
+   count += scnprintf(buf + count, PAGE_SIZE - count,
+  "[%2u]: %02x\n", i, t38_buf[i]);
+   count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
+end:
+   kfree(t38_buf);
+   return count;
+}
+
+static ssize_t mxt_t38_data_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+   struct mxt_data *data = dev_get_drvdata(dev);
+   struct mxt_object *object;
+   ssize_t ret = 0, pos, offset;
+   unsigned int i, len, index;
+   u8 *t38_buf;
+
+   if (!data->object_table)
+   return -ENXIO;
+
+   object = mxt_get_object(data, MXT_SPT_USERDATA_T38);
+
+   /* Pre-allocate buffer large enough to hold max size of t38 object.*/
+   t38_buf = kmalloc(mxt_obj_size(object), GFP_KERNEL);
+   if (!t38_buf)
+   return -ENOMEM;
+
+   ret = sscanf(buf, "%zd %d%zd", &offset, &len, &pos);
+   if (ret != 2) {
+   dev_err(dev, "Bad format: Invalid parameter to update t38\n");
+   ret = -EINVAL;
+   goto end;
+   }
+
+   if (len == 0) {
+   dev_err(dev,
+   "Bad format: Data length should not be equal to 0\n");
+   ret = -EINVAL;
+   goto end;
+   }
+
+   if (offset < 0 || ((offset + len) > 64)) {
+   dev_err(dev, "Invalid offset value to update t38\n");
+   ret = -EINVAL;
+   goto end;
+   }
+
+   index = pos;
+   for (i = 0; i < len; i++) {
+   ret = sscanf(buf + index, "%hhx%zd", t38_buf + i, &pos);
+   if (ret != 1) {
+   dev_err(dev, "Bad format: Invalid Data\n");
+   ret = -EINVAL;
+   goto end;
+   }
+   index += pos;
+   }
+
+   ret = __mxt_write_reg(data->client, object->start_address + offset,
+ len, t38_buf);
+   if (ret)
+   goto end;
+
+   ret = mxt_t6_command(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE,
+true);
+   if (ret)
+   dev_err(dev, "backup command failed\n");
+   else
+   ret = count;
+end:
+   kfree(t38_buf);
+   return ret;
+}
+
 static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
 static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
 static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
@@ -4036,6 +4136,7 @@ static DEVICE_ATTR(debug_v2_enable, S_IWUSR | S_IRUSR, 
NULL,
 static DEVICE_ATTR(debug_notify, S_IRUGO, mxt_debug_notify_show, NULL);
 static DEVICE_ATTR(t25, 0600, mxt_t25_selftest_show, mxt_t25_selftest_store);
 static DEVICE_ATTR(touch_dev_stat, 0444, mxt_touch_device_status, NULL);
+static DEVIC

[PATCH v2 42/49] Input: Atmel: Improve error handling in mxt_initialize_input_device()

2019-08-26 Thread Jiada Wang
From: Deepak Das 

Currently Driver probe continues with a warning message when it fails to
get the proper multitouch object configurations like TouchScreen resolution.
But Driver probe should fail in case of above scneario because it will not 
behave
as expected without the proper touchscreen configurations.

This commit modifies mxt_initialize_input_device() to return error when it fails
to get the proper touch screen configurations.

Signed-off-by: Deepak Das 
Signed-off-by: Dean Jenkins 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 716b91e6fd66..41d92d765aa2 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2759,15 +2759,19 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
case MXT_TOUCH_MULTI_T9:
num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 
1;
error = mxt_read_t9_resolution(data);
-   if (error)
-   dev_warn(dev, "Failed to initialize T9 resolution\n");
+   if (error) {
+   dev_err(dev, "Failed to initialize T9 resolution\n");
+   return error;
+   }
break;
 
case MXT_TOUCH_MULTITOUCHSCREEN_T100:
num_mt_slots = data->num_touchids;
error = mxt_read_t100_config(data);
-   if (error)
-   dev_warn(dev, "Failed to read T100 config\n");
+   if (error) {
+   dev_err(dev, "Failed to read T100 config\n");
+   return error;
+   }
break;
 
default:
-- 
2.19.2



[PATCH v2 40/49] Input: Atmel: improve error handling in mxt_initialize()

2019-08-26 Thread Jiada Wang
From: Deepak Das 

Currently mxt_initialize() tries to probe bootloader mode
even if valid bootloader address is not specified.

This commit modifies mxt_initialize() to return error
if Device is not in appmode and bootloader address is
not specified.

This commit also returns error code from mxt_send_bootloader_cmd()
in mxt_initialize().

Signed-off-by: Deepak Das 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 58 +---
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index dd70f3b9678f..59533753a431 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -713,17 +713,13 @@ static int mxt_lookup_bootloader_address(struct mxt_data 
*data, bool retry)
return 0;
 }
 
-static int mxt_probe_bootloader(struct mxt_data *data, bool alt_address)
+static int mxt_probe_bootloader(struct mxt_data *data)
 {
struct device *dev = &data->client->dev;
int error;
u8 buf[3];
bool crc_failure, extended_id;
 
-   error = mxt_lookup_bootloader_address(data, alt_address);
-   if (error)
-   return error;
-
/* Check bootloader status and version information */
error = mxt_bootloader_read(data, buf, sizeof(buf));
if (error)
@@ -2920,6 +2916,32 @@ static void mxt_config_cb(const struct firmware *cfg, 
void *ctx)
release_firmware(cfg);
 }
 
+static int mxt_bootloader_status(struct mxt_data *data)
+{
+   struct i2c_client *client = data->client;
+   int error;
+
+   error = mxt_lookup_bootloader_address(data, false);
+   if (error) {
+   dev_info(&client->dev,
+"Bootloader address is not specified\n");
+   return error;
+   }
+   /* Check bootloader state */
+   error = mxt_probe_bootloader(data);
+   if (error) {
+   dev_info(&client->dev, "Trying alternate bootloader address\n");
+   mxt_lookup_bootloader_address(data, true);
+   error = mxt_probe_bootloader(data);
+   if (error) {
+   dev_err(&client->dev,
+   "Chip is not in appmode or bootloader mode\n");
+   return error;
+   }
+   }
+   return 0;
+}
+
 static int mxt_initialize(struct mxt_data *data)
 {
struct i2c_client *client = data->client;
@@ -2931,16 +2953,13 @@ static int mxt_initialize(struct mxt_data *data)
if (!error)
break;
 
-   /* Check bootloader state */
-   error = mxt_probe_bootloader(data, false);
-   if (error) {
-   dev_info(&client->dev, "Trying alternate bootloader 
address\n");
-   error = mxt_probe_bootloader(data, true);
-   if (error) {
-   /* Chip is not in appmode or bootloader mode */
-   return error;
-   }
-   }
+   dev_info(&client->dev,
+"info block read failed (%d), so try bootloader 
method\n",
+error);
+
+   error = mxt_bootloader_status(data);
+   if (error)
+   return error;
 
/* OK, we are in bootloader, see if we can recover */
if (++recovery_attempts > 1) {
@@ -2954,7 +2973,9 @@ static int mxt_initialize(struct mxt_data *data)
}
 
/* Attempt to exit bootloader into app mode */
-   mxt_send_bootloader_cmd(data, false);
+   error = mxt_send_bootloader_cmd(data, false);
+   if (error)
+   return error;
msleep(MXT_FW_RESET_TIME);
}
 
@@ -3646,8 +3667,11 @@ static int mxt_enter_bootloader(struct mxt_data *data)
 
msleep(MXT_RESET_TIME);
 
+   ret = mxt_lookup_bootloader_address(data, false);
+   if (ret)
+   return ret;
/* Do not need to scan since we know family ID */
-   ret = mxt_probe_bootloader(data, 0);
+   ret = mxt_probe_bootloader(data);
if (ret)
return ret;
 
-- 
2.19.2



[PATCH v2 36/49] Input: atmel_mxt_ts: Add support for run self-test routine.

2019-08-26 Thread Jiada Wang
From: Nikhil Ravindran 

The self test object T25 runs self test routines in device to find faults
Sysfs entry add to start self test routine and read back the test results
for atmel touchcontrollers.The feature will be used for A-IVI and CAF projects.

Signed-off-by: Nikhil Ravindran 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 111 +++
 1 file changed, 111 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 192cf47ff5f4..aa33962ed1dc 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -336,6 +336,9 @@ struct mxt_data {
u8 t100_aux_ampl;
u8 t100_aux_area;
u8 t100_aux_vect;
+   u16 T25_address;
+   u8  T25_reportid;
+   u8  t25_msg[6];
bool debug_enabled;
bool debug_v2_enabled;
u8 *debug_msg_data;
@@ -413,6 +416,8 @@ struct mxt_data {
 
/* Indicates whether device is updating configuration */
bool updating_config;
+
+   bool t25_status;
 };
 
 struct mxt_vb2_buffer {
@@ -1356,6 +1361,24 @@ static void mxt_proc_t93_messages(struct mxt_data *data, 
u8 *msg)
dev_info(dev, "T93 report double tap %d\n", status);
 }
 
+static void mxt_proc_t25_messages(struct mxt_data *data, u8 *msg)
+{
+   struct device *dev = &data->client->dev;
+
+   /* Output debug if status has changed */
+   dev_dbg(dev, "T25 Status 0x%x Info: %x %x %x %x %x\n",
+   msg[1],
+   msg[2],
+   msg[3],
+   msg[4],
+   msg[5],
+   msg[6]);
+
+   /* Save current status */
+   memcpy(&data->t25_msg[0], &msg[1], sizeof(data->t25_msg));
+   data->t25_status = false;
+}
+
 static int mxt_proc_message(struct mxt_data *data, u8 *message)
 {
u8 report_id = message[0];
@@ -1386,6 +1409,8 @@ static int mxt_proc_message(struct mxt_data *data, u8 
*message)
} else if (report_id == data->T19_reportid) {
mxt_input_button(data, message);
data->update_input = true;
+   } else if (report_id == data->T25_reportid) {
+   mxt_proc_t25_messages(data, message);
} else if (report_id >= data->T15_reportid_min
   && report_id <= data->T15_reportid_max) {
mxt_proc_t15_messages(data, message);
@@ -1610,6 +1635,84 @@ static int mxt_t6_command(struct mxt_data *data, u16 
cmd_offset,
return 0;
 }
 
+static int mxt_t25_command(struct mxt_data *data, u8 cmd, bool wait)
+{
+   u16 reg;
+   int timeout_counter = 0;
+   int ret;
+   u8  val[2];
+
+   reg = data->T25_address;
+   val[0] = 0x3;
+   val[1] = cmd;
+
+   data->t25_status = true;
+   ret = __mxt_write_reg(data->client, reg, sizeof(val), val);
+   if (ret) {
+   data->t25_status = false;
+   return ret;
+   }
+
+   if (!wait)
+   return 0;
+
+   do {
+   msleep(MXT_WAKEUP_TIME);
+   ret = __mxt_read_reg(data->client, reg + 1, 1, &val[1]);
+   if (ret)
+   return ret;
+   } while ((val[1] != 0) && (timeout_counter++ <= 100));
+
+   if (timeout_counter > 100) {
+   dev_err(&data->client->dev, "Command failed!\n");
+   data->t25_status = false;
+   return -EIO;
+   }
+   return 0;
+}
+
+/* Firmware Version is returned as Major.Minor.Build */
+static ssize_t mxt_t25_selftest_show(struct device *dev, struct
+device_attribute *attr, char *buf)
+{
+   struct mxt_data *data = dev_get_drvdata(dev);
+   ssize_t offset = 0;
+
+   if (data->t25_status)
+   return -EAGAIN;
+
+   if (data->t25_msg[0] == 0xFE)
+   offset += scnprintf(buf, PAGE_SIZE, "PASS\n");
+   else
+   offset += scnprintf(buf, PAGE_SIZE, "FAILED\n");
+
+   offset += scnprintf(buf + offset, PAGE_SIZE, "%x %x %x %x %x %x\n",
+data->t25_msg[0],
+data->t25_msg[1],
+data->t25_msg[2],
+data->t25_msg[3],
+data->t25_msg[4],
+data->t25_msg[5]);
+   return offset;
+}
+
+static ssize_t mxt_t25_selftest_store(struct device *dev, struct
+ device_attribute *attr, const char *buf,
+ size_t count)
+{
+   struct mxt_data *data = dev_get_drvdata(dev);
+   u32 cmd;
+
+   if (sscanf(buf, "%x", &cmd) == 1) {
+   if (mxt_t25_command(data, (u8)cmd, 1) == 0)
+   return count;
+
+   dev_dbg(dev, "mxt_t25_cmd_store write cmd %x error\n", cmd);
+   return -EINVAL;
+   }
+   return 0;
+}
+
 static int mxt_acquire_irq(struct mxt_data *data)
 {
int error;
@@ -2088,6 +2

[PATCH v2 32/49] Input: atmel_mxt_ts - Change call-points of mxt_free_* functions

2019-08-26 Thread Jiada Wang
From: Kautuk Consul 

Revamping the code to call mxt_free_object_table and mxt_free_input_device
functions only in the following scenarios and code paths:
1) The error path of the mxt_probe() entry point
2) The mxt_remove de-init path entry point
3) All paths which definitely expect to populate the object table
   like:
   - the mxt_update_fw_store path which first calls
 mxt_load_fw and then resorts to calling mxt_initialize itself.
   - the mxt_read_info_block function which attempts to fill in the
 object table itself as the main non-error part of the logic.
4) All paths in the code expected to definitely allocate and register
   the input device such as:
   - the mxt_update_fw_store path which first calls
 mxt_load_fw and then resorts to calling mxt_initialize itself.
   - the mxt_update_cfg_store function which will call
 mxt_configure_objects.

Signed-off-by: Kautuk Consul 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index f6d65930885a..f8e80471be8a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3336,21 +3336,21 @@ static int mxt_configure_objects(struct mxt_data *data,
error = mxt_init_t7_power_cfg(data);
if (error) {
dev_err(dev, "Failed to initialize power cfg\n");
-   goto err_free_object_table;
+   return error;
}
 
if (cfg) {
error = mxt_update_cfg(data, cfg);
if (error) {
dev_warn(dev, "Error %d updating config\n", error);
-   goto err_free_object_table;
+   return error;
}
}
 
if (data->multitouch) {
error = mxt_initialize_input_device(data);
if (error)
-   goto err_free_object_table;
+   return error;
} else {
dev_warn(dev, "No touch object detected\n");
}
@@ -3358,10 +3358,6 @@ static int mxt_configure_objects(struct mxt_data *data,
mxt_debug_init(data);
 
return 0;
-
-err_free_object_table:
-   mxt_free_object_table(data);
-   return error;
 }
 
 /* Configuration crc check sum is returned as hex xx */
@@ -4098,16 +4094,21 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
 
error = mxt_initialize(data);
if (error)
-   return error;
+   goto err_free_object;
 
error = sysfs_create_group(&client->dev.kobj, &mxt_fw_attr_group);
if (error) {
dev_err(&client->dev, "Failure %d creating fw sysfs group\n",
error);
-   return error;
+   goto err_free_object;
}
 
return 0;
+
+err_free_object:
+   mxt_free_input_device(data);
+   mxt_free_object_table(data);
+   return error;
 }
 
 static int mxt_remove(struct i2c_client *client)
-- 
2.19.2



[PATCH v2 31/49] Input: atmel_mxt_ts - eliminate data->raw_info_block

2019-08-26 Thread Jiada Wang
Dynamically allocated in mxt_read_info_block() buffer buf is assigned
both to data->info and data->raw_info_block, having both data->info
and data->raw_info_block is redundant and confusing.

This patch eliminates data->raw_info_block.

Signed-off-by: Jiada Wang 
Signed-off-by: George G. Davis 
Signed-off-by: Vladimir Zapolskiy 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2d9d2c1e39dd..f6d65930885a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -323,7 +323,6 @@ struct mxt_data {
char phys[64];  /* device physical location */
struct mxt_object *object_table;
struct mxt_info *info;
-   void *raw_info_block;
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
@@ -2067,9 +2066,8 @@ static void mxt_free_object_table(struct mxt_data *data)
v4l2_device_unregister(&data->dbg.v4l2);
 #endif
data->object_table = NULL;
+   kfree(data->info);
data->info = NULL;
-   kfree(data->raw_info_block);
-   data->raw_info_block = NULL;
kfree(data->msg_buf);
data->msg_buf = NULL;
data->T5_address = 0;
@@ -2238,7 +2236,7 @@ static int mxt_read_info_block(struct mxt_data *data)
u8 *crc_ptr;
 
/* If info block already allocated, free it */
-   if (data->raw_info_block)
+   if (data->info)
mxt_free_object_table(data);
 
/* Read 7-byte ID information block starting at address 0 */
@@ -2289,7 +2287,6 @@ static int mxt_read_info_block(struct mxt_data *data)
goto err_free_mem;
}
 
-   data->raw_info_block = id_buf;
data->info = (struct mxt_info *)id_buf;
 
dev_info(&client->dev,
-- 
2.19.2



[PATCH v2 28/49] Input: atmel_mxt_ts - orientation is not present in hover

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

When in hover, the orientation information is not sent

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
0c885d5bd276bd9240c43aa046fc407cbe2ae864)
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5b7ab798f27d..2d2e8ea30547 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1029,10 +1029,6 @@ static void mxt_proc_t100_message(struct mxt_data *data, 
u8 *message)
distance = MXT_DISTANCE_HOVERING;
hover = true;
active = true;
-
-   if (data->t100_aux_vect)
-   orientation = message[data->t100_aux_vect];
-
break;
 
case MXT_T100_TYPE_FINGER:
-- 
2.19.2



[PATCH v2 35/49] input: atmel_mxt_ts: Add Missing Delay for reset handling of Atmel touch panel controller in detachable displays.

2019-08-26 Thread Jiada Wang
From: keerthikumarp 

In case of attached display, the touchpanel reset is controlled
via imx gpio's from  atmel driver and the delay between
touchpanel reset and the time at which the chip becomes capable to
communicate with the host processor, has be taken care.

However in case of detachable displays, the touchpanel reset is
controlled via a deserializer gpio which is triggered just before
the atmel driver is probed.The delay between touchpanel reset and
the time at which the chip becomes capable to communicate (as
specified in datasheet) was not being accounted for. This patch
introduces that delay.

Signed-off-by: keerthikumarp 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 35f41bfa70d5..192cf47ff5f4 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -4110,6 +4110,10 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
msleep(MXT_RESET_GPIO_TIME);
gpiod_set_value(data->reset_gpio, 1);
msleep(MXT_RESET_INVALID_CHG);
+   } else {
+   dev_dbg(&client->dev,
+   "atmel reset pin not found in device tree");
+   msleep(MXT_RESET_TIME);
}
 
error = mxt_initialize(data);
-- 
2.19.2



[PATCH v2 39/49] Input: Atmel: improve error handling in mxt_start()

2019-08-26 Thread Jiada Wang
From: Deepak Das 

mxt_start() does not return error in any of
the failure cases which will allow input_dev->open()
to return success even in case of any failure.

This commit modifies mxt_start() to return error
in failure cases.

Signed-off-by: Deepak Das 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 31 
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index e9a895473ed8..dd70f3b9678f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3971,12 +3971,13 @@ static int mxt_start(struct mxt_data *data)
 
switch (data->suspend_mode) {
case MXT_SUSPEND_T9_CTRL:
-   mxt_soft_reset(data);
-
+   ret = mxt_soft_reset(data);
+   if (ret)
+   break;
/* Touch enable */
/* 0x83 = SCANEN | RPTEN | ENABLE */
-   mxt_write_object(data,
-   MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0x83);
+   ret = mxt_write_object(data,
+  MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0x83);
break;
 
case MXT_SUSPEND_REGULATOR:
@@ -3990,27 +3991,26 @@ static int mxt_start(struct mxt_data *data)
 * Discard any touch messages still in message buffer
 * from before chip went to sleep
 */
-   mxt_process_messages_until_invalid(data);
+   ret = mxt_process_messages_until_invalid(data);
+   if (ret)
+   break;
 
ret = mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
if (ret)
-   return ret;
+   break;
 
/* Recalibrate since chip has been in deep sleep */
ret = mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
if (ret)
-   return ret;
+   break;
 
ret = mxt_acquire_irq(data);
-   if (ret)
-   return ret;
-
-   break;
}
 
-   data->suspended = false;
+   if (!ret)
+   data->suspended = false;
 
-   return 0;
+   return ret;
 }
 
 static int mxt_stop(struct mxt_data *data)
@@ -4331,6 +4331,7 @@ static int __maybe_unused mxt_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct mxt_data *data = i2c_get_clientdata(client);
struct input_dev *input_dev = data->input_dev;
+   int ret = 0;
 
if (!input_dev)
return 0;
@@ -4338,11 +4339,11 @@ static int __maybe_unused mxt_resume(struct device *dev)
mutex_lock(&input_dev->mutex);
 
if (input_dev->users)
-   mxt_start(data);
+   ret = mxt_start(data);
 
mutex_unlock(&input_dev->mutex);
 
-   return 0;
+   return ret;
 }
 
 static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
-- 
2.19.2



[PATCH v2 37/49] Input: atmel_mxt_ts: Limit the max bytes transferred in an i2c transaction

2019-08-26 Thread Jiada Wang
From: Balasubramani Vivekanandan 

In mxt_process_messages_until_invalid() function, driver tries to read
all possible reportid in a single i2c transaction. Number of bytes read
is limited by the max_reportid parameter.
If the max_reportid is a very large value, then a large chunk of bytes
will be requested from the controller in a single i2c transaction.
This transaction can fail due to timeout. This is visible when the
Atmel controller is connected to the SOC via a i2c mux hardware.

mxt_process_messages_t44() reads the T44 message which contains the
pending T5 message count. If the number of pending T5 messages returned
by T44 message is too high then there is a risk of i2c transaction
timeout while reading T5 messages in mxt_process_messages_t44().

New property 'atmel,mtu' is created. This property limits the maximum
number of bytes that can read/transferred in an i2c transcation

Signed-off-by: Balasubramani Vivekanandan 

Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 .../bindings/input/atmel,maxtouch.txt |  3 +
 drivers/input/touchscreen/atmel_mxt_ts.c  | 65 +++
 2 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt 
b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
index d7db16920083..62c93d94bc5d 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
@@ -42,6 +42,8 @@ Optional properties for main touchpad device:
 
 - atmel,input_name: Override name of input device from the default.
 
+- atmel,mtu: Maximum number of bytes that can read/transferred in an i2c 
transaction
+
 Example:
 
touch@4b {
@@ -49,4 +51,5 @@ Example:
reg = <0x4b>;
interrupt-parent = <&gpio>;
interrupts = ;
+   atmel,mtu = <200>
};
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index aa33962ed1dc..169107413823 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -417,6 +417,7 @@ struct mxt_data {
/* Indicates whether device is updating configuration */
bool updating_config;
 
+   unsigned int mtu;
bool t25_status;
 };
 
@@ -1462,11 +1463,32 @@ static int mxt_read_and_process_messages(struct 
mxt_data *data, u8 count)
return num_valid;
 }
 
+static u8 mxt_max_msg_read_count(struct mxt_data *data, u8 max_T5_msg_count)
+{
+   u8 T5_msg_count_limit = data->mtu / data->T5_msg_size;
+
+   if (!data->mtu)
+   return max_T5_msg_count;
+
+   if (data->mtu < data->T5_msg_size) {
+   WARN(1, "mtu set is lesser than the T5 message size\n");
+   /* Return count of 1, as fallback */
+   return 1;
+   }
+   /*
+* Return maximum number of T5 messages in single i2c transaction
+* based on "atmel,mtu" property.
+*/
+   return min(T5_msg_count_limit, max_T5_msg_count);
+}
+
 static irqreturn_t mxt_process_messages_t44(struct mxt_data *data)
 {
struct device *dev = &data->client->dev;
int ret;
-   u8 count, num_left;
+   u8 T5_msg_count, total_pending;
+   u8 total_processed = 0;
+   u8 processed_valid = 0;
 
/* Read T44 and T5 together */
ret = __mxt_read_reg(data->client, data->T44_address,
@@ -1476,18 +1498,19 @@ static irqreturn_t mxt_process_messages_t44(struct 
mxt_data *data)
return IRQ_NONE;
}
 
-   count = data->msg_buf[0];
+   T5_msg_count = data->msg_buf[0];
 
/*
 * This condition may be caused by the CHG line being configured in
 * Mode 0. It results in unnecessary I2C operations but it is benign.
 */
-   if (count == 0)
+   if (!T5_msg_count)
return IRQ_NONE;
 
-   if (count > data->max_reportid) {
-   dev_warn(dev, "T44 count %d exceeded max report id\n", count);
-   count = data->max_reportid;
+   if (T5_msg_count > data->max_reportid) {
+   dev_warn(dev, "T44 count %d exceeded max report id\n",
+T5_msg_count);
+   T5_msg_count = data->max_reportid;
}
 
/* Process first message */
@@ -1497,16 +1520,25 @@ static irqreturn_t mxt_process_messages_t44(struct 
mxt_data *data)
return IRQ_NONE;
}
 
-   num_left = count - 1;
+   total_pending = T5_msg_count - 1;
+   if (!total_pending)
+   goto end;
 
/* Process remaining messages if necessary */
-   if (num_left) {
-   ret = mxt_read_and_process_messages(data, num_left);
+   T5_msg_count = mxt_max_msg_read_count(data, total_pending);
+
+   do {
+   if ((total_pending - total_processed) < T5_msg_count)
+   T5_msg_count = total_pending - total_p

[PATCH v2 38/49] Input: atmel_mxt_ts: return error from mxt_process_messages_until_invalid()

2019-08-26 Thread Jiada Wang
From: Dean Jenkins 

mxt_process_messages_until_invalid() failed to propagate the error
code from mxt_read_and_process_messages() so return the error code.

Signed-off-by: Dean Jenkins 
Signed-off-by: Deepak Das 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 169107413823..e9a895473ed8 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1561,6 +1561,8 @@ static int mxt_process_messages_until_invalid(struct 
mxt_data *data)
/* Read messages until we force an invalid */
do {
read = mxt_read_and_process_messages(data, count);
+   if (read < 0)
+   return read;
if (read < count)
return 0;
} while (--tries);
-- 
2.19.2



[PATCH v2 33/49] Input: atmel_mxt_ts - rely on calculated_crc rather than file config_crc

2019-08-26 Thread Jiada Wang
From: Kautuk Consul 

We now prefer to rely on the calculated CRC and not on the CRC stored in
the file.

The new logic is as follows:
1) stored CRC of file != calculated CRC of file, then refuse the possible
   corrupted file
2) calculated CRC of file != CRC of configuration in controller, then
   update configuration in controller
3) calculated CRC of file == CRC of configuration in controller, then
   ignore configuration file

Signed-off-by: Kautuk Consul 
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 65 +---
 1 file changed, 36 insertions(+), 29 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index f8e80471be8a..560d46634bae 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1905,7 +1905,7 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
int ret;
int offset;
int i;
-   u32 info_crc, config_crc, calculated_crc;
+   u32 info_crc, config_crc, calculated_crc = 0;
u16 crc_start = 0;
 
/* Make zero terminated copy of the OBP_RAW file */
@@ -1968,30 +1968,6 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
}
cfg.raw_pos += offset;
 
-   /*
-* The Info Block CRC is calculated over mxt_info and the object
-* table. If it does not match then we are trying to load the
-* configuration from a different chip or firmware version, so
-* the configuration CRC is invalid anyway.
-*/
-   if (info_crc == data->info_crc) {
-   if (config_crc == 0 || data->config_crc == 0) {
-   dev_info(dev, "CRC zero, attempting to apply config\n");
-   } else if (config_crc == data->config_crc) {
-   dev_dbg(dev, "Config CRC 0x%06X: OK\n",
-data->config_crc);
-   ret = 0;
-   goto release_raw;
-   } else {
-   dev_info(dev, "Config CRC 0x%06X: does not match file 
0x%06X\n",
-data->config_crc, config_crc);
-   }
-   } else {
-   dev_warn(dev,
-"Warning: Info CRC error - device=0x%06X 
file=0x%06X\n",
-data->info_crc, info_crc);
-   }
-
/* Malloc memory to store configuration */
cfg.start_ofs = MXT_OBJECT_START +
data->info->object_num * sizeof(struct mxt_object) +
@@ -2015,14 +1991,45 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
else
dev_warn(dev, "Could not find CRC start\n");
 
-   if (crc_start > cfg.start_ofs) {
+   if (crc_start > cfg.start_ofs)
calculated_crc = mxt_calculate_crc(cfg.mem,
   crc_start - cfg.start_ofs,
   cfg.mem_size);
 
-   if (config_crc > 0 && config_crc != calculated_crc)
-   dev_warn(dev, "Config CRC in file inconsistent, 
calculated=%06X, file=%06X\n",
-calculated_crc, config_crc);
+   /* If the CRC stored in the file is not the same as what
+* was calculated by mxt_calculate_crc, this means we
+* have to refuse the config file and abort download.
+*/
+   if (config_crc != calculated_crc) {
+   dev_warn(dev,
+"Config CRC in file inconsistent, calculated=%06X, 
file=%06X\n",
+calculated_crc, config_crc);
+   ret = 0;
+   goto release_mem;
+   }
+
+   /*
+* The Info Block CRC is calculated over mxt_info and the object
+* table. If it does not match then we are trying to load the
+* configuration from a different chip or firmware version, so
+* the configuration CRC is invalid anyway.
+*/
+   if (info_crc == data->info_crc) {
+   if (config_crc == 0 || data->config_crc == 0) {
+   dev_info(dev, "CRC zero, attempting to apply config\n");
+   } else if (config_crc == data->config_crc) {
+   dev_dbg(dev, "Config CRC 0x%06X: OK\n",
+   data->config_crc);
+   ret = 0;
+   goto release_mem;
+   } else {
+   dev_info(dev, "Config CRC 0x%06X: does not match file 
0x%06X\n",
+data->config_crc, config_crc);
+   }
+   } else {
+   dev_warn(dev,
+"Warning: Info CRC error - device=0x%06X 
file=0x%06X\n",
+data->info_crc, info_crc);
}
 
ret = mxt_upload_cfg_mem

[PATCH v2 30/49] Input: atmel_mxt_ts - implement improved debug message interface

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
078569c13c88dcb6f8d882bfe17168587712df7d)
[gdavis: Resolve forward port conflicts due to v4.14.51 commit
 960fe000b1d3 ("Input: atmel_mxt_ts - fix the firmware
 update").]
Signed-off-by: George G. Davis 
[gdavis: Squash fixes from Dirk Behme:
 - Input: atmel_mxt_ts - add missing unlock in error path
 - Input: atmel_mxt_ts - add missing unlock in error path
 - Input: atmel_mxt_ts - call mxt_debug_msg_remove() in error path
 - Input: atmel_mxt_ts - protect debug_v2_enabled by mutex
Signed-off-by: Dirk Behme 
[gdavis: Squash fix from Vladimir Zapolskiy:
 - Input: atmel_mxt_ts - simplify debug_msg binary attribute
   handling]
Signed-off-by: Vladimir Zapolskiy 
---
Notes:
- Squash fixes from Dirk Behme:
  + Input: atmel_mxt_ts - add missing unlock in error path

Unlock the mutex in case the function is exited in the error case.
  + Input: atmel_mxt_ts - add missing unlock in error path
  + Input: atmel_mxt_ts - protect debug_v2_enabled by mutex

Put the modification of debug_v2_enabled into the protected section.
Same as in mxt_debug_msg_enable().
  + Input: atmel_mxt_ts - call mxt_debug_msg_remove() in error path

Add the missing mxt_debug_msg_remove() to the error path.
- Squash fix from Vladimir Zapolskiy:
  + Input: atmel_mxt_ts - simplify debug_msg binary attribute handling

The change introduces several updates, but all of them are related to
"debug_msg" binary attribute:

* removed dynamic initialization of data->debug_msg_attr
* removed mxt_debug_msg_write callback
* removed wrong check in mxt_debug_msg_remove()
* mxt_debug_msg_remove() now is not called from mxt_free_object_table()
  avoiding multiple double deallocations.

[jiada: Add NULL check for sysfs attribute debug_msg_attr]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 194 ++-
 1 file changed, 192 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 941c6970cb70..2d9d2c1e39dd 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -242,6 +242,8 @@ enum t100_type {
 
 #define MXT_PIXELS_PER_MM  20
 
+#define DEBUG_MSG_MAX  200
+
 struct mxt_info {
u8 family_id;
u8 variant_id;
@@ -336,6 +338,11 @@ struct mxt_data {
u8 t100_aux_area;
u8 t100_aux_vect;
bool debug_enabled;
+   bool debug_v2_enabled;
+   u8 *debug_msg_data;
+   u16 debug_msg_count;
+   struct bin_attribute *debug_msg_attr;
+   struct mutex debug_msg_lock;
u8 max_reportid;
u32 config_crc;
u32 info_crc;
@@ -465,6 +472,144 @@ static void mxt_dump_message(struct mxt_data *data, u8 
*message)
   data->T5_msg_size, message);
 }
 
+static void mxt_debug_msg_enable(struct mxt_data *data)
+{
+   struct device *dev = &data->client->dev;
+
+   if (data->debug_v2_enabled)
+   return;
+
+   mutex_lock(&data->debug_msg_lock);
+
+   data->debug_msg_data = kcalloc(DEBUG_MSG_MAX,
+   data->T5_msg_size, GFP_KERNEL);
+   if (!data->debug_msg_data) {
+   mutex_unlock(&data->debug_msg_lock);
+   return;
+   }
+
+   data->debug_v2_enabled = true;
+   mutex_unlock(&data->debug_msg_lock);
+
+   dev_dbg(dev, "Enabled message output\n");
+}
+
+static void mxt_debug_msg_disable(struct mxt_data *data)
+{
+   struct device *dev = &data->client->dev;
+
+   if (!data->debug_v2_enabled)
+   return;
+
+   mutex_lock(&data->debug_msg_lock);
+
+   data->debug_v2_enabled = false;
+
+   kfree(data->debug_msg_data);
+   data->debug_msg_data = NULL;
+   data->debug_msg_count = 0;
+   mutex_unlock(&data->debug_msg_lock);
+   dev_dbg(dev, "Disabled message output\n");
+}
+
+static void mxt_debug_msg_add(struct mxt_data *data, u8 *msg)
+{
+   struct device *dev = &data->client->dev;
+
+   mutex_lock(&data->debug_msg_lock);
+
+   if (!data->debug_msg_data) {
+   mutex_unlock(&data->debug_msg_lock);
+   dev_err(dev, "No buffer!\n");
+   return;
+   }
+
+   if (data->debug_msg_count < DEBUG_MSG_MAX) {
+   memcpy(data->debug_msg_data +
+  data->debug_msg_count * data->T5_msg_size,
+  msg,
+  data->T5_msg_size);
+   data->debug_msg_count++;
+   } else {
+   dev_dbg(dev, "Discarding %u messages\n", data->debug_msg_count);
+   data->debug_msg_count = 0;
+   }
+
+   mutex_unlock(&data->debug_msg_lock);
+
+   sysfs_notify(&data->client->dev.kobj, NULL, "debug_notify");
+}
+
+static ssize_t mxt_debug_msg_read(struct file 

[PATCH v2 34/49] input: atmel_mxt_ts: export GPIO reset line via sysfs

2019-08-26 Thread Jiada Wang
From: "George G. Davis" 

N.B. Modifying the atmel_mxt_ts GPIO reset line during operation will
cause problems with normal driver operation.  This feature is provided
as a diagnostic debug aid.  It does not take into consideration any
pending operations which may be in progress.  Modifying the atmel_mxt_ts
GPIO reset line at any time will inevitably cause the driver to fail.

Signed-off-by: George G. Davis 
Signed-off-by: Rajeev Kumar 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 560d46634bae..35f41bfa70d5 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -4083,6 +4083,19 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
return error;
}
 
+   if (data->reset_gpio) {
+   error = gpiod_export(data->reset_gpio, 0);
+   if (error)
+   return error;
+
+   error = gpiod_export_link(&client->dev, "reset",
+ data->reset_gpio);
+   if (error) {
+   gpiod_unexport(data->reset_gpio);
+   return error;
+   }
+   }
+
if (data->suspend_mode == MXT_SUSPEND_REGULATOR) {
error = mxt_acquire_irq(data);
if (error)
@@ -4115,6 +4128,10 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
 err_free_object:
mxt_free_input_device(data);
mxt_free_object_table(data);
+   if (data->reset_gpio) {
+   sysfs_remove_link(&client->dev.kobj, "reset");
+   gpiod_unexport(data->reset_gpio);
+   }
return error;
 }
 
@@ -4124,6 +4141,10 @@ static int mxt_remove(struct i2c_client *client)
 
disable_irq(data->irq);
sysfs_remove_group(&client->dev.kobj, &mxt_fw_attr_group);
+   if (data->reset_gpio) {
+   sysfs_remove_link(&client->dev.kobj, "reset");
+   gpiod_unexport(data->reset_gpio);
+   }
mxt_debug_msg_remove(data);
mxt_sysfs_remove(data);
mxt_free_input_device(data);
-- 
2.19.2



[PATCH v2 29/49] Input: atmel_mxt_ts - implement debug output for messages

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Add a debug switch which causes all messages from the touch controller to
be dumped to the dmesg log with a set prefix "MXT MSG:". This is used by
Atmel user-space utilities to debug touch operation. Enabling this output
does impact touch performance.

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
3c3fcfdd4889dfeb1c80ae8cd94a622c6342b06a)
[gdavis: Forward port and fix conflicts.]
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 44 ++--
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2d2e8ea30547..941c6970cb70 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -335,6 +335,7 @@ struct mxt_data {
u8 t100_aux_ampl;
u8 t100_aux_area;
u8 t100_aux_vect;
+   bool debug_enabled;
u8 max_reportid;
u32 config_crc;
u32 info_crc;
@@ -460,8 +461,8 @@ static bool mxt_object_readable(unsigned int type)
 
 static void mxt_dump_message(struct mxt_data *data, u8 *message)
 {
-   dev_dbg(&data->client->dev, "message: %*ph\n",
-   data->T5_msg_size, message);
+   dev_dbg(&data->client->dev, "MXT MSG: %*ph\n",
+  data->T5_msg_size, message);
 }
 
 static int mxt_wait_for_completion(struct mxt_data *data,
@@ -1214,6 +1215,7 @@ static void mxt_proc_t93_messages(struct mxt_data *data, 
u8 *msg)
 static int mxt_proc_message(struct mxt_data *data, u8 *message)
 {
u8 report_id = message[0];
+   bool dump = data->debug_enabled;
 
if (report_id == MXT_RPTID_NOMSG)
return 0;
@@ -1248,9 +1250,12 @@ static int mxt_proc_message(struct mxt_data *data, u8 
*message)
} else if (report_id == data->T93_reportid) {
mxt_proc_t93_messages(data, message);
} else {
-   mxt_dump_message(data, message);
+   dump = true;
}
 
+   if (dump)
+   mxt_dump_message(data, message);
+
return 1;
 }
 
@@ -3522,6 +3527,36 @@ static ssize_t mxt_update_cfg_store(struct device *dev,
return ret;
 }
 
+static ssize_t mxt_debug_enable_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct mxt_data *data = dev_get_drvdata(dev);
+   char c;
+
+   c = data->debug_enabled ? '1' : '0';
+   return scnprintf(buf, PAGE_SIZE, "%c\n", c);
+}
+
+static ssize_t mxt_debug_enable_store(struct device *dev,
+   struct device_attribute *attr, const char *buf, size_t count)
+{
+   struct mxt_data *data = dev_get_drvdata(dev);
+   u8 i;
+   ssize_t ret;
+
+   if (kstrtou8(buf, 0, &i) == 0 && i < 2) {
+   data->debug_enabled = (i == 1);
+
+   dev_dbg(dev, "%s\n", i ? "debug enabled" : "debug disabled");
+   ret = count;
+   } else {
+   dev_dbg(dev, "debug_enabled write error\n");
+   ret = -EINVAL;
+   }
+
+   return ret;
+}
+
 static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
 
 static struct attribute *mxt_fw_attrs[] = {
@@ -3538,6 +3573,8 @@ static DEVICE_ATTR(hw_version, S_IRUGO, 
mxt_hw_version_show, NULL);
 static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
 static DEVICE_ATTR(update_cfg, S_IWUSR, NULL, mxt_update_cfg_store);
 static DEVICE_ATTR(config_crc, S_IRUGO, mxt_config_crc_show, NULL);
+static DEVICE_ATTR(debug_enable, S_IWUSR | S_IRUSR, mxt_debug_enable_show,
+  mxt_debug_enable_store);
 
 static struct attribute *mxt_attrs[] = {
&dev_attr_fw_version.attr,
@@ -3545,6 +3582,7 @@ static struct attribute *mxt_attrs[] = {
&dev_attr_object.attr,
&dev_attr_update_cfg.attr,
&dev_attr_config_crc.attr,
+   &dev_attr_debug_enable.attr,
NULL
 };
 
-- 
2.19.2



Re: KASAN: slab-out-of-bounds Read in sctp_inq_pop

2019-08-26 Thread Xin Long
On Tue, Aug 27, 2019 at 1:15 AM syzbot
 wrote:
>
> Hello,
>
> syzbot found the following crash on:
>
> HEAD commit:9733a7c6 Add linux-next specific files for 20190823
> git tree:   linux-next
> console output: https://syzkaller.appspot.com/x/log.txt?x=143ec11e60
> kernel config:  https://syzkaller.appspot.com/x/.config?x=f6c78a1438582bd1
> dashboard link: https://syzkaller.appspot.com/bug?extid=3ca06c5cb35ee3fc1f89
> compiler:   gcc (GCC) 9.0.0 20181231 (experimental)
>
> Unfortunately, I don't have any reproducer for this crash yet.
>
> IMPORTANT: if you fix the bug, please add the following tag to the commit:
> Reported-by: syzbot+3ca06c5cb35ee3fc1...@syzkaller.appspotmail.com
>
> ==
> BUG: KASAN: slab-out-of-bounds in sctp_inq_pop+0xafd/0xd80
> net/sctp/inqueue.c:201
> Read of size 2 at addr 8880a4e37222 by task syz-executor.3/32407
>
> CPU: 1 PID: 32407 Comm: syz-executor.3 Not tainted 5.3.0-rc5-next-20190823
> #72
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> Google 01/01/2011
> Call Trace:
>   __dump_stack lib/dump_stack.c:77 [inline]
>   dump_stack+0x172/0x1f0 lib/dump_stack.c:113
>   print_address_description.cold+0xd4/0x306 mm/kasan/report.c:351
>   __kasan_report.cold+0x1b/0x36 mm/kasan/report.c:482
>   kasan_report+0x12/0x17 mm/kasan/common.c:610
>   __asan_report_load2_noabort+0x14/0x20 mm/kasan/generic_report.c:130
>   sctp_inq_pop+0xafd/0xd80 net/sctp/inqueue.c:201
>   sctp_endpoint_bh_rcv+0x184/0x8d0 net/sctp/endpointola.c:335
>   sctp_inq_push+0x1e4/0x280 net/sctp/inqueue.c:80
>   sctp_rcv+0x2807/0x3590 net/sctp/input.c:256
>   sctp6_rcv+0x17/0x30 net/sctp/ipv6.c:1049
>   ip6_protocol_deliver_rcu+0x2fe/0x1660 net/ipv6/ip6_input.c:397
>   ip6_input_finish+0x84/0x170 net/ipv6/ip6_input.c:438
>   NF_HOOK include/linux/netfilter.h:305 [inline]
>   NF_HOOK include/linux/netfilter.h:299 [inline]
>   ip6_input+0xe4/0x3f0 net/ipv6/ip6_input.c:447
>   dst_input include/net/dst.h:442 [inline]
>   ip6_sublist_rcv_finish+0x98/0x1e0 net/ipv6/ip6_input.c:84
>   ip6_list_rcv_finish net/ipv6/ip6_input.c:118 [inline]
>   ip6_sublist_rcv+0x80c/0xcf0 net/ipv6/ip6_input.c:282
>   ipv6_list_rcv+0x373/0x4b0 net/ipv6/ip6_input.c:316
>   __netif_receive_skb_list_ptype net/core/dev.c:5049 [inline]
>   __netif_receive_skb_list_core+0x1a2/0x9d0 net/core/dev.c:5087
>   __netif_receive_skb_list net/core/dev.c:5149 [inline]
>   netif_receive_skb_list_internal+0x7eb/0xe60 net/core/dev.c:5244
>   gro_normal_list.part.0+0x1e/0xb0 net/core/dev.c:5757
>   gro_normal_list net/core/dev.c:5755 [inline]
>   gro_normal_one net/core/dev.c:5769 [inline]
>   napi_frags_finish net/core/dev.c:5782 [inline]
>   napi_gro_frags+0xa6a/0xea0 net/core/dev.c:5855
>   tun_get_user+0x2e98/0x3fa0 drivers/net/tun.c:1974
>   tun_chr_write_iter+0xbd/0x156 drivers/net/tun.c:2020
>   call_write_iter include/linux/fs.h:1890 [inline]
>   do_iter_readv_writev+0x5f8/0x8f0 fs/read_write.c:693
>   do_iter_write fs/read_write.c:976 [inline]
>   do_iter_write+0x17b/0x380 fs/read_write.c:957
>   vfs_writev+0x1b3/0x2f0 fs/read_write.c:1021
>   do_writev+0x15b/0x330 fs/read_write.c:1064
>   __do_sys_writev fs/read_write.c:1137 [inline]
>   __se_sys_writev fs/read_write.c:1134 [inline]
>   __x64_sys_writev+0x75/0xb0 fs/read_write.c:1134
>   do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290
>   entry_SYSCALL_64_after_hwframe+0x49/0xbe
> RIP: 0033:0x459731
> Code: 75 14 b8 14 00 00 00 0f 05 48 3d 01 f0 ff ff 0f 83 34 b9 fb ff c3 48
> 83 ec 08 e8 fa 2c 00 00 48 89 04 24 b8 14 00 00 00 0f 05 <48> 8b 3c 24 48
> 89 c2 e8 43 2d 00 00 48 89 d0 48 83 c4 08 48 3d 01
> RSP: 002b:7fb4cd361ba0 EFLAGS: 0293 ORIG_RAX: 0014
> RAX: ffda RBX: 002a RCX: 00459731
> RDX: 0001 RSI: 7fb4cd361c00 RDI: 00f0
> RBP: 0075bf20 R08:  R09: 
> R10:  R11: 0293 R12: 7fb4cd3626d4
> R13: 004c87e3 R14: 004df640 R15: 
>
> Allocated by task 32407:
>   save_stack+0x23/0x90 mm/kasan/common.c:69
>   set_track mm/kasan/common.c:77 [inline]
>   __kasan_kmalloc mm/kasan/common.c:486 [inline]
>   __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:459
>   kasan_slab_alloc+0xf/0x20 mm/kasan/common.c:494
>   slab_post_alloc_hook mm/slab.h:584 [inline]
>   slab_alloc mm/slab.c:3319 [inline]
>   kmem_cache_alloc+0x121/0x710 mm/slab.c:3483
>   __build_skb+0x26/0x70 net/core/skbuff.c:310
>   __napi_alloc_skb+0x1d2/0x300 net/core/skbuff.c:523
>   napi_alloc_skb include/linux/skbuff.h:2801 [inline]
>   napi_get_frags net/core/dev.c:5742 [inline]
>   napi_get_frags+0x65/0x140 net/core/dev.c:5737
>   tun_napi_alloc_frags drivers/net/tun.c:1473 [inline]
>   tun_get_user+0x16bd/0x3fa0 drivers/net/tun.c:1834
>   tun_chr_write_iter+0xbd/0x156 drivers/net/tun.c:2020
>   call_write_iter include/linux/fs.h:1890 [inline]
>  

[PATCH v2 22/49] Input: atmel_mxt_ts - combine bootloader version query with probe

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

This removes some complexity from the bootloader state machine, and means
that we always output some debug about the version as soon as we start
talking to the bootloader.

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
a2d141f170c80fea6663af98aab0be32abc0ddb0)
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 45 +++-
 1 file changed, 13 insertions(+), 32 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3da3f27ed580..4ec28b73ee83 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -558,47 +558,31 @@ static int mxt_probe_bootloader(struct mxt_data *data, 
bool alt_address)
 {
struct device *dev = &data->client->dev;
int error;
-   u8 val;
-   bool crc_failure;
+   u8 buf[3];
+   bool crc_failure, extended_id;
 
error = mxt_lookup_bootloader_address(data, alt_address);
if (error)
return error;
 
-   error = mxt_bootloader_read(data, &val, 1);
+   /* Check bootloader status and version information */
+   error = mxt_bootloader_read(data, buf, sizeof(buf));
if (error)
return error;
 
-   /* Check app crc fail mode */
-   crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL;
+   crc_failure = (buf[0] & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL;
+   extended_id = buf[0] & MXT_BOOT_EXTENDED_ID;
 
-   dev_err(dev, "Detected bootloader, status:%02X%s\n",
-   val, crc_failure ? ", APP_CRC_FAIL" : "");
+   dev_info(dev, "Found bootloader addr:%02x ID:%u%s%u%s\n",
+data->bootloader_addr,
+extended_id ? (buf[1] & MXT_BOOT_ID_MASK) : buf[0],
+extended_id ? " version:" : "",
+extended_id ? buf[2] : 0,
+crc_failure ? ", APP_CRC_FAIL" : "");
 
return 0;
 }
 
-static u8 mxt_get_bootloader_version(struct mxt_data *data, u8 val)
-{
-   struct device *dev = &data->client->dev;
-   u8 buf[3];
-
-   if (val & MXT_BOOT_EXTENDED_ID) {
-   if (mxt_bootloader_read(data, &buf[0], 3) != 0) {
-   dev_err(dev, "%s: i2c failure\n", __func__);
-   return val;
-   }
-
-   dev_dbg(dev, "Bootloader ID:%d Version:%d\n", buf[1], buf[2]);
-
-   return buf[0];
-   } else {
-   dev_dbg(dev, "Bootloader ID:%d\n", val & MXT_BOOT_ID_MASK);
-
-   return val;
-   }
-}
-
 static int mxt_check_bootloader(struct mxt_data *data, unsigned int state,
bool wait)
 {
@@ -632,9 +616,6 @@ static int mxt_check_bootloader(struct mxt_data *data, 
unsigned int state,
if (ret)
return ret;
 
-   if (state == MXT_WAITING_BOOTLOAD_CMD)
-   val = mxt_get_bootloader_version(data, val);
-
switch (state) {
case MXT_WAITING_BOOTLOAD_CMD:
case MXT_WAITING_FRAME_DATA:
@@ -3283,7 +3264,7 @@ static int mxt_enter_bootloader(struct mxt_data *data)
msleep(MXT_RESET_TIME);
 
/* Do not need to scan since we know family ID */
-   ret = mxt_lookup_bootloader_address(data, 0);
+   ret = mxt_probe_bootloader(data, 0);
if (ret)
return ret;
 
-- 
2.19.2



[PATCH v2 25/49] Input: atmel_mxt_ts - make bootloader interrupt driven

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
67a3eea0cfc724c3c2a7410ac064f74227c7c6ef)
[gdavis: Resolve forward port conflicts due to applying upstream
 commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
 data support").]
Signed-off-by: George G. Davis 
[jiada: Replace two use msecs_to_jiffies() instead of HZ]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 118 ---
 1 file changed, 60 insertions(+), 58 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index e5843cb9a35e..cfc84f3b5a9e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -218,6 +219,7 @@ enum t100_type {
 #define MXT_REGULATOR_DELAY150 /* msec */
 #define MXT_CHG_DELAY  100 /* msec */
 #define MXT_POWERON_DELAY  150 /* msec */
+#define MXT_BOOTLOADER_WAIT36E5/* 1 minute */
 
 /* Command to unlock bootloader */
 #define MXT_UNLOCK_CMD_MSB 0xaa
@@ -299,6 +301,7 @@ struct mxt_fw_frame {
 
 /* Firmware update context */
 struct mxt_flash {
+   struct mxt_data *data;
const struct firmware *fw;
struct mxt_fw_frame *frame;
loff_t pos;
@@ -306,7 +309,8 @@ struct mxt_flash {
unsigned int count;
unsigned int retry;
u8 previous;
-   bool complete;
+   struct completion flash_completion;
+   struct delayed_work work;
 };
 
 /* Each client has this additional data */
@@ -355,6 +359,7 @@ struct mxt_data {
char *cfg_name;
const char *pcfg_name;
const char *input_name;
+   struct mxt_flash *flash;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -599,28 +604,17 @@ static int mxt_write_firmware_frame(struct mxt_data 
*data, struct mxt_flash *f)
   f->frame_size);
 }
 
-static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f)
+static int mxt_check_bootloader(struct mxt_data *data)
 {
struct device *dev = &data->client->dev;
+   struct mxt_flash *f = data->flash;
u8 state;
int ret;
 
-   /*
-* In application update mode, the interrupt
-* line signals state transitions. We must wait for the
-* CHG assertion before reading the status byte.
-* Once the status byte has been read, the line is deasserted.
-*/
-   ret = mxt_wait_for_completion(data, &data->chg_completion,
- MXT_FW_CHG_TIMEOUT);
-   if (ret) {
-   /*
-* TODO: handle -ERESTARTSYS better by terminating
-* fw update process before returning to userspace
-* by writing length 0x000 to device (iff we are in
-* WAITING_FRAME_DATA state).
-*/
-   dev_warn(dev, "Update wait error %d\n", ret);
+   /* Handle interrupt after download/flash process */
+   if (f->pos >= f->fw->size) {
+   complete(&f->flash_completion);
+   return 0;
}
 
ret = mxt_bootloader_read(data, &state, 1);
@@ -666,14 +660,12 @@ static int mxt_check_bootloader(struct mxt_data *data, 
struct mxt_flash *f)
f->pos += f->frame_size;
f->count++;
 
-   if (f->pos >= f->fw->size) {
-   f->complete = true;
+   if (f->pos >= f->fw->size)
dev_info(dev, "Sent %u frames, %zu bytes\n",
f->count, f->fw->size);
-   } else if (f->count % 50 == 0) {
+   else if (f->count % 50 == 0)
dev_dbg(dev, "Sent %u frames, %lld/%zu bytes\n",
f->count, f->pos, f->fw->size);
-   }
 
break;
 
@@ -695,6 +687,9 @@ static int mxt_check_bootloader(struct mxt_data *data, 
struct mxt_flash *f)
 
f->previous = state;
 
+   /* Poll after 0.1s if no interrupt received */
+   schedule_delayed_work(&f->work, msecs_to_jiffies(100));
+
return 0;
 
 unexpected:
@@ -1403,7 +1398,11 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 
if (data->in_bootloader) {
complete(&data->chg_completion);
-   return IRQ_HANDLED;
+
+   if (data->flash && &data->flash->work)
+   cancel_delayed_work_sync(&data->flash->work);
+
+   return IRQ_RETVAL(mxt_check_bootloader(data));
}
 
if (!data->object_table)
@@ -3304,16 +3303,13 @@ static int mxt_enter_bootloader(struct mxt_data *data)
if (data->suspend_mode == MXT_SUSPEND_REGULATOR)
mxt_regulator_enable(data);
 
-   if (data->suspend_mode == MXT_

[PATCH v2 21/49] Input: atmel_mxt_ts - refactor code to enter bootloader into separate func

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
bedd706a32522b946467e15f4f4f24de86a1b4d7)
[gdavis: Resolve forward port conflicts due to applying upstream
 commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
 data support").]
Signed-off-by: George G. Davis 
[jiada: Squash change from ndyer/linux/for-upstream commit 
d691d3ee6c6de84b38464a42
3207b3e23cb9dc3a
- Input: atmel_mxt_ts - check firmware format before entering 
bootloader]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 43 +++-
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 85eefd4fbc9a..3da3f27ed580 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3257,23 +3257,10 @@ static int mxt_check_firmware_format(struct device *dev,
return -EINVAL;
 }
 
-static int mxt_load_fw(struct device *dev)
+static int mxt_enter_bootloader(struct mxt_data *data)
 {
-   struct mxt_data *data = dev_get_drvdata(dev);
-   struct mxt_flash f = { 0, };
int ret;
 
-   ret = request_firmware(&f.fw, data->fw_name, dev);
-   if (ret) {
-   dev_err(dev, "Unable to open firmware %s\n", data->fw_name);
-   return ret;
-   }
-
-   /* Check for incorrect enc file */
-   ret = mxt_check_firmware_format(dev, f.fw);
-   if (ret)
-   goto release_firmware;
-
if (data->suspended) {
if (data->suspend_mode == MXT_SUSPEND_REGULATOR)
mxt_regulator_enable(data);
@@ -3291,14 +3278,14 @@ static int mxt_load_fw(struct device *dev)
ret = mxt_t6_command(data, MXT_COMMAND_RESET,
 MXT_BOOT_VALUE, false);
if (ret)
-   goto release_firmware;
+   return ret;
 
msleep(MXT_RESET_TIME);
 
/* Do not need to scan since we know family ID */
ret = mxt_lookup_bootloader_address(data, 0);
if (ret)
-   goto release_firmware;
+   return ret;
 
mxt_sysfs_remove(data);
mxt_free_input_device(data);
@@ -3309,6 +3296,30 @@ static int mxt_load_fw(struct device *dev)
 
reinit_completion(&data->bl_completion);
 
+   return 0;
+}
+
+static int mxt_load_fw(struct device *dev)
+{
+   struct mxt_data *data = dev_get_drvdata(dev);
+   struct mxt_flash f = { 0, };
+   int ret;
+
+   ret = request_firmware(&f.fw, data->fw_name, dev);
+   if (ret) {
+   dev_err(dev, "Unable to open firmware %s\n", data->fw_name);
+   return ret;
+   }
+
+   /* Check for incorrect enc file */
+   ret = mxt_check_firmware_format(dev, f.fw);
+   if (ret)
+   goto release_firmware;
+
+   ret = mxt_enter_bootloader(data);
+   if (ret)
+   goto release_firmware;
+
ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false);
if (ret) {
/* Bootloader may still be unlocked from previous attempt */
-- 
2.19.2



[PATCH v2 20/49] Input: atmel_mxt_ts - refactor firmware flash to extract context into struct

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
1bbe20ff3dcd6612e7942c495929eae5c138ece2)
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 59 +++-
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 77a1f8209cee..85eefd4fbc9a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -291,6 +291,22 @@ struct mxt_cfg {
struct mxt_info info;
 };
 
+/* Firmware frame structure */
+struct mxt_fw_frame {
+   __be16 size;
+   u8 data[];
+};
+
+/* Firmware update context */
+struct mxt_flash {
+   const struct firmware *fw;
+   struct mxt_fw_frame *frame;
+   loff_t pos;
+   size_t frame_size;
+   unsigned int count;
+   unsigned int retry;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -3244,21 +3260,17 @@ static int mxt_check_firmware_format(struct device *dev,
 static int mxt_load_fw(struct device *dev)
 {
struct mxt_data *data = dev_get_drvdata(dev);
-   const struct firmware *fw = NULL;
-   unsigned int frame_size;
-   unsigned int pos = 0;
-   unsigned int retry = 0;
-   unsigned int frame = 0;
+   struct mxt_flash f = { 0, };
int ret;
 
-   ret = request_firmware(&fw, data->fw_name, dev);
+   ret = request_firmware(&f.fw, data->fw_name, dev);
if (ret) {
dev_err(dev, "Unable to open firmware %s\n", data->fw_name);
return ret;
}
 
/* Check for incorrect enc file */
-   ret = mxt_check_firmware_format(dev, fw);
+   ret = mxt_check_firmware_format(dev, f.fw);
if (ret)
goto release_firmware;
 
@@ -3312,41 +3324,42 @@ static int mxt_load_fw(struct device *dev)
goto disable_irq;
}
 
-   while (pos < fw->size) {
+   while (f.pos < f.fw->size) {
+   f.frame = (struct mxt_fw_frame *)(f.fw->data + f.pos);
+
ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA, true);
if (ret)
goto disable_irq;
 
-   frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));
-
/* Take account of CRC bytes */
-   frame_size += 2;
+   f.frame_size = __be16_to_cpu(f.frame->size) + 2U;
 
/* Write one frame to device */
-   ret = mxt_bootloader_write(data, fw->data + pos, frame_size);
+   ret = mxt_bootloader_write(data, f.fw->data + f.pos,
+  f.frame_size);
if (ret)
goto disable_irq;
 
ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS, true);
if (ret) {
-   retry++;
+   f.retry++;
 
/* Back off by 20ms per retry */
-   msleep(retry * 20);
+   msleep(f.retry * 20);
 
-   if (retry > 20) {
+   if (f.retry > 20) {
dev_err(dev, "Retry count exceeded\n");
goto disable_irq;
}
} else {
-   retry = 0;
-   pos += frame_size;
-   frame++;
+   f.retry = 0;
+   f.pos += f.frame_size;
+   f.count++;
}
 
-   if (frame % 50 == 0)
-   dev_dbg(dev, "Sent %d frames, %d/%zd bytes\n",
-   frame, pos, fw->size);
+   if (f.count % 50 == 0)
+   dev_dbg(dev, "Sent %u frames, %lld/%zu bytes\n",
+   f.count, f.pos, f.fw->size);
}
 
/* Wait for flash. */
@@ -3355,7 +3368,7 @@ static int mxt_load_fw(struct device *dev)
if (ret)
goto disable_irq;
 
-   dev_dbg(dev, "Sent %d frames, %d bytes\n", frame, pos);
+   dev_dbg(dev, "Sent %u frames, %lld bytes\n", f.count, f.pos);
 
/*
 * Wait for device to reset. Some bootloader versions do not assert
@@ -3369,7 +3382,7 @@ static int mxt_load_fw(struct device *dev)
 disable_irq:
disable_irq(data->irq);
 release_firmware:
-   release_firmware(fw);
+   release_firmware(f.fw);
return ret;
 }
 
-- 
2.19.2



[PATCH v2 27/49] Input: atmel_mxt_ts - implement I2C retries

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Some maXTouch chips (eg mXT1386) will not respond on the first I2C request
when they are in a sleep state. It must be retried after a delay for the
chip to wake up.

Signed-off-by: Nick Dyer 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
63fd7a2cd03c3a572a5db39c52f4856819e1835d)
[gdavis: Forward port and fix conflicts.]
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 45 
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index daf119c2957d..5b7ab798f27d 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -216,6 +216,7 @@ enum t100_type {
 #define MXT_CRC_TIMEOUT1000/* msec */
 #define MXT_FW_RESET_TIME  3000/* msec */
 #define MXT_FW_CHG_TIMEOUT 300 /* msec */
+#define MXT_WAKEUP_TIME25  /* msec */
 #define MXT_REGULATOR_DELAY150 /* msec */
 #define MXT_CHG_DELAY  100 /* msec */
 #define MXT_POWERON_DELAY  150 /* msec */
@@ -723,6 +724,7 @@ static int __mxt_read_chunk(struct i2c_client *client,
struct i2c_msg xfer[2];
u8 buf[2];
int ret;
+   bool retry = false;
 
buf[0] = reg & 0xff;
buf[1] = (reg >> 8) & 0xff;
@@ -739,17 +741,22 @@ static int __mxt_read_chunk(struct i2c_client *client,
xfer[1].len = len;
xfer[1].buf = val;
 
-   ret = i2c_transfer(client->adapter, xfer, 2);
-   if (ret == 2) {
-   ret = 0;
-   } else {
-   if (ret >= 0)
-   ret = -EIO;
-   dev_err(&client->dev, "%s: i2c transfer failed (%d)\n",
-   __func__, ret);
+retry_read:
+   ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer));
+   if (ret != ARRAY_SIZE(xfer)) {
+   if (!retry) {
+   dev_dbg(&client->dev, "%s: i2c retry\n", __func__);
+   msleep(MXT_WAKEUP_TIME);
+   retry = true;
+   goto retry_read;
+   } else {
+   dev_err(&client->dev, "%s: i2c transfer failed (%d)\n",
+   __func__, ret);
+   return -EIO;
+   }
}
 
-   return ret;
+   return 0;
 }
 
 static int __mxt_read_reg(struct i2c_client *client,
@@ -780,6 +787,7 @@ static int __mxt_write_reg(struct i2c_client *client, u16 
reg, u16 len,
u8 *buf;
size_t count;
int ret;
+   bool retry = false;
 
count = len + 2;
buf = kmalloc(count, GFP_KERNEL);
@@ -790,14 +798,21 @@ static int __mxt_write_reg(struct i2c_client *client, u16 
reg, u16 len,
buf[1] = (reg >> 8) & 0xff;
memcpy(&buf[2], val, len);
 
+retry_write:
ret = i2c_master_send(client, buf, count);
-   if (ret == count) {
-   ret = 0;
-   } else {
-   if (ret >= 0)
+   if (ret != count) {
+   if (!retry) {
+   dev_dbg(&client->dev, "%s: i2c retry\n", __func__);
+   msleep(MXT_WAKEUP_TIME);
+   retry = true;
+   goto retry_write;
+   } else {
+   dev_err(&client->dev, "%s: i2c send failed (%d)\n",
+   __func__, ret);
ret = -EIO;
-   dev_err(&client->dev, "%s: i2c send failed (%d)\n",
-   __func__, ret);
+   }
+   } else {
+   ret = 0;
}
 
kfree(buf);
-- 
2.19.2



[PATCH v2 23/49] Input: atmel_mxt_ts - improve bootloader state machine handling

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

The code is much clearer if we switch on the actual state the bootloader
is in, rather than the state we want it to be in, and allows the removal
of a goto retry tangle.

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
463e15ee95ee6e6274017ff645839dbe34d75c99)
[gdavis: Squash fix from George G. Davis:
 - input: atmel_mxt_ts - Fix 'mxt_send_bootloader_cmd' was not
   declared warning]
Signed-off-by: George G. Davis 
---
Notes:
- Squash fix from George G. Davis:
  + input: atmel_mxt_ts - Fix 'mxt_send_bootloader_cmd' was not declared warning

The following sparse warning was introduced by ndyer/linux/for-upstream
commit 463e15ee95ee ("Input: atmel_mxt_ts - improve bootloader state
machine handling"):

drivers/input/touchscreen/atmel_mxt_ts.c:888:5: warning: symbol 
'mxt_send_bootloader_cmd' was not declared. Should it be static?

Fix the above sparse warning by restoring the 'mxt_send_bootloader_cmd'
static declaration which was errantly removed by
ndyer/linux/for-upstream commit 463e15ee95ee ("Input: atmel_mxt_ts -
improve bootloader state machine handling").

Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 183 ---
 1 file changed, 98 insertions(+), 85 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4ec28b73ee83..4e7f82e2fc0c 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -305,6 +305,8 @@ struct mxt_flash {
size_t frame_size;
unsigned int count;
unsigned int retry;
+   u8 previous;
+   bool complete;
 };
 
 /* Each client has this additional data */
@@ -583,64 +585,121 @@ static int mxt_probe_bootloader(struct mxt_data *data, 
bool alt_address)
return 0;
 }
 
-static int mxt_check_bootloader(struct mxt_data *data, unsigned int state,
-   bool wait)
+static int mxt_send_bootloader_cmd(struct mxt_data *data, bool unlock);
+
+static int mxt_write_firmware_frame(struct mxt_data *data, struct mxt_flash *f)
+{
+   f->frame = (struct mxt_fw_frame *)(f->fw->data + f->pos);
+
+   /* Take account of CRC bytes */
+   f->frame_size = __be16_to_cpu(f->frame->size) + 2U;
+
+   /* Write one frame to device */
+   return mxt_bootloader_write(data, f->fw->data + f->pos,
+  f->frame_size);
+}
+
+static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f)
 {
struct device *dev = &data->client->dev;
-   u8 val;
+   u8 state;
int ret;
 
-recheck:
-   if (wait) {
+   /*
+* In application update mode, the interrupt
+* line signals state transitions. We must wait for the
+* CHG assertion before reading the status byte.
+* Once the status byte has been read, the line is deasserted.
+*/
+   ret = mxt_wait_for_completion(data, &data->bl_completion,
+ MXT_FW_CHG_TIMEOUT);
+   if (ret) {
/*
-* In application update mode, the interrupt
-* line signals state transitions. We must wait for the
-* CHG assertion before reading the status byte.
-* Once the status byte has been read, the line is deasserted.
+* TODO: handle -ERESTARTSYS better by terminating
+* fw update process before returning to userspace
+* by writing length 0x000 to device (iff we are in
+* WAITING_FRAME_DATA state).
 */
-   ret = mxt_wait_for_completion(data, &data->bl_completion,
- MXT_FW_CHG_TIMEOUT);
-   if (ret) {
-   /*
-* TODO: handle -ERESTARTSYS better by terminating
-* fw update process before returning to userspace
-* by writing length 0x000 to device (iff we are in
-* WAITING_FRAME_DATA state).
-*/
-   dev_err(dev, "Update wait error %d\n", ret);
-   return ret;
-   }
+   dev_warn(dev, "Update wait error %d\n", ret);
}
 
-   ret = mxt_bootloader_read(data, &val, 1);
+   ret = mxt_bootloader_read(data, &state, 1);
if (ret)
return ret;
 
+   /* Remove don't care bits */
+   if (state & ~MXT_BOOT_STATUS_MASK)
+   state &= ~MXT_BOOT_STATUS_MASK;
+
switch (state) {
case MXT_WAITING_BOOTLOAD_CMD:
+   dev_info(dev, "Unlocking bootloader\n");
+   ret = mxt_send_bootloader_cmd(data, true);
+   if (ret)
+   return ret;
+
+   break;
+
case MXT_WAITING_FRAME_DATA:
-   case MXT_APP_CR

[PATCH v2 24/49] Input: atmel_mxt_ts - rename bl_completion to chg_completion

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
dda8453bfb44216645ede798918a314d4fca2481)
[gdavis: Resolve forward port conflicts due to applying upstream
 commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
 data support").]
Signed-off-by: George G. Davis 
[jiada: call complete(&data->chg_completion) only when in_bootloader is TRUE]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4e7f82e2fc0c..e5843cb9a35e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -381,9 +381,6 @@ struct mxt_data {
u8 T100_reportid_max;
u16 T107_address;
 
-   /* for fw update in bootloader */
-   struct completion bl_completion;
-
/* for reset handling */
struct completion reset_completion;
 
@@ -395,6 +392,9 @@ struct mxt_data {
 
enum mxt_suspend_mode suspend_mode;
 
+   /* for power up handling */
+   struct completion chg_completion;
+
/* Indicates whether device is in suspend */
bool suspended;
 
@@ -611,7 +611,7 @@ static int mxt_check_bootloader(struct mxt_data *data, 
struct mxt_flash *f)
 * CHG assertion before reading the status byte.
 * Once the status byte has been read, the line is deasserted.
 */
-   ret = mxt_wait_for_completion(data, &data->bl_completion,
+   ret = mxt_wait_for_completion(data, &data->chg_completion,
  MXT_FW_CHG_TIMEOUT);
if (ret) {
/*
@@ -1402,8 +1402,7 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
struct mxt_data *data = dev_id;
 
if (data->in_bootloader) {
-   /* bootloader state transition completion */
-   complete(&data->bl_completion);
+   complete(&data->chg_completion);
return IRQ_HANDLED;
}
 
@@ -2167,9 +2166,9 @@ static void mxt_regulator_enable(struct mxt_data *data)
msleep(MXT_CHG_DELAY);
 
 retry_wait:
-   reinit_completion(&data->bl_completion);
+   reinit_completion(&data->chg_completion);
data->in_bootloader = true;
-   error = mxt_wait_for_completion(data, &data->bl_completion,
+   error = mxt_wait_for_completion(data, &data->chg_completion,
MXT_POWERON_DELAY);
if (error == -EINTR)
goto retry_wait;
@@ -3334,7 +,7 @@ static int mxt_enter_bootloader(struct mxt_data *data)
enable_irq(data->irq);
}
 
-   reinit_completion(&data->bl_completion);
+   reinit_completion(&data->chg_completion);
 
return 0;
 }
@@ -3370,7 +3369,7 @@ static int mxt_load_fw(struct device *dev)
}
 
/* Wait for flash. */
-   ret = mxt_wait_for_completion(data, &data->bl_completion,
+   ret = mxt_wait_for_completion(data, &data->chg_completion,
  MXT_FW_RESET_TIME);
if (ret)
goto disable_irq;
@@ -3381,7 +3380,7 @@ static int mxt_load_fw(struct device *dev)
 * the CHG line after bootloading has finished, so ignore potential
 * errors.
 */
-   mxt_wait_for_completion(data, &data->bl_completion, MXT_FW_RESET_TIME);
+   mxt_wait_for_completion(data, &data->chg_completion, MXT_FW_RESET_TIME);
 
data->in_bootloader = false;
 disable_irq:
@@ -3803,7 +3802,7 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
data->irq = client->irq;
i2c_set_clientdata(client, data);
 
-   init_completion(&data->bl_completion);
+   init_completion(&data->chg_completion);
init_completion(&data->reset_completion);
init_completion(&data->crc_completion);
 
-- 
2.19.2



[PATCH v2 26/49] Input: atmel_mxt_ts - delay enabling IRQ when not using regulators

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

The path of enabling the IRQ in the probe function is not safe in level
triggered operation, if it was already powered up and there is a message
waiting on the device (eg finger down) because the object table has not yet
been read. This forces the ISR into a hard loop.

Delay enabling the interrupt until it is first needed.

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
64c9dadc4a3250a185baf06ab0f628be45d5d9a0)
[gdavis: Resolve forward port conflicts due to v4.14-rc1 commit
 8cc8446b9b62 ("Input: atmel_mxt_ts - use more managed
 resources") and applying upstream commit 96a938aa214e ("Input:
 atmel_mxt_ts - remove platform data support").]
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 40 +++-
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index cfc84f3b5a9e..daf119c2957d 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1451,9 +1451,24 @@ static int mxt_acquire_irq(struct mxt_data *data)
 {
int error;
 
-   enable_irq(data->irq);
+   if (!data->irq) {
+   error = devm_request_threaded_irq(&data->client->dev,
+ data->client->irq,
+ NULL, mxt_interrupt,
+ IRQF_ONESHOT,
+ data->client->name, data);
+   if (error) {
+   dev_err(&data->client->dev, "Error requesting irq\n");
+   return error;
+   }
+
+   /* Presence of data->irq means IRQ initialised */
+   data->irq = data->client->irq;
+   } else {
+   enable_irq(data->irq);
+   }
 
-   if (data->use_retrigen_workaround) {
+   if (data->object_table && data->use_retrigen_workaround) {
error = mxt_process_messages_until_invalid(data);
if (error)
return error;
@@ -3373,7 +3388,9 @@ static int mxt_load_fw(struct device *dev)
goto release_firmware;
}
 
-   enable_irq(data->irq);
+   ret = mxt_acquire_irq(data);
+   if (ret)
+   goto release_firmware;
 
/* Poll after 0.1s if no interrupt received */
schedule_delayed_work(&data->flash->work, msecs_to_jiffies(100));
@@ -3801,7 +3818,6 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
 client->adapter->nr, client->addr);
 
data->client = client;
-   data->irq = client->irq;
i2c_set_clientdata(client, data);
 
init_completion(&data->chg_completion);
@@ -3829,26 +3845,22 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
return error;
}
 
-   error = devm_request_threaded_irq(&client->dev, client->irq,
- NULL, mxt_interrupt, IRQF_ONESHOT,
- client->name, data);
-   if (error) {
-   dev_err(&client->dev, "Failed to register interrupt\n");
-   return error;
-   }
-
if (data->suspend_mode == MXT_SUSPEND_REGULATOR) {
+   error = mxt_acquire_irq(data);
+   if (error)
+   return error;
+
error = mxt_probe_regulators(data);
if (error)
return error;
+
+   disable_irq(data->irq);
} else if (data->reset_gpio) {
msleep(MXT_RESET_GPIO_TIME);
gpiod_set_value(data->reset_gpio, 1);
msleep(MXT_RESET_INVALID_CHG);
}
 
-   disable_irq(data->irq);
-
error = mxt_initialize(data);
if (error)
return error;
-- 
2.19.2



[PATCH v2 19/49] Input: atmel_mxt_ts - add config checksum attribute to sysfs

2019-08-26 Thread Jiada Wang
From: karl tsou 

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
03477477ddbe5dcad42853ab3f84166a8f807acf)
[gdavis: Forward port and fix conflicts.]
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 923ceb5118c5..77a1f8209cee 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3128,6 +3128,15 @@ static int mxt_configure_objects(struct mxt_data *data,
return error;
 }
 
+/* Configuration crc check sum is returned as hex xx */
+static ssize_t mxt_config_crc_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct mxt_data *data = dev_get_drvdata(dev);
+
+   return scnprintf(buf, PAGE_SIZE, "%06x\n", data->config_crc);
+}
+
 /* Firmware Version is returned as Major.Minor.Build */
 static ssize_t mxt_fw_version_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -3481,12 +3490,14 @@ static DEVICE_ATTR(fw_version, S_IRUGO, 
mxt_fw_version_show, NULL);
 static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
 static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
 static DEVICE_ATTR(update_cfg, S_IWUSR, NULL, mxt_update_cfg_store);
+static DEVICE_ATTR(config_crc, S_IRUGO, mxt_config_crc_show, NULL);
 
 static struct attribute *mxt_attrs[] = {
&dev_attr_fw_version.attr,
&dev_attr_hw_version.attr,
&dev_attr_object.attr,
&dev_attr_update_cfg.attr,
+   &dev_attr_config_crc.attr,
NULL
 };
 
-- 
2.19.2



[PATCH v2 18/49] Input: atmel_mxt_ts - allow input name to be specified in platform data

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Android systems identify the input device and map to IDC file by using the
input device name. To avoid unnecessary deltas to the driver file, allow
this to be set from the platform data.

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
cbf94a7bda754d2e1899d9f50313a0bccc91422d)
[gdavis: Resolve forward port conflicts due to applying upstream
 commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
 data support").]
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 .../devicetree/bindings/input/atmel,maxtouch.txt | 2 ++
 drivers/input/touchscreen/atmel_mxt_ts.c | 9 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt 
b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
index 713ce870805c..d7db16920083 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
@@ -40,6 +40,8 @@ Optional properties for main touchpad device:
 - atmel,cfg_name: Provide name of configuration file in OBP_RAW format. This
 will be downloaded from the firmware loader on probe to the device.
 
+- atmel,input_name: Override name of input device from the default.
+
 Example:
 
touch@4b {
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index c6be716a974c..923ceb5118c5 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -336,6 +336,7 @@ struct mxt_data {
char *fw_name;
char *cfg_name;
const char *pcfg_name;
+   const char *input_name;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2412,7 +2413,11 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
if (!input_dev)
return -ENOMEM;
 
-   input_dev->name = "Atmel maXTouch Touchscreen";
+   if (data->input_name)
+   input_dev->name = data->input_name;
+   else
+   input_dev->name = "Atmel maXTouch Touchscreen";
+
input_dev->phys = data->phys;
input_dev->id.bustype = BUS_I2C;
input_dev->dev.parent = dev;
@@ -3653,6 +3658,8 @@ static int mxt_parse_device_properties(struct mxt_data 
*data)
 
device_property_read_string(dev, "atmel,cfg_name", &data->pcfg_name);
 
+   device_property_read_string(dev, "atmel,input_name", &data->input_name);
+
if (device_property_present(dev, keymap_property)) {
n_keys = device_property_read_u32_array(dev, keymap_property,
NULL, 0);
-- 
2.19.2



[PATCH v2 16/49] Input: atmel_mxt_ts - allow specification of firmware file name

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

On platforms which have multiple device instances using this driver, the
firmware may be different on each device. This patch makes the user give
the name of the firmware file when flashing.

This also prevents accidental triggering of the firmware load process.

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
76ebb7cee971cb42dfb0a3a9224403b8b09abcf1)
[gdavis: Forward port and fix conflicts.]
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 43 
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 641dd14489e1..14f665f12778 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -33,8 +33,7 @@
 #include 
 #include 
 
-/* Firmware files */
-#define MXT_FW_NAME"maxtouch.fw"
+/* Configuration file */
 #define MXT_CFG_NAME   "maxtouch.cfg"
 #define MXT_CFG_MAGIC  "OBP_RAW V1"
 
@@ -335,6 +334,7 @@ struct mxt_data {
bool use_retrigen_workaround;
struct regulator *reg_vdd;
struct regulator *reg_avdd;
+   char *fw_name;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -3207,7 +3207,7 @@ static int mxt_check_firmware_format(struct device *dev,
return -EINVAL;
 }
 
-static int mxt_load_fw(struct device *dev, const char *fn)
+static int mxt_load_fw(struct device *dev)
 {
struct mxt_data *data = dev_get_drvdata(dev);
const struct firmware *fw = NULL;
@@ -3217,9 +3217,9 @@ static int mxt_load_fw(struct device *dev, const char *fn)
unsigned int frame = 0;
int ret;
 
-   ret = request_firmware(&fw, fn, dev);
+   ret = request_firmware(&fw, data->fw_name, dev);
if (ret) {
-   dev_err(dev, "Unable to open firmware %s\n", fn);
+   dev_err(dev, "Unable to open firmware %s\n", data->fw_name);
return ret;
}
 
@@ -3339,6 +3339,33 @@ static int mxt_load_fw(struct device *dev, const char 
*fn)
return ret;
 }
 
+static int mxt_update_file_name(struct device *dev, char **file_name,
+   const char *buf, size_t count)
+{
+   char *file_name_tmp;
+
+   /* Simple sanity check */
+   if (count > 64) {
+   dev_warn(dev, "File name too long\n");
+   return -EINVAL;
+   }
+
+   file_name_tmp = krealloc(*file_name, count + 1, GFP_KERNEL);
+   if (!file_name_tmp)
+   return -ENOMEM;
+
+   *file_name = file_name_tmp;
+   memcpy(*file_name, buf, count);
+
+   /* Echo into the sysfs entry may append newline at the end of buf */
+   if (buf[count - 1] == '\n')
+   (*file_name)[count - 1] = '\0';
+   else
+   (*file_name)[count] = '\0';
+
+   return 0;
+}
+
 static ssize_t mxt_update_fw_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -3346,7 +3373,11 @@ static ssize_t mxt_update_fw_store(struct device *dev,
struct mxt_data *data = dev_get_drvdata(dev);
int error;
 
-   error = mxt_load_fw(dev, MXT_FW_NAME);
+   error = mxt_update_file_name(dev, &data->fw_name, buf, count);
+   if (error)
+   return error;
+
+   error = mxt_load_fw(dev);
if (error) {
dev_err(dev, "The firmware update failed(%d)\n", error);
count = error;
-- 
2.19.2



[PATCH v2 15/49] Input: atmel_mxt_ts - report failures in suspend/resume

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

(cherry picked from ndyer/linux/for-upstream commit 
93a57575403de4dd07cd64807d3c2ed7f2cca262)
[gdavis: Resolve forward port conflicts due to applying upstream
 commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
 data support").]
Signed-off-by: George G. Davis 
[jiada: Fix compilation warning]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 51 ++--
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 83ac2f1ba3be..641dd14489e1 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3425,10 +3425,12 @@ static void mxt_reset_slots(struct mxt_data *data)
mxt_input_sync(data);
 }
 
-static void mxt_start(struct mxt_data *data)
+static int mxt_start(struct mxt_data *data)
 {
+   int ret = 0;
+
if (!data->suspended || data->in_bootloader)
-   return;
+   return 0;
 
switch (data->suspend_mode) {
case MXT_SUSPEND_T9_CTRL:
@@ -3453,28 +3455,42 @@ static void mxt_start(struct mxt_data *data)
 */
mxt_process_messages_until_invalid(data);
 
-   mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
+   ret = mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
+   if (ret)
+   return ret;
 
/* Recalibrate since chip has been in deep sleep */
-   mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
+   ret = mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
+   if (ret)
+   return ret;
+
+   ret = mxt_acquire_irq(data);
+   if (ret)
+   return ret;
 
-   mxt_acquire_irq(data);
break;
}
 
data->suspended = false;
+
+   return 0;
 }
 
-static void mxt_stop(struct mxt_data *data)
+static int mxt_stop(struct mxt_data *data)
 {
+   int ret;
+
if (data->suspended || data->in_bootloader)
-   return;
+   return 0;
 
switch (data->suspend_mode) {
case MXT_SUSPEND_T9_CTRL:
/* Touch disable */
-   mxt_write_object(data,
+   ret = mxt_write_object(data,
MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0);
+   if (ret)
+   return ret;
+
break;
 
case MXT_SUSPEND_REGULATOR:
@@ -3487,29 +3503,40 @@ static void mxt_stop(struct mxt_data *data)
default:
disable_irq(data->irq);
 
-   mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
+   ret = mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
+   if (ret)
+   return ret;
 
mxt_reset_slots(data);
break;
}
 
data->suspended = true;
+   return 0;
 }
 
 static int mxt_input_open(struct input_dev *dev)
 {
struct mxt_data *data = input_get_drvdata(dev);
+   int ret;
 
-   mxt_start(data);
+   ret = mxt_start(data);
 
-   return 0;
+   if (ret)
+   dev_err(&data->client->dev, "%s failed rc=%d\n", __func__, ret);
+
+   return ret;
 }
 
 static void mxt_input_close(struct input_dev *dev)
 {
struct mxt_data *data = input_get_drvdata(dev);
+   int ret;
 
-   mxt_stop(data);
+   ret = mxt_stop(data);
+
+   if (ret)
+   dev_err(&data->client->dev, "%s failed rc=%d\n", __func__, ret);
 }
 
 static int mxt_parse_device_properties(struct mxt_data *data)
-- 
2.19.2



[PATCH v2 17/49] Input: atmel_mxt_ts - handle cfg filename via pdata/sysfs

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

There may be multiple maXTouch chips on a single device which will require
different configuration files. Add a platform data value for the
configuration filename.

Add sysfs entry to write configuration file if the platform data is not
set.

Split out the object initialisation code from mxt_initialize() into
mxt_configure_objects() to allow this.

Signed-off-by: Nick Dyer 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
71a2a4d1954460b949a16b607f72bafab294ca79)
[gdavis: Resolve forward port conflicts due to applying upstream
 commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
 data support").]
Signed-off-by: George G. Davis 
[gdavis: Squash fix from Vladimir Zapolskiy:
 - Input: atmel_mxt_ts - fix error paths in mxt_configure_objects()]
Signed-off-by: Vladimir Zapolskiy 
---
Notes:
- Squash fix from Vladimir Zapolskiy:
  + Input: atmel_mxt_ts - fix error paths in mxt_configure_objects()

Fail in mxt_update_cfg() is critical, because the driver state machine
is broken and it can not be safely used afterwards.

[jiada: Squash fix from ndyer/linux/for-upstream commit 
c909ada856861f305653b127db3ea0fa60264331
- Input: atmel_mxt_ts - check data->input_dev is not null in 
mxt_input_sync()]
Signed-off-by: Jiada Wang 
---
 .../bindings/input/atmel,maxtouch.txt |   3 +
 drivers/input/touchscreen/atmel_mxt_ts.c  | 109 +++---
 2 files changed, 97 insertions(+), 15 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt 
b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
index e28139ce3cae..713ce870805c 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
@@ -37,6 +37,9 @@ Optional properties for main touchpad device:
 MXT_SUSPEND_REGULATOR - use regulators to power down device during suspend
 Definitions are in .
 
+- atmel,cfg_name: Provide name of configuration file in OBP_RAW format. This
+will be downloaded from the firmware loader on probe to the device.
+
 Example:
 
touch@4b {
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 14f665f12778..c6be716a974c 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -34,7 +34,6 @@
 #include 
 
 /* Configuration file */
-#define MXT_CFG_NAME   "maxtouch.cfg"
 #define MXT_CFG_MAGIC  "OBP_RAW V1"
 
 /* Registers */
@@ -335,6 +334,8 @@ struct mxt_data {
struct regulator *reg_vdd;
struct regulator *reg_avdd;
char *fw_name;
+   char *cfg_name;
+   const char *pcfg_name;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -377,6 +378,9 @@ struct mxt_data {
 
/* Indicates whether device is in suspend */
bool suspended;
+
+   /* Indicates whether device is updating configuration */
+   bool updating_config;
 };
 
 struct mxt_vb2_buffer {
@@ -833,9 +837,11 @@ static void mxt_input_button(struct mxt_data *data, u8 
*message)
 
 static void mxt_input_sync(struct mxt_data *data)
 {
-   input_mt_report_pointer_emulation(data->input_dev,
- data->t19_num_keys);
-   input_sync(data->input_dev);
+   if (data->input_dev) {
+   input_mt_report_pointer_emulation(data->input_dev,
+ data->t19_num_keys);
+   input_sync(data->input_dev);
+   }
 }
 
 static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
@@ -2578,13 +2584,21 @@ static int mxt_initialize(struct mxt_data *data)
if (error)
return error;
 
-   error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
-   &client->dev, GFP_KERNEL, data,
-   mxt_config_cb);
-   if (error) {
-   dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
-   error);
-   goto err_free_sysfs;
+   if (data->cfg_name) {
+   error = request_firmware_nowait(THIS_MODULE, true,
+   data->cfg_name,
+   &client->dev,
+   GFP_KERNEL, data,
+   mxt_config_cb);
+   if (error) {
+   dev_err(&client->dev, "Failed to invoke firmware 
loader: %d\n",
+   error);
+   goto err_free_sysfs;
+   }
+   } else {
+   error = mxt_configure_objects(data, NULL);
+   if (error)
+   goto err_free_sysfs;
}
 
return 0;
@@ -3081,19 +3095,21 @@ static int mxt_configure_objects(struct mxt_data *

Re: [PATCH] powerpc: Perform a bounds check in arch_add_memory

2019-08-26 Thread Michal Hocko
On Tue 27-08-19 15:20:46, Alastair D'Silva wrote:
> From: Alastair D'Silva 
> 
> It is possible for firmware to allocate memory ranges outside
> the range of physical memory that we support (MAX_PHYSMEM_BITS).

Doesn't that count as a FW bug? Do you have any evidence of that in the
field? Just wondering...

> This patch adds a bounds check to ensure that any hotplugged
> memory is addressable.
> 
> Signed-off-by: Alastair D'Silva 
> ---
>  arch/powerpc/mm/mem.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index 9191a66b3bc5..de18fb73de30 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -111,6 +111,9 @@ int __ref arch_add_memory(int nid, u64 start, u64 size,
>   unsigned long nr_pages = size >> PAGE_SHIFT;
>   int rc;
>  
> + if ((start + size - 1) >> MAX_PHYSMEM_BITS)
> + return -EINVAL;
> +
>   resize_hpt_for_hotplug(memblock_phys_mem_size());
>  
>   start = (unsigned long)__va(start);
> -- 
> 2.21.0

-- 
Michal Hocko
SUSE Labs


[PATCH v2 14/49] Input: atmel_mxt_ts - add regulator control support

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Allow the driver to optionally manage enabling/disable power to the touch
controller itself. If the regulators are not present then use the deep
sleep power mode instead.

For a correct power on sequence, it is required that we have control over
the RESET line.

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
14052b61bb66c2f2283c00e733e131be7a9b8bfc)
[gdavis: Resolve forward port conflicts due to v4.14-rc1 commmit
 f657b00df22e ("Input: atmel_mxt_ts - add support for reset
 line") and applying upstream commit 96a938aa214e ("Input:
 atmel_mxt_ts - remove platform data support").]
Signed-off-by: George G. Davis 
[gdavis: Squash fixes from Dirk Behme:
 - Input: atmel_mxt_ts - in failure case disable the regulator
 - Input: atmel_mxt_ts - disable only enabled regulators
 - Input: atmel_mxt_ts - use devm_regulator_get()]
Signed-off-by: Dirk Behme 
---
Notes:
- Squash fixes by Dirk Behme:
  + Input: atmel_mxt_ts - in failure case disable the regulator

If the second regulator_enable(), disable the previously enabled
regulator, again.
  + Input: atmel_mxt_ts - disable only enabled regulators

As enabling the regulators in mxt_regulator_enable() might fail,
check if the regulators are really enabled and disable them only
in this case.
  + Input: atmel_mxt_ts - use devm_regulator_get()

Switch to devm_regulator_get() enabling us to drop the regulator_put()
in the remove function.

[jiada: Resolve forward port conflicts due to commit
5cecc2bccc03f ("Input: atmel_mxt_ts - fix
-Wunused-const-variable")]
Signed-off-by: Jiada Wang 
---
 .../bindings/input/atmel,maxtouch.txt |   6 +
 MAINTAINERS   |   1 +
 drivers/input/touchscreen/atmel_mxt_ts.c  | 129 --
 include/dt-bindings/input/atmel_mxt_ts.h  |  22 +++
 4 files changed, 149 insertions(+), 9 deletions(-)
 create mode 100644 include/dt-bindings/input/atmel_mxt_ts.h

diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt 
b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
index c88919480d37..e28139ce3cae 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
@@ -31,6 +31,12 @@ Optional properties for main touchpad device:
 
 - reset-gpios: GPIO specifier for the touchscreen's reset pin (active low)
 
+- atmel,suspend-mode: Select method used to suspend:
+MXT_SUSPEND_DEEP_SLEEP - use T7 to suspend the device into deep sleep
+MXT_SUSPEND_T9_CTRL - use T9.CTRL to turn off touch processing
+MXT_SUSPEND_REGULATOR - use regulators to power down device during suspend
+Definitions are in .
+
 Example:
 
touch@4b {
diff --git a/MAINTAINERS b/MAINTAINERS
index 47800d32cfbc..1509bb9072fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2777,6 +2777,7 @@ T:git git://github.com/ndyer/linux.git
 S: Maintained
 F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
 F: drivers/input/touchscreen/atmel_mxt_ts.c
+F: include/dt-bindings/input/atmel_mxt_ts.h
 
 ATMEL WIRELESS DRIVER
 M: Simon Kelley 
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4d28b30c4f76..83ac2f1ba3be 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -26,10 +26,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 /* Firmware files */
 #define MXT_FW_NAME"maxtouch.fw"
@@ -215,6 +217,9 @@ enum t100_type {
 #define MXT_CRC_TIMEOUT1000/* msec */
 #define MXT_FW_RESET_TIME  3000/* msec */
 #define MXT_FW_CHG_TIMEOUT 300 /* msec */
+#define MXT_REGULATOR_DELAY150 /* msec */
+#define MXT_CHG_DELAY  100 /* msec */
+#define MXT_POWERON_DELAY  150 /* msec */
 
 /* Command to unlock bootloader */
 #define MXT_UNLOCK_CMD_MSB 0xaa
@@ -275,11 +280,6 @@ enum v4l_dbg_inputs {
MXT_V4L_INPUT_MAX,
 };
 
-enum mxt_suspend_mode {
-   MXT_SUSPEND_DEEP_SLEEP  = 0,
-   MXT_SUSPEND_T9_CTRL = 1,
-};
-
 /* Config update context */
 struct mxt_cfg {
u8 *raw;
@@ -333,6 +333,8 @@ struct mxt_data {
u8 stylus_aux_pressure;
u8 stylus_aux_peak;
bool use_retrigen_workaround;
+   struct regulator *reg_vdd;
+   struct regulator *reg_avdd;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2073,6 +2075,94 @@ static int mxt_read_info_block(struct mxt_data *data)
return error;
 }
 
+static void mxt_regulator_enable(struct mxt_data *data)
+{
+   int error;
+
+   if (!data->reg_vdd || !data->reg_avdd)
+   return;
+
+   gpiod_set_value(data->reset_gpio, 0);
+
+   error = regulator_ena

[PATCH v2 05/49] Input: atmel_mxt_ts - split large i2c transfers into blocks

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

On some firmware variants, the size of the info block exceeds what can
be read in a single transfer.

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
74c4f5277cfa403d43fafc404119dc57a08677db)
[gdavis: Forward port and fix conflicts due to v4.14.51 commit
 960fe000b1d3 ("Input: atmel_mxt_ts - fix the firmware
 update").]
Signed-off-by: George G. Davis 
[jiada: Change mxt_read_blks() to __mxt_read_reg(), original __mxt_read_reg() to
__mxt_read_chunk()]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 28 +---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 35cbe60094ab..45bab5253775 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -40,7 +40,7 @@
 #define MXT_OBJECT_START   0x07
 #define MXT_OBJECT_SIZE6
 #define MXT_INFO_CHECKSUM_SIZE 3
-#define MXT_MAX_BLOCK_WRITE256
+#define MXT_MAX_BLOCK_WRITE255
 
 /* Object types */
 #define MXT_DEBUG_DIAGNOSTIC_T37   37
@@ -624,8 +624,8 @@ static int mxt_send_bootloader_cmd(struct mxt_data *data, 
bool unlock)
return 0;
 }
 
-static int __mxt_read_reg(struct i2c_client *client,
-  u16 reg, u16 len, void *val)
+static int __mxt_read_chunk(struct i2c_client *client,
+   u16 reg, u16 len, void *val)
 {
struct i2c_msg xfer[2];
u8 buf[2];
@@ -659,6 +659,28 @@ static int __mxt_read_reg(struct i2c_client *client,
return ret;
 }
 
+static int __mxt_read_reg(struct i2c_client *client,
+ u16 reg, u16 len, void *buf)
+{
+   u16 offset = 0;
+   int error;
+   u16 size;
+
+   while (offset < len) {
+   size = min(MXT_MAX_BLOCK_WRITE, len - offset);
+
+   error = __mxt_read_chunk(client,
+reg + offset,
+size, buf + offset);
+   if (error)
+   return error;
+
+   offset += size;
+   }
+
+   return 0;
+}
+
 static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
   const void *val)
 {
-- 
2.19.2



[PATCH v2 06/49] Input: atmel_mxt_ts - output status from T48 Noise Supression

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
2895a6ff150a49f27a02938f8d262be238b296d8)
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 25 
 1 file changed, 25 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 45bab5253775..351347e2eced 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -324,6 +324,7 @@ struct mxt_data {
u16 T18_address;
u8 T19_reportid;
u16 T44_address;
+   u8 T48_reportid;
u8 T100_reportid_min;
u8 T100_reportid_max;
 
@@ -978,6 +979,24 @@ static void mxt_proc_t100_message(struct mxt_data *data, 
u8 *message)
data->update_input = true;
 }
 
+static int mxt_proc_t48_messages(struct mxt_data *data, u8 *msg)
+{
+   struct device *dev = &data->client->dev;
+   u8 status, state;
+
+   status = msg[1];
+   state  = msg[4];
+
+   dev_dbg(dev, "T48 state %d status %02X %s%s%s%s%s\n", state, status,
+   status & 0x01 ? "FREQCHG " : "",
+   status & 0x02 ? "APXCHG " : "",
+   status & 0x04 ? "ALGOERR " : "",
+   status & 0x10 ? "STATCHG " : "",
+   status & 0x20 ? "NLVLCHG " : "");
+
+   return 0;
+}
+
 static int mxt_proc_message(struct mxt_data *data, u8 *message)
 {
u8 report_id = message[0];
@@ -987,6 +1006,8 @@ static int mxt_proc_message(struct mxt_data *data, u8 
*message)
 
if (report_id == data->T6_reportid) {
mxt_proc_t6_messages(data, message);
+   } else if (report_id == data->T48_reportid) {
+   mxt_proc_t48_messages(data, message);
} else if (!data->input_dev) {
/*
 * Do not report events if input device
@@ -1666,6 +1687,7 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T18_address = 0;
data->T19_reportid = 0;
data->T44_address = 0;
+   data->T48_reportid = 0;
data->T100_reportid_min = 0;
data->T100_reportid_max = 0;
data->max_reportid = 0;
@@ -1747,6 +1769,9 @@ static int mxt_parse_object_table(struct mxt_data *data,
case MXT_SPT_GPIOPWM_T19:
data->T19_reportid = min_id;
break;
+   case MXT_PROCG_NOISESUPPRESSION_T48:
+   data->T48_reportid = min_id;
+   break;
case MXT_TOUCH_MULTITOUCHSCREEN_T100:
data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100;
data->T100_reportid_min = min_id;
-- 
2.19.2



[PATCH v2 13/49] Input: atmel_mxt_ts - release touch state during suspend

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

If fingers are down as the MXT chip goes into suspend it does not send a
lift message. In addition, it may not complete its final measurement cycle
immediately, which means touch messages may be received by the interrupt
handler after mxt_stop() has completed.

So:
- disable irq during suspend
- flush any messages created after suspend
- tell app layer that slots were released at suspend

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
26794433086dbc7dea18d2f6a1c8d61ab25bcfda)
[gdavis: Resolve forward port conflicts due to applying upstream
 commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
 data support").]
Signed-off-by: George G. Davis 
[gdavis: Squash fix from Dirk Behme:
 - Input: atmel_mxt_ts - remove superfluous data->suspended]
Signed-off-by: Dirk Behme 
---
Notes:
- Squash fix from Dirk Behme:
  + Input: atmel_mxt_ts - remove superfluous data->suspended

data->suspended is already set to false in mxt_load_fw(), so it's not
needed here.

Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 52 ++--
 1 file changed, 49 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 26861252c088..4d28b30c4f76 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -372,6 +372,9 @@ struct mxt_data {
unsigned int t19_num_keys;
 
enum mxt_suspend_mode suspend_mode;
+
+   /* Indicates whether device is in suspend */
+   bool suspended;
 };
 
 struct mxt_vb2_buffer {
@@ -1151,10 +1154,10 @@ static int mxt_proc_message(struct mxt_data *data, u8 
*message)
mxt_proc_t42_messages(data, message);
} else if (report_id == data->T48_reportid) {
mxt_proc_t48_messages(data, message);
-   } else if (!data->input_dev) {
+   } else if (!data->input_dev || data->suspended) {
/*
-* Do not report events if input device
-* is not yet registered.
+* Do not report events if input device is not
+* yet registered or returning from suspend
 */
mxt_dump_message(data, message);
} else if (report_id >= data->T9_reportid_min &&
@@ -3135,6 +3138,11 @@ static int mxt_load_fw(struct device *dev, const char 
*fn)
if (ret)
goto release_firmware;
 
+   if (data->suspended) {
+   enable_irq(data->irq);
+   data->suspended = false;
+   }
+
if (!data->in_bootloader) {
/* Change to the bootloader mode */
data->in_bootloader = true;
@@ -3306,8 +3314,27 @@ static void mxt_sysfs_remove(struct mxt_data *data)
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
 }
 
+static void mxt_reset_slots(struct mxt_data *data)
+{
+   struct input_dev *input_dev = data->input_dev;
+   int id;
+
+   if (!input_dev)
+   return;
+
+   for (id = 0; id < data->num_touchids; id++) {
+   input_mt_slot(input_dev, id);
+   input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
+   }
+
+   mxt_input_sync(data);
+}
+
 static void mxt_start(struct mxt_data *data)
 {
+   if (!data->suspended || data->in_bootloader)
+   return;
+
switch (data->suspend_mode) {
case MXT_SUSPEND_T9_CTRL:
mxt_soft_reset(data);
@@ -3320,16 +3347,29 @@ static void mxt_start(struct mxt_data *data)
 
case MXT_SUSPEND_DEEP_SLEEP:
default:
+   /*
+* Discard any touch messages still in message buffer
+* from before chip went to sleep
+*/
+   mxt_process_messages_until_invalid(data);
+
mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
 
/* Recalibrate since chip has been in deep sleep */
mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
+
+   mxt_acquire_irq(data);
break;
}
+
+   data->suspended = false;
 }
 
 static void mxt_stop(struct mxt_data *data)
 {
+   if (data->suspended || data->in_bootloader)
+   return;
+
switch (data->suspend_mode) {
case MXT_SUSPEND_T9_CTRL:
/* Touch disable */
@@ -3339,9 +3379,15 @@ static void mxt_stop(struct mxt_data *data)
 
case MXT_SUSPEND_DEEP_SLEEP:
default:
+   disable_irq(data->irq);
+
mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
+
+   mxt_reset_slots(data);
break;
}
+
+   data->suspended = true;
 }
 
 static int mxt_input_open(struct input_dev *dev)
-- 
2.19.2



[PATCH v2 07/49] Input: atmel_mxt_ts - output status from T42 Touch Suppression

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
ab95b5a30d2c098daaa9f88d9fcfae7eb516)
Signed-off-by: George G. Davis 
[jiada: Replace dev_info() with dev_dbg()]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 25 
 1 file changed, 25 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 351347e2eced..19fa3e58269a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -155,6 +155,9 @@ struct t37_debug {
 #define MXT_RESET_VALUE0x01
 #define MXT_BACKUP_VALUE   0x55
 
+/* Define for MXT_PROCI_TOUCHSUPPRESSION_T42 */
+#define MXT_T42_MSG_TCHSUP BIT(0)
+
 /* T100 Multiple Touch Touchscreen */
 #define MXT_T100_CTRL  0
 #define MXT_T100_CFG1  1
@@ -323,6 +326,8 @@ struct mxt_data {
u8 T9_reportid_max;
u16 T18_address;
u8 T19_reportid;
+   u8 T42_reportid_min;
+   u8 T42_reportid_max;
u16 T44_address;
u8 T48_reportid;
u8 T100_reportid_min;
@@ -979,6 +984,17 @@ static void mxt_proc_t100_message(struct mxt_data *data, 
u8 *message)
data->update_input = true;
 }
 
+static void mxt_proc_t42_messages(struct mxt_data *data, u8 *msg)
+{
+   struct device *dev = &data->client->dev;
+   u8 status = msg[1];
+
+   if (status & MXT_T42_MSG_TCHSUP)
+   dev_dbg(dev, "T42 suppress\n");
+   else
+   dev_dbg(dev, "T42 normal\n");
+}
+
 static int mxt_proc_t48_messages(struct mxt_data *data, u8 *msg)
 {
struct device *dev = &data->client->dev;
@@ -1006,6 +1022,9 @@ static int mxt_proc_message(struct mxt_data *data, u8 
*message)
 
if (report_id == data->T6_reportid) {
mxt_proc_t6_messages(data, message);
+   } else if (report_id >= data->T42_reportid_min
+  && report_id <= data->T42_reportid_max) {
+   mxt_proc_t42_messages(data, message);
} else if (report_id == data->T48_reportid) {
mxt_proc_t48_messages(data, message);
} else if (!data->input_dev) {
@@ -1686,6 +1705,8 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T9_reportid_max = 0;
data->T18_address = 0;
data->T19_reportid = 0;
+   data->T42_reportid_min = 0;
+   data->T42_reportid_max = 0;
data->T44_address = 0;
data->T48_reportid = 0;
data->T100_reportid_min = 0;
@@ -1763,6 +1784,10 @@ static int mxt_parse_object_table(struct mxt_data *data,
case MXT_SPT_COMMSCONFIG_T18:
data->T18_address = object->start_address;
break;
+   case MXT_PROCI_TOUCHSUPPRESSION_T42:
+   data->T42_reportid_min = min_id;
+   data->T42_reportid_max = max_id;
+   break;
case MXT_SPT_MESSAGECOUNT_T44:
data->T44_address = object->start_address;
break;
-- 
2.19.2



[PATCH v2 11/49] Input: atmel_mxt_ts - implement support for T107 active stylus

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
20e357dd9acf8c2040068c8b22d6bc1401a1893f)
[gdavis: Forward port and fix conflicts due to applying upstream commit
 96a938aa214e ("Input: atmel_mxt_ts - remove platform data
 support").]
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 117 ++-
 1 file changed, 113 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 83dad225458e..4e237209cb34 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -72,6 +72,7 @@
 #define MXT_SPT_CTECONFIG_T46  46
 #define MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71 71
 #define MXT_TOUCH_MULTITOUCHSCREEN_T100 100
+#define MXT_PROCI_ACTIVESTYLUS_T107107
 
 /* MXT_GEN_MESSAGE_T5 object */
 #define MXT_RPTID_NOMSG0xff
@@ -181,6 +182,7 @@ struct t37_debug {
 enum t100_type {
MXT_T100_TYPE_FINGER= 1,
MXT_T100_TYPE_PASSIVE_STYLUS= 2,
+   MXT_T100_TYPE_ACTIVE_STYLUS = 3,
MXT_T100_TYPE_HOVERING_FINGER   = 4,
MXT_T100_TYPE_GLOVE = 5,
MXT_T100_TYPE_LARGE_TOUCH   = 6,
@@ -192,6 +194,16 @@ enum t100_type {
 #define MXT_TOUCH_MAJOR_DEFAULT1
 #define MXT_PRESSURE_DEFAULT   1
 
+/* Gen2 Active Stylus */
+#define MXT_T107_STYLUS_STYAUX 42
+#define MXT_T107_STYLUS_STYAUX_PRESSUREBIT(0)
+#define MXT_T107_STYLUS_STYAUX_PEAKBIT(4)
+
+#define MXT_T107_STYLUS_HOVER  BIT(0)
+#define MXT_T107_STYLUS_TIPSWITCH  BIT(1)
+#define MXT_T107_STYLUS_BUTTON0BIT(2)
+#define MXT_T107_STYLUS_BUTTON1BIT(3)
+
 /* Delay times */
 #define MXT_BACKUP_TIME50  /* msec */
 #define MXT_RESET_GPIO_TIME20  /* msec */
@@ -313,10 +325,12 @@ struct mxt_data {
struct t7_config t7_cfg;
struct mxt_dbg dbg;
struct gpio_desc *reset_gpio;
-   bool use_retrigen_workaround;
unsigned long t15_keystatus;
int t15_num_keys;
const unsigned int *t15_keymap;
+   u8 stylus_aux_pressure;
+   u8 stylus_aux_peak;
+   bool use_retrigen_workaround;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -337,6 +351,7 @@ struct mxt_data {
u8 T48_reportid;
u8 T100_reportid_min;
u8 T100_reportid_max;
+   u16 T107_address;
 
/* for fw update in bootloader */
struct completion bl_completion;
@@ -908,6 +923,8 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 
*message)
u8 major = 0;
u8 pressure = 0;
u8 orientation = 0;
+   bool active = false;
+   bool hover = false;
 
id = message[0] - data->T100_reportid_min - 2;
 
@@ -926,6 +943,8 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 
*message)
case MXT_T100_TYPE_HOVERING_FINGER:
tool = MT_TOOL_FINGER;
distance = MXT_DISTANCE_HOVERING;
+   hover = true;
+   active = true;
 
if (data->t100_aux_vect)
orientation = message[data->t100_aux_vect];
@@ -936,6 +955,8 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 
*message)
case MXT_T100_TYPE_GLOVE:
tool = MT_TOOL_FINGER;
distance = MXT_DISTANCE_ACTIVE_TOUCH;
+   hover = false;
+   active = true;
 
if (data->t100_aux_area)
major = message[data->t100_aux_area];
@@ -950,6 +971,9 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 
*message)
 
case MXT_T100_TYPE_PASSIVE_STYLUS:
tool = MT_TOOL_PEN;
+   distance = MXT_DISTANCE_ACTIVE_TOUCH;
+   hover = false;
+   active = true;
 
/*
 * Passive stylus is reported with size zero so
@@ -962,6 +986,31 @@ static void mxt_proc_t100_message(struct mxt_data *data, 
u8 *message)
 
break;
 
+   case MXT_T100_TYPE_ACTIVE_STYLUS:
+   /* Report input buttons */
+   input_report_key(input_dev, BTN_STYLUS,
+message[6] & MXT_T107_STYLUS_BUTTON0);
+   input_report_key(input_dev, BTN_STYLUS2,
+message[6] & MXT_T107_STYLUS_BUTTON1);
+
+   /* stylus in range, but position unavailable */
+   if (!(message[6] & MXT_T107_STYLUS_HOVER))
+   break;
+
+   tool = MT_TOOL_

[PATCH v2 08/49] Input: atmel_mxt_ts - implement T9 vector/orientation support

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

The atmel touch messages contain orientation information as a byte in a
packed format which can be passed straight on to Android if the input
device configuration is correct.

This requires vector reports to be enabled in maXTouch config (zero
DISVECT bit 3 in T9 CTRL field)

Android converts the format in InputReader.cpp, search for
ORIENTATION_CALIBRATION_VECTOR.

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
a6f0ee919d2631678169b23fb18f55b6dbabcd4c)
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 19fa3e58269a..68c8237f7932 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -817,6 +817,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
int y;
int area;
int amplitude;
+   u8 vector;
 
id = message[0] - data->T9_reportid_min;
status = message[1];
@@ -831,9 +832,10 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
 
area = message[5];
amplitude = message[6];
+   vector = message[7];
 
dev_dbg(dev,
-   "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n",
+   "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u vector: 
%02X\n",
id,
(status & MXT_T9_DETECT) ? 'D' : '.',
(status & MXT_T9_PRESS) ? 'P' : '.',
@@ -843,7 +845,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
(status & MXT_T9_AMP) ? 'A' : '.',
(status & MXT_T9_SUPPRESS) ? 'S' : '.',
(status & MXT_T9_UNGRIP) ? 'U' : '.',
-   x, y, area, amplitude);
+   x, y, area, amplitude, vector);
 
input_mt_slot(input_dev, id);
 
@@ -868,6 +870,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude);
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
+   input_report_abs(input_dev, ABS_MT_ORIENTATION, vector);
} else {
/* Touch no longer active, close out slot */
input_mt_report_slot_inactive(input_dev);
@@ -2180,8 +2183,9 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
 0, 255, 0, 0);
}
 
-   if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
-   data->t100_aux_vect) {
+   if (data->multitouch == MXT_TOUCH_MULTI_T9 ||
+   (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
+   data->t100_aux_vect)) {
input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
 0, 255, 0, 0);
}
-- 
2.19.2



[PATCH v2 09/49] Input: atmel_mxt_ts - implement T15 Key Array support

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

There is a key array object in many maXTouch chips which allows some X/Y
lines to be used as a key array. This patch maps them to a series of keys
which may be configured in a platform data array.

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
15bb074b5abf3a101f7b79544213f1c110ea4cab)
[gdavis: Resolve forward port conflicts due to applying upstream
 commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
 data support").]
Signed-off-by: George G. Davis 
[jiada: Fix compilation warning]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 85 
 1 file changed, 85 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 68c8237f7932..1d738c488bdd 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -314,6 +314,9 @@ struct mxt_data {
struct mxt_dbg dbg;
struct gpio_desc *reset_gpio;
bool use_retrigen_workaround;
+   unsigned long t15_keystatus;
+   int t15_num_keys;
+   const unsigned int *t15_keymap;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -324,6 +327,8 @@ struct mxt_data {
u16 T71_address;
u8 T9_reportid_min;
u8 T9_reportid_max;
+   u8 T15_reportid_min;
+   u8 T15_reportid_max;
u16 T18_address;
u8 T19_reportid;
u8 T42_reportid_min;
@@ -987,6 +992,38 @@ static void mxt_proc_t100_message(struct mxt_data *data, 
u8 *message)
data->update_input = true;
 }
 
+static void mxt_proc_t15_messages(struct mxt_data *data, u8 *msg)
+{
+   struct input_dev *input_dev = data->input_dev;
+   struct device *dev = &data->client->dev;
+   int key;
+   bool curr_state, new_state;
+   bool sync = false;
+   unsigned long keystates = le32_to_cpu((__force __le32)msg[2]);
+
+   for (key = 0; key < data->t15_num_keys; key++) {
+   curr_state = test_bit(key, &data->t15_keystatus);
+   new_state = test_bit(key, &keystates);
+
+   if (!curr_state && new_state) {
+   dev_dbg(dev, "T15 key press: %u\n", key);
+   __set_bit(key, &data->t15_keystatus);
+   input_event(input_dev, EV_KEY,
+   data->t15_keymap[key], 1);
+   sync = true;
+   } else if (curr_state && !new_state) {
+   dev_dbg(dev, "T15 key release: %u\n", key);
+   __clear_bit(key, &data->t15_keystatus);
+   input_event(input_dev, EV_KEY,
+   data->t15_keymap[key], 0);
+   sync = true;
+   }
+   }
+
+   if (sync)
+   input_sync(input_dev);
+}
+
 static void mxt_proc_t42_messages(struct mxt_data *data, u8 *msg)
 {
struct device *dev = &data->client->dev;
@@ -1045,6 +1082,9 @@ static int mxt_proc_message(struct mxt_data *data, u8 
*message)
} else if (report_id == data->T19_reportid) {
mxt_input_button(data, message);
data->update_input = true;
+   } else if (report_id >= data->T15_reportid_min
+  && report_id <= data->T15_reportid_max) {
+   mxt_proc_t15_messages(data, message);
} else {
mxt_dump_message(data, message);
}
@@ -1706,6 +1746,8 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T71_address = 0;
data->T9_reportid_min = 0;
data->T9_reportid_max = 0;
+   data->T15_reportid_min = 0;
+   data->T15_reportid_max = 0;
data->T18_address = 0;
data->T19_reportid = 0;
data->T42_reportid_min = 0;
@@ -1784,6 +1826,10 @@ static int mxt_parse_object_table(struct mxt_data *data,
object->num_report_ids - 1;
data->num_touchids = object->num_report_ids;
break;
+   case MXT_TOUCH_KEYARRAY_T15:
+   data->T15_reportid_min = min_id;
+   data->T15_reportid_max = max_id;
+   break;
case MXT_SPT_COMMSCONFIG_T18:
data->T18_address = object->start_address;
break;
@@ -2077,6 +2123,7 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
int error;
unsigned int num_mt_slots;
unsigned int mt_flags = 0;
+   int i;
 
switch (data->multitouch) {
case MXT_TOUCH_MULTI_T9:
@@ -2190,6 +2237,15 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
 0, 255, 0, 0);
}
 
+   /* For T15 Key Array */
+   if (data->T15_reportid_min) {
+   data

[PATCH v2 12/49] Input: atmel_mxt_ts - add debug for T92 gesture and T93 touch seq msgs

2019-08-26 Thread Jiada Wang
From: Karl Tsou 

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
cb98986f8342107bf4a536aed4160b20839e97c1)
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4e237209cb34..26861252c088 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -71,6 +71,8 @@
 #define MXT_SPT_MESSAGECOUNT_T44   44
 #define MXT_SPT_CTECONFIG_T46  46
 #define MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71 71
+#define MXT_PROCI_SYMBOLGESTUREPROCESSOR   92
+#define MXT_PROCI_TOUCHSEQUENCELOGGER  93
 #define MXT_TOUCH_MULTITOUCHSCREEN_T100 100
 #define MXT_PROCI_ACTIVESTYLUS_T107107
 
@@ -349,6 +351,10 @@ struct mxt_data {
u8 T42_reportid_max;
u16 T44_address;
u8 T48_reportid;
+   u16 T92_address;
+   u8 T92_reportid;
+   u16 T93_address;
+   u8 T93_reportid;
u8 T100_reportid_min;
u8 T100_reportid_max;
u16 T107_address;
@@ -1113,6 +1119,24 @@ static int mxt_proc_t48_messages(struct mxt_data *data, 
u8 *msg)
return 0;
 }
 
+static void mxt_proc_t92_messages(struct mxt_data *data, u8 *msg)
+{
+   struct device *dev = &data->client->dev;
+   u8 status = msg[1];
+
+   dev_info(dev, "T92 long stroke LSTR=%d %d\n",
+(status & 0x80) ? 1 : 0,
+status & 0x0F);
+}
+
+static void mxt_proc_t93_messages(struct mxt_data *data, u8 *msg)
+{
+   struct device *dev = &data->client->dev;
+   u8 status = msg[1];
+
+   dev_info(dev, "T93 report double tap %d\n", status);
+}
+
 static int mxt_proc_message(struct mxt_data *data, u8 *message)
 {
u8 report_id = message[0];
@@ -1145,6 +1169,10 @@ static int mxt_proc_message(struct mxt_data *data, u8 
*message)
} else if (report_id >= data->T15_reportid_min
   && report_id <= data->T15_reportid_max) {
mxt_proc_t15_messages(data, message);
+   } else if (report_id == data->T92_reportid) {
+   mxt_proc_t92_messages(data, message);
+   } else if (report_id == data->T93_reportid) {
+   mxt_proc_t93_messages(data, message);
} else {
mxt_dump_message(data, message);
}
@@ -1814,6 +1842,10 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T42_reportid_max = 0;
data->T44_address = 0;
data->T48_reportid = 0;
+   data->T92_reportid = 0;
+   data->T92_address = 0;
+   data->T93_reportid = 0;
+   data->T93_address = 0;
data->T100_reportid_min = 0;
data->T100_reportid_max = 0;
data->max_reportid = 0;
@@ -1906,6 +1938,14 @@ static int mxt_parse_object_table(struct mxt_data *data,
case MXT_PROCG_NOISESUPPRESSION_T48:
data->T48_reportid = min_id;
break;
+   case MXT_PROCI_SYMBOLGESTUREPROCESSOR:
+   data->T92_reportid = min_id;
+   data->T92_address = object->start_address;
+   break;
+   case MXT_PROCI_TOUCHSEQUENCELOGGER:
+   data->T93_reportid = min_id;
+   data->T93_address = object->start_address;
+   break;
case MXT_TOUCH_MULTITOUCHSCREEN_T100:
data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100;
data->T100_reportid_min = min_id;
-- 
2.19.2



[PATCH v2 10/49] Input: atmel_mxt_ts - handle reports from T47 Stylus object

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
56405a5ea08eb34cfe83f3121867c9de0a5c48c1)
Signed-off-by: George G. Davis 
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 1d738c488bdd..83dad225458e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -823,6 +823,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
int area;
int amplitude;
u8 vector;
+   int tool;
 
id = message[0] - data->T9_reportid_min;
status = message[1];
@@ -836,6 +837,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
y >>= 2;
 
area = message[5];
+
amplitude = message[6];
vector = message[7];
 
@@ -865,12 +867,20 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
mxt_input_sync(data);
}
 
+   /* A size of zero indicates touch is from a linked T47 Stylus */
+   if (area == 0) {
+   area = MXT_TOUCH_MAJOR_DEFAULT;
+   tool = MT_TOOL_PEN;
+   } else {
+   tool = MT_TOOL_FINGER;
+   }
+
/* if active, pressure must be non-zero */
if (!amplitude)
amplitude = MXT_PRESSURE_DEFAULT;
 
/* Touch active */
-   input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
+   input_mt_report_slot_state(input_dev, tool, 1);
input_report_abs(input_dev, ABS_MT_POSITION_X, x);
input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude);
-- 
2.19.2



[PATCH v2 01/49] Input: switch to use return value of input_mt_report_slot_state

2019-08-26 Thread Jiada Wang
Currently several places are calling input_mt_report_slot_state()
like following:

input_mt_report_slot_state(dev, tool_type, active)
if (active) {
...
< report events for active slot >
}

when 'active' is false, input_mt_report_slot_state() will always
return false, so instead of checking 'active', switch to use
return value of input_mt_report_slot_state()

Signed-off-by: Jiada Wang 
---
 drivers/hid/hid-asus.c  |  3 +--
 drivers/hid/hid-elan.c  |  3 +--
 drivers/hid/hid-logitech-hidpp.c|  5 ++---
 drivers/hid/hid-magicmouse.c|  3 +--
 drivers/hid/hid-multitouch.c|  3 +--
 drivers/hid/hid-sony.c  |  8 
 drivers/hid/wacom_wac.c | 15 +--
 drivers/input/mouse/elantech.c  |  5 ++---
 drivers/input/mouse/focaltech.c |  3 +--
 drivers/input/mouse/sentelic.c  |  3 +--
 drivers/input/mouse/synaptics.c |  3 +--
 drivers/input/rmi4/rmi_2d_sensor.c  |  6 ++
 drivers/input/touchscreen/chipone_icn8505.c |  4 ++--
 drivers/input/touchscreen/egalax_ts.c   |  3 +--
 drivers/input/touchscreen/hideep.c  |  7 +++
 drivers/input/touchscreen/ili210x.c |  3 +--
 drivers/input/touchscreen/mms114.c  |  4 ++--
 drivers/input/touchscreen/penmount.c|  5 ++---
 drivers/input/touchscreen/raydium_i2c_ts.c  |  4 ++--
 drivers/input/touchscreen/sis_i2c.c |  5 ++---
 drivers/input/touchscreen/surface3_spi.c|  4 ++--
 drivers/input/touchscreen/wacom_w8001.c |  3 +--
 drivers/input/touchscreen/zforce_ts.c   |  6 ++
 23 files changed, 42 insertions(+), 66 deletions(-)

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 8063b1d567b1..55f1004f0e58 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -240,9 +240,8 @@ static int asus_report_input(struct asus_drvdata *drvdat, 
u8 *data, int size)
MT_TOOL_PALM : MT_TOOL_FINGER;
 
input_mt_slot(drvdat->input, i);
-   input_mt_report_slot_state(drvdat->input, toolType, down);
 
-   if (down) {
+   if (input_mt_report_slot_state(drvdat->input, toolType, down)) {
asus_report_contact_down(drvdat, toolType, contactData);
contactData += drvdat->tp->contact_size;
}
diff --git a/drivers/hid/hid-elan.c b/drivers/hid/hid-elan.c
index 45c4f888b7c4..84a317c6feb6 100644
--- a/drivers/hid/hid-elan.c
+++ b/drivers/hid/hid-elan.c
@@ -216,8 +216,7 @@ static void elan_report_mt_slot(struct elan_drvdata 
*drvdata, u8 *data,
bool active = !!data;
 
input_mt_slot(input, slot_num);
-   input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
-   if (active) {
+   if (input_mt_report_slot_state(input, MT_TOOL_FINGER, active)) {
x = ((data[0] & 0xF0) << 4) | data[1];
y = drvdata->max_y -
(((data[0] & 0x07) << 8) | data[2]);
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 21268c9fa71a..a7b552a797f1 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -2295,9 +2295,8 @@ static void wtp_touch_event(struct hidpp_device *hidpp,
slot = input_mt_get_slot_by_key(hidpp->input, touch_report->finger_id);
 
input_mt_slot(hidpp->input, slot);
-   input_mt_report_slot_state(hidpp->input, MT_TOOL_FINGER,
-   touch_report->contact_status);
-   if (touch_report->contact_status) {
+   if (input_mt_report_slot_state(hidpp->input, MT_TOOL_FINGER,
+   touch_report->contact_status)) {
input_event(hidpp->input, EV_ABS, ABS_MT_POSITION_X,
touch_report->x);
input_event(hidpp->input, EV_ABS, ABS_MT_POSITION_Y,
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 34138667f8af..5f9f6426d7b8 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -282,10 +282,9 @@ static void magicmouse_emit_touch(struct magicmouse_sc 
*msc, int raw_id, u8 *tda
msc->ntouches++;
 
input_mt_slot(input, id);
-   input_mt_report_slot_state(input, MT_TOOL_FINGER, down);
 
/* Generate the input events for this touch. */
-   if (down) {
+   if (input_mt_report_slot_state(input, MT_TOOL_FINGER, down)) {
input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
input_report_abs(input, ABS_MT_ORIENTATION, -orientation);
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index b603c14d043b..672396ed413e 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1020,8 +1020,7

[PATCH v2 02/49] Input: introduce input_mt_report_slot_inactive

2019-08-26 Thread Jiada Wang
input_mt_report_slot_state() ignores the tool when the slot is closed.
which has caused a bit of confusion.
This patch introduces input_mt_report_slot_inactive() to report slot
inactive state.
replaces all input_mt_report_slot_state() with
input_mt_report_slot_inactive() in case of close of slot.

Signed-off-by: Jiada Wang 
---
 drivers/hid/hid-alps.c | 3 +--
 drivers/hid/hid-multitouch.c   | 6 ++
 drivers/input/input-mt.c   | 2 +-
 drivers/input/misc/xen-kbdfront.c  | 2 +-
 drivers/input/mouse/elan_i2c_core.c| 2 +-
 drivers/input/touchscreen/atmel_mxt_ts.c   | 7 +++
 drivers/input/touchscreen/cyttsp4_core.c   | 5 ++---
 drivers/input/touchscreen/cyttsp_core.c| 2 +-
 drivers/input/touchscreen/melfas_mip4.c| 4 ++--
 drivers/input/touchscreen/mms114.c | 2 +-
 drivers/input/touchscreen/raspberrypi-ts.c | 2 +-
 drivers/input/touchscreen/stmfts.c | 2 +-
 include/linux/input/mt.h   | 5 +
 13 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
index ae79a7c66737..36ca1d815d53 100644
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -387,8 +387,7 @@ static int u1_raw_event(struct alps_dev *hdata, u8 *data, 
int size)
input_report_abs(hdata->input,
ABS_MT_PRESSURE, z);
} else {
-   input_mt_report_slot_state(hdata->input,
-   MT_TOOL_FINGER, 0);
+   input_mt_report_slot_inactive(hdata->input);
}
}
 
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 672396ed413e..b2221f2030c1 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -880,7 +880,7 @@ static void mt_release_pending_palms(struct mt_device *td,
clear_bit(slotnum, app->pending_palm_slots);
 
input_mt_slot(input, slotnum);
-   input_mt_report_slot_state(input, MT_TOOL_PALM, false);
+   input_mt_report_slot_inactive(input);
 
need_sync = true;
}
@@ -1620,9 +1620,7 @@ static void mt_release_contacts(struct hid_device *hid)
if (mt) {
for (i = 0; i < mt->num_slots; i++) {
input_mt_slot(input_dev, i);
-   input_mt_report_slot_state(input_dev,
-  MT_TOOL_FINGER,
-  false);
+   input_mt_report_slot_inactive(input_dev);
}
input_mt_sync_frame(input_dev);
input_sync(input_dev);
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index a81e14148407..7626fe5bfe44 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -145,7 +145,7 @@ bool input_mt_report_slot_state(struct input_dev *dev,
slot->frame = mt->frame;
 
if (!active) {
-   input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+   input_mt_report_slot_inactive(dev);
return false;
}
 
diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c
index 24bc5c5d876f..a1bba722b234 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -146,7 +146,7 @@ static void xenkbd_handle_mt_event(struct xenkbd_info *info,
break;
 
case XENKBD_MT_EV_UP:
-   input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, false);
+   input_mt_report_slot_inactive(info->mtouch);
break;
 
case XENKBD_MT_EV_SYN:
diff --git a/drivers/input/mouse/elan_i2c_core.c 
b/drivers/input/mouse/elan_i2c_core.c
index d9b103a81a79..b72358d4b35c 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -938,7 +938,7 @@ static void elan_report_contact(struct elan_tp_data *data,
input_report_abs(input, ABS_MT_TOUCH_MINOR, minor);
} else {
input_mt_slot(input, contact_num);
-   input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+   input_mt_report_slot_inactive(input);
}
 }
 
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4a5f482cf1af..573b94a049b2 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -822,8 +822,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
 * have happened.
 */
if (status & MXT_T9_RELEASE) {
-   input_mt_report_slot_state(input_dev,
-  

[PATCH v2 03/49] Input: atmel_mxt_ts - rework sysfs init/remove

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

An error in the sysfs init may otherwise interfere with the async return
from the firmware loader

Signed-off-by: Nick Dyer 
(cherry picked from ndyer/linux/for-upstream commit 
3114584ae77c2b03b6dad87174f010d002e9c05d)
[gdavis: Forward port and fixup conflicts. Also fixed sysfs leaks in
 both the mxt_initialize() and mxt_probe() error return cases.]
Signed-off-by: George G. Davis 
[jiada: keep call mxt_initialize() before sysfs creation]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 64 +++-
 1 file changed, 52 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 573b94a049b2..17263c260124 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2086,10 +2086,14 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
return 0;
 
 err_free_mem:
+   data->input_dev = NULL;
input_free_device(input_dev);
return error;
 }
 
+static int mxt_sysfs_init(struct mxt_data *data);
+static void mxt_sysfs_remove(struct mxt_data *data);
+
 static int mxt_configure_objects(struct mxt_data *data,
 const struct firmware *cfg);
 
@@ -2141,16 +2145,24 @@ static int mxt_initialize(struct mxt_data *data)
if (error)
return error;
 
+   error = mxt_sysfs_init(data);
+   if (error)
+   return error;
+
error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
&client->dev, GFP_KERNEL, data,
mxt_config_cb);
if (error) {
dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
error);
-   return error;
+   goto err_free_sysfs;
}
 
return 0;
+
+err_free_sysfs:
+   mxt_sysfs_remove(data);
+   return error;
 }
 
 static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep)
@@ -2803,6 +2815,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
if (ret)
goto release_firmware;
 
+   mxt_sysfs_remove(data);
mxt_free_input_device(data);
mxt_free_object_table(data);
} else {
@@ -2909,16 +2922,25 @@ static ssize_t mxt_update_fw_store(struct device *dev,
return count;
 }
 
+static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+static struct attribute *mxt_fw_attrs[] = {
+   &dev_attr_update_fw.attr,
+   NULL
+};
+
+static const struct attribute_group mxt_fw_attr_group = {
+   .attrs = mxt_fw_attrs,
+};
+
 static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
 static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
 static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
-static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
 
 static struct attribute *mxt_attrs[] = {
&dev_attr_fw_version.attr,
&dev_attr_hw_version.attr,
&dev_attr_object.attr,
-   &dev_attr_update_fw.attr,
NULL
 };
 
@@ -2926,6 +2948,28 @@ static const struct attribute_group mxt_attr_group = {
.attrs = mxt_attrs,
 };
 
+static int mxt_sysfs_init(struct mxt_data *data)
+{
+   struct i2c_client *client = data->client;
+   int error;
+
+   error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
+   if (error) {
+   dev_err(&client->dev, "Failure %d creating sysfs group\n",
+   error);
+   return error;
+   }
+
+   return 0;
+}
+
+static void mxt_sysfs_remove(struct mxt_data *data)
+{
+   struct i2c_client *client = data->client;
+
+   sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
+}
+
 static void mxt_start(struct mxt_data *data)
 {
switch (data->suspend_mode) {
@@ -3113,19 +3157,14 @@ static int mxt_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
if (error)
return error;
 
-   error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
+   error = sysfs_create_group(&client->dev.kobj, &mxt_fw_attr_group);
if (error) {
-   dev_err(&client->dev, "Failure %d creating sysfs group\n",
+   dev_err(&client->dev, "Failure %d creating fw sysfs group\n",
error);
-   goto err_free_object;
+   return error;
}
 
return 0;
-
-err_free_object:
-   mxt_free_input_device(data);
-   mxt_free_object_table(data);
-   return error;
 }
 
 static int mxt_remove(struct i2c_client *client)
@@ -3133,7 +3172,8 @@ static int mxt_remove(struct i2c_client *client)
struct mxt_data *data = i2c_get_clientdata(client);
 
disable_irq(data->irq);
-   sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);

[PATCH v2 04/49] Input: atmel_mxt_ts - only read messages in mxt_acquire_irq() when necessary

2019-08-26 Thread Jiada Wang
From: Nick Dyer 

The workaround of reading all messages until an invalid is received is a
way of forcing the CHG line high, which means that when using
edge-triggered interrupts the interrupt can be acquired.

With level-triggered interrupts the workaround is unnecessary.

Also, most recent maXTouch chips have a feature called RETRIGEN which, when
enabled, reasserts the interrupt line every cycle if there are messages
waiting. This also makes the workaround unnecessary.

Note: the RETRIGEN feature is only in some firmware versions/chips, it's
not valid simply to enable the bit.

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
(cherry picked from ndyer/linux/for-upstream commit 
1ae4e8281e491b22442cd5acdfca1862555f8ecb)
[gdavis: Fix conflicts due to v4.6-rc7 commit eb43335c4095 ("Input:
 atmel_mxt_ts - use mxt_acquire_irq in mxt_soft_reset").]
Signed-off-by: George G. Davis 
[jiada: reset use_retrigen_workaround at beginning of mxt_check_retrigen()]
Signed-off-by: Jiada Wang 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 51 ++--
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 17263c260124..35cbe60094ab 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -129,6 +130,7 @@ struct t9_range {
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
+#define MXT_COMMS_RETRIGEN  BIT(6)
 
 /* MXT_DEBUG_DIAGNOSTIC_T37 */
 #define MXT_DIAGNOSTIC_PAGEUP  0x01
@@ -308,6 +310,7 @@ struct mxt_data {
struct t7_config t7_cfg;
struct mxt_dbg dbg;
struct gpio_desc *reset_gpio;
+   bool use_retrigen_workaround;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -318,6 +321,7 @@ struct mxt_data {
u16 T71_address;
u8 T9_reportid_min;
u8 T9_reportid_max;
+   u16 T18_address;
u8 T19_reportid;
u16 T44_address;
u8 T100_reportid_min;
@@ -1190,9 +1194,11 @@ static int mxt_acquire_irq(struct mxt_data *data)
 
enable_irq(data->irq);
 
-   error = mxt_process_messages_until_invalid(data);
-   if (error)
-   return error;
+   if (data->use_retrigen_workaround) {
+   error = mxt_process_messages_until_invalid(data);
+   if (error)
+   return error;
+   }
 
return 0;
 }
@@ -1282,6 +1288,33 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, 
off_t end_off)
return crc;
 }
 
+static int mxt_check_retrigen(struct mxt_data *data)
+{
+   struct i2c_client *client = data->client;
+   int error;
+   int val;
+
+   data->use_retrigen_workaround = false;
+
+   if (irq_get_trigger_type(data->irq) & IRQF_TRIGGER_LOW)
+   return 0;
+
+   if (data->T18_address) {
+   error = __mxt_read_reg(client,
+  data->T18_address + MXT_COMMS_CTRL,
+  1, &val);
+   if (error)
+   return error;
+
+   if (val & MXT_COMMS_RETRIGEN)
+   return 0;
+   }
+
+   dev_warn(&client->dev, "Enabling RETRIGEN workaround\n");
+   data->use_retrigen_workaround = true;
+   return 0;
+}
+
 static int mxt_prepare_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg)
 {
struct device *dev = &data->client->dev;
@@ -1561,6 +1594,10 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
 
mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
 
+   ret = mxt_check_retrigen(data);
+   if (ret)
+   goto release_mem;
+
ret = mxt_soft_reset(data);
if (ret)
goto release_mem;
@@ -1604,6 +1641,7 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T71_address = 0;
data->T9_reportid_min = 0;
data->T9_reportid_max = 0;
+   data->T18_address = 0;
data->T19_reportid = 0;
data->T44_address = 0;
data->T100_reportid_min = 0;
@@ -1678,6 +1716,9 @@ static int mxt_parse_object_table(struct mxt_data *data,
object->num_report_ids - 1;
data->num_touchids = object->num_report_ids;
break;
+   case MXT_SPT_COMMSCONFIG_T18:
+   data->T18_address = object->start_address;
+   break;
case MXT_SPT_MESSAGECOUNT_T44:
data->T44_address = object->start_address;
break;
@@ -2141,6 +2182,10 @@ static int mxt_initialize(struct mxt_data *data)
msleep(MXT_FW_RESET_TIME);
}
 
+ 

[PATCH v2 00/49] atmel_mxt_ts misc

2019-08-26 Thread Jiada Wang
This patch-set forward ports Nick Dyer's work in ndyer/linux github repository
as long as some other features and fixes

Balasubramani Vivekanandan (2):
  Input: atmel_mxt_ts: Limit the max bytes transferred in an i2c
transaction
  Input: atmel_mxt_ts: use gpiod_set_value_cansleep for reset pin

Dean Jenkins (1):
  Input: atmel_mxt_ts: return error from
mxt_process_messages_until_invalid()

Deepak Das (6):
  Input: Atmel: improve error handling in mxt_start()
  Input: Atmel: improve error handling in mxt_initialize()
  Input: Atmel: improve error handling in mxt_update_cfg()
  Input: Atmel: Improve error handling in mxt_initialize_input_device()
  Input: Atmel: handle ReportID "0x00" while processing T5 messages
  Input: Atmel: use T44 object to process T5 messages

George G. Davis (1):
  input: atmel_mxt_ts: export GPIO reset line via sysfs

Jiada Wang (4):
  Input: switch to use return value of input_mt_report_slot_state
  Input: introduce input_mt_report_slot_inactive
  Input: atmel_mxt_ts - eliminate data->raw_info_block
  Input: atmel_mxt_ts - Fix compilation warning

Karl Tsou (1):
  Input: atmel_mxt_ts - add debug for T92 gesture and T93 touch seq msgs

Kautuk Consul (2):
  Input: atmel_mxt_ts - Change call-points of mxt_free_* functions
  Input: atmel_mxt_ts - rely on calculated_crc rather than file
config_crc

Naveen Chakka (2):
  input: touchscreen: atmel_mxt_ts: Added sysfs entry for touchscreen
status
  input: atmel_mxt_ts: added sysfs interface to update atmel T38 data

Nick Dyer (26):
  Input: atmel_mxt_ts - rework sysfs init/remove
  Input: atmel_mxt_ts - only read messages in mxt_acquire_irq() when
necessary
  Input: atmel_mxt_ts - split large i2c transfers into blocks
  Input: atmel_mxt_ts - output status from T48 Noise Supression
  Input: atmel_mxt_ts - output status from T42 Touch Suppression
  Input: atmel_mxt_ts - implement T9 vector/orientation support
  Input: atmel_mxt_ts - implement T15 Key Array support
  Input: atmel_mxt_ts - handle reports from T47 Stylus object
  Input: atmel_mxt_ts - implement support for T107 active stylus
  Input: atmel_mxt_ts - release touch state during suspend
  Input: atmel_mxt_ts - add regulator control support
  Input: atmel_mxt_ts - report failures in suspend/resume
  Input: atmel_mxt_ts - allow specification of firmware file name
  Input: atmel_mxt_ts - handle cfg filename via pdata/sysfs
  Input: atmel_mxt_ts - allow input name to be specified in platform
data
  Input: atmel_mxt_ts - refactor firmware flash to extract context into
struct
  Input: atmel_mxt_ts - refactor code to enter bootloader into separate
func
  Input: atmel_mxt_ts - combine bootloader version query with probe
  Input: atmel_mxt_ts - improve bootloader state machine handling
  Input: atmel_mxt_ts - rename bl_completion to chg_completion
  Input: atmel_mxt_ts - make bootloader interrupt driven
  Input: atmel_mxt_ts - delay enabling IRQ when not using regulators
  Input: atmel_mxt_ts - implement I2C retries
  Input: atmel_mxt_ts - orientation is not present in hover
  Input: atmel_mxt_ts - implement debug output for messages
  Input: atmel_mxt_ts - implement improved debug message interface

Nikhil Ravindran (1):
  Input: atmel_mxt_ts: Add support for run self-test routine.

Sanjeev Chugh (1):
  Input: atmel_mxt_ts: Implement synchronization during various
operation

karl tsou (1):
  Input: atmel_mxt_ts - add config checksum attribute to sysfs

keerthikumarp (1):
  input: atmel_mxt_ts: Add Missing Delay for reset handling of Atmel
touch panel controller in detachable displays.
---
v2: 
Following commit in v1 patchset has been split into two commits
Input: introduce input_mt_report_slot_inactive

Following commits have been updated compared to v1 patchset
Input: atmel_mxt_ts - split large i2c transfers into blocks
Input: atmel_mxt_ts - output status from T42 Touch Suppression

Following commits in v1 patchset have been squashed
Input: touchscreen: Atmel: Add device tree support for T15 key array objects
Input: atmel_mxt_ts - check data->input_dev is not null in mxt_input_sync()
Input: atmel_mxt_ts - check firmware format before entering bootloader
Input: atmel_mxt_ts: update stale use_retrigen_workaround flag
input: atmel_mxt_ts: move bootloader probe from mxt_initialize()
input: Atmel: limit the max bytes transferred while reading T5 messages
Input: atmel_mxt_ts: Use msecs_to_jiffies() instead of HZ
Input: atmel_mxt_ts: Use complete when in_bootloader true 
Input: atmel_mxt_ts: Prevent crash due to freeing of input device
input: atmel_mxt_ts: Add NULL check for sysfs attribute debug_msg_attr

Following commits in v1 patchset have been dropped:
Input: atmel_mxt_ts - configure and use gpios as real gpios
Input: touchscreen: Atmel: Enable IRQ_DISABLE_UNLAZY flag for interrupt
Input: atmel_mxt_ts - add memory access interface via sysfs
Input: atmel_mxt_ts: Remove sysfs attributes during driver detach
Input: atmel_mxt_ts: Avoid race condition in f

Re: [PATCH 1/2] mm: Don't manually decrement num_poisoned_pages

2019-08-26 Thread Michal Hocko
On Tue 27-08-19 15:36:54, Alastair D'Silva wrote:
> From: Alastair D'Silva 
> 
> Use the function written to do it instead.
> 
> Signed-off-by: Alastair D'Silva 

Acked-by: Michal Hocko 

> ---
>  mm/sparse.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/sparse.c b/mm/sparse.c
> index 72f010d9bff5..e41917a7e844 100644
> --- a/mm/sparse.c
> +++ b/mm/sparse.c
> @@ -11,6 +11,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  
>  #include "internal.h"
>  #include 
> @@ -898,7 +900,7 @@ static void clear_hwpoisoned_pages(struct page *memmap, 
> int nr_pages)
>  
>   for (i = 0; i < nr_pages; i++) {
>   if (PageHWPoison(&memmap[i])) {
> - atomic_long_sub(1, &num_poisoned_pages);
> + num_poisoned_pages_dec();
>   ClearPageHWPoison(&memmap[i]);
>   }
>   }
> -- 
> 2.21.0

-- 
Michal Hocko
SUSE Labs


Re: [PATCH 2/2] mm: don't hide potentially null memmap pointer in sparse_remove_section

2019-08-26 Thread Michal Hocko
On Tue 27-08-19 15:36:55, Alastair D'Silva wrote:
> From: Alastair D'Silva 
> 
> By adding offset to memmap before passing it in to clear_hwpoisoned_pages,
> we hide a theoretically null memmap from the null check inside
> clear_hwpoisoned_pages.

Isn't that other way around? Calculating the offset struct page pointer
will actually make the null check effective. Besides that I cannot
really see how pfn_to_page would return NULL. I have to confess that I
cannot really see how offset could lead to a NULL struct page either and
I strongly suspect that the NULL check is not really needed. Maybe it
used to be in the past.

> This patch passes the offset to clear_hwpoisoned_pages instead, allowing
> memmap to successfully perform it's null check.

I do not see any improvement in this patch. It just adds a new argument
unnecessarily.

> Signed-off-by: Alastair D'Silva 
> ---
>  mm/sparse.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/mm/sparse.c b/mm/sparse.c
> index e41917a7e844..3ff84e627e58 100644
> --- a/mm/sparse.c
> +++ b/mm/sparse.c
> @@ -882,7 +882,7 @@ int __meminit sparse_add_section(int nid, unsigned long 
> start_pfn,
>  }
>  
>  #ifdef CONFIG_MEMORY_FAILURE
> -static void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
> +static void clear_hwpoisoned_pages(struct page *memmap, int start, int count)
>  {
>   int i;
>  
> @@ -898,7 +898,7 @@ static void clear_hwpoisoned_pages(struct page *memmap, 
> int nr_pages)
>   if (atomic_long_read(&num_poisoned_pages) == 0)
>   return;
>  
> - for (i = 0; i < nr_pages; i++) {
> + for (i = start; i < start + count; i++) {
>   if (PageHWPoison(&memmap[i])) {
>   num_poisoned_pages_dec();
>   ClearPageHWPoison(&memmap[i]);
> @@ -906,7 +906,8 @@ static void clear_hwpoisoned_pages(struct page *memmap, 
> int nr_pages)
>   }
>  }
>  #else
> -static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
> +static inline void clear_hwpoisoned_pages(struct page *memmap, int start,
> + int count)
>  {
>  }
>  #endif
> @@ -915,7 +916,7 @@ void sparse_remove_section(struct mem_section *ms, 
> unsigned long pfn,
>   unsigned long nr_pages, unsigned long map_offset,
>   struct vmem_altmap *altmap)
>  {
> - clear_hwpoisoned_pages(pfn_to_page(pfn) + map_offset,
> + clear_hwpoisoned_pages(pfn_to_page(pfn), map_offset,
>   nr_pages - map_offset);
>   section_deactivate(pfn, nr_pages, altmap);
>  }
> -- 
> 2.21.0
> 

-- 
Michal Hocko
SUSE Labs


[PATCH v7 0/3] media: venus: Update clock scaling

2019-08-26 Thread Aniket Masule
In this patch series, clock scaling and core selection methods are
updated. Current clock scaling is same for vpu4 and previous versions.
Introducing load calculations using vpp cycles, which indicates the
cycles required by video hardware to process each macroblock. Also
adding vsp cycles, cycles require by stream processor. Clock scaling
is now done more precisely using vpp and vsp cycles.
Removing core selection from this series, there will be separate patch
once issue related to power domain is fixed.

This patch depends on the following patches:
https://lore.kernel.org/patchwork/patch/1114762/ - Venus interconnect support 
for sdm845
https://lore.kernel.org/patchwork/patch/1114761/ - Venus interconnect support 
for sdm845

Changes since v6:
 - Removed core selection.
 - Corrected frequency calculations.
 - Removed instance lock used while iterating over buffers.
 
Changes since v5:
 - Corrected load_per_core calculations.

Changes since v4:
 - Added call to load_scale_clocks from venus_helper_vb2_buf_queue.
 - Modified check to match core_id in core_selection.

Changes since v3:
 - vsp_cycles and vpp_cyles are now unsigned long.
 - Core number counting aligned with VIDC_CORE_ID_.
 - Aligned hardware overload handling of scale_clocks_v4 with scale_clocks.
 - Added bitrate based clock scaling patch in this patch series.
 - Instance state check is now moved from scale_clocks to load_scale_clocks

Aniket Masule (3):
  media: venus: Add codec data table
  media: venus: Update clock scaling
  media: venus: Update to bitrate based clock scaling

 drivers/media/platform/qcom/venus/core.c|  13 ++
 drivers/media/platform/qcom/venus/core.h|  16 +++
 drivers/media/platform/qcom/venus/helpers.c | 188 +---
 drivers/media/platform/qcom/venus/helpers.h |   3 +-
 drivers/media/platform/qcom/venus/vdec.c|   8 +-
 drivers/media/platform/qcom/venus/venc.c|   4 +
 6 files changed, 209 insertions(+), 23 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v7 3/3] media: venus: Update to bitrate based clock scaling

2019-08-26 Thread Aniket Masule
Introduced clock scaling using bitrate, preavious
calculations consider only the cycles per mb.
Also, clock scaling is now triggered before every
buffer being queued to the device. This helps in
deciding precise clock cycles required.

Signed-off-by: Aniket Masule 
---
 drivers/media/platform/qcom/venus/helpers.c | 33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 4ed630b..8fee0ef 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -516,17 +516,26 @@ static int scale_clocks(struct venus_inst *inst)
return 0;
 }
 
-static unsigned long calculate_vpp_freq(struct venus_inst *inst)
+static unsigned long calculate_inst_freq(struct venus_inst *inst,
+unsigned long filled_len)
 {
-   unsigned long vpp_freq = 0;
+   unsigned long vpp_freq = 0, vsp_freq = 0;
+   u64 fps = inst->fps;
u32 mbs_per_sec;
 
-   mbs_per_sec = load_per_instance(inst);
+   mbs_per_sec = load_per_instance(inst) / inst->fps;
vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
/* 21 / 20 is overhead factor */
vpp_freq += vpp_freq / 20;
+   vsp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vsp_freq;
 
-   return vpp_freq;
+   /* 10 / 7 is overhead factor */
+   if (inst->session_type == VIDC_SESSION_TYPE_ENC)
+   vsp_freq += (inst->controls.enc.bitrate * 10) / 7;
+   else
+   vsp_freq += ((fps * filled_len * 8) * 10) / 7;
+
+   return max(vpp_freq, vsp_freq);
 }
 
 static int scale_clocks_v4(struct venus_inst *inst)
@@ -534,12 +543,24 @@ static int scale_clocks_v4(struct venus_inst *inst)
struct venus_core *core = inst->core;
const struct freq_tbl *table = core->res->freq_tbl;
unsigned int num_rows = core->res->freq_tbl_size;
+   struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
struct device *dev = core->dev;
unsigned int i;
unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
+   unsigned long filled_len = 0;
+   struct venus_buffer *buf, *n;
+   struct vb2_buffer *vb;
int ret;
 
-   freq = calculate_vpp_freq(inst);
+   v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
+   vb = &buf->vb.vb2_buf;
+   filled_len = max(filled_len, vb2_get_plane_payload(vb, 0));
+   }
+
+   if (inst->session_type == VIDC_SESSION_TYPE_DEC && !filled_len)
+   return 0;
+
+   freq = calculate_inst_freq(inst, filled_len);
inst->clk_data.freq = freq;
 
mutex_lock(&core->lock);
@@ -701,6 +722,8 @@ void venus_helper_get_ts_metadata(struct venus_inst *inst, 
u64 timestamp_us,
 
if (inst->session_type == VIDC_SESSION_TYPE_DEC)
put_ts_metadata(inst, vbuf);
+
+   venus_helper_load_scale_clocks(inst);
} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (inst->session_type == VIDC_SESSION_TYPE_ENC)
fdata.buffer_type = HFI_BUFFER_OUTPUT;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v7 2/3] media: venus: Update clock scaling

2019-08-26 Thread Aniket Masule
Current clock scaling calculations are same for vpu4 and
previous versions. For vpu4, Clock scaling calculations
are updated with cycles/mb. This helps in getting precise
clock required

Signed-off-by: Aniket Masule 
---
 drivers/media/platform/qcom/venus/helpers.c | 135 +++-
 drivers/media/platform/qcom/venus/helpers.h |   2 +-
 drivers/media/platform/qcom/venus/vdec.c|   4 +-
 3 files changed, 118 insertions(+), 23 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 71af237..4ed630b 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -448,12 +448,32 @@ static int load_scale_bw(struct venus_core *core)
return icc_set_bw(core->video_path, total_avg, total_peak);
 }
 
-int venus_helper_load_scale_clocks(struct venus_core *core)
+static int set_clk_freq(struct venus_core *core, unsigned long freq)
 {
+   struct clk *clk = core->clks[0];
+   int ret;
+
+   ret = clk_set_rate(clk, freq);
+   if (ret)
+   return ret;
+
+   ret = clk_set_rate(core->core0_clk, freq);
+   if (ret)
+   return ret;
+
+   ret = clk_set_rate(core->core1_clk, freq);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static int scale_clocks(struct venus_inst *inst)
+{
+   struct venus_core *core = inst->core;
const struct freq_tbl *table = core->res->freq_tbl;
unsigned int num_rows = core->res->freq_tbl_size;
unsigned long freq = table[0].freq;
-   struct clk *clk = core->clks[0];
struct device *dev = core->dev;
u32 mbs_per_sec;
unsigned int i;
@@ -479,28 +499,103 @@ int venus_helper_load_scale_clocks(struct venus_core 
*core)
 
 set_freq:
 
-   ret = clk_set_rate(clk, freq);
-   if (ret)
-   goto err;
+   ret = set_clk_freq(core, freq);
+   if (ret) {
+   dev_err(dev, "failed to set clock rate %lu (%d)\n",
+   freq, ret);
+   return ret;
+   }
 
-   ret = clk_set_rate(core->core0_clk, freq);
-   if (ret)
-   goto err;
+   ret = load_scale_bw(core);
+   if (ret) {
+   dev_err(dev, "failed to set bandwidth (%d)\n",
+   ret);
+   return ret;
+   }
 
-   ret = clk_set_rate(core->core1_clk, freq);
-   if (ret)
-   goto err;
+   return 0;
+}
+
+static unsigned long calculate_vpp_freq(struct venus_inst *inst)
+{
+   unsigned long vpp_freq = 0;
+   u32 mbs_per_sec;
+
+   mbs_per_sec = load_per_instance(inst);
+   vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
+   /* 21 / 20 is overhead factor */
+   vpp_freq += vpp_freq / 20;
+
+   return vpp_freq;
+}
+
+static int scale_clocks_v4(struct venus_inst *inst)
+{
+   struct venus_core *core = inst->core;
+   const struct freq_tbl *table = core->res->freq_tbl;
+   unsigned int num_rows = core->res->freq_tbl_size;
+   struct device *dev = core->dev;
+   unsigned int i;
+   unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
+   int ret;
+
+   freq = calculate_vpp_freq(inst);
+   inst->clk_data.freq = freq;
+
+   mutex_lock(&core->lock);
+   list_for_each_entry(inst, &core->instances, list) {
+   if (inst->clk_data.core_id == VIDC_CORE_ID_1) {
+   freq_core1 += inst->clk_data.freq;
+   } else if (inst->clk_data.core_id == VIDC_CORE_ID_2) {
+   freq_core2 += inst->clk_data.freq;
+   } else if (inst->clk_data.core_id == VIDC_CORE_ID_3) {
+   freq_core1 += inst->clk_data.freq;
+   freq_core2 += inst->clk_data.freq;
+   }
+   }
+   mutex_unlock(&core->lock);
+
+   freq = max(freq_core1, freq_core2);
+
+   if (freq >= table[0].freq) {
+   freq = table[0].freq;
+   dev_warn(dev, "HW is overloaded, needed: %lu max: %lu\n",
+freq, table[0].freq);
+   goto set_freq;
+   }
+
+   for (i = num_rows - 1 ; i >= 0; i--) {
+   if (freq <= table[i].freq) {
+   freq = table[i].freq;
+   break;
+   }
+   }
+
+set_freq:
+
+   ret = set_clk_freq(core, freq);
+   if (ret) {
+   dev_err(dev, "failed to set clock rate %lu (%d)\n",
+   freq, ret);
+   return ret;
+   }
 
ret = load_scale_bw(core);
-   if (ret)
-   goto err;
+   if (ret) {
+   dev_err(dev, "failed to set bandwidth (%d)\n",
+   ret);
+   return ret;
+   }
 
return 0;
+}
 
-err:
-   dev_err(dev, "failed to set clock rate %lu or bandwidth (%d)\n",
-   freq, ret);
-   return ret;
+int venus_helper_load_scale_

[PATCH v7 1/3] media: venus: Add codec data table

2019-08-26 Thread Aniket Masule
Add vpp cycles for different types of codec.
It indicates the cycles required by video hardware
to process each macroblock. Add vsp cycles, cycles
required by stream processor. Initialize the codec
data with core resources.

Signed-off-by: Aniket Masule 
---
 drivers/media/platform/qcom/venus/core.c| 13 +
 drivers/media/platform/qcom/venus/core.h| 16 +++
 drivers/media/platform/qcom/venus/helpers.c | 30 +
 drivers/media/platform/qcom/venus/helpers.h |  1 +
 drivers/media/platform/qcom/venus/vdec.c|  4 
 drivers/media/platform/qcom/venus/venc.c|  4 
 6 files changed, 68 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/core.c 
b/drivers/media/platform/qcom/venus/core.c
index 19cbe9d..49d32b2 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -480,6 +480,17 @@ static __maybe_unused int venus_runtime_resume(struct 
device *dev)
{  244800, 1 }, /* 1920x1080@30 */
 };
 
+static struct codec_freq_data sdm845_codec_freq_data[] =  {
+   { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10 },
+   { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10 },
+   { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10 },
+   { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 10 },
+   { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 10 },
+   { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 10 },
+   { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 10 },
+   { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10 },
+};
+
 static const struct bw_tbl sdm845_bw_table_enc[] = {
{ 1944000, 1612000, 0, 2416000, 0 },/* 3840x2160@60 */
{  972000,  951000, 0, 1434000, 0 },/* 3840x2160@30 */
@@ -501,6 +512,8 @@ static __maybe_unused int venus_runtime_resume(struct 
device *dev)
.bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
.bw_tbl_dec = sdm845_bw_table_dec,
.bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
+   .codec_freq_data = sdm845_codec_freq_data,
+   .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
.clks = {"core", "iface", "bus" },
.clks_num = 3,
.max_load = 3110400,/* 4096x2160@90 */
diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 13e35f3..684a950 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -26,6 +26,13 @@ struct reg_val {
u32 value;
 };
 
+struct codec_freq_data {
+   u32 pixfmt;
+   u32 session_type;
+   unsigned long vpp_freq;
+   unsigned long vsp_freq;
+};
+
 struct bw_tbl {
u32 mbs_per_sec;
u32 avg;
@@ -44,6 +51,8 @@ struct venus_resources {
unsigned int bw_tbl_dec_size;
const struct reg_val *reg_tbl;
unsigned int reg_tbl_size;
+   const struct codec_freq_data *codec_freq_data;
+   unsigned int codec_freq_data_size;
const char * const clks[VIDC_CLKS_NUM_MAX];
unsigned int clks_num;
enum hfi_version hfi_version;
@@ -221,6 +230,12 @@ struct venus_buffer {
struct list_head ref_list;
 };
 
+struct clock_data {
+   u32 core_id;
+   unsigned long freq;
+   const struct codec_freq_data *codec_freq_data;
+};
+
 #define to_venus_buffer(ptr)   container_of(ptr, struct venus_buffer, vb)
 
 enum venus_dec_state {
@@ -301,6 +316,7 @@ struct venus_inst {
struct list_head list;
struct mutex lock;
struct venus_core *core;
+   struct clock_data clk_data;
struct list_head dpbbufs;
struct list_head internalbufs;
struct list_head registeredbufs;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 4320ea9..71af237 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -883,6 +883,36 @@ int venus_helper_set_core_usage(struct venus_inst *inst, 
u32 usage)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_core_usage);
 
+int venus_helper_init_codec_freq_data(struct venus_inst *inst)
+{
+   const struct codec_freq_data *data;
+   unsigned int i, data_size;
+   u32 pixfmt;
+   int ret = 0;
+
+   if (!IS_V4(inst->core))
+   return 0;
+
+   data = inst->core->res->codec_freq_data;
+   data_size = inst->core->res->codec_freq_data_size;
+   pixfmt = inst->session_type == VIDC_SESSION_TYPE_DEC ?
+   inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
+
+   for (i = 0; i < data_size; i++) {
+   if (data[i].pixfmt == pixfmt &&
+   data[i].session_type == inst->session_type) {
+   inst->clk_data.codec_freq_data = &data[i];
+   break;
+   }
+   }
+
+   if (!inst->clk_data.codec_freq_data)
+   ret = -EINVAL;
+
+   return ret;
+}
+EXPORT_S

Re: Early EFI-related boot freeze in parse_setup_data()

2019-08-26 Thread Daniel Drake
On Fri, Aug 16, 2019 at 2:14 PM Daniel Drake  wrote:
> Anyway, the system freeze occurs in parse_setup_data(), specifically:
>
> data = early_memremap(pa_data, sizeof(*data));
> data_len = data->len + sizeof(struct setup_data);
>
> Dereferencing data->len causes the system to hang. I presume it
> triggers an exception handler due to some kind of invalid memory
> access.
>
> By returning early in that function, boot continues basically fine. So
> I could then log the details: pa_data has value 0x892bb018 and
> early_memremap returns address 0xff200018. Accessing just a
> single byte at that address causes the system hang.

I noticed a complaint about NX in the logs, right where it does the
early_memremap of this data (which is now at address 0x893c0018):

 Notice: NX (Execute Disable) protection missing in CPU!
 e820: update [mem 0x893c0018-0x893cec57] usable ==> usable
 e820: update [mem 0x893c0018-0x893cec57] usable ==> usable
 e820: update [mem 0x893b3018-0x893bf057] usable ==> usable
 e820: update [mem 0x893b3018-0x893bf057] usable ==> usable

Indeed, in the BIOS setup menu, "NX Mode" was Disabled.
Setting it to Enabled avoids the hang and Linux boots as normal. Weird!

Daniel


Re: [PATCH v2 2/2] PCI/AER: Split the AER stats into multiple sysfs attributes

2019-08-26 Thread Greg KH
On Mon, Aug 26, 2019 at 05:51:14PM -0700, Rajat Jain wrote:
> --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
> +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
> @@ -9,89 +9,72 @@ errors may be "seen" / reported by the link partner and not 
> the
>  problematic endpoint itself (which may report all counters as 0 as it never
>  saw any problems).
>  
> -What:/sys/bus/pci/devices//aer_dev_correctable
> -Date:July 2018
> -KernelVersion: 4.19.0
> +What: Following files in /sys/bus/pci/devices//aer_stats/
> +correctable_bit0_RxErr
> +correctable_bit12_Timeout
> +correctable_bit13_NonFatalErr
> +correctable_bit14_CorrIntErr
> +correctable_bit15_HeaderOF
> +correctable_bit6_BadTLP
> +correctable_bit7_BadDLLP
> +correctable_bit8_Rollover
> +fatal_bit0_Undefined
> +fatal_bit12_TLP
> +fatal_bit13_FCP
> +fatal_bit14_CmpltTO
> +fatal_bit15_CmpltAbrt
> +fatal_bit16_UnxCmplt
> +fatal_bit17_RxOF
> +fatal_bit18_MalfTLP
> +fatal_bit19_ECRC
> +fatal_bit20_UnsupReq
> +fatal_bit21_ACSViol
> +fatal_bit22_UncorrIntErr
> +fatal_bit23_BlockedTLP
> +fatal_bit24_AtomicOpBlocked
> +fatal_bit25_TLPBlockedErr
> +fatal_bit26_PoisonTLPBlocked
> +fatal_bit4_DLP
> +fatal_bit5_SDES
> +nonfatal_bit0_Undefined
> +nonfatal_bit12_TLP
> +nonfatal_bit13_FCP
> +nonfatal_bit14_CmpltTO
> +nonfatal_bit15_CmpltAbrt
> +nonfatal_bit16_UnxCmplt
> +nonfatal_bit17_RxOF
> +nonfatal_bit18_MalfTLP
> +nonfatal_bit19_ECRC
> +nonfatal_bit20_UnsupReq
> +nonfatal_bit21_ACSViol
> +nonfatal_bit22_UncorrIntErr
> +nonfatal_bit23_BlockedTLP
> +nonfatal_bit24_AtomicOpBlocked
> +nonfatal_bit25_TLPBlockedErr
> +nonfatal_bit26_PoisonTLPBlocked
> +nonfatal_bit4_DLP
> +nonfatal_bit5_SDES

All of those should be indented, right?

Same for other entries

thanks,

greg k-h


[PATCH 0/3] media: venus: Update clock scaling

2019-08-26 Thread Aniket Masule
In this patch series, clock scaling and core selection methods are
updated. Current clock scaling is same for vpu4 and previous versions.
Introducing load calculations using vpp cycles, which indicates the
cycles required by video hardware to process each macroblock. Also
adding vsp cycles, cycles require by stream processor. Clock scaling
is now done more precisely using vpp and vsp cycles.
Removing core selection from this series, there will be separate patch
once issue related to power domain is fixed.

This patch depends on the following patches:
https://lore.kernel.org/patchwork/patch/1114762/ - Venus interconnect support 
for sdm845
https://lore.kernel.org/patchwork/patch/1114761/ - Venus interconnect support 
for sdm845

Changes since v6:
 - Removed core selection.
 - Corrected frequency calculations.
 - Removed instance lock used while iterating over buffers.
 
Changes since v5:
 - Corrected load_per_core calculations.

Changes since v4:
 - Added call to load_scale_clocks from venus_helper_vb2_buf_queue.
 - Modified check to match core_id in core_selection.

Changes since v3:
 - vsp_cycles and vpp_cyles are now unsigned long.
 - Core number counting aligned with VIDC_CORE_ID_.
 - Aligned hardware overload handling of scale_clocks_v4 with scale_clocks.
 - Added bitrate based clock scaling patch in this patch series.
 - Instance state check is now moved from scale_clocks to load_scale_clocks.

Aniket Masule (3):
  media: venus: Add codec data table
  media: venus: Update clock scaling
  media: venus: Update to bitrate based clock scaling

 drivers/media/platform/qcom/venus/core.c|  13 ++
 drivers/media/platform/qcom/venus/core.h|  16 +++
 drivers/media/platform/qcom/venus/helpers.c | 188 +---
 drivers/media/platform/qcom/venus/helpers.h |   3 +-
 drivers/media/platform/qcom/venus/vdec.c|   8 +-
 drivers/media/platform/qcom/venus/venc.c|   4 +
 6 files changed, 209 insertions(+), 23 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 1/3] media: venus: Add codec data table

2019-08-26 Thread Aniket Masule
Add vpp cycles for different types of codec.
It indicates the cycles required by video hardware
to process each macroblock. Add vsp cycles, cycles
required by stream processor. Initialize the codec
data with core resources.

Signed-off-by: Aniket Masule 
---
 drivers/media/platform/qcom/venus/core.c| 13 +
 drivers/media/platform/qcom/venus/core.h| 16 +++
 drivers/media/platform/qcom/venus/helpers.c | 30 +
 drivers/media/platform/qcom/venus/helpers.h |  1 +
 drivers/media/platform/qcom/venus/vdec.c|  4 
 drivers/media/platform/qcom/venus/venc.c|  4 
 6 files changed, 68 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/core.c 
b/drivers/media/platform/qcom/venus/core.c
index 19cbe9d..49d32b2 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -480,6 +480,17 @@ static __maybe_unused int venus_runtime_resume(struct 
device *dev)
{  244800, 1 }, /* 1920x1080@30 */
 };
 
+static struct codec_freq_data sdm845_codec_freq_data[] =  {
+   { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10 },
+   { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10 },
+   { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10 },
+   { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 10 },
+   { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 10 },
+   { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 10 },
+   { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 10 },
+   { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10 },
+};
+
 static const struct bw_tbl sdm845_bw_table_enc[] = {
{ 1944000, 1612000, 0, 2416000, 0 },/* 3840x2160@60 */
{  972000,  951000, 0, 1434000, 0 },/* 3840x2160@30 */
@@ -501,6 +512,8 @@ static __maybe_unused int venus_runtime_resume(struct 
device *dev)
.bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
.bw_tbl_dec = sdm845_bw_table_dec,
.bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
+   .codec_freq_data = sdm845_codec_freq_data,
+   .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
.clks = {"core", "iface", "bus" },
.clks_num = 3,
.max_load = 3110400,/* 4096x2160@90 */
diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 13e35f3..684a950 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -26,6 +26,13 @@ struct reg_val {
u32 value;
 };
 
+struct codec_freq_data {
+   u32 pixfmt;
+   u32 session_type;
+   unsigned long vpp_freq;
+   unsigned long vsp_freq;
+};
+
 struct bw_tbl {
u32 mbs_per_sec;
u32 avg;
@@ -44,6 +51,8 @@ struct venus_resources {
unsigned int bw_tbl_dec_size;
const struct reg_val *reg_tbl;
unsigned int reg_tbl_size;
+   const struct codec_freq_data *codec_freq_data;
+   unsigned int codec_freq_data_size;
const char * const clks[VIDC_CLKS_NUM_MAX];
unsigned int clks_num;
enum hfi_version hfi_version;
@@ -221,6 +230,12 @@ struct venus_buffer {
struct list_head ref_list;
 };
 
+struct clock_data {
+   u32 core_id;
+   unsigned long freq;
+   const struct codec_freq_data *codec_freq_data;
+};
+
 #define to_venus_buffer(ptr)   container_of(ptr, struct venus_buffer, vb)
 
 enum venus_dec_state {
@@ -301,6 +316,7 @@ struct venus_inst {
struct list_head list;
struct mutex lock;
struct venus_core *core;
+   struct clock_data clk_data;
struct list_head dpbbufs;
struct list_head internalbufs;
struct list_head registeredbufs;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 4320ea9..71af237 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -883,6 +883,36 @@ int venus_helper_set_core_usage(struct venus_inst *inst, 
u32 usage)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_core_usage);
 
+int venus_helper_init_codec_freq_data(struct venus_inst *inst)
+{
+   const struct codec_freq_data *data;
+   unsigned int i, data_size;
+   u32 pixfmt;
+   int ret = 0;
+
+   if (!IS_V4(inst->core))
+   return 0;
+
+   data = inst->core->res->codec_freq_data;
+   data_size = inst->core->res->codec_freq_data_size;
+   pixfmt = inst->session_type == VIDC_SESSION_TYPE_DEC ?
+   inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
+
+   for (i = 0; i < data_size; i++) {
+   if (data[i].pixfmt == pixfmt &&
+   data[i].session_type == inst->session_type) {
+   inst->clk_data.codec_freq_data = &data[i];
+   break;
+   }
+   }
+
+   if (!inst->clk_data.codec_freq_data)
+   ret = -EINVAL;
+
+   return ret;
+}
+EXPORT_S

[PATCH 2/3] media: venus: Update clock scaling

2019-08-26 Thread Aniket Masule
Current clock scaling calculations are same for vpu4 and
previous versions. For vpu4, Clock scaling calculations
are updated with cycles/mb. This helps in getting precise
clock required

Signed-off-by: Aniket Masule 
---
 drivers/media/platform/qcom/venus/helpers.c | 135 +++-
 drivers/media/platform/qcom/venus/helpers.h |   2 +-
 drivers/media/platform/qcom/venus/vdec.c|   4 +-
 3 files changed, 118 insertions(+), 23 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 71af237..4ed630b 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -448,12 +448,32 @@ static int load_scale_bw(struct venus_core *core)
return icc_set_bw(core->video_path, total_avg, total_peak);
 }
 
-int venus_helper_load_scale_clocks(struct venus_core *core)
+static int set_clk_freq(struct venus_core *core, unsigned long freq)
 {
+   struct clk *clk = core->clks[0];
+   int ret;
+
+   ret = clk_set_rate(clk, freq);
+   if (ret)
+   return ret;
+
+   ret = clk_set_rate(core->core0_clk, freq);
+   if (ret)
+   return ret;
+
+   ret = clk_set_rate(core->core1_clk, freq);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static int scale_clocks(struct venus_inst *inst)
+{
+   struct venus_core *core = inst->core;
const struct freq_tbl *table = core->res->freq_tbl;
unsigned int num_rows = core->res->freq_tbl_size;
unsigned long freq = table[0].freq;
-   struct clk *clk = core->clks[0];
struct device *dev = core->dev;
u32 mbs_per_sec;
unsigned int i;
@@ -479,28 +499,103 @@ int venus_helper_load_scale_clocks(struct venus_core 
*core)
 
 set_freq:
 
-   ret = clk_set_rate(clk, freq);
-   if (ret)
-   goto err;
+   ret = set_clk_freq(core, freq);
+   if (ret) {
+   dev_err(dev, "failed to set clock rate %lu (%d)\n",
+   freq, ret);
+   return ret;
+   }
 
-   ret = clk_set_rate(core->core0_clk, freq);
-   if (ret)
-   goto err;
+   ret = load_scale_bw(core);
+   if (ret) {
+   dev_err(dev, "failed to set bandwidth (%d)\n",
+   ret);
+   return ret;
+   }
 
-   ret = clk_set_rate(core->core1_clk, freq);
-   if (ret)
-   goto err;
+   return 0;
+}
+
+static unsigned long calculate_vpp_freq(struct venus_inst *inst)
+{
+   unsigned long vpp_freq = 0;
+   u32 mbs_per_sec;
+
+   mbs_per_sec = load_per_instance(inst);
+   vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
+   /* 21 / 20 is overhead factor */
+   vpp_freq += vpp_freq / 20;
+
+   return vpp_freq;
+}
+
+static int scale_clocks_v4(struct venus_inst *inst)
+{
+   struct venus_core *core = inst->core;
+   const struct freq_tbl *table = core->res->freq_tbl;
+   unsigned int num_rows = core->res->freq_tbl_size;
+   struct device *dev = core->dev;
+   unsigned int i;
+   unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
+   int ret;
+
+   freq = calculate_vpp_freq(inst);
+   inst->clk_data.freq = freq;
+
+   mutex_lock(&core->lock);
+   list_for_each_entry(inst, &core->instances, list) {
+   if (inst->clk_data.core_id == VIDC_CORE_ID_1) {
+   freq_core1 += inst->clk_data.freq;
+   } else if (inst->clk_data.core_id == VIDC_CORE_ID_2) {
+   freq_core2 += inst->clk_data.freq;
+   } else if (inst->clk_data.core_id == VIDC_CORE_ID_3) {
+   freq_core1 += inst->clk_data.freq;
+   freq_core2 += inst->clk_data.freq;
+   }
+   }
+   mutex_unlock(&core->lock);
+
+   freq = max(freq_core1, freq_core2);
+
+   if (freq >= table[0].freq) {
+   freq = table[0].freq;
+   dev_warn(dev, "HW is overloaded, needed: %lu max: %lu\n",
+freq, table[0].freq);
+   goto set_freq;
+   }
+
+   for (i = num_rows - 1 ; i >= 0; i--) {
+   if (freq <= table[i].freq) {
+   freq = table[i].freq;
+   break;
+   }
+   }
+
+set_freq:
+
+   ret = set_clk_freq(core, freq);
+   if (ret) {
+   dev_err(dev, "failed to set clock rate %lu (%d)\n",
+   freq, ret);
+   return ret;
+   }
 
ret = load_scale_bw(core);
-   if (ret)
-   goto err;
+   if (ret) {
+   dev_err(dev, "failed to set bandwidth (%d)\n",
+   ret);
+   return ret;
+   }
 
return 0;
+}
 
-err:
-   dev_err(dev, "failed to set clock rate %lu or bandwidth (%d)\n",
-   freq, ret);
-   return ret;
+int venus_helper_load_scale_

[PATCH 3/3] media: venus: Update to bitrate based clock scaling

2019-08-26 Thread Aniket Masule
Introduced clock scaling using bitrate, preavious
calculations consider only the cycles per mb.
Also, clock scaling is now triggered before every
buffer being queued to the device. This helps in
deciding precise clock cycles required.

Signed-off-by: Aniket Masule 
---
 drivers/media/platform/qcom/venus/helpers.c | 33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 4ed630b..8fee0ef 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -516,17 +516,26 @@ static int scale_clocks(struct venus_inst *inst)
return 0;
 }
 
-static unsigned long calculate_vpp_freq(struct venus_inst *inst)
+static unsigned long calculate_inst_freq(struct venus_inst *inst,
+unsigned long filled_len)
 {
-   unsigned long vpp_freq = 0;
+   unsigned long vpp_freq = 0, vsp_freq = 0;
+   u64 fps = inst->fps;
u32 mbs_per_sec;
 
-   mbs_per_sec = load_per_instance(inst);
+   mbs_per_sec = load_per_instance(inst) / inst->fps;
vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
/* 21 / 20 is overhead factor */
vpp_freq += vpp_freq / 20;
+   vsp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vsp_freq;
 
-   return vpp_freq;
+   /* 10 / 7 is overhead factor */
+   if (inst->session_type == VIDC_SESSION_TYPE_ENC)
+   vsp_freq += (inst->controls.enc.bitrate * 10) / 7;
+   else
+   vsp_freq += ((fps * filled_len * 8) * 10) / 7;
+
+   return max(vpp_freq, vsp_freq);
 }
 
 static int scale_clocks_v4(struct venus_inst *inst)
@@ -534,12 +543,24 @@ static int scale_clocks_v4(struct venus_inst *inst)
struct venus_core *core = inst->core;
const struct freq_tbl *table = core->res->freq_tbl;
unsigned int num_rows = core->res->freq_tbl_size;
+   struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
struct device *dev = core->dev;
unsigned int i;
unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
+   unsigned long filled_len = 0;
+   struct venus_buffer *buf, *n;
+   struct vb2_buffer *vb;
int ret;
 
-   freq = calculate_vpp_freq(inst);
+   v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
+   vb = &buf->vb.vb2_buf;
+   filled_len = max(filled_len, vb2_get_plane_payload(vb, 0));
+   }
+
+   if (inst->session_type == VIDC_SESSION_TYPE_DEC && !filled_len)
+   return 0;
+
+   freq = calculate_inst_freq(inst, filled_len);
inst->clk_data.freq = freq;
 
mutex_lock(&core->lock);
@@ -701,6 +722,8 @@ void venus_helper_get_ts_metadata(struct venus_inst *inst, 
u64 timestamp_us,
 
if (inst->session_type == VIDC_SESSION_TYPE_DEC)
put_ts_metadata(inst, vbuf);
+
+   venus_helper_load_scale_clocks(inst);
} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (inst->session_type == VIDC_SESSION_TYPE_ENC)
fdata.buffer_type = HFI_BUFFER_OUTPUT;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2] powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB

2019-08-26 Thread Greg Kroah-Hartman
On Wed, Aug 21, 2019 at 10:19:27AM +1000, Alastair D'Silva wrote:
> From: Alastair D'Silva 
> 
> The upstream commit:
> 22e9c88d486a ("powerpc/64: reuse PPC32 static inline flush_dcache_range()")
> has a similar effect, but since it is a rewrite of the assembler to C, is
> too invasive for stable. This patch is a minimal fix to address the issue in
> assembler.
> 
> This patch applies cleanly to v5.2, v4.19 & v4.14.
> 
> When calling flush_(inval_)dcache_range with a size >4GB, we were masking
> off the upper 32 bits, so we would incorrectly flush a range smaller
> than intended.
> 
> This patch replaces the 32 bit shifts with 64 bit ones, so that
> the full size is accounted for.
> 
> Changelog:
> v2
>   - Add related upstream commit

Now applied, thanks.

greg k-h


RE: [PATCH] input: keyboard: snvs_pwrkey: Send press and release event for i.MX6 S,DL and Q

2019-08-26 Thread Robin Gong
On Fri, Aug 23, 2019 at 02:30:02PM +0200, Robin van der Gracht wrote:> 
> The older generation i.MX6 processors send a powerdown request interrupt
> if the powerkey is released before a hard shutdown (5 second press). This
> should allow software to bring down the SoC safely.
> 
> For this driver to work as a regular powerkey with the older SoCs, we need to
> send a keypress AND release when we get the powerdown request interrupt.
Please clarify here more clearly that because there is NO press interrupt 
triggered
but only release interrupt on elder i.mx6 processors and that HW issue fixed 
from
i.mx6sx.
> 
> Signed-off-by: Robin van der Gracht 
> ---
>  arch/arm/boot/dts/imx6qdl.dtsi   |  2 +-
>  arch/arm/boot/dts/imx6sll.dtsi   |  2 +-
>  arch/arm/boot/dts/imx6sx.dtsi|  2 +-
>  arch/arm/boot/dts/imx6ul.dtsi|  2 +-
>  arch/arm/boot/dts/imx7s.dtsi |  2 +-
As Shawn talked, please keep the original "fsl,sec-v4.0-pwrkey", just add
'imx6qdl-snvs-pwrkey' for elder i.mx6 processor i.mx6q/dl/sl, thus no need
to touch other newer processor's dts.

> 
>  static void imx_imx_snvs_check_for_events(struct timer_list *t) @@ -67,13
> +85,23 @@ static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void
> *dev_id)  {
>   struct platform_device *pdev = dev_id;
>   struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
> + struct input_dev *input = pdata->input;
>   u32 lp_status;
> 
> - pm_wakeup_event(pdata->input->dev.parent, 0);
> + pm_wakeup_event(input->dev.parent, 0);
> 
>   regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status);
> - if (lp_status & SNVS_LPSR_SPO)
> - mod_timer(&pdata->check_timer, jiffies +
> msecs_to_jiffies(DEBOUNCE_TIME));
> + if (lp_status & SNVS_LPSR_SPO) {
> + if (pdata->hwtype == IMX6QDL_SNVS) {
> + input_report_key(input, pdata->keycode, 1);
> + input_report_key(input, pdata->keycode, 0);
> + input_sync(input);
> + pm_relax(input->dev.parent);
Could you move the above input event report steps into 
imx_imx_snvs_check_for_events()
as before? That make code better to understand and less operation in ISR.
> + } else {
> + mod_timer(&pdata->check_timer,
> + jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
> + }
> + }
> 
>   /* clear SPO status */
>   regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO); @@
> -88,11 +116,24 @@ static void imx_snvs_pwrkey_act(void *pdata)
>   del_timer_sync(&pd->check_timer);
>  }
> 
> +static const struct of_device_id imx_snvs_pwrkey_ids[] = {
> + {
> + .compatible = "fsl,imx6sx-sec-v4.0-pwrkey",
> + .data = &imx_snvs_devtype[IMX6SX_SNVS],
> + }, {
> + .compatible = "fsl,imx6qdl-sec-v4.0-pwrkey",
> + .data = &imx_snvs_devtype[IMX6QDL_SNVS],
No ' IMX6QDL_SNVS ' defined in your patch or am I missing?
> + },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imx_snvs_pwrkey_ids);
> --
> 2.20.1



Re: [PATCH v2] powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB

2019-08-26 Thread Greg Kroah-Hartman
On Mon, Aug 26, 2019 at 10:08:26PM +0200, Christophe Leroy wrote:
> 
> 
> Le 26/08/2019 à 18:50, Greg Kroah-Hartman a écrit :
> > On Wed, Aug 21, 2019 at 10:19:27AM +1000, Alastair D'Silva wrote:
> > > From: Alastair D'Silva 
> > > 
> > > The upstream commit:
> > > 22e9c88d486a ("powerpc/64: reuse PPC32 static inline 
> > > flush_dcache_range()")
> > > has a similar effect, but since it is a rewrite of the assembler to C, is
> > > too invasive for stable. This patch is a minimal fix to address the issue 
> > > in
> > > assembler.
> > > 
> > > This patch applies cleanly to v5.2, v4.19 & v4.14.
> > > 
> > > When calling flush_(inval_)dcache_range with a size >4GB, we were masking
> > > off the upper 32 bits, so we would incorrectly flush a range smaller
> > > than intended.
> > > 
> > > This patch replaces the 32 bit shifts with 64 bit ones, so that
> > > the full size is accounted for.
> > > 
> > > Changelog:
> > > v2
> > >- Add related upstream commit
> > > 
> > > Signed-off-by: Alastair D'Silva 
> > > ---
> > >   arch/powerpc/kernel/misc_64.S | 4 ++--
> > >   1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
> > > index 1ad4089dd110..d4d096f80f4b 100644
> > > --- a/arch/powerpc/kernel/misc_64.S
> > > +++ b/arch/powerpc/kernel/misc_64.S
> > > @@ -130,7 +130,7 @@ _GLOBAL_TOC(flush_dcache_range)
> > >   subfr8,r6,r4/* compute length */
> > >   add r8,r8,r5/* ensure we get enough */
> > >   lwz r9,DCACHEL1LOGBLOCKSIZE(r10)/* Get log-2 of dcache 
> > > block size */
> > > - srw.r8,r8,r9/* compute line count */
> > > + srd.r8,r8,r9/* compute line count */
> > >   beqlr   /* nothing to do? */
> > >   mtctr   r8
> > >   0:  dcbst   0,r6
> > > @@ -148,7 +148,7 @@ _GLOBAL(flush_inval_dcache_range)
> > >   subfr8,r6,r4/* compute length */
> > >   add r8,r8,r5/* ensure we get enough */
> > >   lwz r9,DCACHEL1LOGBLOCKSIZE(r10)/* Get log-2 of dcache 
> > > block size */
> > > - srw.r8,r8,r9/* compute line count */
> > > + srd.r8,r8,r9/* compute line count */
> > >   beqlr   /* nothing to do? */
> > >   sync
> > >   isync
> > 
> > I need an ack from the powerpc maintainer(s) before I can take this.
> 
> I think you already got an ack (on v1). See
> https://patchwork.ozlabs.org/patch/1147403/#2239663

How am I supposed to remember that?  :)

greg k-h


Re: [RFC PATCH 0/2] Add predictive memory reclamation and compaction

2019-08-26 Thread Michal Hocko
On Tue 27-08-19 02:14:20, Bharath Vedartham wrote:
> Hi Michal,
> 
> Here are some of my thoughts,
> On Wed, Aug 21, 2019 at 04:06:32PM +0200, Michal Hocko wrote:
> > On Thu 15-08-19 14:51:04, Khalid Aziz wrote:
> > > Hi Michal,
> > > 
> > > The smarts for tuning these knobs can be implemented in userspace and
> > > more knobs added to allow for what is missing today, but we get back to
> > > the same issue as before. That does nothing to make kernel self-tuning
> > > and adds possibly even more knobs to userspace. Something so fundamental
> > > to kernel memory management as making free pages available when they are
> > > needed really should be taken care of in the kernel itself. Moving it to
> > > userspace just means the kernel is hobbled unless one installs and tunes
> > > a userspace package correctly.
> > 
> > From my past experience the existing autotunig works mostly ok for a
> > vast variety of workloads. A more clever tuning is possible and people
> > are doing that already. Especially for cases when the machine is heavily
> > overcommited. There are different ways to achieve that. Your new
> > in-kernel auto tuning would have to be tested on a large variety of
> > workloads to be proven and riskless. So I am quite skeptical to be
> > honest.
> Could you give some references to such works regarding tuning the kernel? 

Talk to Facebook guys and their usage of PSI to control the memory
distribution and OOM situations.

> Essentially, Our idea here is to foresee potential memory exhaustion.
> This foreseeing is done by observing the workload, observing the memory
> usage of the workload. Based on this observations, we make a prediction
> whether or not memory exhaustion could occur.

I understand that and I am not disputing this can be useful. All I do
argue here is that there is unlikely a good "crystall ball" for most/all
workloads that would justify its inclusion into the kernel and that this
is something better done in the userspace where you can experiment and
tune the behavior for a particular workload of your interest.

Therefore I would like to shift the discussion towards existing APIs and
whether they are suitable for such an advance auto-tuning. I haven't
heard any arguments about missing pieces.

> If memory exhaustion
> occurs, we reclaim some more memory. kswapd stops reclaim when
> hwmark is reached. hwmark is usually set to a fairly low percentage of
> total memory, in my system for zone Normal hwmark is 13% of total pages.
> So there is scope for reclaiming more pages to make sure system does not
> suffer from a lack of pages. 

Yes and we have ways to control those watermarks that your monitoring
tool can use to alter the reclaim behavior.
 
[...]
> > Therefore I would really focus on discussing whether we have sufficient
> > APIs to tune the kernel to do the right thing when needed. That requires
> > to identify gaps in that area. 
> One thing that comes to my mind is based on the issue Khalid mentioned
> earlier on how his desktop took more than 30secs to boot up because of
> the caches using up a lot of memory.
> Rather than allowing any unused memory to be the page cache, would it be
> a good idea to fix a size for the caches and elastically change the size
> based on the workload?

I do not think so. Limiting the pagecache is unlikely to help as it is
really cheap to reclaim most of the time. In those cases when this is
not the case (e.g. the underlying FS needs to flush and/or metadata)
then the same would be possible in a restricted page cache situation
and you could easily end up stalled waiting for pagecache (e.g. any
executable/library) while there is a lot of memory.

I cannot comment on the Khalid's example because there were no details
there but I would be really surprised if the primary source of stall was
the pagecache.
-- 
Michal Hocko
SUSE Labs


Re: [PATCH 4/4] iio: adc: ina2xx: Use label proper for device identification

2019-08-26 Thread Michal Simek
On 27. 08. 19 5:55, Phil Reid wrote:
> On 26/08/2019 02:07, Jonathan Cameron wrote:
>> On Wed, 21 Aug 2019 11:12:00 +0200
>> Michal Simek  wrote:
>>
>>> On 21. 08. 19 4:11, Phil Reid wrote:
 On 20/08/2019 22:11, Michal Simek wrote:
> Add support for using label property for easier device
> identification via
> iio framework.
>
> Signed-off-by: Michal Simek 
> ---
>
>    drivers/iio/adc/ina2xx-adc.c | 2 +-
>    1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iio/adc/ina2xx-adc.c
> b/drivers/iio/adc/ina2xx-adc.c
> index 7c7c63677bf4..077c54915f70 100644
> --- a/drivers/iio/adc/ina2xx-adc.c
> +++ b/drivers/iio/adc/ina2xx-adc.c
> @@ -1033,7 +1033,7 @@ static int ina2xx_probe(struct i2c_client
> *client,
>    snprintf(chip->name, sizeof(chip->name), "%s-%s",
>     client->name, dev_name(&client->dev));
>    -    indio_dev->name = chip->name;
> +    indio_dev->name = of_get_property(np, "label", NULL) ? :
> chip->name;
>    indio_dev->setup_ops = &ina2xx_setup_ops;
>      buffer = devm_iio_kfifo_allocate(&indio_dev->dev);
>   
 I like this personally. It'd be nice if it was a core function so
 it could be an opt in to any iio device.

 Don't know how well received that'd be thou.
    
>> I'm not particularly keen on changing the semantics of existing
>> ABI, but how about adding new ABI to provide this?
>>
>> /sys/bus/iio/devices/iio\:device0/label for example?
>>
>> I haven't thought about it in depth yet though.  If you spin
>> a patch with that and the DT docs we'll be more likely to get
>> a view from DT maintainers if this is acceptable use of label.
>>
> 
> I've sent "iio: core: Add optional symbolic label to device attributes"
> for further discussion.

Series looks good. I expect that there will be also update in libiio if
this is accepted.

Thanks,
Michal


Re: [patch V2 38/38] posix-cpu-timers: Utilize timerqueue for storage

2019-08-26 Thread Thomas Gleixner
On Tue, 27 Aug 2019, Frederic Weisbecker wrote:

> On Wed, Aug 21, 2019 at 09:09:25PM +0200, Thomas Gleixner wrote:
> >  /**
> > @@ -92,14 +130,10 @@ struct posix_cputimers {
> >  
> >  static inline void posix_cputimers_init(struct posix_cputimers *pct)
> >  {
> > -   pct->timers_active = 0;
> > -   pct->expiry_active = 0;
> 
> No more need to initialize these?
> 
> > +   memset(pct->bases, 0, sizeof(pct->bases));

memset() does that IIRC :)

> > pct->bases[0].nextevt = U64_MAX;
> > pct->bases[1].nextevt = U64_MAX;
> > pct->bases[2].nextevt = U64_MAX;
> > -   INIT_LIST_HEAD(&pct->bases[0].cpu_timers);
> > -   INIT_LIST_HEAD(&pct->bases[1].cpu_timers);
> > -   INIT_LIST_HEAD(&pct->bases[2].cpu_timers);
> >  }
> 
> [...]
> 
> > @@ -393,15 +395,15 @@ static int posix_cpu_timer_del(struct k_
> > sighand = lock_task_sighand(p, &flags);
> > if (unlikely(sighand == NULL)) {
> > /*
> > -* We raced with the reaping of the task.
> > -* The deletion should have cleared us off the list.
> > +* This raced with the reaping of the task. The exit cleanup
> > +* should have removed this timer from the timer queue.
> >  */
> > -   WARN_ON_ONCE(!list_empty(&timer->it.cpu.entry));
> > +   WARN_ON_ONCE(ctmr->head || timerqueue_node_queued(&ctmr->node));
> 
> Should we clear ctmr->head upon cleanup_timerqueue() ?

Probably.
 


Re: [RESEND PATCH v3 09/20] mtd: spi-nor: Create a ->set_4byte() method

2019-08-26 Thread Vignesh Raghavendra



On 26/08/19 5:38 PM, tudor.amba...@microchip.com wrote:
> From: Boris Brezillon 
> 
> The procedure used to enable 4 byte addressing mode depends on the NOR
> device, so let's provide a hook so that manufacturer specific handling
> can be implemented in a sane way.
> 
> Signed-off-by: Boris Brezillon 
> [tudor.amba...@microchip.com: use nor->params.set_4byte() instead of
> nor->set_4byte()]
> Signed-off-by: Tudor Ambarus 
> ---

Reviewed-by: Vignesh Raghavendra 

Regards
Vignesh

> v3: no changes>
>  drivers/mtd/spi-nor/spi-nor.c | 76 
> ++-
>  include/linux/mtd/spi-nor.h   |  2 ++
>  2 files changed, 41 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 1e7f8dc3457d..235e82a121a1 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -633,6 +633,17 @@ static int macronix_set_4byte(struct spi_nor *nor, bool 
> enable)
> NULL, 0);
>  }
>  
> +static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
> +{
> + int ret;
> +
> + write_enable(nor);
> + ret = macronix_set_4byte(nor, enable);
> + write_disable(nor);
> +
> + return ret;
> +}
> +
>  static int spansion_set_4byte(struct spi_nor *nor, bool enable)
>  {
>   nor->bouncebuf[0] = enable << 7;
> @@ -667,45 +678,24 @@ static int spi_nor_write_ear(struct spi_nor *nor, u8 
> ear)
>   return nor->write_reg(nor, SPINOR_OP_WREAR, nor->bouncebuf, 1);
>  }
>  
> -/* Enable/disable 4-byte addressing mode. */
> -static int set_4byte(struct spi_nor *nor, bool enable)
> +static int winbond_set_4byte(struct spi_nor *nor, bool enable)
>  {
> - int status;
> - bool need_wren = false;
> -
> - switch (JEDEC_MFR(nor->info)) {
> - case SNOR_MFR_ST:
> - case SNOR_MFR_MICRON:
> - /* Some Micron need WREN command; all will accept it */
> - need_wren = true;
> - /* fall through */
> - case SNOR_MFR_MACRONIX:
> - case SNOR_MFR_WINBOND:
> - if (need_wren)
> - write_enable(nor);
> + int ret;
>  
> - status = macronix_set_4byte(nor, enable);
> - if (need_wren)
> - write_disable(nor);
> + ret = macronix_set_4byte(nor, enable);
> + if (ret || enable)
> + return ret;
>  
> - if (!status && !enable &&
> - JEDEC_MFR(nor->info) == SNOR_MFR_WINBOND) {
> - /*
> -  * On Winbond W25Q256FV, leaving 4byte mode causes
> -  * the Extended Address Register to be set to 1, so all
> -  * 3-byte-address reads come from the second 16M.
> -  * We must clear the register to enable normal behavior.
> -  */
> - write_enable(nor);
> - spi_nor_write_ear(nor, 0);
> - write_disable(nor);
> - }
> + /*
> +  * On Winbond W25Q256FV, leaving 4byte mode causes the Extended Address
> +  * Register to be set to 1, so all 3-byte-address reads come from the
> +  * second 16M. We must clear the register to enable normal behavior.
> +  */
> + write_enable(nor);
> + ret = spi_nor_write_ear(nor, 0);
> + write_disable(nor);
>  
> - return status;
> - default:
> - /* Spansion style */
> - return spansion_set_4byte(nor, enable);
> - }
> + return ret;
>  }
>  
>  static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
> @@ -4153,11 +4143,18 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
>  static void macronix_set_default_init(struct spi_nor *nor)
>  {
>   nor->params.quad_enable = macronix_quad_enable;
> + nor->params.set_4byte = macronix_set_4byte;
>  }
>  
>  static void st_micron_set_default_init(struct spi_nor *nor)
>  {
>   nor->params.quad_enable = NULL;
> + nor->params.set_4byte = st_micron_set_4byte;
> +}
> +
> +static void winbond_set_default_init(struct spi_nor *nor)
> +{
> + nor->params.set_4byte = winbond_set_4byte;
>  }
>  
>  /**
> @@ -4178,6 +4175,10 @@ static void spi_nor_manufacturer_init_params(struct 
> spi_nor *nor)
>   st_micron_set_default_init(nor);
>   break;
>  
> + case SNOR_MFR_WINBOND:
> + winbond_set_default_init(nor);
> + break;
> +
>   default:
>   break;
>   }
> @@ -4222,6 +4223,7 @@ static void spi_nor_info_init_params(struct spi_nor 
> *nor)
>  
>   /* Initialize legacy flash parameters and settings. */
>   params->quad_enable = spansion_quad_enable;
> + params->set_4byte = spansion_set_4byte;
>  
>   /* Set SPI NOR sizes. */
>   params->size = (u64)info->sector_size * info->n_sectors;
> @@ -4587,7 +4589,7 @@ static int spi_nor_init(struct spi_nor *nor)
>*/
>   WARN_ONCE(nor->flags & SNOR_

Re: [v2 PATCH -mm] mm: account deferred split THPs into MemAvailable

2019-08-26 Thread Michal Hocko
On Mon 26-08-19 16:15:38, Kirill A. Shutemov wrote:
> On Mon, Aug 26, 2019 at 09:40:35AM +0200, Michal Hocko wrote:
> > On Thu 22-08-19 18:29:34, Kirill A. Shutemov wrote:
> > > On Thu, Aug 22, 2019 at 02:56:56PM +0200, Vlastimil Babka wrote:
> > > > On 8/22/19 10:04 AM, Michal Hocko wrote:
> > > > > On Thu 22-08-19 01:55:25, Yang Shi wrote:
> > > > >> Available memory is one of the most important metrics for memory
> > > > >> pressure.
> > > > > 
> > > > > I would disagree with this statement. It is a rough estimate that 
> > > > > tells
> > > > > how much memory you can allocate before going into a more expensive
> > > > > reclaim (mostly swapping). Allocating that amount still might result 
> > > > > in
> > > > > direct reclaim induced stalls. I do realize that this is simple metric
> > > > > that is attractive to use and works in many cases though.
> > > > > 
> > > > >> Currently, the deferred split THPs are not accounted into
> > > > >> available memory, but they are reclaimable actually, like reclaimable
> > > > >> slabs.
> > > > >> 
> > > > >> And, they seems very common with the common workloads when THP is
> > > > >> enabled.  A simple run with MariaDB test of mmtest with THP enabled 
> > > > >> as
> > > > >> always shows it could generate over fifteen thousand deferred split 
> > > > >> THPs
> > > > >> (accumulated around 30G in one hour run, 75% of 40G memory for my 
> > > > >> VM).
> > > > >> It looks worth accounting in MemAvailable.
> > > > > 
> > > > > OK, this makes sense. But your above numbers are really worrying.
> > > > > Accumulating such a large amount of pages that are likely not going to
> > > > > be used is really bad. They are essentially blocking any higher order
> > > > > allocations and also push the system towards more memory pressure.
> > > > > 
> > > > > IIUC deferred splitting is mostly a workaround for nasty locking 
> > > > > issues
> > > > > during splitting, right? This is not really an optimization to cache
> > > > > THPs for reuse or something like that. What is the reason this is not
> > > > > done from a worker context? At least THPs which would be freed
> > > > > completely sound like a good candidate for kworker tear down, no?
> > > > 
> > > > Agreed that it's a good question. For Kirill :) Maybe with kworker 
> > > > approach we
> > > > also wouldn't need the cgroup awareness?
> > > 
> > > I don't remember a particular locking issue, but I cannot say there's
> > > none :P
> > > 
> > > It's artifact from decoupling PMD split from compound page split: the same
> > > page can be mapped multiple times with combination of PMDs and PTEs. Split
> > > of one PMD doesn't need to trigger split of all PMDs and underlying
> > > compound page.
> > > 
> > > Other consideration is the fact that page split can fail and we need to
> > > have fallback for this case.
> > > 
> > > Also in most cases THP split would be just waste of time if we would do
> > > them at the spot. If you don't have memory pressure it's better to wait
> > > until process termination: less pages on LRU is still beneficial.
> > 
> > This might be true but the reality shows that a lot of THPs might be
> > waiting for the memory pressure that is essentially freeable on the
> > spot. So I am not really convinced that "less pages on LRUs" is really a
> > plausible justification. Can we free at least those THPs which are
> > unmapped completely without any pte mappings?
> 
> Unmapped completely pages will be freed with current code. Deferred split
> only applies to partly mapped THPs: at least on 4k of the THP is still
> mapped somewhere.

Hmm, I am probably misreading the code but at least current Linus' tree
reads page_remove_rmap -> [page_remove_anon_compound_rmap ->\ 
deferred_split_huge_page even
for fully mapped THP.

> > > Main source of partly mapped THPs comes from exit path. When PMD mapping
> > > of THP got split across multiple VMAs (for instance due to mprotect()),
> > > in exit path we unmap PTEs belonging to one VMA just before unmapping the
> > > rest of the page. It would be total waste of time to split the page in
> > > this scenario.
> > > 
> > > The whole deferred split thing still looks as a reasonable compromise
> > > to me.
> > 
> > Even when it leads to all other problems mentioned in this and memcg
> > deferred reclaim series?
> 
> Yes.
> 
> You would still need deferred split even if you *try* to split the page on
> the spot. split_huge_page() can fail (due to pin on the page) and you will
> need to have a way to try again later.
> 
> You'll not win anything in complexity by trying split_huge_page()
> immediately. I would ague you'll create much more complexity.

I am not arguing for in place split. I am arguing to do it ASAP rather
than to wait for memory pressure which might be in an unbound amount of
time. So let me ask again. Why cannot we do that in the worker context?
Essentially schedure the work item right away?

> > > We may have some kind of watermark and try to keep the number

Re: [v2 PATCH -mm] mm: account deferred split THPs into MemAvailable

2019-08-26 Thread Michal Hocko
On Mon 26-08-19 21:27:38, Yang Shi wrote:
> 
> 
> On 8/26/19 12:43 AM, Michal Hocko wrote:
> > On Thu 22-08-19 08:33:40, Yang Shi wrote:
> > > 
> > > On 8/22/19 1:04 AM, Michal Hocko wrote:
> > > > On Thu 22-08-19 01:55:25, Yang Shi wrote:
> > [...]
> > > > > And, they seems very common with the common workloads when THP is
> > > > > enabled.  A simple run with MariaDB test of mmtest with THP enabled as
> > > > > always shows it could generate over fifteen thousand deferred split 
> > > > > THPs
> > > > > (accumulated around 30G in one hour run, 75% of 40G memory for my VM).
> > > > > It looks worth accounting in MemAvailable.
> > > > OK, this makes sense. But your above numbers are really worrying.
> > > > Accumulating such a large amount of pages that are likely not going to
> > > > be used is really bad. They are essentially blocking any higher order
> > > > allocations and also push the system towards more memory pressure.
> > > That is accumulated number, during the running of the test, some of them
> > > were freed by shrinker already. IOW, it should not reach that much at any
> > > given time.
> > Then the above description is highly misleading. What is the actual
> > number of lingering THPs that wait for the memory pressure in the peak?
> 
> By rerunning sysbench mariadb test of mmtest, I didn't see too many THPs in
> the peak. I saw around 2K THPs sometimes on my VM with 40G memory. But they
> were short-lived (should be freed when the test exit). And, the number of
> accumulated THPs are variable.
> 
> And, this reminded me to go back double check our internal bug report which
> lead to the "make deferred split shrinker memcg aware" patchset.
> 
> In that case, a mysql instance with real production load was running in a
> memcg with ~86G limit, the number of deferred split THPs may reach to ~68G
> (~34K deferred split THPs) in a few hours. The deferred split THP shrinker
> was not invoked since global memory pressure is still fine since the host
> has 256G memory, but memcg limit reclaim was triggered.
> 
> And, I can't tell if all those deferred split THPs came from mysql or not
> since there were some other processes run in that container too according to
> the oom log.
> 
> I will update the commit log with the more solid data from production
> environment.

This is a very useful information. Thanks!

> > > > IIUC deferred splitting is mostly a workaround for nasty locking issues
> > > > during splitting, right? This is not really an optimization to cache
> > > > THPs for reuse or something like that. What is the reason this is not
> > > > done from a worker context? At least THPs which would be freed
> > > > completely sound like a good candidate for kworker tear down, no?
> > > Yes, deferred split THP was introduced to avoid locking issues according 
> > > to
> > > the document. Memcg awareness would help to trigger the shrinker more 
> > > often.
> > > 
> > > I think it could be done in a worker context, but when to trigger to 
> > > worker
> > > is a subtle problem.
> > Why? What is the problem to trigger it after unmap of a batch worth of
> > THPs?
> 
> This leads to another question, how many THPs are "a batch of worth"?

Some arbitrary reasonable number. Few dozens of THPs waiting for split
are no big deal. Going into GB as you pointed out above is definitely a
problem.

-- 
Michal Hocko
SUSE Labs


Re: [RESEND PATCH v3 08/20] mtd: spi-nor: Split spi_nor_init_params()

2019-08-26 Thread Vignesh Raghavendra



On 26/08/19 5:38 PM, tudor.amba...@microchip.com wrote:
> From: Tudor Ambarus 
> 
> Add functions to delimit what the chunks of code do:
> 
> static void spi_nor_init_params()
> {
>   spi_nor_info_init_params()
>   spi_nor_manufacturer_init_params()
>   spi_nor_sfdp_init_params()
> }
> 
> Add descriptions to all methods.
> 
> spi_nor_init_params() becomes of type void, as all its children
> return void.
> 
> Signed-off-by: Tudor Ambarus 
> Reviewed-by: Boris Brezillon 
> ---
> v3: rename spi_nor_legacy_init_params() to spi_nor_info_init_params()


Reviewed-by: Vignesh Raghavendra 

Minor nits below...

[...]
>  
> +/**
> + * spi_nor_init_params() - Initialize the flash's parameters and settings.
> + * @nor: pointer to a 'struct spi-nor'.
> + *
> + * The flash parameters and settings are initialized based on a sequence of
> + * calls that are ordered by priority:
> + *
> + * 1/ Default flash parameters initialization. The initializations are done
> + *based on nor->info data:
> + *   spi_nor_info_init_params()
> + *
> + * which can be overwritten by:
> + * 2/ Manufacturer flash parameters initialization. The initializations are
> + *done based on MFR register, or when the decisions can not be done 
> solely
> + *based on MFR, by using specific flash_info tweeks, ->default_init():
> + *   spi_nor_manufacturer_init_params()
> + *
> + * which can be overwritten by:
> + * 3/ SFDP flash parameters initialization. JESD216 SFDP is a standard and
> + *should be more accurate that the above.
> + *   spi_nor_sfdp_init_params()
> + *
> + *Please not that there is a ->post_bfpt() fixup hook that can overwrite 
> the

s/not/note

> + *flash parameters and settings imediately after parsing the Basic Flash

s/imediately/immediately

> + *Parameter Table.
> + */
> +static void spi_nor_init_params(struct spi_nor *nor)
> +{
> + spi_nor_info_init_params(nor);
>  
>   spi_nor_manufacturer_init_params(nor);
>  
> - if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&
> - !(info->flags & SPI_NOR_SKIP_SFDP)) {
> - struct spi_nor_flash_parameter sfdp_params;
> -
> - memcpy(&sfdp_params, params, sizeof(sfdp_params));
> -
> - if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
> - nor->addr_width = 0;
> - nor->flags &= ~SNOR_F_4B_OPCODES;
> - } else {
> - memcpy(params, &sfdp_params, sizeof(*params));
> - }
> - }
> -
> - return 0;
> + if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&
> + !(nor->info->flags & SPI_NOR_SKIP_SFDP))
> + spi_nor_sfdp_init_params(nor);
>  }
>  
>  static int spi_nor_select_read(struct spi_nor *nor,
> @@ -4670,10 +4715,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>   nor->info->flags & SPI_NOR_HAS_LOCK)
>   nor->clear_sr_bp = spi_nor_clear_sr_bp;
>  
> - /* Parse the Serial Flash Discoverable Parameters table. */
> - ret = spi_nor_init_params(nor);
> - if (ret)
> - return ret;
> + /* Init flash parameters based on flash_info struct and SFDP */
> + spi_nor_init_params(nor);
>  
>   if (!mtd->name)
>   mtd->name = dev_name(dev);
> 

-- 
Regards
Vignesh


Re: [linux-sunxi] [PATCH v6 1/3] ASoC: sun4i-i2s: incorrect regmap for A83T

2019-08-26 Thread Code Kipper
On Tue, 27 Aug 2019 at 06:13, Chen-Yu Tsai  wrote:
>
> On Tue, Aug 27, 2019 at 2:07 AM  wrote:
> >
> > From: Marcus Cooper 
> >
> > The regmap configuration is set up for the legacy block on the
> > A83T whereas it uses the new block with a larger register map.
>
> Looking at the code Allwinner previously released [1], that doesn't seem to be
> the case. Keep in mind that the register map shown in the user manual is for
> the TDM interface, which we don't actually support right now.

Should it matter what we support right now?, the block according to the user
manual shows the bigger range. I don't have a A83T device and from what I
gather not many users do. But the compatible for the H3 has been removed
and replaced with the settings for the A83T which also has default settings in
registers further up than SUNXI_RXCHMAP.

>
> The file shows the base address as 0x01c22800, and the last defined register
> is SUNXI_RXCHMAP at 0x3c.
>
> The I2S driver [2] also shows that it is the old register map size, but with
> TX_FIFO and INT_STA swapped around. This might mean that it would need a
> separate regmap_config, as the read/write callbacks need to be changed to
> fit the swapped registers.
>
> Finally, the TDM driver [3], which matches the TDM section in the manual, 
> shows
> a larger register map.
>
> A83T is SUN8IW6, while SUN8IW7 refers to the H3.

Since when have we trusted Allwinner code?, the TDM labelled block
clearly supports
I2S. The biggest use case for this block is getting HDMI audio working
on the newer
devices(LibreELEC nightlies has a user base of over 300) and I've tested this on
numerous set ups over the last couple of years.

Failing that reverting (3e9acd7ac693: "ASoC: sun4i-i2s: Remove
duplicated quirks structure")
would help.

BR,
CK
>
> ChenYu
>
> [1] 
> https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/sound/soc/sunxi/hdmiaudio/sunxi-hdmipcm.h
> [2] 
> https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/sound/soc/sunxi/i2s0/sunxi-i2s0.h
> [3] 
> https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/sound/soc/sunxi/daudio0/sunxi-daudio0.h
>
> > Fixes: 21faaea1343f ("ASoC: sun4i-i2s: Add support for A83T")
> > Signed-off-by: Marcus Cooper 
> > ---
> >  sound/soc/sunxi/sun4i-i2s.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> > index 57bf2a33753e..34575a8aa9f6 100644
> > --- a/sound/soc/sunxi/sun4i-i2s.c
> > +++ b/sound/soc/sunxi/sun4i-i2s.c
> > @@ -1100,7 +1100,7 @@ static const struct sun4i_i2s_quirks 
> > sun6i_a31_i2s_quirks = {
> >  static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
> > .has_reset  = true,
> > .reg_offset_txdata  = SUN8I_I2S_FIFO_TX_REG,
> > -   .sun4i_i2s_regmap   = &sun4i_i2s_regmap_config,
> > +   .sun4i_i2s_regmap   = &sun8i_i2s_regmap_config,
> > .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
> > .field_fmt_wss  = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
> > .field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
> > --
> > 2.23.0
> >
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "linux-sunxi" group.
> > To unsubscribe from this group and stop receiving emails from it, send an 
> > email to linux-sunxi+unsubscr...@googlegroups.com.
> > To view this discussion on the web, visit 
> > https://groups.google.com/d/msgid/linux-sunxi/20190826180734.15801-2-codekipper%40gmail.com.


Re: [RESEND PATCH v3 07/20] mtd: spi_nor: Move manufacturer quad_enable() in ->default_init()

2019-08-26 Thread Vignesh Raghavendra



On 26/08/19 5:38 PM, tudor.amba...@microchip.com wrote:
> From: Tudor Ambarus 
> 
> The goal is to move the quad_enable manufacturer specific init in the
> nor->manufacturer->fixups->default_init()
> 
> The legacy quad_enable() implementation is spansion_quad_enable(),
> select this method by default.
> 
> Set specific manufacturer fixups->default_init() hooks to overwrite
> the default quad_enable() implementation when needed.
> 
> Signed-off-by: Tudor Ambarus 
> Reviewed-by: Boris Brezillon 
> ---


Reviewed-by: Vignesh Raghavendra 

Regards
Vignesh


> v3: collect R-b
> 
>  drivers/mtd/spi-nor/spi-nor.c | 48 
> ++-
>  1 file changed, 29 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 3dbbfe34d1d2..2a239531704a 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -4150,13 +4150,38 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
>   return err;
>  }
>  
> +static void macronix_set_default_init(struct spi_nor *nor)
> +{
> + nor->params.quad_enable = macronix_quad_enable;
> +}
> +
> +static void st_micron_set_default_init(struct spi_nor *nor)
> +{
> + nor->params.quad_enable = NULL;
> +}
> +
>  /**
>   * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and
> - * settings based on ->default_init() hook.
> + * settings based on MFR register and ->default_init() hook.
>   * @nor: pointer to a 'struct spi-nor'.
>   */
>  static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
>  {
> + /* Init flash parameters based on MFR */
> + switch (JEDEC_MFR(nor->info)) {
> + case SNOR_MFR_MACRONIX:
> + macronix_set_default_init(nor);
> + break;
> +
> + case SNOR_MFR_ST:
> + case SNOR_MFR_MICRON:
> + st_micron_set_default_init(nor);
> + break;
> +
> + default:
> + break;
> + }
> +
>   if (nor->info->fixups && nor->info->fixups->default_init)
>   nor->info->fixups->default_init(nor);
>  }
> @@ -4168,6 +4193,9 @@ static int spi_nor_init_params(struct spi_nor *nor)
>   const struct flash_info *info = nor->info;
>   u8 i, erase_mask;
>  
> + /* Initialize legacy flash parameters and settings. */
> + params->quad_enable = spansion_quad_enable;
> +
>   /* Set SPI NOR sizes. */
>   params->size = (u64)info->sector_size * info->n_sectors;
>   params->page_size = info->page_size;
> @@ -4233,24 +4261,6 @@ static int spi_nor_init_params(struct spi_nor *nor)
>  SPINOR_OP_SE);
>   spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
>  
> - /* Select the procedure to set the Quad Enable bit. */
> - if (params->hwcaps.mask & (SNOR_HWCAPS_READ_QUAD |
> -SNOR_HWCAPS_PP_QUAD)) {
> - switch (JEDEC_MFR(info)) {
> - case SNOR_MFR_MACRONIX:
> - params->quad_enable = macronix_quad_enable;
> - break;
> -
> - case SNOR_MFR_ST:
> - case SNOR_MFR_MICRON:
> - break;
> -
> - default:
> - /* Kept only for backward compatibility purpose. */
> - params->quad_enable = spansion_quad_enable;
> - break;
> - }
> - }
>  
>   spi_nor_manufacturer_init_params(nor);
>  
> 

-- 
Regards
Vignesh


Re: [RFC PATCH v2 1/3] x86/mm/tlb: Change __flush_tlb_one_user interface

2019-08-26 Thread Juergen Gross

On 26.08.19 18:38, Nadav Amit wrote:

On Aug 26, 2019, at 12:51 AM, Juergen Gross  wrote:

On 24.08.19 00:52, Nadav Amit wrote:

__flush_tlb_one_user() currently flushes a single entry, and flushes it
both in the kernel and user page-tables, when PTI is enabled.
Change __flush_tlb_one_user() and related interfaces into
__flush_tlb_range() that flushes a range and does not flush the user
page-table.
This refactoring is needed for the next patch, but regardless makes
sense and has several advantages. First, only Xen-PV, which does not
use PTI, implements the paravirtual interface of flush_tlb_one_user() so
nothing is broken by separating the user and kernel page-table flushes,
and the interface is more intuitive.
Second, INVLPG can flush unrelated mappings, and it is also a
serializing instruction. It is better to have a tight loop that flushes
the entries.
Third, currently __flush_tlb_one_kernel() also flushes the user
page-tables, which is not needed. This allows to avoid this redundant
flush.
Cc: Boris Ostrovsky 
Cc: Juergen Gross 
Cc: Stefano Stabellini 
Cc: xen-de...@lists.xenproject.org
Signed-off-by: Nadav Amit 
---
  arch/x86/include/asm/paravirt.h   |  5 ++--
  arch/x86/include/asm/paravirt_types.h |  3 ++-
  arch/x86/include/asm/tlbflush.h   | 24 +
  arch/x86/kernel/paravirt.c|  7 ++---
  arch/x86/mm/tlb.c | 39 ++-
  arch/x86/xen/mmu_pv.c | 21 +--
  6 files changed, 62 insertions(+), 37 deletions(-)


...


diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 48f7c7eb4dbc..ed68657f5e77 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -1325,22 +1325,27 @@ static noinline void xen_flush_tlb(void)
preempt_enable();
  }
  -static void xen_flush_tlb_one_user(unsigned long addr)
+static void xen_flush_tlb_range(unsigned long start, unsigned long end,
+   u8 stride_shift)
  {
struct mmuext_op *op;
struct multicall_space mcs;
-
-   trace_xen_mmu_flush_tlb_one_user(addr);
+   unsigned long addr;
preempt_disable();
mcs = xen_mc_entry(sizeof(*op));
op = mcs.args;
-   op->cmd = MMUEXT_INVLPG_LOCAL;
-   op->arg1.linear_addr = addr & PAGE_MASK;
-   MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
  - xen_mc_issue(PARAVIRT_LAZY_MMU);
+   for (addr = start; addr < end; addr += 1ul << stride_shift) {
+   trace_xen_mmu_flush_tlb_one_user(addr);
+
+   op->cmd = MMUEXT_INVLPG_LOCAL;
+   op->arg1.linear_addr = addr & PAGE_MASK;
+   MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+
+   xen_mc_issue(PARAVIRT_LAZY_MMU);
+   }


For this kind of usage (a loop) you should:

- replace the call of xen_mc_entry() with xen_mc_batch()
- use xen_extend_mmuext_op() for each loop iteration
- call xen_mc_issue() after the loop

Additionally I'd like you to replace trace_xen_mmu_flush_tlb_one_user()
with trace_xen_mmu_flush_tlb_range() taking all three parameters and
keep it where it was (out of the loop).

The paravirt parts seem to be okay.


Thanks for the quick response. I don’t think the preempt_disable/enable() is
needed in this case, but I kept them. Does the following match what you had
in mind?


Yes, it does.

BTW, preempt_disable/enable() is needed as xen_mc_batch() ...
xen_mc_issue() is using a percpu buffer.


Juergen



---
  arch/x86/xen/mmu_pv.c  | 25 ++---
  include/trace/events/xen.h | 18 --
  2 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 48f7c7eb4dbc..faa01591df36 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -1325,20 +1325,23 @@ static noinline void xen_flush_tlb(void)
preempt_enable();
  }
  
-static void xen_flush_tlb_one_user(unsigned long addr)

+static void xen_flush_tlb_range(unsigned long start, unsigned long end,
+   u8 stride_shift)
  {
-   struct mmuext_op *op;
-   struct multicall_space mcs;
-
-   trace_xen_mmu_flush_tlb_one_user(addr);
+   struct mmuext_op op;
+   unsigned long addr;
  
  	preempt_disable();
  
-	mcs = xen_mc_entry(sizeof(*op));

-   op = mcs.args;
-   op->cmd = MMUEXT_INVLPG_LOCAL;
-   op->arg1.linear_addr = addr & PAGE_MASK;
-   MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+   xen_mc_batch();
+   op.cmd = MMUEXT_INVLPG_LOCAL;
+
+   trace_xen_mmu_flush_tlb_range(start, end, stride_shift);
+
+   for (addr = start; addr < end; addr += 1ul << stride_shift) {
+   op.arg1.linear_addr = addr & PAGE_MASK;
+   xen_extend_mmuext_op(&op);
+   }
  
  	xen_mc_issue(PARAVIRT_LAZY_MMU);
  
@@ -2394,7 +2397,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
  
  	.flush_tlb_user = xen_flush_tlb,

.flush_tlb_kernel = xen_flush_tl

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

2019-08-26 Thread Stephen Rothwell
Hi all,

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

ERROR: "__arm_smccc_smc" [drivers/phy/marvell/phy-mvebu-cp110-comphy.ko] 
undefined!

Caused by commit

  ccee80654309 ("phy: mvebu-cp110-comphy: Add SMC call support")

I have used the phy-next tree from next-20190826 for today.

-- 
Cheers,
Stephen Rothwell


pgpcsCZMbwn6u.pgp
Description: OpenPGP digital signature


Re: [PATCH V5 1/3] riscv: Add perf callchain support

2019-08-26 Thread Guo Ren
We need know the values of *regs, eg: regs->sepc, regs->ra, regs->fp,
regs->sp, regs->tp

void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
   struct pt_regs *regs)
{
...
 walk_stackframe(&fr, entry);

// May be we could detect error here and print the regs' value
}

On Mon, Aug 26, 2019 at 4:03 PM Greentime Hu  wrote:
>
> Hi Guo,
>
> Guo Ren  於 2019年8月24日 週六 上午8:54寫道:
> >
> > Please check CONFIG_FRAME_POINTER
> >
> > 1 *frame = *((struct stackframe *)frame->fp - 1);
> > This code is origionally from riscv/kernel/stacktrace.c: walk_stackframe
> >
> > In linux/Makefile it'll involve the options for gcc to definitely
> > store ra & prev_fp in fp pointer.
> > ifdef CONFIG_FRAME_POINTER
> > KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
> >
> > So --call-graph fp need depends on CONFIG_FRAME_POINTER.
> >
>
> I am pretty sure CONFIG_FRAME_POINTER is Y
> # zcat /proc/config.gz |grep CONFIG_FRAME_POINTER
> CONFIG_FRAME_POINTER=y
>
> This is not going to go wrong every time, the probability of error is
> about one tenth or one quarter. randomly
> There may be some conditions that we have not considered.
>
> I add one more condition to check if it is a valid virtual address and
> it( ./perf record -e cpu-clock --call-graph fp ls) passes 1000 times
> without failure in Unleashed board based on 5.3-rc5.
> Here is my patch. Please have  a look at it. I am not sure if it is a
> good solution.
>
> diff --git a/arch/riscv/kernel/perf_callchain.c
> b/arch/riscv/kernel/perf_callchain.c
> index d75d15c13dc7..4717942435df 100644
> --- a/arch/riscv/kernel/perf_callchain.c
> +++ b/arch/riscv/kernel/perf_callchain.c
> @@ -18,6 +18,8 @@ static int unwind_frame_kernel(struct stackframe *frame)
> return -EPERM;
> if (frame->fp < CONFIG_PAGE_OFFSET)
> return -EPERM;
> +   if (!virt_addr_valid(frame->fp))
> +   return -EPERM;
>
> *frame = *((struct stackframe *)frame->fp - 1);
> if (__kernel_text_address(frame->ra)) {
>
> It could catch cases called in this way.
>
> [ 1381.936586] frame->fp=:00547550
> [ 1382.038542] CPU: 1 PID: 135 Comm: ls Not tainted
> 5.3.0-rc5-3-gb008f6bcd67c-dirty #14
> [ 1382.307440] Call Trace:
> [ 1382.388947] [] walk_stackframe+0x0/0x9a
> [ 1382.568053] [] show_stack+0x2a/0x34
> [ 1382.735960] [] dump_stack+0x62/0x7c
> [ 1382.903863] [] perf_callchain_kernel+0xd8/0x102
> [ 1383.106558] [] get_perf_callchain+0x136/0x1f2
> [ 1383.303128] [] perf_callchain+0x52/0x6e
> [ 1383.482553] [] perf_prepare_sample+0x6e/0x476
> [ 1383.679357] [] perf_event_output_forward+0x1c/0x50
> [ 1383.890633] [] __perf_event_overflow+0x6a/0xa4
> [ 1384.090279] [] perf_swevent_hrtimer+0xba/0x106
> [ 1384.290094] [] __hrtimer_run_queues+0x84/0x108
> [ 1384.489694] [] hrtimer_interrupt+0xca/0x1ce
> [ 1384.680974] [] riscv_timer_interrupt+0x32/0x3a
> [ 1384.880449] [] do_IRQ+0x64/0xbe
> [ 1385.036698] [] ret_from_exception+0x0/0xc
>
> [13915.697989] frame->fp=:f000
> [13915.799937] CPU: 2 PID: 663 Comm: ls Not tainted
> 5.3.0-rc5-3-gb008f6bcd67c-dirty #14
> [13916.068832] Call Trace:
> [13916.150380] [] walk_stackframe+0x0/0x9a
> [13916.329450] [] show_stack+0x2a/0x34
> [13916.497360] [] dump_stack+0x62/0x7c
> [13916.665265] [] perf_callchain_kernel+0xd8/0x102
> [13916.867949] [] get_perf_callchain+0x136/0x1f2
> [13917.064526] [] perf_callchain+0x52/0x6e
> [13917.243950] [] perf_prepare_sample+0x6e/0x476
> [13917.440759] [] perf_event_output_forward+0x1c/0x50
> [13917.652021] [] __perf_event_overflow+0x6a/0xa4
> [13917.851683] [] perf_swevent_hrtimer+0xba/0x106
> [13918.051494] [] __hrtimer_run_queues+0x84/0x108
> [13918.251094] [] hrtimer_interrupt+0xca/0x1ce
> [13918.442379] [] riscv_timer_interrupt+0x32/0x3a
> [13918.641840] [] do_IRQ+0x64/0xbe
> [13918.798082] [] ret_from_exception+0x0/0xc



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


Re: [RESEND PATCH v3 05/20] mtd: spi-nor: Add default_init() hook to tweak flash parameters

2019-08-26 Thread Vignesh Raghavendra



On 26/08/19 5:38 PM, tudor.amba...@microchip.com wrote:
> From: Tudor Ambarus 
> 
> As of now, the flash parameters initialization logic is as following:
> 
> a/ default flash parameters init in spi_nor_init_params()
> b/ manufacturer specific flash parameters updates, split across entire
>spi-nor core code
> c/ flash parameters updates based on SFDP tables
> d/ post BFPT flash parameter updates
> 
> In the quest of removing the manufacturer specific code from the spi-nor
> core, we want to impose a timeline/priority on how the flash parameters
> are updated. The following sequence of calls is pursued:
> 
> 1/ spi-nor core parameters init based on 'flash_info' struct:
>   spi_nor_info_init_params()
> 
> which can be overwritten by:
> 2/ MFR-based manufacturer flash parameters init:
>   nor->manufacturer->fixups->default_init()
> 
> which can be overwritten by:
> 3/ specific flash_info tweeks done when decisions can not be done just on
>MFR:
>   nor->info->fixups->default_init()
> 
> which can be overwritten by:
> 4/ SFDP tables flash parameters init - SFDP knows better:
>   spi_nor_sfdp_init_params()
> 
> which can be overwritten by:
> 5/ post SFDP tables flash parameters updates - in case manufacturers get
>the serial flash tables wrong or incomplete.
>   nor->info->fixups->post_sfdp()
>The later can be extended to nor->manufacturer->fixups->post_sfdp() if
>needed.
> 
> This patch opens doors for steps 2/ and 3/.
> 
> Signed-off-by: Tudor Ambarus 
> Reviewed-by: Boris Brezillon 
> ---


Reviewed-by: Vignesh Raghavendra 

Regards
Vignesh

> v3: reword description
> 
>  drivers/mtd/spi-nor/spi-nor.c | 17 +
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 9dd6cd8cd13c..8fd60e1eebd2 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -154,12 +154,16 @@ struct sfdp_bfpt {
>  
>  /**
>   * struct spi_nor_fixups - SPI NOR fixup hooks
> + * @default_init: called after default flash parameters init. Used to tweak
> + *flash parameters when information provided by the 
> flash_info
> + *table is incomplete or wrong.
>   * @post_bfpt: called after the BFPT table has been parsed
>   *
>   * Those hooks can be used to tweak the SPI NOR configuration when the SFDP
>   * table is broken or not available.
>   */
>  struct spi_nor_fixups {
> + void (*default_init)(struct spi_nor *nor);
>   int (*post_bfpt)(struct spi_nor *nor,
>const struct sfdp_parameter_header *bfpt_header,
>const struct sfdp_bfpt *bfpt,
> @@ -4133,6 +4137,17 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
>   return err;
>  }
>  
> +/**
> + * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and
> + * settings based on ->default_init() hook.
> + * @nor: pointer to a 'struct spi-nor'.
> + */
> +static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
> +{
> + if (nor->info->fixups && nor->info->fixups->default_init)
> + nor->info->fixups->default_init(nor);
> +}
> +
>  static int spi_nor_init_params(struct spi_nor *nor)
>  {
>   struct spi_nor_flash_parameter *params = &nor->params;
> @@ -4233,6 +4248,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
>   params->quad_enable = info->quad_enable;
>   }
>  
> + spi_nor_manufacturer_init_params(nor);
> +
>   if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&
>   !(info->flags & SPI_NOR_SKIP_SFDP)) {
>   struct spi_nor_flash_parameter sfdp_params;
> 

-- 
Regards
Vignesh


Re: [RESEND PATCH v3 06/20] mtd: spi-nor: Add a default_init() fixup hook for gd25q256

2019-08-26 Thread Vignesh Raghavendra



On 26/08/19 5:38 PM, tudor.amba...@microchip.com wrote:
> From: Boris Brezillon 
> 
> gd25q256 needs to tweak the ->quad_enable() implementation and the
> ->default_init() fixup hook is the perfect place to do that. This way,
> if we ever need to tweak more things for this flash, we won't have to
> add new fields in flash_info.
> 
> We can get rid of the flash_info->quad_enable field as gd25q256 was
> the only user.
> 
> Signed-off-by: Boris Brezillon 
> [tudor.amba...@microchip.com: use ->default_init() hook instead of
> ->post_sfdp()]
> Signed-off-by: Tudor Ambarus 
> ---


Reviewed-by: Vignesh Raghavendra 

Regards
Vignesh

> v3: no changes
> >  drivers/mtd/spi-nor/spi-nor.c | 28 
>  1 file changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 8fd60e1eebd2..3dbbfe34d1d2 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -222,8 +222,6 @@ struct flash_info {
>  
>   /* Part specific fixup hooks. */
>   const struct spi_nor_fixups *fixups;
> -
> - int (*quad_enable)(struct spi_nor *nor);
>  };
>  
>  #define JEDEC_MFR(info)  ((info)->id[0])
> @@ -2126,6 +2124,21 @@ static struct spi_nor_fixups mx25l25635_fixups = {
>   .post_bfpt = mx25l25635_post_bfpt_fixups,
>  };
>  
> +static void gd25q256_default_init(struct spi_nor *nor)
> +{
> + /*
> +  * Some manufacturer like GigaDevice may use different
> +  * bit to set QE on different memories, so the MFR can't
> +  * indicate the quad_enable method for this case, we need
> +  * to set it in the default_init fixup hook.
> +  */
> + nor->params.quad_enable = macronix_quad_enable;
> +}
> +
> +static struct spi_nor_fixups gd25q256_fixups = {
> + .default_init = gd25q256_default_init,
> +};
> +
>  /* NOTE: double check command sets and memory organization when you add
>   * more nor chips.  This current list focusses on newer chips, which
>   * have been converging on command sets which including JEDEC ID.
> @@ -2218,7 +2231,7 @@ static const struct flash_info spi_nor_ids[] = {
>   "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,
>   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>   SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
> - .quad_enable = macronix_quad_enable,
> + .fixups = &gd25q256_fixups,
>   },
>  
>   /* Intel/Numonyx -- xxxs33b */
> @@ -4237,15 +4250,6 @@ static int spi_nor_init_params(struct spi_nor *nor)
>   params->quad_enable = spansion_quad_enable;
>   break;
>   }
> -
> - /*
> -  * Some manufacturer like GigaDevice may use different
> -  * bit to set QE on different memories, so the MFR can't
> -  * indicate the quad_enable method for this case, we need
> -  * set it in flash info list.
> -  */
> - if (info->quad_enable)
> - params->quad_enable = info->quad_enable;
>   }
>  
>   spi_nor_manufacturer_init_params(nor);
> 

-- 
Regards
Vignesh


Re: [PATCH] ext4: change the type of ext4 cache stats to percpu_counter to improve performance

2019-08-26 Thread Shaokun Zhang
Hi Theodore,

On 2019/8/26 23:57, Theodore Y. Ts'o wrote:
> On Mon, Aug 26, 2019 at 04:24:20PM +0800, Shaokun Zhang wrote:
>>> The other problem with this patch is that it initializes
>>> es_stats_cache_hits and es_stats_cache_miesses too late.  They will
>>> get used when the journal inode is loaded.  This is mostly harmless,
>>
>> I have checked it again, @es_stats_cache_hits and @es_stats_cache_miesses
>> have been initialized before the journal inode is loaded, Maybe I miss
>> something else?
> 
> No, sorry, that was my mistake.  I misread things when I was looking
> over your patch last night.
> 
> Please resubmit your patch once you've fixed things up and tested it.
> 

Sure, will do it soon.

> I would recommend that you at least try running your patch using the
> kvm-xfstests's smoke test[1] before submitting them.  It will save you
> and me time.
> 

Ok, thanks your guidance.

Shaokun,

> [1] 
> https://github.com/tytso/xfstests-bld/blob/master/Documentation/kvm-quickstart.md
> 
> Thanks,
> 
>   - Ted
>   
> 
> .
> 



Re: PageBlocks and Migrate Types

2019-08-26 Thread Michal Hocko
On Mon 26-08-19 22:35:08, Pankaj Suryawanshi wrote:
> On Mon, Aug 26, 2019 at 12:34 PM Michal Hocko  wrote:
> >
> > On Thu 22-08-19 23:54:19, Pankaj Suryawanshi wrote:
> > > On Thu, Aug 22, 2019 at 6:22 PM Michal Hocko  wrote:
> > > >
> > > > On Wed 21-08-19 22:23:44, Pankaj Suryawanshi wrote:
> > > > > Hello,
> > > > >
> > > > > 1. What are Pageblocks and migrate types(MIGRATE_CMA) in Linux
> memory ?
> > > >
> > > > Pageblocks are a simple grouping of physically contiguous pages with
> > > > common set of flags. I haven't checked closely recently so I might
> > > > misremember but my recollection is that only the migrate type is
> stored
> > > > there. Normally we would store that information into page flags but
> > > > there is not enough room there.
> > > >
> > > > MIGRATE_CMA represent pages allocated for the CMA allocator. There are
> > > > other migrate types denoting unmovable/movable allocations or pages
> that
> > > > are isolated from the page allocator.
> > > >
> > > > Very broadly speaking, the migrate type groups pages with similar
> > > > movability properties to reduce fragmentation that compaction cannot
> > > > do anything about because there are objects of different properti
> > > > around. Please note that pageblock might contain objects of a
> different
> > > > migrate type in some cases (e.g. low on memory).
> > > >
> > > > Have a look at gfpflags_to_migratetype and how the gfp mask is
> converted
> > > > to a migratetype for the allocation. Also follow different
> MIGRATE_$TYPE
> > > > to see how it is used in the code.
> > > >
> > > > > How many movable/unmovable pages are defined by default?
> > > >
> > > > There is nothing like that. It depends on how many objects of a
> specific
> > > > type are allocated.
> > >
> > >
> > > It means that it started creating pageblocks after allocation of
> > > different objects, but from which block it allocate initially when
> > > there is nothing like pageblocks ? (when memory subsystem up)
> >
> > Pageblocks are just a way to group physically contiguous pages. They
> > just exist along with the physically contiguous memory. The migrate type
> > for most of the memory is set to MIGRATE_MOVABLE. Portion of the memory
> > might be reserved by CMA then that memory has MIGRATE_CMA. Following
> > set_pageblock_migratetype call paths will give you a good picture.
> 
> it means if i have 4096 continuous pages = 1 pageblock
> then all the 4096 pages of same type. but if any one page is different than
> block type then ? it changed the block type or something else ?

That really depends on the specific migrate type. CMA, ISOLATE migrate
types are all or nothing IIRC. I would have to check the code to tell
exactly when MOVABLE/UNMOVABLE pageblocks transitions are done.
steal_suitable_fallback sounds like a good start to look at.
-- 
Michal Hocko
SUSE Labs


Re: [RESEND PATCH v3 04/20] mtd: spi-nor: Move erase_map to 'struct spi_nor_flash_parameter'

2019-08-26 Thread Vignesh Raghavendra



On 26/08/19 5:38 PM, tudor.amba...@microchip.com wrote:
> From: Tudor Ambarus 
> 
> All flash parameters and settings should reside inside
> 'struct spi_nor_flash_parameter'. Move the SMPT parsed erase map
> from 'struct spi_nor' to 'struct spi_nor_flash_parameter'.
> 
> Please note that there is a roll-back mechanism for the flash
> parameter and settings, for cases when SFDP parser fails. The SFDP
> parser receives a Stack allocated copy of nor->params, called
> sfdp_params, and uses it to retrieve the serial flash discoverable
> parameters. JESD216 SFDP is a standard and has a higher priority
> than the default initialized flash parameters, so will overwrite the
> sfdp_params data when needed. All SFDP code uses the local copy of
> nor->params, that will overwrite it in the end, if the parser succeds.
> 
> Saving and restoring the nor->params.erase_map is no longer needed,
> since the SFDP code does not touch it.
> 
> Signed-off-by: Tudor Ambarus 
> ---


Reviewed-by: Vignesh Raghavendra 

Regards
Vignesh

> v3: Collect R-b
> 
>  drivers/mtd/spi-nor/spi-nor.c | 40 +---
>  include/linux/mtd/spi-nor.h   |  8 +---
>  2 files changed, 26 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index effda372cb33..9dd6cd8cd13c 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -600,7 +600,7 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
>   nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
>  
>   if (!spi_nor_has_uniform_erase(nor)) {
> - struct spi_nor_erase_map *map = &nor->erase_map;
> + struct spi_nor_erase_map *map = &nor->params.erase_map;
>   struct spi_nor_erase_type *erase;
>   int i;
>  
> @@ -1133,7 +1133,7 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor 
> *nor,
>  struct list_head *erase_list,
>  u64 addr, u32 len)
>  {
> - const struct spi_nor_erase_map *map = &nor->erase_map;
> + const struct spi_nor_erase_map *map = &nor->params.erase_map;
>   const struct spi_nor_erase_type *erase, *prev_erase = NULL;
>   struct spi_nor_erase_region *region;
>   struct spi_nor_erase_command *cmd = NULL;
> @@ -3328,7 +3328,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
> const struct sfdp_parameter_header *bfpt_header,
> struct spi_nor_flash_parameter *params)
>  {
> - struct spi_nor_erase_map *map = &nor->erase_map;
> + struct spi_nor_erase_map *map = ¶ms->erase_map;
>   struct spi_nor_erase_type *erase_type = map->erase_type;
>   struct sfdp_bfpt bfpt;
>   size_t len;
> @@ -3409,7 +3409,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
>* Erase Types defined in the bfpt table.
>*/
>   erase_mask = 0;
> - memset(&nor->erase_map, 0, sizeof(nor->erase_map));
> + memset(¶ms->erase_map, 0, sizeof(params->erase_map));
>   for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) {
>   const struct sfdp_bfpt_erase *er = &sfdp_bfpt_erases[i];
>   u32 erasesize;
> @@ -3684,14 +3684,18 @@ spi_nor_region_check_overlay(struct 
> spi_nor_erase_region *region,
>  /**
>   * spi_nor_init_non_uniform_erase_map() - initialize the non-uniform erase 
> map
>   * @nor: pointer to a 'struct spi_nor'
> + * @params: pointer to a duplicate 'struct spi_nor_flash_parameter' that 
> is
> + *  used for storing SFDP parsed data
>   * @smpt:pointer to the sector map parameter table
>   *
>   * Return: 0 on success, -errno otherwise.
>   */
> -static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
> -   const u32 *smpt)
> +static int
> +spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
> +struct spi_nor_flash_parameter *params,
> +const u32 *smpt)
>  {
> - struct spi_nor_erase_map *map = &nor->erase_map;
> + struct spi_nor_erase_map *map = ¶ms->erase_map;
>   struct spi_nor_erase_type *erase = map->erase_type;
>   struct spi_nor_erase_region *region;
>   u64 offset;
> @@ -3770,6 +3774,8 @@ static int spi_nor_init_non_uniform_erase_map(struct 
> spi_nor *nor,
>   * spi_nor_parse_smpt() - parse Sector Map Parameter Table
>   * @nor: pointer to a 'struct spi_nor'
>   * @smpt_header: sector map parameter table header
> + * @params:  pointer to a duplicate 'struct spi_nor_flash_parameter'
> + *  that is used for storing SFDP parsed data
>   *
>   * This table is optional, but when available, we parse it to identify the
>   * location and size of sectors within the main data array of the flash 
> memory
> @@ -3778,7 +3784,8 @@ static int spi_nor_init_non_uniform_erase_map(struct 
>

[PATCH 1/2] mm: Don't manually decrement num_poisoned_pages

2019-08-26 Thread Alastair D'Silva
From: Alastair D'Silva 

Use the function written to do it instead.

Signed-off-by: Alastair D'Silva 
---
 mm/sparse.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/mm/sparse.c b/mm/sparse.c
index 72f010d9bff5..e41917a7e844 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -11,6 +11,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "internal.h"
 #include 
@@ -898,7 +900,7 @@ static void clear_hwpoisoned_pages(struct page *memmap, int 
nr_pages)
 
for (i = 0; i < nr_pages; i++) {
if (PageHWPoison(&memmap[i])) {
-   atomic_long_sub(1, &num_poisoned_pages);
+   num_poisoned_pages_dec();
ClearPageHWPoison(&memmap[i]);
}
}
-- 
2.21.0



[PATCH 2/2] mm: don't hide potentially null memmap pointer in sparse_remove_section

2019-08-26 Thread Alastair D'Silva
From: Alastair D'Silva 

By adding offset to memmap before passing it in to clear_hwpoisoned_pages,
we hide a theoretically null memmap from the null check inside
clear_hwpoisoned_pages.

This patch passes the offset to clear_hwpoisoned_pages instead, allowing
memmap to successfully perform it's null check.

Signed-off-by: Alastair D'Silva 
---
 mm/sparse.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/mm/sparse.c b/mm/sparse.c
index e41917a7e844..3ff84e627e58 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -882,7 +882,7 @@ int __meminit sparse_add_section(int nid, unsigned long 
start_pfn,
 }
 
 #ifdef CONFIG_MEMORY_FAILURE
-static void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
+static void clear_hwpoisoned_pages(struct page *memmap, int start, int count)
 {
int i;
 
@@ -898,7 +898,7 @@ static void clear_hwpoisoned_pages(struct page *memmap, int 
nr_pages)
if (atomic_long_read(&num_poisoned_pages) == 0)
return;
 
-   for (i = 0; i < nr_pages; i++) {
+   for (i = start; i < start + count; i++) {
if (PageHWPoison(&memmap[i])) {
num_poisoned_pages_dec();
ClearPageHWPoison(&memmap[i]);
@@ -906,7 +906,8 @@ static void clear_hwpoisoned_pages(struct page *memmap, int 
nr_pages)
}
 }
 #else
-static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
+static inline void clear_hwpoisoned_pages(struct page *memmap, int start,
+   int count)
 {
 }
 #endif
@@ -915,7 +916,7 @@ void sparse_remove_section(struct mem_section *ms, unsigned 
long pfn,
unsigned long nr_pages, unsigned long map_offset,
struct vmem_altmap *altmap)
 {
-   clear_hwpoisoned_pages(pfn_to_page(pfn) + map_offset,
+   clear_hwpoisoned_pages(pfn_to_page(pfn), map_offset,
nr_pages - map_offset);
section_deactivate(pfn, nr_pages, altmap);
 }
-- 
2.21.0



[PATCH 0/2] mm: Minor cleanup

2019-08-26 Thread Alastair D'Silva
From: Alastair D'Silva 

This series addresses some minor issues & obsoletes:
mm: Cleanup & allow modules to hotplug memory

Alastair D'Silva (2):
  mm: Don't manually decrement num_poisoned_pages
  mm: don't hide potentially null memmap pointer in
sparse_remove_section

 mm/sparse.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

-- 
2.21.0



Re: [RESEND PATCH v3 00/20] mtd: spi-nor: move manuf out of the core

2019-08-26 Thread Vignesh Raghavendra



On 26/08/19 5:38 PM, tudor.amba...@microchip.com wrote:
> From: Tudor Ambarus 
[...]
> 
> Tested on sst26vf064b with atmel-quadspi SPIMEM driver.
> 

Tested s25fl256s, mx66l51235l with ti-qspi and s25fl512s with
cadence-quadspi. n25q128a13 with legacy 1 bit SPI controller.

> Boris Brezillon (7):
>   mtd: spi-nor: Add a default_init() fixup hook for gd25q256
>   mtd: spi-nor: Create a ->set_4byte() method
>   mtd: spi-nor: Rework the SPI NOR lock/unlock logic
>   mtd: spi-nor: Add post_sfdp() hook to tweak flash config
>   mtd: spi-nor: Add spansion_post_sfdp_fixups()
>   mtd: spi-nor: Add a ->convert_addr() method
>   mtd: spi-nor: Add the SPI_NOR_XSR_RDY flag
> 
> Tudor Ambarus (13):
>   mtd: spi-nor: Regroup flash parameter and settings
>   mtd: spi-nor: Use nor->params
>   mtd: spi-nor: Drop quad_enable() from 'struct spi-nor'
>   mtd: spi-nor: Move erase_map to 'struct spi_nor_flash_parameter'
>   mtd: spi-nor: Add default_init() hook to tweak flash parameters
>   mtd: spi_nor: Move manufacturer quad_enable() in ->default_init()
>   mtd: spi-nor: Split spi_nor_init_params()
>   mtd: spi_nor: Add a ->setup() method
>   mtd: spi-nor: Add s3an_post_sfdp_fixups()
>   mtd: spi-nor: Bring flash params init together
>   mtd: spi_nor: Introduce spi_nor_set_addr_width()
>   mtd: spi-nor: Introduce spi_nor_get_flash_info()
>   mtd: spi-nor: Rework the disabling of block write protection
> 
>  drivers/mtd/spi-nor/spi-nor.c | 1304 
> +++--
>  include/linux/mtd/spi-nor.h   |  298 +++---
>  2 files changed, 927 insertions(+), 675 deletions(-)
> 

-- 
Regards
Vignesh


  1   2   3   4   5   6   7   8   9   10   >