Re: [PATCH v3 1/2] GPIO: add single-register GPIO via CREG driver

2018-09-24 Thread Eugeniy Paltsev
Hi Linus,

Maybe you have any comments or remarks about this patch? And if you don't could 
you please apply it.
Thanks!

On Tue, 2018-09-11 at 18:09 +0300, Eugeniy Paltsev wrote:
> Add single-register MMIO GPIO driver for complex cases where
> only several fields in register belong to GPIO lines and each GPIO
> line owns a field with different length and on/off value.
> 
> Such CREG GPIOs are used in Synopsys AXS10x and HSDK boards.
> 
> Signed-off-by: Eugeniy Paltsev 
> ---
> Changes v2->v3:
>  * Move parameters into a lookup table instead of device tree.
>  * Use the ngpios attribute for instead of snps,ngpios.
> 
>  MAINTAINERS   |   6 ++
>  drivers/gpio/Kconfig  |  10 ++
>  drivers/gpio/Makefile |   1 +
>  drivers/gpio/gpio-creg-snps.c | 212 
> ++
>  4 files changed, 229 insertions(+)
>  create mode 100644 drivers/gpio/gpio-creg-snps.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 544cac829cf4..e731f2f9648a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13734,6 +13734,12 @@ S:   Supported
>  F:   drivers/reset/reset-axs10x.c
>  F:   Documentation/devicetree/bindings/reset/snps,axs10x-reset.txt
>  
> +SYNOPSYS CREG GPIO DRIVER
> +M:   Eugeniy Paltsev 
> +S:   Maintained
> +F:   drivers/gpio/gpio-creg-snps.c
> +F:   Documentation/devicetree/bindings/gpio/snps,creg-gpio.txt
> +
>  SYNOPSYS DESIGNWARE 8250 UART DRIVER
>  R:   Andy Shevchenko 
>  S:   Maintained
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 71c0ab46f216..78155ac22b0c 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -430,6 +430,16 @@ config GPIO_REG
> A 32-bit single register GPIO fixed in/out implementation.  This
> can be used to represent any register as a set of GPIO signals.
>  
> +config GPIO_SNPS_CREG
> + bool "Synopsys GPIO via CREG (Control REGisters) driver"
> + depends on ARC || COMPILE_TEST
> + select OF_GPIO
> + help
> +   This driver supports GPIOs via CREG on various Synopsys SoCs.
> +   This is a single-register MMIO GPIO driver for complex cases
> +   where only several fields in register belong to GPIO lines and
> +   each GPIO line owns a field with different length and on/off value.
> +
>  config GPIO_SPEAR_SPICS
>   bool "ST SPEAr13xx SPI Chip Select as GPIO support"
>   depends on PLAT_SPEAR
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 1324c8f966a7..993f8ad54a19 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -109,6 +109,7 @@ obj-$(CONFIG_GPIO_REG)+= gpio-reg.o
>  obj-$(CONFIG_ARCH_SA1100)+= gpio-sa1100.o
>  obj-$(CONFIG_GPIO_SCH)   += gpio-sch.o
>  obj-$(CONFIG_GPIO_SCH311X)   += gpio-sch311x.o
> +obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o
>  obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
>  obj-$(CONFIG_GPIO_SPEAR_SPICS)   += gpio-spear-spics.o
>  obj-$(CONFIG_GPIO_SPRD)  += gpio-sprd.o
> diff --git a/drivers/gpio/gpio-creg-snps.c b/drivers/gpio/gpio-creg-snps.c
> new file mode 100644
> index ..2400dec529b2
> --- /dev/null
> +++ b/drivers/gpio/gpio-creg-snps.c
> @@ -0,0 +1,212 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +//
> +// Synopsys CREG (Control REGisters) GPIO driver
> +//
> +// Copyright (C) 2018 Synopsys
> +// Author: Eugeniy Paltsev 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "gpiolib.h"
> +
> +#define MAX_GPIO 32
> +
> +struct creg_layout {
> + u8 ngpio;
> + u8 shift[MAX_GPIO];
> + u8 on[MAX_GPIO];
> + u8 off[MAX_GPIO];
> + u8 bit_per_gpio[MAX_GPIO];
> +};
> +
> +struct creg_gpio {
> + struct of_mm_gpio_chip mmchip;
> + spinlock_t lock;
> + const struct creg_layout *layout;
> +};
> +
> +static void creg_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
> +{
> + struct creg_gpio *hcg = gpiochip_get_data(gc);
> + const struct creg_layout *layout = hcg->layout;
> + u32 reg, reg_shift, value;
> + unsigned long flags;
> + int i;
> +
> + value = val ? hcg->layout->on[gpio] : hcg->layout->off[gpio];
> +
> + reg_shift = layout->shift[gpio];
> + for (i = 0; i < gpio; i++)
> + reg_shift += layout->bit_per_gpio[i] + layout->shift[i];
> +
> + spin_lock_irqsave(&hcg->lock, flags);
> + reg = readl(hcg->mmchip.regs);
> + reg &= ~(GENMASK(layout->bit_per_gpio[i] - 1, 0) << reg_shift);
> + reg |=  (value << reg_shift);
> + writel(reg, hcg->mmchip.regs);
> + spin_unlock_irqrestore(&hcg->lock, flags);
> +}
> +
> +static int creg_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int 
> val)
> +{
> + creg_gpio_set(gc, gpio, val);
> +
> + return 0;
> +}
> +
> +static int creg_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
> +{
> + return 0; /* output */
> +}
> +
> +static int creg_gpio_xlate(struct gpio_chip *gc,
> + 

Re: [PATCH v2 1/2] mtd: spi-nor: Add support of sst26wf* flash ICs protection ops

2018-09-24 Thread Eugeniy Paltsev
Hi Marek,

Maybe you have any comments or remarks about this patch? And if you don't could 
you please apply it.
Thanks!

On Mon, 2018-09-10 at 14:46 +0300, Eugeniy Paltsev wrote:
> sst26wf flash series block protection implementation differs
> from other SST series, so add specific implementation
> flash_lock/flash_unlock/flash_is_locked functions for sst26wf
> flash ICs.
> 
> NOTE:
> this patch is basically following mine u-boot commit port:
> http://git.denx.de/?p=u-boot.git;a=commitdiff;h=3d4fed87a5fa3ffedf64ff2811cd95c5ac4503ac
> 
> Signed-off-by: Eugeniy Paltsev 
> ---
> Changes v1->v2:
>  * Check return value of {read | write}_reg callbacks.
> 
>  drivers/mtd/spi-nor/spi-nor.c | 177 
> ++
>  include/linux/mtd/spi-nor.h   |   4 +
>  2 files changed, 181 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index d9c368c44194..d0e7c85b6002 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -598,6 +598,177 @@ static int write_sr_and_check(struct spi_nor *nor, u8 
> status_new, u8 mask)
>   return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
>  }
>  
> +/*
> + * sst26wf016/sst26wf032/sst26wf064 have next block protection:
> + * 4x   - 8  KByte blocks - read & write protection bits - upper addresses
> + * 1x   - 32 KByte blocks - write protection bits
> + * rest - 64 KByte blocks - write protection bits
> + * 1x   - 32 KByte blocks - write protection bits
> + * 4x   - 8  KByte blocks - read & write protection bits - lower addresses
> + *
> + * We'll support only per 64k lock/unlock so lower and upper 64 KByte region
> + * will be treated as single block.
> + */
> +#define SST26_BPR_8K_NUM 4
> +#define SST26_MAX_BPR_REG_LEN(18 + 1)
> +#define SST26_BOUND_REG_SIZE ((32 + SST26_BPR_8K_NUM * 8) * SZ_1K)
> +
> +enum lock_ctl {
> + SST26_CTL_LOCK,
> + SST26_CTL_UNLOCK,
> + SST26_CTL_CHECK
> +};
> +
> +static bool sst26_process_bpr(u32 bpr_size, u8 *cmd, u32 bit, enum lock_ctl 
> ctl)
> +{
> + switch (ctl) {
> + case SST26_CTL_LOCK:
> + cmd[bpr_size - (bit / 8) - 1] |= BIT(bit % 8);
> + break;
> + case SST26_CTL_UNLOCK:
> + cmd[bpr_size - (bit / 8) - 1] &= ~BIT(bit % 8);
> + break;
> + case SST26_CTL_CHECK:
> + return !!(cmd[bpr_size - (bit / 8) - 1] & BIT(bit % 8));
> + }
> +
> + return false;
> +}
> +
> +/*
> + * Lock, unlock or check lock status of the flash region of the flash 
> (depending
> + * on the lock_ctl value)
> + */
> +static int sst26_lock_ctl(struct spi_nor *nor, loff_t ofs, uint64_t len, 
> enum lock_ctl ctl)
> +{
> + struct mtd_info *mtd = &nor->mtd;
> + u32 i, bpr_ptr, rptr_64k, lptr_64k, bpr_size;
> + bool lower_64k = false, upper_64k = false;
> + u8 bpr_buff[SST26_MAX_BPR_REG_LEN] = {};
> + int ret;
> +
> + /* Check length and offset for 64k alignment */
> + if ((ofs & (SZ_64K - 1)) || (len & (SZ_64K - 1))) {
> + dev_err(nor->dev, "length or offset is not 64KiB allighned\n");
> + return -EINVAL;
> + }
> +
> + if (ofs + len > mtd->size) {
> + dev_err(nor->dev, "range is more than device size: %#llx + 
> %#llx > %#llx\n",
> + ofs, len, mtd->size);
> + return -EINVAL;
> + }
> +
> + /* SST26 family has only 16 Mbit, 32 Mbit and 64 Mbit IC */
> + if (mtd->size != SZ_2M &&
> + mtd->size != SZ_4M &&
> + mtd->size != SZ_8M)
> + return -EINVAL;
> +
> + bpr_size = 2 + (mtd->size / SZ_64K / 8);
> +
> + ret = nor->read_reg(nor, SPINOR_OP_READ_BPR, bpr_buff, bpr_size);
> + if (ret < 0) {
> + dev_err(nor->dev, "fail to read block-protection register\n");
> + return ret;
> + }
> +
> + rptr_64k = min_t(u32, ofs + len, mtd->size - SST26_BOUND_REG_SIZE);
> + lptr_64k = max_t(u32, ofs, SST26_BOUND_REG_SIZE);
> +
> + upper_64k = ((ofs + len) > (mtd->size - SST26_BOUND_REG_SIZE));
> + lower_64k = (ofs < SST26_BOUND_REG_SIZE);
> +
> + /* Lower bits in block-protection register are about 64k region */
> + bpr_ptr = lptr_64k / SZ_64K - 1;
> +
> + /* Process 64K blocks region */
> + while (lptr_64k < rptr_64k) {
> + if (sst26_process_bpr(bpr_size, bpr_buff, bpr_ptr, ctl))
> + return EACCES;
> +
> + bpr_ptr++;
> + lptr_64k += SZ_64K;
> + }
> +
> + /* 32K and 8K region bits in BPR are after 64k region bits */
> + bpr_ptr = (mtd->size - 2 * SST26_BOUND_REG_SIZE) / SZ_64K;
> +
> + /* Process lower 32K block region */
> + if (lower_64k)
> + if (sst26_process_bpr(bpr_size, bpr_buff, bpr_ptr, ctl))
> + return EACCES;
> +
> + bpr_ptr++;
> +
> + /* Process upper 32K block region */
> + if (upper_64k)
> + if (sst26_process_bpr(b

Re: [PATCH] ARC: HSDK: improve reset driver

2018-09-24 Thread Eugeniy Paltsev
Hi Philip,

On Fri, 2018-09-14 at 12:38 +0200, Philipp Zabel wrote:
> Hi Eugeniy,
> 
> On Mon, 2018-08-27 at 17:38 +0300, Eugeniy Paltsev wrote:
> > As for today HSDK reset driver implements only
> > .reset() callback.
> > 
> > In case of driver which implements one of standard
> > reset controller usage pattern
> > (call *_deassert() in probe(), call *_assert() in remove())
> > that leads to inoperability of this reset driver.
> > 
> > Improve HSDK reset driver by calling .reset() callback inside of
> > .assert()/.deassert() callbacks to avoid each reset controller
> > user adaptation for work with both reset methods
> > (reset() and .assert()/.deassert() pair)
> > 
> > Signed-off-by: Eugeniy Paltsev 
> > ---
> >  drivers/reset/reset-hsdk.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/reset/reset-hsdk.c b/drivers/reset/reset-hsdk.c
> > index 8bce391c6943..1fd91df91343 100644
> > --- a/drivers/reset/reset-hsdk.c
> > +++ b/drivers/reset/reset-hsdk.c
> > @@ -86,6 +86,8 @@ static int hsdk_reset_reset(struct reset_controller_dev 
> > *rcdev,
> >  
> >  static const struct reset_control_ops hsdk_reset_ops = {
> > .reset  = hsdk_reset_reset,
> > += hsdk_reset_reset,
> 
> This is incorrect for exclusive reset controls.
> It will cause reset_control_assert() to return success for exclusive
> reset controls, even though the .assert op failed to leave the reset
> line asserted after the function returns.
> 
> While calling hsdk_reset_reset from .assert for shared reset controls
> would be fine, I don't see how this is necessary of useful.
> If a consumer driver requires the reset to be asserted upon remove(), it
> must not request a shared reset control anyway, because with shared
> reset controls other drivers may keep the reset line deasserted
> indefinitely.

Ok, I agree that doing reset from .assert isn't necessary/useful here.
The reason I added hsdk_reset_reset into .assert is to prevent -ENOTSUPP
returning by reset_control_assert().

Lots of drivers implement following pattern to reset HW:
->8--
reset_control_assert(resets);
usleep_range(10, 1000);
reset_control_deassert(resets);
->8--

And some of them check reset_control_assert() and reset_control_deassert()
return status.

So these driver will fail if I implement only .reset and .deassert callback in 
my
reset driver.

I can implement something like that:
->8--
static int hsdk_dummy_assert(struct reset_controller_dev *rd, unsigned long id)
{
return 0;
}

static const struct reset_control_ops hsdk_reset_ops = {
.reset= hsdk_reset_reset,
.assert   = hsdk_dummy_assert,
.deassert = hsdk_reset_reset,
};
->8--



> > +   .deassert = hsdk_reset_reset,
> 
> This should be fine. 

> I wonder from time to time whether this should be
> implemented in the core, in reset_control_deassert().

Sounds OK for me. At least I don't see any issues it may cause.

> regards
> Philipp
-- 
 Eugeniy Paltsev
___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[REVIEW][PATCH 0/2] signal/arc: siginfo cleanups

2018-09-24 Thread Eric W. Biederman


I have been slowly cleaning up the architectues ever since I discovered
that the pattern of passing in struct siginfo is error prone, and
occassionally results in borken siginfo being sent to userspace.

What is happening on arc is pretty tame and I have compile tested
these changes, so I don't expect problems.

Still I would appreciate if people can look over the code and perhaps
test it and see if they can spot anything that has perhaps gone wrong.
appreciate it.

My intention is to merge this through my siginfo tree.  If you feel it
should go through your arch tree let me know.   All of the prerequisites
should have been merged several releases ago.

Eric W. Biederman (2):
  signal/arc: Push siginfo generation into unhandled_exception
  signal/arc: Use force_sig_fault where appropriate

 arch/arc/kernel/traps.c | 22 --
 arch/arc/mm/fault.c | 20 +---
 2 files changed, 13 insertions(+), 29 deletions(-)

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[REVIEW][PATCH 2/2] signal/arc: Use force_sig_fault where appropriate

2018-09-24 Thread Eric W. Biederman
Signed-off-by: "Eric W. Biederman" 
---
 arch/arc/mm/fault.c | 20 +---
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index db6913094be3..c9da6102eb4f 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -66,14 +66,12 @@ void do_page_fault(unsigned long address, struct pt_regs 
*regs)
struct vm_area_struct *vma = NULL;
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
-   siginfo_t info;
+   int si_code;
int ret;
vm_fault_t fault;
int write = regs->ecr_cause & ECR_C_PROTV_STORE;  /* ST/EX */
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
-   clear_siginfo(&info);
-
/*
 * We fault-in kernel-space virtual memory on-demand. The
 * 'reference' page table is init_mm.pgd.
@@ -91,7 +89,7 @@ void do_page_fault(unsigned long address, struct pt_regs 
*regs)
return;
}
 
-   info.si_code = SEGV_MAPERR;
+   si_code = SEGV_MAPERR;
 
/*
 * If we're in an interrupt or have no user
@@ -119,7 +117,7 @@ void do_page_fault(unsigned long address, struct pt_regs 
*regs)
 * we can handle it..
 */
 good_area:
-   info.si_code = SEGV_ACCERR;
+   si_code = SEGV_ACCERR;
 
/* Handle protection violation, execute on heap or stack */
 
@@ -199,11 +197,7 @@ void do_page_fault(unsigned long address, struct pt_regs 
*regs)
/* User mode accesses just cause a SIGSEGV */
if (user_mode(regs)) {
tsk->thread.fault_address = address;
-   info.si_signo = SIGSEGV;
-   info.si_errno = 0;
-   /* info.si_code has been set above */
-   info.si_addr = (void __user *)address;
-   force_sig_info(SIGSEGV, &info, tsk);
+   force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk);
return;
}
 
@@ -238,9 +232,5 @@ void do_page_fault(unsigned long address, struct pt_regs 
*regs)
goto no_context;
 
tsk->thread.fault_address = address;
-   info.si_signo = SIGBUS;
-   info.si_errno = 0;
-   info.si_code = BUS_ADRERR;
-   info.si_addr = (void __user *)address;
-   force_sig_info(SIGBUS, &info, tsk);
+   force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, tsk);
 }
-- 
2.17.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[REVIEW][PATCH 1/2] signal/arc: Push siginfo generation into unhandled_exception

2018-09-24 Thread Eric W. Biederman
Pass signr, sicode, and address into unhandled_exception as explicit
parameters instead of members of struct siginfo.  Then in unhandled
exception generate and send the siginfo using force_sig_fault.

This keeps the code simpler and less error prone.

Signed-off-by: "Eric W. Biederman" 
---
 arch/arc/kernel/traps.c | 22 --
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c
index b123558bf0bb..a7fcbc0d3943 100644
--- a/arch/arc/kernel/traps.c
+++ b/arch/arc/kernel/traps.c
@@ -42,21 +42,22 @@ void die(const char *str, struct pt_regs *regs, unsigned 
long address)
  *  -for kernel, chk if due to copy_(to|from)_user, otherwise die()
  */
 static noinline int
-unhandled_exception(const char *str, struct pt_regs *regs, siginfo_t *info)
+unhandled_exception(const char *str, struct pt_regs *regs,
+   int signo, int si_code, void __user *addr)
 {
if (user_mode(regs)) {
struct task_struct *tsk = current;
 
-   tsk->thread.fault_address = (__force unsigned int)info->si_addr;
+   tsk->thread.fault_address = (__force unsigned int)addr;
 
-   force_sig_info(info->si_signo, info, tsk);
+   force_sig_fault(signo, si_code, addr, tsk);
 
} else {
/* If not due to copy_(to|from)_user, we are doomed */
if (fixup_exception(regs))
return 0;
 
-   die(str, regs, (unsigned long)info->si_addr);
+   die(str, regs, (unsigned long)addr);
}
 
return 1;
@@ -64,16 +65,9 @@ unhandled_exception(const char *str, struct pt_regs *regs, 
siginfo_t *info)
 
 #define DO_ERROR_INFO(signr, str, name, sicode) \
 int name(unsigned long address, struct pt_regs *regs) \
-{  \
-   siginfo_t info; \
-   \
-   clear_siginfo(&info);   \
-   info.si_signo = signr;  \
-   info.si_errno = 0;  \
-   info.si_code  = sicode; \
-   info.si_addr = (void __user *)address;  \
-   \
-   return unhandled_exception(str, regs, &info);\
+{  \
+   return unhandled_exception(str, regs, signr, sicode,\
+  (void __user *)address); \
 }
 
 /*
-- 
2.17.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


Re: [REVIEW][PATCH 1/2] signal/arc: Push siginfo generation into unhandled_exception

2018-09-24 Thread Vineet Gupta
On 09/24/2018 07:49 AM, Eric W. Biederman wrote:
> Pass signr, sicode, and address into unhandled_exception as explicit
> parameters instead of members of struct siginfo.  Then in unhandled
> exception generate and send the siginfo using force_sig_fault.
>
> This keeps the code simpler and less error prone.
>
> Signed-off-by: "Eric W. Biederman" 

LGTM.

Acked-by: Vineet Gupta 

Thx,
-Vineet

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


Re: [REVIEW][PATCH 2/2] signal/arc: Use force_sig_fault where appropriate

2018-09-24 Thread Vineet Gupta
On 09/24/2018 07:49 AM, Eric W. Biederman wrote:
> Signed-off-by: "Eric W. Biederman" 

Acked-by: Vineet Gupta 

Thx,
-Vineet

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc