[PATCH resend] can: rcar_canfd: fix possible IRQ storm on high load

2019-06-26 Thread Nikita Yushchenko
We have observed rcar_canfd driver entering IRQ storm under high load,
with following scenario:
- rcar_canfd_global_interrupt() in entered due to Rx available,
- napi_schedule_prep() is called, and sets NAPIF_STATE_SCHED in state
- Rx fifo interrupts are masked,
- rcar_canfd_global_interrupt() is entered again, this time due to
  error interrupt (e.g. due to overflow),
- since scheduled napi poller has not yet executed, condition for calling
  napi_schedule_prep() from rcar_canfd_global_interrupt() remains true,
  thus napi_schedule_prep() gets called and sets NAPIF_STATE_MISSED flag
  in state,
- later, napi poller function rcar_canfd_rx_poll() gets executed, and
  calls napi_complete_done(),
- due to NAPIF_STATE_MISSED flag in state, this call does not clear
  NAPIF_STATE_SCHED flag from state,
- on return from napi_complete_done(), rcar_canfd_rx_poll() unmasks Rx
  interrutps,
- Rx interrupt happens, rcar_canfd_global_interrupt() gets called
  and calls napi_schedule_prep(),
- since NAPIF_STATE_SCHED is set in state at this time, this call
  returns false,
- due to that false return, rcar_canfd_global_interrupt() returns
  without masking Rx interrupt
- and this results into IRQ storm: unmasked Rx interrupt happens again
  and again is misprocessed in the same way.

This patch fixes that scenario by unmasking Rx interrupts only when
napi_complete_done() returns true, which means it has cleared
NAPIF_STATE_SCHED in state.

Signed-off-by: Nikita Yushchenko 
---
 drivers/net/can/rcar/rcar_canfd.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/rcar/rcar_canfd.c 
b/drivers/net/can/rcar/rcar_canfd.c
index 05410008aa6b..de34a4b82d4a 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -1508,10 +1508,11 @@ static int rcar_canfd_rx_poll(struct napi_struct *napi, 
int quota)
 
/* All packets processed */
if (num_pkts < quota) {
-   napi_complete_done(napi, num_pkts);
-   /* Enable Rx FIFO interrupts */
-   rcar_canfd_set_bit(priv->base, RCANFD_RFCC(ridx),
-  RCANFD_RFCC_RFIE);
+   if (napi_complete_done(napi, num_pkts)) {
+   /* Enable Rx FIFO interrupts */
+   rcar_canfd_set_bit(priv->base, RCANFD_RFCC(ridx),
+  RCANFD_RFCC_RFIE);
+   }
}
return num_pkts;
 }
-- 
2.11.0



Re: [PATCH] net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0

2019-05-31 Thread Nikita Yushchenko
>> Kernel currently does, but it is caught in
>> mv88e6xxx_port_check_hw_vlan() and returns -ENOTSUPP from there.
> 
> But VID 0 has a special meaning for the kernel, it means the port's private
> database (when it is isolated, non-bridged), it is not meant to be programmed
> in the switch. That's why I would've put that knowledge into the DSA layer,
> which job is to translate the kernel operations to the (dumb) DSA drivers.
> 
> I hope I'm seeing things correctly here.

I'm ok with either solution.


Re: [PATCH] net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0

2019-05-31 Thread Nikita Yushchenko



31.05.2019 17:37, Andrew Lunn wrote:
>> I'm not sure that I like the semantic of it, because the driver can actually
>> support VID 0 per-se, only the kernel does not use VLAN 0. Thus I would avoid
>> calling the port_vlan_del() ops for VID 0, directly into the upper DSA layer.
>>
>> Florian, Andrew, wouldn't the following patch be more adequate?
>>
>> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
>> index 1e2ae9d59b88..80f228258a92 100644
>> --- a/net/dsa/slave.c
>> +++ b/net/dsa/slave.c
>> @@ -1063,6 +1063,10 @@ static int dsa_slave_vlan_rx_kill_vid(struct 
>> net_device *dev, __be16 proto,
>> struct bridge_vlan_info info;
>> int ret;
>>  
>> +   /* VID 0 has a special meaning and is never programmed in 
>> hardware */
>> +   if (!vid)
>> +   return 0;
>> +
>> /* Check for a possible bridge VLAN entry now since there is no
>>  * need to emulate the switchdev prepare + commit phase.
>>  */
>  
> Hi Vivien
> 
> If we put this in rx_kill_vid, we should probably have something
> similar in rx_add_vid, just in case the kernel does start using VID 0.

Kernel currently does, but it is caught in
mv88e6xxx_port_check_hw_vlan() and returns -ENOTSUPP from there.


[PATCH] media: avoid skipping MEDIA_PAD_FL_MUST_CONNECT logic

2019-05-31 Thread Nikita Yushchenko
In the current code, __media_pipeline_start() skips check of
MEDIA_PAD_FL_MUST_CONNECT logic for entity not providing link_validate()
op.

Fix that by checking for existence of link_validate() at different code
location.

Signed-off-by: Nikita Yushchenko 
---
 drivers/media/mc/mc-entity.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c
index a998a2e0ea1d..8b4912be30d1 100644
--- a/drivers/media/mc/mc-entity.c
+++ b/drivers/media/mc/mc-entity.c
@@ -449,9 +449,6 @@ __must_check int __media_pipeline_start(struct media_entity 
*entity,
if (entity->stream_count > 1)
continue;
 
-   if (!entity->ops || !entity->ops->link_validate)
-   continue;
-
bitmap_zero(active, entity->num_pads);
bitmap_fill(has_no_links, entity->num_pads);
 
@@ -479,6 +476,9 @@ __must_check int __media_pipeline_start(struct media_entity 
*entity,
!(link->flags & MEDIA_LNK_FL_ENABLED))
continue;
 
+   if (!entity->ops || !entity->ops->link_validate)
+   continue;
+
ret = entity->ops->link_validate(link);
if (ret < 0 && ret != -ENOIOCTLCMD) {
dev_dbg(entity->graph_obj.mdev->dev,
-- 
2.11.0



[PATCH] net: phy: support C45 phys in SIOCGMIIREG/SIOCSMIIREG ioctls

2019-05-31 Thread Nikita Yushchenko
This change allows phytool [1] and similar tools to read and write C45 phy
registers from userspace.

This is useful for debugging and for porting vendor phy diagnostics tools.

[1] https://github.com/wkz/phytool

Signed-off-by: Nikita Yushchenko 
---
 drivers/net/phy/phy.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index e8885429293a..3d991958bde0 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -407,6 +407,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq 
*ifr, int cmd)
struct mii_ioctl_data *mii_data = if_mii(ifr);
u16 val = mii_data->val_in;
bool change_autoneg = false;
+   int ret;
 
switch (cmd) {
case SIOCGMIIPHY:
@@ -414,12 +415,28 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq 
*ifr, int cmd)
/* fall through */
 
case SIOCGMIIREG:
+   if (mdio_phy_id_is_c45(mii_data->phy_id)) {
+   ret = phy_read_mmd(phydev,
+  mdio_phy_id_devad(mii_data->phy_id),
+  mii_data->reg_num);
+   if (ret < 0)
+   return ret;
+   mii_data->val_out = ret;
+   return 0;
+   }
mii_data->val_out = mdiobus_read(phydev->mdio.bus,
 mii_data->phy_id,
 mii_data->reg_num);
return 0;
 
case SIOCSMIIREG:
+   if (mdio_phy_id_is_c45(mii_data->phy_id)) {
+   ret = phy_write_mmd(phydev,
+   mdio_phy_id_devad(mii_data->phy_id),
+   mii_data->reg_num,
+   mii_data->val_in);
+   return ret;
+   }
if (mii_data->phy_id == phydev->mdio.addr) {
switch (mii_data->reg_num) {
case MII_BMCR:
-- 
2.11.0



[PATCH] net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0

2019-05-31 Thread Nikita Yushchenko
When non-bridged, non-vlan'ed mv88e6xxx port is moving down, error
message is logged:

failed to kill vid 0081/0 for device eth_cu_1000_4

This is caused by call from __vlan_vid_del() with vin set to zero, over
call chain this results into _mv88e6xxx_port_vlan_del() called with
vid=0, and mv88e6xxx_vtu_get() called from there returns -EINVAL.

On symmetric path moving port up, call goes through
mv88e6xxx_port_vlan_prepare() that calls mv88e6xxx_port_check_hw_vlan()
that returns -EOPNOTSUPP for zero vid.

This patch changes mv88e6xxx_vtu_get() to also return -EOPNOTSUPP for
zero vid, then this error code is explicitly cleared in
dsa_slave_vlan_rx_kill_vid() and error message is no longer logged.

Signed-off-by: Nikita Yushchenko 
---
 drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 28414db979b0..6b77fde5f0e4 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1392,7 +1392,7 @@ static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, 
u16 vid,
int err;
 
if (!vid)
-   return -EINVAL;
+   return -EOPNOTSUPP;
 
entry->vid = vid - 1;
entry->valid = false;
-- 
2.11.0



[PATCH] net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0

2019-05-31 Thread Nikita Yushchenko
When non-bridged, non-vlan'ed mv88e6xxx port is moving down, error
message is logged:

failed to kill vid 0081/0 for device eth_cu_1000_4

This is caused by call from __vlan_vid_del() with vin set to zero, over
call chain this results into _mv88e6xxx_port_vlan_del() called with
vid=0, and mv88e6xxx_vtu_get() called from there returns -EINVAL.

On symmetric path moving port up, call goes through
mv88e6xxx_port_vlan_prepare() that calls mv88e6xxx_port_check_hw_vlan()
that returns -EOPNOTSUPP for zero vid.

This patch changes mv88e6xxx_vtu_get() to also return -EOPNOTSUPP for
zero vid, then this error code is explicitly cleared in
dsa_slave_vlan_rx_kill_vid() and error message is no longer logged.
---
 drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 28414db979b0..6b77fde5f0e4 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1392,7 +1392,7 @@ static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, 
u16 vid,
int err;
 
if (!vid)
-   return -EINVAL;
+   return -EOPNOTSUPP;
 
entry->vid = vid - 1;
entry->valid = false;
-- 
2.11.0



Re: [1/3] ARM: dts: imx51-zii-common: create common include dtsi

2018-06-27 Thread Nikita Yushchenko
> There are three boards that share that configuration almost to a T,
> with the only difference is the particular GPIOs used. Putting it into
> a common file avoids repeating the boilerplate and makes it explicit
> to the reader that those settings are shared.

I'd agree if that boilerplate was 100 lines.

But here it is small, and mostly containing lines that are required for
any i2c-gpio definition. It does not any value of itself.

Saving 5 lines at cost of loose of integrity is not something I agree with.

> There are at least two boards that use that UART2 as is. Same as above
> this was done to reduce boilerplate.

Here have choice between two logical blocks - definitions of uart2 in
two boards that use them, and two logical blocks - definition in dtsi
and undo in board that does not use it.

You trade a couple of saved dts lines against keeping things consistent.

Nikita

P.S.
In case of these zii boards I doubt that dtsi worths at all. Despite of
all being imx51 boards from ZII, these boards don't seem to have large
common logical blocks. Perhaos RDU1 and babbage have more in common - so
what, create a dtsi for them?


Re: [1/3] ARM: dts: imx51-zii-common: create common include dtsi

2018-06-27 Thread Nikita Yushchenko
> There are three boards that share that configuration almost to a T,
> with the only difference is the particular GPIOs used. Putting it into
> a common file avoids repeating the boilerplate and makes it explicit
> to the reader that those settings are shared.

I'd agree if that boilerplate was 100 lines.

But here it is small, and mostly containing lines that are required for
any i2c-gpio definition. It does not any value of itself.

Saving 5 lines at cost of loose of integrity is not something I agree with.

> There are at least two boards that use that UART2 as is. Same as above
> this was done to reduce boilerplate.

Here have choice between two logical blocks - definitions of uart2 in
two boards that use them, and two logical blocks - definition in dtsi
and undo in board that does not use it.

You trade a couple of saved dts lines against keeping things consistent.

Nikita

P.S.
In case of these zii boards I doubt that dtsi worths at all. Despite of
all being imx51 boards from ZII, these boards don't seem to have large
common logical blocks. Perhaos RDU1 and babbage have more in common - so
what, create a dtsi for them?


Re: [1/3] ARM: dts: imx51-zii-common: create common include dtsi

2018-06-27 Thread Nikita Yushchenko
> + i2c_gpio: i2c-gpio {
> + compatible = "i2c-gpio";
> + pinctrl-names = "default";
> + pinctrl-0 = <_swi2c>;
> + i2c-gpio,delay-us = <50>;
> + status = "okay";
> +
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };

You add i2c-gpio node to dtsi file without defining gpios, with reference
to pinctrl not defined inside your dtsi file or it's includes, and without
any usage inside dtsi file.

Saving several text lines that way is a bad idea. Please move it to where
it is fully defined and used.

> +_vbus {
> + regulator-always-on;

usb_vbus is regilator-fixed, what for is this?

> + {
> + pinctrl-names = "default";
> + pinctrl-0 = <_uart2>;
> + status = "okay";
> +};

In your further patches you include this and then revert by marking  as
disabled. Better to enable it in dts for boards that have it.

Same with ecspi2, ipu and maybe more.

> - flash@1 {
> - #address-cells = <1>;
> - #size-cells = <1>;
> - compatible = "atmel,at45db642d", "atmel,at45", 
> "atmel,dataflash";
> - spi-max-frequency = <2500>;
> - reg = <1>;
> - };

> + flash@1 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "atmel,at45", "atmel,dataflash";
> + spi-max-frequency = <2500>;
> + reg = <1>;
> + };

Lost a compatible key?

> - sysled0@3 {
> - reg = <3>;
> - label = "system:green:status";
> - linux,default-trigger = "default-on";
> - };

> + sysled3: led3@3 {
> + reg = <3>;
> + label = "system:red:power";
> + linux,default-trigger = "default-on";
> + };

> + {
> + label = "system:green:status";
 
What for this label games?
Maybe just define things for boards that use it?



Re: [1/3] ARM: dts: imx51-zii-common: create common include dtsi

2018-06-27 Thread Nikita Yushchenko
> + i2c_gpio: i2c-gpio {
> + compatible = "i2c-gpio";
> + pinctrl-names = "default";
> + pinctrl-0 = <_swi2c>;
> + i2c-gpio,delay-us = <50>;
> + status = "okay";
> +
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };

You add i2c-gpio node to dtsi file without defining gpios, with reference
to pinctrl not defined inside your dtsi file or it's includes, and without
any usage inside dtsi file.

Saving several text lines that way is a bad idea. Please move it to where
it is fully defined and used.

> +_vbus {
> + regulator-always-on;

usb_vbus is regilator-fixed, what for is this?

> + {
> + pinctrl-names = "default";
> + pinctrl-0 = <_uart2>;
> + status = "okay";
> +};

In your further patches you include this and then revert by marking  as
disabled. Better to enable it in dts for boards that have it.

Same with ecspi2, ipu and maybe more.

> - flash@1 {
> - #address-cells = <1>;
> - #size-cells = <1>;
> - compatible = "atmel,at45db642d", "atmel,at45", 
> "atmel,dataflash";
> - spi-max-frequency = <2500>;
> - reg = <1>;
> - };

> + flash@1 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "atmel,at45", "atmel,dataflash";
> + spi-max-frequency = <2500>;
> + reg = <1>;
> + };

Lost a compatible key?

> - sysled0@3 {
> - reg = <3>;
> - label = "system:green:status";
> - linux,default-trigger = "default-on";
> - };

> + sysled3: led3@3 {
> + reg = <3>;
> + label = "system:red:power";
> + linux,default-trigger = "default-on";
> + };

> + {
> + label = "system:green:status";
 
What for this label games?
Maybe just define things for boards that use it?



Re: [PATCH v2] ARM: dts: imx51-zii-rdu1: Make sure SD1_WP is low

2018-05-31 Thread Nikita Yushchenko
> Make sure that MX51_PAD_GPIO1_1 does not remain configure as
> ALT0/SD1_WP (it is out of reset). This is needed because of external
> pull-up resistor attached to that pad that, when left unchanged, will
> drive SD1_WP high preventing eSDHC1/eMMC from working correctly.
> 
> To fix that add a pinmux configuration line configureing the pad to
> function as a GPIO. While we are at it, add a corresponding
> output-high GPIO hog in an effort to minimize current consumption.
> 
> Cc: Nikita Yushchenko 
> Cc: Shawn Guo 
> Cc: Fabio Estevam 
> Cc: Lucas Stach 
> Cc: Chris Healy 
> Cc: Rob Herring 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: devicet...@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Andrey Smirnov 

Tested-By: Nikita Yushchenko 

With this patch, eMMC works correctly.

Nikita


Re: [PATCH v2] ARM: dts: imx51-zii-rdu1: Make sure SD1_WP is low

2018-05-31 Thread Nikita Yushchenko
> Make sure that MX51_PAD_GPIO1_1 does not remain configure as
> ALT0/SD1_WP (it is out of reset). This is needed because of external
> pull-up resistor attached to that pad that, when left unchanged, will
> drive SD1_WP high preventing eSDHC1/eMMC from working correctly.
> 
> To fix that add a pinmux configuration line configureing the pad to
> function as a GPIO. While we are at it, add a corresponding
> output-high GPIO hog in an effort to minimize current consumption.
> 
> Cc: Nikita Yushchenko 
> Cc: Shawn Guo 
> Cc: Fabio Estevam 
> Cc: Lucas Stach 
> Cc: Chris Healy 
> Cc: Rob Herring 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: devicet...@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Andrey Smirnov 

Tested-By: Nikita Yushchenko 

With this patch, eMMC works correctly.

Nikita


[PATCH] ARM: dts: imx51-zii-rdu1: add rave-sp subdevices

2018-05-17 Thread Nikita Yushchenko
This adds rave-sp powerbutton and backlight devices to RDU1 device tree.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 0c99ac04ad08..98cc107098e0 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -581,6 +581,14 @@
watchdog {
compatible = "zii,rave-sp-watchdog";
};
+
+   backlight {
+   compatible = "zii,rave-sp-backlight";
+   };
+
+   pwrbutton {
+   compatible = "zii,rave-sp-pwrbutton";
+   };
};
 };
 
-- 
2.11.0



[PATCH] ARM: dts: imx51-zii-rdu1: add rave-sp subdevices

2018-05-17 Thread Nikita Yushchenko
This adds rave-sp powerbutton and backlight devices to RDU1 device tree.

Signed-off-by: Nikita Yushchenko 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 0c99ac04ad08..98cc107098e0 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -581,6 +581,14 @@
watchdog {
compatible = "zii,rave-sp-watchdog";
};
+
+   backlight {
+   compatible = "zii,rave-sp-backlight";
+   };
+
+   pwrbutton {
+   compatible = "zii,rave-sp-pwrbutton";
+   };
};
 };
 
-- 
2.11.0



[PATCH] ARM: dts: imx51-zii-rdu1: cleanup eMMC node

2018-05-16 Thread Nikita Yushchenko
On RDU1, sdhc1 is used for eMMC, and that is 3.3V only.

Thus configure device node not to probe it as SD/SDIO and not try 1.8V.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 0c99ac04ad08..ad2a7c9b203e 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -462,7 +462,10 @@
pinctrl-names = "default";
pinctrl-0 = <_esdhc1>;
bus-width = <4>;
+   no-1-8-v;
non-removable;
+   no-sdio;
+   no-sd;
status = "okay";
 };
 
-- 
2.11.0



[PATCH] ARM: dts: imx51-zii-rdu1: cleanup eMMC node

2018-05-16 Thread Nikita Yushchenko
On RDU1, sdhc1 is used for eMMC, and that is 3.3V only.

Thus configure device node not to probe it as SD/SDIO and not try 1.8V.

Signed-off-by: Nikita Yushchenko 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 0c99ac04ad08..ad2a7c9b203e 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -462,7 +462,10 @@
pinctrl-names = "default";
pinctrl-0 = <_esdhc1>;
bus-width = <4>;
+   no-1-8-v;
non-removable;
+   no-sdio;
+   no-sd;
status = "okay";
 };
 
-- 
2.11.0



[PATCH] ARM: dts: vf610-zii-dev: enable vf610 builtin temp sensor

2018-05-16 Thread Nikita Yushchenko
Vybrid has single internal temperature sensor connected to both internal
ADC modules.

vf610-zii-dev already has ADC0 enabled. Now, to get temperature sensor
captured by iio_hwmon driver, need to configure iio_hwmon node to use
that ADC.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 arch/arm/boot/dts/vf610-zii-dev.dtsi | 4 
 arch/arm/boot/dts/vfxxx.dtsi | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vf610-zii-dev.dtsi 
b/arch/arm/boot/dts/vf610-zii-dev.dtsi
index 4890b8a5aa44..5ae5abfe1d55 100644
--- a/arch/arm/boot/dts/vf610-zii-dev.dtsi
+++ b/arch/arm/boot/dts/vf610-zii-dev.dtsi
@@ -222,6 +222,10 @@
status = "okay";
 };
 
+ {
+   io-channels = < 16>;
+};
+
  {
pinctrl_adc0_ad5: adc0ad5grp {
fsl,pins = <
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index c3f09b737924..d392794d9c13 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -84,7 +84,7 @@
mask = <0x1000>;
};
 
-   iio-hwmon {
+   tempsensor: iio-hwmon {
compatible = "iio-hwmon";
io-channels = < 16>, < 16>;
};
-- 
2.11.0



[PATCH] ARM: dts: vf610-zii-dev: enable vf610 builtin temp sensor

2018-05-16 Thread Nikita Yushchenko
Vybrid has single internal temperature sensor connected to both internal
ADC modules.

vf610-zii-dev already has ADC0 enabled. Now, to get temperature sensor
captured by iio_hwmon driver, need to configure iio_hwmon node to use
that ADC.

Signed-off-by: Nikita Yushchenko 
---
 arch/arm/boot/dts/vf610-zii-dev.dtsi | 4 
 arch/arm/boot/dts/vfxxx.dtsi | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vf610-zii-dev.dtsi 
b/arch/arm/boot/dts/vf610-zii-dev.dtsi
index 4890b8a5aa44..5ae5abfe1d55 100644
--- a/arch/arm/boot/dts/vf610-zii-dev.dtsi
+++ b/arch/arm/boot/dts/vf610-zii-dev.dtsi
@@ -222,6 +222,10 @@
status = "okay";
 };
 
+ {
+   io-channels = < 16>;
+};
+
  {
pinctrl_adc0_ad5: adc0ad5grp {
fsl,pins = <
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index c3f09b737924..d392794d9c13 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -84,7 +84,7 @@
mask = <0x1000>;
};
 
-   iio-hwmon {
+   tempsensor: iio-hwmon {
compatible = "iio-hwmon";
io-channels = < 16>, < 16>;
};
-- 
2.11.0



[PATCH] ARM: dts: imx51-zii-rdu1: limit usbh1 to full-speed

2018-05-15 Thread Nikita Yushchenko
On RDU1, imx51 usbh1 interface is either not used, or used via external
block that breaks USB2 signalling.

To keep things working if high-speed device gets connected to that
block, use ChipIdea feature to limit port to full speed.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 36a63ae52e48..c26f053f29b0 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -603,6 +603,7 @@
phy_type = "ulpi";
fsl,usbphy = <>;
disable-over-current;
+   maximum-speed = "full-speed";
vbus-supply = <_5p0v_main>;
status = "okay";
 };
-- 
2.11.0



[PATCH] ARM: dts: imx51-zii-rdu1: limit usbh1 to full-speed

2018-05-15 Thread Nikita Yushchenko
On RDU1, imx51 usbh1 interface is either not used, or used via external
block that breaks USB2 signalling.

To keep things working if high-speed device gets connected to that
block, use ChipIdea feature to limit port to full speed.

Signed-off-by: Nikita Yushchenko 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 36a63ae52e48..c26f053f29b0 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -603,6 +603,7 @@
phy_type = "ulpi";
fsl,usbphy = <>;
disable-over-current;
+   maximum-speed = "full-speed";
vbus-supply = <_5p0v_main>;
status = "okay";
 };
-- 
2.11.0



[PATCH] ARM: dts: imx51-zii-rdu1: fix touchscreen bindings

2018-05-07 Thread Nikita Yushchenko
This fixes errors in RDU1 device tree that cause touch screens not
working.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 0c99ac04ad08..6464f2560e06 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -523,7 +523,7 @@
};
 
touchscreen@20 {
-   compatible = "syna,rmi4_i2c";
+   compatible = "syna,rmi4-i2c";
reg = <0x20>;
pinctrl-names = "default";
pinctrl-0 = <_ts>;
@@ -541,8 +541,8 @@
 
rmi4-f11@11 {
reg = <0x11>;
-   touch-inverted-y;
-   touch-swapped-x-y;
+   touchscreen-inverted-y;
+   touchscreen-swapped-x-y;
syna,sensor-type = <1>;
};
};
-- 
2.11.0



[PATCH] ARM: dts: imx51-zii-rdu1: fix touchscreen bindings

2018-05-07 Thread Nikita Yushchenko
This fixes errors in RDU1 device tree that cause touch screens not
working.

Signed-off-by: Nikita Yushchenko 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 0c99ac04ad08..6464f2560e06 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -523,7 +523,7 @@
};
 
touchscreen@20 {
-   compatible = "syna,rmi4_i2c";
+   compatible = "syna,rmi4-i2c";
reg = <0x20>;
pinctrl-names = "default";
pinctrl-0 = <_ts>;
@@ -541,8 +541,8 @@
 
rmi4-f11@11 {
reg = <0x11>;
-   touch-inverted-y;
-   touch-swapped-x-y;
+   touchscreen-inverted-y;
+   touchscreen-swapped-x-y;
syna,sensor-type = <1>;
};
};
-- 
2.11.0



[PATCH] ASoC: rsnd: set pm_ops in hibernate-compatible way

2018-03-20 Thread Nikita Yushchenko
Use SET_SYSTEM_SLEEP_PM_OPS() macro instead of direct assignment to
.suspend and .resume fields.

This makes driver working after restore from hibernation.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 sound/soc/sh/rcar/core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 64d5ecb86528..dabf9a35c25c 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1560,8 +1560,7 @@ static int rsnd_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops rsnd_pm_ops = {
-   .suspend= rsnd_suspend,
-   .resume = rsnd_resume,
+   SET_SYSTEM_SLEEP_PM_OPS(rsnd_suspend, rsnd_resume)
 };
 
 static struct platform_driver rsnd_driver = {
-- 
2.11.0



[PATCH] ASoC: rsnd: set pm_ops in hibernate-compatible way

2018-03-20 Thread Nikita Yushchenko
Use SET_SYSTEM_SLEEP_PM_OPS() macro instead of direct assignment to
.suspend and .resume fields.

This makes driver working after restore from hibernation.

Signed-off-by: Nikita Yushchenko 
---
 sound/soc/sh/rcar/core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 64d5ecb86528..dabf9a35c25c 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1560,8 +1560,7 @@ static int rsnd_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops rsnd_pm_ops = {
-   .suspend= rsnd_suspend,
-   .resume = rsnd_resume,
+   SET_SYSTEM_SLEEP_PM_OPS(rsnd_suspend, rsnd_resume)
 };
 
 static struct platform_driver rsnd_driver = {
-- 
2.11.0



[PATCH] clk: cs2000: set pm_ops in hibernate-compatible way

2018-03-20 Thread Nikita Yushchenko
Use SET_LATE_SYSTEM_SLEEP_PM_OPS() macro instead of direct assignment to
.resume_early field.

This fixes initialization of CS2000 in restore from hibernation in case
of kernel used to load image did not initialize CS2000 while kernel
being restored had CS2000 initialized.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/clk/clk-cs2000-cp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c
index e8ea81c30f0c..c58019750b7e 100644
--- a/drivers/clk/clk-cs2000-cp.c
+++ b/drivers/clk/clk-cs2000-cp.c
@@ -549,7 +549,7 @@ static int cs2000_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops cs2000_pm_ops = {
-   .resume_early   = cs2000_resume,
+   SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, cs2000_resume)
 };
 
 static struct i2c_driver cs2000_driver = {
-- 
2.11.0



[PATCH] clk: cs2000: set pm_ops in hibernate-compatible way

2018-03-20 Thread Nikita Yushchenko
Use SET_LATE_SYSTEM_SLEEP_PM_OPS() macro instead of direct assignment to
.resume_early field.

This fixes initialization of CS2000 in restore from hibernation in case
of kernel used to load image did not initialize CS2000 while kernel
being restored had CS2000 initialized.

Signed-off-by: Nikita Yushchenko 
---
 drivers/clk/clk-cs2000-cp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c
index e8ea81c30f0c..c58019750b7e 100644
--- a/drivers/clk/clk-cs2000-cp.c
+++ b/drivers/clk/clk-cs2000-cp.c
@@ -549,7 +549,7 @@ static int cs2000_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops cs2000_pm_ops = {
-   .resume_early   = cs2000_resume,
+   SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, cs2000_resume)
 };
 
 static struct i2c_driver cs2000_driver = {
-- 
2.11.0



cancel_work_sync() can cause priority invertion

2017-12-27 Thread Nikita Yushchenko
Hi

For those who care about linux RT behavior:

while analyzing traces, just found priority inversion caused by RT task
calling cancel_work_sync(), while work item in question is executing in
non-RT kworker that was preempted for significant time.

WBR,
Nikita Yushchenko



cancel_work_sync() can cause priority invertion

2017-12-27 Thread Nikita Yushchenko
Hi

For those who care about linux RT behavior:

while analyzing traces, just found priority inversion caused by RT task
calling cancel_work_sync(), while work item in question is executing in
non-RT kworker that was preempted for significant time.

WBR,
Nikita Yushchenko



Re: [PATCH v6 1/2] platform: Add driver for RAVE Supervisory Processor

2017-08-31 Thread Nikita Yushchenko
>> I think that trying to make this generic is purely synthetic. This
>> information is board-specific per it's nature, it comes from what board
>> is designed for, different boards have quite different sets of possible
>> reset reasons. What is needed is - pass this board-specific information
>> to board-specific user space.
>>
>> What's proper API for that, if not a sysfs attribute?
> 
> Please go through the thread.
> 
> Sysfs attribute is okay, but:
> 
> 1) it should probably be a string
> 
> 2) it should certainly be superset of all the reasons
> 
> 3) it should be in generic place, say /sys/power/reset_reason
> 
> 4) it should be documented what each state means

What I'm concerned here is that a requirement appears for kernel driver
to keep and maintain knowledge of what all that codes mean. For me, it
looks like information locality breakage. Information in question is
application-specific, it definitely changes from board to board and
probably will change for particular board over time.

It's desirable to keep this information application-private, and have
kernel only passed it from hardware to application, unmodified and
uninterpreted.

Requiring kernel driver to interpret application-specific information
only increases complexity (i.e. any changes will have to be maintained
in two places - in driver and in application).

So question is - is there any proper API to communicate
application-private information from hardware through kernel to
userspace without any in-kernel interpretation?


Re: [PATCH v6 1/2] platform: Add driver for RAVE Supervisory Processor

2017-08-31 Thread Nikita Yushchenko
>> I think that trying to make this generic is purely synthetic. This
>> information is board-specific per it's nature, it comes from what board
>> is designed for, different boards have quite different sets of possible
>> reset reasons. What is needed is - pass this board-specific information
>> to board-specific user space.
>>
>> What's proper API for that, if not a sysfs attribute?
> 
> Please go through the thread.
> 
> Sysfs attribute is okay, but:
> 
> 1) it should probably be a string
> 
> 2) it should certainly be superset of all the reasons
> 
> 3) it should be in generic place, say /sys/power/reset_reason
> 
> 4) it should be documented what each state means

What I'm concerned here is that a requirement appears for kernel driver
to keep and maintain knowledge of what all that codes mean. For me, it
looks like information locality breakage. Information in question is
application-specific, it definitely changes from board to board and
probably will change for particular board over time.

It's desirable to keep this information application-private, and have
kernel only passed it from hardware to application, unmodified and
uninterpreted.

Requiring kernel driver to interpret application-specific information
only increases complexity (i.e. any changes will have to be maintained
in two places - in driver and in application).

So question is - is there any proper API to communicate
application-private information from hardware through kernel to
userspace without any in-kernel interpretation?


Re: [PATCH v6 1/2] platform: Add driver for RAVE Supervisory Processor

2017-08-31 Thread Nikita Yushchenko


30.08.2017 23:38, Pavel Machek wrote:
> Hi!
> 
 + * 9  -> Illegal Trap
 + * 10 -> Unknown
 + * 11 -> Crew Panel Requested
>>>
>>> Anyway... If you move management chip to .. I don't know, i2c, the
>>> path would change. Also it would be different path on N900. Userland
>>> should not have to deal with this.
>>>
>>> And... this should really be string, as the list will need to grow on
>>> different hardware.
>>
>> I think we have a misunderstanding, with this part of the patch set I
>> am not trying to propose a generic ABI that would be useful for any
>> other driver but this one. Hence the lack of concern for different
> 
> Yes, but sorry, that's no-go.  Kernel should hide differences between
> different machiens, and it should be rather easy in this case.

There is an interest to have reset reason exported on other ZII hardware
as well.

I think that trying to make this generic is purely synthetic. This
information is board-specific per it's nature, it comes from what board
is designed for, different boards have quite different sets of possible
reset reasons. What is needed is - pass this board-specific information
to board-specific user space.

What's proper API for that, if not a sysfs attribute?


Re: [PATCH v6 1/2] platform: Add driver for RAVE Supervisory Processor

2017-08-31 Thread Nikita Yushchenko


30.08.2017 23:38, Pavel Machek wrote:
> Hi!
> 
 + * 9  -> Illegal Trap
 + * 10 -> Unknown
 + * 11 -> Crew Panel Requested
>>>
>>> Anyway... If you move management chip to .. I don't know, i2c, the
>>> path would change. Also it would be different path on N900. Userland
>>> should not have to deal with this.
>>>
>>> And... this should really be string, as the list will need to grow on
>>> different hardware.
>>
>> I think we have a misunderstanding, with this part of the patch set I
>> am not trying to propose a generic ABI that would be useful for any
>> other driver but this one. Hence the lack of concern for different
> 
> Yes, but sorry, that's no-go.  Kernel should hide differences between
> different machiens, and it should be rather easy in this case.

There is an interest to have reset reason exported on other ZII hardware
as well.

I think that trying to make this generic is purely synthetic. This
information is board-specific per it's nature, it comes from what board
is designed for, different boards have quite different sets of possible
reset reasons. What is needed is - pass this board-specific information
to board-specific user space.

What's proper API for that, if not a sysfs attribute?


[PATCH v2] rtc: ds1307: add basic support for ds1341 chip

2017-08-24 Thread Nikita Yushchenko
This adds support for reading and writing date/time from/to ds1341 chip.

ds1341 chip has other features - alarms, input clock (can be used instead
of intercal oscillator for better accuracy), output clock ("square wave
generation"). However, not all of that is available at the same time.
Same chip pins, CLKIN/nINTA and SQW/nINTB, can be used either for
input/output clocks, or for alarm interrupts. Role of these pins on
particular board depends on hardware wiring.

We can add device tree properties that describe if each of pins is wired
as clock, or as interrupt, or left unconnected, and enable support for
corresponding functionality based on that. But that is cumbersome, requires
hardware for testing, and has to deal with bit enabling/disabling output
clock also affects which pins alarm interrupts are routed to.

Another factor is that there are hardware setups (i.e. ZII RDU2) that
power DS1341 from SuperCap, which makes power saving critical. For such
setups, kernel driver should leave register bits that control mentioned
pins in the state configured by bootloader.

Given all that, it was decided to limit support to "only date/time" for
now. That is enough for common use case. Full (and cumbersome)
implementation can be added later if ever needed.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
Reviewed-by: Linus Walleij <linus.wall...@linaro.org>
Tested-by: Aleksander Morgado <aleksan...@aleksander.es>
---
 drivers/rtc/Kconfig  | 10 +-
 drivers/rtc/rtc-ds1307.c | 13 +
 2 files changed, 18 insertions(+), 5 deletions(-)
===
Changes from v1:
- added information on why support was limited to date/time only to commit
  message, as suggested by Linus Walleij
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 72419ac2c52a..db63592a0f57 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -227,14 +227,14 @@ config RTC_DRV_AS3722
  will be called rtc-as3722.
 
 config RTC_DRV_DS1307
-   tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025, 
ISL12057"
+   tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, 
ISL12057"
help
  If you say yes here you get support for various compatible RTC
  chips (often with battery backup) connected with I2C. This driver
- should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
- EPSON RX-8025, Intersil ISL12057 and probably other chips. In some
- cases the RTC must already have been initialized (by manufacturing or
- a bootloader).
+ should handle DS1307, DS1337, DS1338, DS1339, DS1340, DS1341,
+ ST M41T00, EPSON RX-8025, Intersil ISL12057 and probably other chips.
+ In some cases the RTC must already have been initialized (by
+ manufacturing or a bootloader).
 
  The first seven registers on these chips hold an RTC, and other
  registers may add features such as NVRAM, a trickle charger for
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 4fac49e55d47..1d11f8000f8a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -39,6 +39,7 @@ enum ds_type {
ds_1338,
ds_1339,
ds_1340,
+   ds_1341,
ds_1388,
ds_3231,
m41t0,
@@ -179,6 +180,10 @@ static struct chip_desc chips[last_ds_type] = {
.century_bit= DS1340_BIT_CENTURY,
.trickle_charger_reg = 0x08,
},
+   [ds_1341] = {
+   .century_reg= DS1307_REG_MONTH,
+   .century_bit= DS1337_BIT_CENTURY,
+   },
[ds_1388] = {
.trickle_charger_reg = 0x0a,
},
@@ -209,6 +214,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1339", ds_1339 },
{ "ds1388", ds_1388 },
{ "ds1340", ds_1340 },
+   { "ds1341", ds_1341 },
{ "ds3231", ds_3231 },
{ "m41t0", m41t0 },
{ "m41t00", m41t00 },
@@ -253,6 +259,10 @@ static const struct of_device_id ds1307_of_match[] = {
.data = (void *)ds_1340
},
{
+   .compatible = "dallas,ds1341",
+   .data = (void *)ds_1341
+   },
+   {
.compatible = "maxim,ds3231",
.data = (void *)ds_3231
},
@@ -298,6 +308,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = {
{ .id = "DS1339", .driver_data = ds_1339 },
{ .id = "DS1388", .driver_data = ds_1388 },
{ .id = "DS1340", .driver_data = ds_1340 },
+   { .id = "DS1341", .driver_data = ds_1341 },
{ .id = "DS3231", .driver_data = ds_3231 },
{ .id = "M41T0", .driver_data = m41t0 },
{ .id = "M41T00", .driver_data = m41t00 },
@@ -132

[PATCH v2] rtc: ds1307: add basic support for ds1341 chip

2017-08-24 Thread Nikita Yushchenko
This adds support for reading and writing date/time from/to ds1341 chip.

ds1341 chip has other features - alarms, input clock (can be used instead
of intercal oscillator for better accuracy), output clock ("square wave
generation"). However, not all of that is available at the same time.
Same chip pins, CLKIN/nINTA and SQW/nINTB, can be used either for
input/output clocks, or for alarm interrupts. Role of these pins on
particular board depends on hardware wiring.

We can add device tree properties that describe if each of pins is wired
as clock, or as interrupt, or left unconnected, and enable support for
corresponding functionality based on that. But that is cumbersome, requires
hardware for testing, and has to deal with bit enabling/disabling output
clock also affects which pins alarm interrupts are routed to.

Another factor is that there are hardware setups (i.e. ZII RDU2) that
power DS1341 from SuperCap, which makes power saving critical. For such
setups, kernel driver should leave register bits that control mentioned
pins in the state configured by bootloader.

Given all that, it was decided to limit support to "only date/time" for
now. That is enough for common use case. Full (and cumbersome)
implementation can be added later if ever needed.

Signed-off-by: Nikita Yushchenko 
Reviewed-by: Linus Walleij 
Tested-by: Aleksander Morgado 
---
 drivers/rtc/Kconfig  | 10 +-
 drivers/rtc/rtc-ds1307.c | 13 +
 2 files changed, 18 insertions(+), 5 deletions(-)
===
Changes from v1:
- added information on why support was limited to date/time only to commit
  message, as suggested by Linus Walleij
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 72419ac2c52a..db63592a0f57 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -227,14 +227,14 @@ config RTC_DRV_AS3722
  will be called rtc-as3722.
 
 config RTC_DRV_DS1307
-   tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025, 
ISL12057"
+   tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, 
ISL12057"
help
  If you say yes here you get support for various compatible RTC
  chips (often with battery backup) connected with I2C. This driver
- should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
- EPSON RX-8025, Intersil ISL12057 and probably other chips. In some
- cases the RTC must already have been initialized (by manufacturing or
- a bootloader).
+ should handle DS1307, DS1337, DS1338, DS1339, DS1340, DS1341,
+ ST M41T00, EPSON RX-8025, Intersil ISL12057 and probably other chips.
+ In some cases the RTC must already have been initialized (by
+ manufacturing or a bootloader).
 
  The first seven registers on these chips hold an RTC, and other
  registers may add features such as NVRAM, a trickle charger for
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 4fac49e55d47..1d11f8000f8a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -39,6 +39,7 @@ enum ds_type {
ds_1338,
ds_1339,
ds_1340,
+   ds_1341,
ds_1388,
ds_3231,
m41t0,
@@ -179,6 +180,10 @@ static struct chip_desc chips[last_ds_type] = {
.century_bit= DS1340_BIT_CENTURY,
.trickle_charger_reg = 0x08,
},
+   [ds_1341] = {
+   .century_reg= DS1307_REG_MONTH,
+   .century_bit= DS1337_BIT_CENTURY,
+   },
[ds_1388] = {
.trickle_charger_reg = 0x0a,
},
@@ -209,6 +214,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1339", ds_1339 },
{ "ds1388", ds_1388 },
{ "ds1340", ds_1340 },
+   { "ds1341", ds_1341 },
{ "ds3231", ds_3231 },
{ "m41t0", m41t0 },
{ "m41t00", m41t00 },
@@ -253,6 +259,10 @@ static const struct of_device_id ds1307_of_match[] = {
.data = (void *)ds_1340
},
{
+   .compatible = "dallas,ds1341",
+   .data = (void *)ds_1341
+   },
+   {
.compatible = "maxim,ds3231",
.data = (void *)ds_3231
},
@@ -298,6 +308,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = {
{ .id = "DS1339", .driver_data = ds_1339 },
{ .id = "DS1388", .driver_data = ds_1388 },
{ .id = "DS1340", .driver_data = ds_1340 },
+   { .id = "DS1341", .driver_data = ds_1341 },
{ .id = "DS3231", .driver_data = ds_3231 },
{ .id = "M41T0", .driver_data = m41t0 },
{ .id = "M41T00", .driver_data = m41t00 },
@@ -1323,6 +1334,7 @@ static int ds1307_probe(struct i2c_client *client,
static const intbbsq

[PATCH] rtc: ds1307: add basic support for ds1341 chip

2017-08-22 Thread Nikita Yushchenko
This adds support for reading and writing date/time from/to ds1314 chip.

Other functionality (alarms, inout clock, output clock) is not added
yet, because availability of that depends on chip connections.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/rtc/Kconfig  | 10 +-
 drivers/rtc/rtc-ds1307.c | 13 +
 2 files changed, 18 insertions(+), 5 deletions(-)
===
DS1341/1342 chips have additional features, namely
- alarms,
- input clock (can be used instead of intercal oscillator for better
  accuracy),
- output clock ("square wave generation")

However, not all of that is available at the same time. Same chip pins,
CLKIN/nINTA and SQW/nINTB, can be used either for input/output clocks,
or for alarm interrupts. Role of these pins on particular board depends
on hardware wiring.

We can add device tree properties that describe if each of pins is wired
as clock, or as interrupt, or left unconnected, and enable support for
corresponding functionality based on that. But that requires hardware setups
for testing, and also is somewhat cumbersome. Additional complexity is
caused by bit enabling/disabling output clock also affects which pins alarm
interrupts are routed to.

Another factor is that there are hardware setups (i.e. ZII RDU2) that
power DS1341 from SuperCap, which makes power saving critical. For such
setups, kernel driver should leave register bits that control mentioned
pins in the state configured by bootloader.

Given all that, it was decided to limit support to "only date/time" for
now. That is enough for common use case. Full (and cumbersome) implementation
can be added later if ever needed.

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 72419ac2c52a..db63592a0f57 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -227,14 +227,14 @@ config RTC_DRV_AS3722
  will be called rtc-as3722.
 
 config RTC_DRV_DS1307
-   tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025, 
ISL12057"
+   tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, 
ISL12057"
help
  If you say yes here you get support for various compatible RTC
  chips (often with battery backup) connected with I2C. This driver
- should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
- EPSON RX-8025, Intersil ISL12057 and probably other chips. In some
- cases the RTC must already have been initialized (by manufacturing or
- a bootloader).
+ should handle DS1307, DS1337, DS1338, DS1339, DS1340, DS1341,
+ ST M41T00, EPSON RX-8025, Intersil ISL12057 and probably other chips.
+ In some cases the RTC must already have been initialized (by
+ manufacturing or a bootloader).
 
  The first seven registers on these chips hold an RTC, and other
  registers may add features such as NVRAM, a trickle charger for
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 4fac49e55d47..1d11f8000f8a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -39,6 +39,7 @@ enum ds_type {
ds_1338,
ds_1339,
ds_1340,
+   ds_1341,
ds_1388,
ds_3231,
m41t0,
@@ -179,6 +180,10 @@ static struct chip_desc chips[last_ds_type] = {
.century_bit= DS1340_BIT_CENTURY,
.trickle_charger_reg = 0x08,
},
+   [ds_1341] = {
+   .century_reg= DS1307_REG_MONTH,
+   .century_bit= DS1337_BIT_CENTURY,
+   },
[ds_1388] = {
.trickle_charger_reg = 0x0a,
},
@@ -209,6 +214,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1339", ds_1339 },
{ "ds1388", ds_1388 },
{ "ds1340", ds_1340 },
+   { "ds1341", ds_1341 },
{ "ds3231", ds_3231 },
{ "m41t0", m41t0 },
{ "m41t00", m41t00 },
@@ -253,6 +259,10 @@ static const struct of_device_id ds1307_of_match[] = {
.data = (void *)ds_1340
},
{
+   .compatible = "dallas,ds1341",
+   .data = (void *)ds_1341
+   },
+   {
.compatible = "maxim,ds3231",
.data = (void *)ds_3231
},
@@ -298,6 +308,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = {
{ .id = "DS1339", .driver_data = ds_1339 },
{ .id = "DS1388", .driver_data = ds_1388 },
{ .id = "DS1340", .driver_data = ds_1340 },
+   { .id = "DS1341", .driver_data = ds_1341 },
{ .id = "DS3231", .driver_data = ds_3231 },
{ .id = "M41T0", .driver_data = m41t0 },
{ .id = "M41T00", .driver_data = m41t00 },
@@ -1323,6 +1334,7 @@ static int ds1307_probe(stru

[PATCH] rtc: ds1307: add basic support for ds1341 chip

2017-08-22 Thread Nikita Yushchenko
This adds support for reading and writing date/time from/to ds1314 chip.

Other functionality (alarms, inout clock, output clock) is not added
yet, because availability of that depends on chip connections.

Signed-off-by: Nikita Yushchenko 
---
 drivers/rtc/Kconfig  | 10 +-
 drivers/rtc/rtc-ds1307.c | 13 +
 2 files changed, 18 insertions(+), 5 deletions(-)
===
DS1341/1342 chips have additional features, namely
- alarms,
- input clock (can be used instead of intercal oscillator for better
  accuracy),
- output clock ("square wave generation")

However, not all of that is available at the same time. Same chip pins,
CLKIN/nINTA and SQW/nINTB, can be used either for input/output clocks,
or for alarm interrupts. Role of these pins on particular board depends
on hardware wiring.

We can add device tree properties that describe if each of pins is wired
as clock, or as interrupt, or left unconnected, and enable support for
corresponding functionality based on that. But that requires hardware setups
for testing, and also is somewhat cumbersome. Additional complexity is
caused by bit enabling/disabling output clock also affects which pins alarm
interrupts are routed to.

Another factor is that there are hardware setups (i.e. ZII RDU2) that
power DS1341 from SuperCap, which makes power saving critical. For such
setups, kernel driver should leave register bits that control mentioned
pins in the state configured by bootloader.

Given all that, it was decided to limit support to "only date/time" for
now. That is enough for common use case. Full (and cumbersome) implementation
can be added later if ever needed.

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 72419ac2c52a..db63592a0f57 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -227,14 +227,14 @@ config RTC_DRV_AS3722
  will be called rtc-as3722.
 
 config RTC_DRV_DS1307
-   tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025, 
ISL12057"
+   tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, 
ISL12057"
help
  If you say yes here you get support for various compatible RTC
  chips (often with battery backup) connected with I2C. This driver
- should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
- EPSON RX-8025, Intersil ISL12057 and probably other chips. In some
- cases the RTC must already have been initialized (by manufacturing or
- a bootloader).
+ should handle DS1307, DS1337, DS1338, DS1339, DS1340, DS1341,
+ ST M41T00, EPSON RX-8025, Intersil ISL12057 and probably other chips.
+ In some cases the RTC must already have been initialized (by
+ manufacturing or a bootloader).
 
  The first seven registers on these chips hold an RTC, and other
  registers may add features such as NVRAM, a trickle charger for
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 4fac49e55d47..1d11f8000f8a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -39,6 +39,7 @@ enum ds_type {
ds_1338,
ds_1339,
ds_1340,
+   ds_1341,
ds_1388,
ds_3231,
m41t0,
@@ -179,6 +180,10 @@ static struct chip_desc chips[last_ds_type] = {
.century_bit= DS1340_BIT_CENTURY,
.trickle_charger_reg = 0x08,
},
+   [ds_1341] = {
+   .century_reg= DS1307_REG_MONTH,
+   .century_bit= DS1337_BIT_CENTURY,
+   },
[ds_1388] = {
.trickle_charger_reg = 0x0a,
},
@@ -209,6 +214,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1339", ds_1339 },
{ "ds1388", ds_1388 },
{ "ds1340", ds_1340 },
+   { "ds1341", ds_1341 },
{ "ds3231", ds_3231 },
{ "m41t0", m41t0 },
{ "m41t00", m41t00 },
@@ -253,6 +259,10 @@ static const struct of_device_id ds1307_of_match[] = {
.data = (void *)ds_1340
},
{
+   .compatible = "dallas,ds1341",
+   .data = (void *)ds_1341
+   },
+   {
.compatible = "maxim,ds3231",
.data = (void *)ds_3231
},
@@ -298,6 +308,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = {
{ .id = "DS1339", .driver_data = ds_1339 },
{ .id = "DS1388", .driver_data = ds_1388 },
{ .id = "DS1340", .driver_data = ds_1340 },
+   { .id = "DS1341", .driver_data = ds_1341 },
{ .id = "DS3231", .driver_data = ds_3231 },
{ .id = "M41T0", .driver_data = m41t0 },
{ .id = "M41T00", .driver_data = m41t00 },
@@ -1323,6 +1334,7 @@ static int ds1307_probe(struct i2c_client *client,
static const int 

Re: [PATCH 4/4] iio: hi8435: cleanup reset gpio

2017-05-29 Thread Nikita Yushchenko
>> - Thinking further on this, I realized that for common case signal
>> polarity is something defined by chip, and thus this knowledge belongs
>> to chip's driver and not to chip user's device tree. Moreover, device
>> tree writer could easily be not aware of signal polarity (too many
>> datasheets are NDA-closed), thus hello copy-pasting, try-and-check and
>> other counterproductive approaches.
>>
>> - Then Vladimir pointed real-life case with signal inversion by handmade
>> level shifter. Although scope of this is likely limited to hw labs,
>> support for this is wanted and thus some way to override polarity in
>> chip user's dts be available.  Still, this should be optional, without
>> requiring dts to always define polarity of each gpio.
>
> I have real hardware that effectively does the equivalent for interrupt
> lines coming into the processor from some sensors.  Note quite the same,
> but shows these things often do turn up as a fix on 'real' hardware.

Well no doubt that sometimes there is need to invert polarity for
particular use case.

But still forcing explicit definition of polarity of each and every gpio
usage is a bad way to solve this.

> You are correct, this needs some wider guidance.  I've cc'd Linus
> Walleij more to make sure he has a heads up than to suggest
> we continue this conversation in this thread.

As I've already written elsewhere, possible solution is a new pair of
gpio flags, GPIO_DEFAULT_POLARITY / GPIO_INVERTED_POLARITY, which means
that polarity of signal is, corresponding, chip's default or inverted
chip's default.  And matching API for drivers to set default when
requesting gpio.

> 
> I don't know what the 'correct' way forward is.  Funnily enough
> my immediate thought is to it it with a big hammer and define
> an inverting gpiochip to represent the possible inverter.
> So a bit like a gpiochip setting on i2c but in this case
> it sits on a gpio.  So when you set the front gpio
> (representing the inverter) it knows to set the opposite
> on the actual gpio on the processor.

This may be alternative to GPIO_DEFAULT_POLARITY /
GPIO_INVERTED_POLARITY, that perhaps allows for device tree to better
follow schematics.  Still this does not play well with existing
requirement to explicitly set ACTIVE_LOW / ACTIVE_HIGH at gpio usage side.


Nikita

P.S.

Another view is that for such a trivial entity as gpio, we already have
- physical gpio values,
- logical values that come from ACTIVE_LOW / ACTIVE_HIGH,
- for gpios used as interrupts, active low / active high irq's,
and discussing addition more to that... for simplification? Joking?

At least, if adding default-polarity / inverted-polarity, this should be
done mutually-exclusive with active-high / active-low.  And if adding
inverter gpiochip, then also this should be mutual exclusive with
setting active-high / active-low.


Re: [PATCH 4/4] iio: hi8435: cleanup reset gpio

2017-05-29 Thread Nikita Yushchenko
>> - Thinking further on this, I realized that for common case signal
>> polarity is something defined by chip, and thus this knowledge belongs
>> to chip's driver and not to chip user's device tree. Moreover, device
>> tree writer could easily be not aware of signal polarity (too many
>> datasheets are NDA-closed), thus hello copy-pasting, try-and-check and
>> other counterproductive approaches.
>>
>> - Then Vladimir pointed real-life case with signal inversion by handmade
>> level shifter. Although scope of this is likely limited to hw labs,
>> support for this is wanted and thus some way to override polarity in
>> chip user's dts be available.  Still, this should be optional, without
>> requiring dts to always define polarity of each gpio.
>
> I have real hardware that effectively does the equivalent for interrupt
> lines coming into the processor from some sensors.  Note quite the same,
> but shows these things often do turn up as a fix on 'real' hardware.

Well no doubt that sometimes there is need to invert polarity for
particular use case.

But still forcing explicit definition of polarity of each and every gpio
usage is a bad way to solve this.

> You are correct, this needs some wider guidance.  I've cc'd Linus
> Walleij more to make sure he has a heads up than to suggest
> we continue this conversation in this thread.

As I've already written elsewhere, possible solution is a new pair of
gpio flags, GPIO_DEFAULT_POLARITY / GPIO_INVERTED_POLARITY, which means
that polarity of signal is, corresponding, chip's default or inverted
chip's default.  And matching API for drivers to set default when
requesting gpio.

> 
> I don't know what the 'correct' way forward is.  Funnily enough
> my immediate thought is to it it with a big hammer and define
> an inverting gpiochip to represent the possible inverter.
> So a bit like a gpiochip setting on i2c but in this case
> it sits on a gpio.  So when you set the front gpio
> (representing the inverter) it knows to set the opposite
> on the actual gpio on the processor.

This may be alternative to GPIO_DEFAULT_POLARITY /
GPIO_INVERTED_POLARITY, that perhaps allows for device tree to better
follow schematics.  Still this does not play well with existing
requirement to explicitly set ACTIVE_LOW / ACTIVE_HIGH at gpio usage side.


Nikita

P.S.

Another view is that for such a trivial entity as gpio, we already have
- physical gpio values,
- logical values that come from ACTIVE_LOW / ACTIVE_HIGH,
- for gpios used as interrupts, active low / active high irq's,
and discussing addition more to that... for simplification? Joking?

At least, if adding default-polarity / inverted-polarity, this should be
done mutually-exclusive with active-high / active-low.  And if adding
inverter gpiochip, then also this should be mutual exclusive with
setting active-high / active-low.


Re: [PATCH/RFC] iio: hi8435: do not enable all events by default

2017-05-28 Thread Nikita Yushchenko
>> Still, isn't there subsystem-level default that all events are disabled
>> by default?  If such, then current hi8435 state breaks subsystem-level
>> rules, which is a [userspace-visible] bug.  I'm not sure how far should
>> we go in bug compatibility.
>
> It is indeed the subsystem default (as much as we have one)
> 
> This is a moderately obscure chip for linux systems, do we have a good handle
> on where it is being used - i.e. are most of the devices under control of
> people we can discuss this with?

Company I work with, uses this chip in several boards; what they need is
a service that monitors all connected chip's outputs and detects
changes.  They originally wanted gpio-style access to use with userspace
polling, and were not pleased with entire IIO thing. However it's
important for them to minimize required kernel patches against mainline,
thus if mainline supports this chip as IIO device that's ok for them.

Questions like default event enable state has little practical impact.
It's more about keeping architecture clean.

Nikita


Re: [PATCH/RFC] iio: hi8435: do not enable all events by default

2017-05-28 Thread Nikita Yushchenko
>> Still, isn't there subsystem-level default that all events are disabled
>> by default?  If such, then current hi8435 state breaks subsystem-level
>> rules, which is a [userspace-visible] bug.  I'm not sure how far should
>> we go in bug compatibility.
>
> It is indeed the subsystem default (as much as we have one)
> 
> This is a moderately obscure chip for linux systems, do we have a good handle
> on where it is being used - i.e. are most of the devices under control of
> people we can discuss this with?

Company I work with, uses this chip in several boards; what they need is
a service that monitors all connected chip's outputs and detects
changes.  They originally wanted gpio-style access to use with userspace
polling, and were not pleased with entire IIO thing. However it's
important for them to minimize required kernel patches against mainline,
thus if mainline supports this chip as IIO device that's ok for them.

Questions like default event enable state has little practical impact.
It's more about keeping architecture clean.

Nikita


Re: [PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-25 Thread Nikita Yushchenko
>> + {
>> +status = "okay";
>> +};
>> +
>> + {
> 
> Please keep these labelled nodes sort alphabetically.

Ok

>> +bus-num = <1>;
>> +pinctrl-names = "default";
>> +pinctrl-0 = <_dspi2>;
>> +status = "okay";
> 
> We usually have 'status' line at the bottom of property list.

Ok

>> +spi-num-chipselects = <2>;
>> +
>> +hi8435@1 {
> 
> Node name should be something generic, while label can be specific
> model name.  The following form might be better.
> 
>   hi8435: sensor@1

Ok

Although the same file, in lines nearby, has m25p128@0 and at93c46d@1.

Anyway let's delay this a bit, up to the reset polarity description
thing in hi8435 is resolved.

Nikita



Re: [PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-25 Thread Nikita Yushchenko
>> + {
>> +status = "okay";
>> +};
>> +
>> + {
> 
> Please keep these labelled nodes sort alphabetically.

Ok

>> +bus-num = <1>;
>> +pinctrl-names = "default";
>> +pinctrl-0 = <_dspi2>;
>> +status = "okay";
> 
> We usually have 'status' line at the bottom of property list.

Ok

>> +spi-num-chipselects = <2>;
>> +
>> +hi8435@1 {
> 
> Node name should be something generic, while label can be specific
> model name.  The following form might be better.
> 
>   hi8435: sensor@1

Ok

Although the same file, in lines nearby, has m25p128@0 and at93c46d@1.

Anyway let's delay this a bit, up to the reset polarity description
thing in hi8435 is resolved.

Nikita



Re: [PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-25 Thread Nikita Yushchenko
>> "Crap origin" here is that in vast majority of cases, polarity is
>> per-chip, not per-chip-use, knowledge. And proper location for per-chip
>> knowledge is chip's driver.  Moving this knowledge to per-chip-use
>> location in device trees only provides a source for errors, with little
>> gain.
>>
>> Vladimir Barinov mentions possibility that signal can be inverted by
>> board between gpio provider and chip's pin ...   but do we have at least
>> one practical case of this?  And if we even do, it's quite uncommon, and
>> something special should be required in device tree for these special
>> cases and not for "normal" cases.
> 
> I disagree.  Not for hi8435, but I have seen quite some board designs
> invert GPIOs before getting them into board level components.  That's
> why we should define those xxx-gpios properties on board level DTS,
> where polarity can be chosen per board design.

Even if such, still board specific knowledge is "is gpio as-is or
inverted", but knowledge if chip expects signal to be active low or
active high, remains chip-specific.

I'm thinking of proposing new flags in gpio binding, say
GPIO_NATIVE_POLARITY / GPIO_INVERTED_POLARITY,  that could be used
instead of GPIO_ACTIVE_HIGH / GPIO_ACTIVE_LOW, and leave knowledge about
signal polarity to chip's driver, while still allow to describe
inversion of needed.

Nikita


Re: [PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-25 Thread Nikita Yushchenko
>> "Crap origin" here is that in vast majority of cases, polarity is
>> per-chip, not per-chip-use, knowledge. And proper location for per-chip
>> knowledge is chip's driver.  Moving this knowledge to per-chip-use
>> location in device trees only provides a source for errors, with little
>> gain.
>>
>> Vladimir Barinov mentions possibility that signal can be inverted by
>> board between gpio provider and chip's pin ...   but do we have at least
>> one practical case of this?  And if we even do, it's quite uncommon, and
>> something special should be required in device tree for these special
>> cases and not for "normal" cases.
> 
> I disagree.  Not for hi8435, but I have seen quite some board designs
> invert GPIOs before getting them into board level components.  That's
> why we should define those xxx-gpios properties on board level DTS,
> where polarity can be chosen per board design.

Even if such, still board specific knowledge is "is gpio as-is or
inverted", but knowledge if chip expects signal to be active low or
active high, remains chip-specific.

I'm thinking of proposing new flags in gpio binding, say
GPIO_NATIVE_POLARITY / GPIO_INVERTED_POLARITY,  that could be used
instead of GPIO_ACTIVE_HIGH / GPIO_ACTIVE_LOW, and leave knowledge about
signal polarity to chip's driver, while still allow to describe
inversion of needed.

Nikita


Re: [PATCH 4/4] iio: hi8435: cleanup reset gpio

2017-05-25 Thread Nikita Yushchenko
> Reset GPIO is active low.
>
> Currently driver uses gpiod_set_value(1) to clean reset, which depends
> on device tree to contain GPIO_ACTIVE_HIGH - that does not match reality.
>
> This fixes driver to use _raw version of gpiod_set_value() to enforce
> active-low semantics despite of what's written in device tree. Allowing
> device tree to override that only opens possibility for errors and does
> not add any value.
>
> Additionally, use _cansleep version to make things work with i2c-gpio
> and other sleeping gpio drivers.  
 The reset gpio comes from platform hence it should be handled by DTS.

 In driver the gpio should not be raw.

 Even the hi8435 is active low but platform may invert signal (f.e. by
 adding trigger on the circuit path).  
>>> I see.  However - isn't this pure theoretic?  Does such case exist?  
>> I assure you that this is frequently used.
>>
>> Simply search google for "simple voltage level shifter"
>> It might be on PNP or NPN transistor, hence logic might be inverted.
>>
>>>
>>> In vast majority of cases, GPIO polarity is chip-specific, not
>>> chip-use-specific.  Thus this knowlege belongs to driver and not to
>>> device tree describing particular chip usage.  Having this always
>>> defined at usage side is IMO major source of errors.  
>> GPIO comes from SoC then "circuit path" and finally chip reset input.
>>
>> What do you propose if h/w circuit path has simple voltage level shifter 
>> on transistor. How to differentiate PNP and NPN cases?
> 
> Hmm. Ah well, I clearly jumped too fast on this set and should have
> left it for a while longer (I rushed a little as I'm away next weekend
> and the cycle is moving towards rc3)
> 
> Sorry about that.
> 
> Anyhow, I am tempted to queue a revert of this patch.  The level
> shifting case hadn't occurred to me (oops).
> 
> Thoughts?

Well here is the full story.

- I found that chip's reset line is active low per datasheet, but device
tree for board I work with states it is active high

- I checked driver code and found that driver depends on this incorrect
setting, it won't work if device tree will state that gpio is active low

- I could revert values in driver code AND in device tree, this way make
device tree be correct (against reality) but make dtb files flashed into
existing systems incompatible with future kernels -  which I disliked

- Thus I thought that I can remove explicit definition of polarity from
device tree (replacing it with neutrally-looking zero), and change
driver to use _raw.  I assumed that there is no real gain to let device
tree override gpio polarity for signal that is per-datasheet always
active low

- Thinking further on this, I realized that for common case signal
polarity is something defined by chip, and thus this knowledge belongs
to chip's driver and not to chip user's device tree. Moreover, device
tree writer could easily be not aware of signal polarity (too many
datasheets are NDA-closed), thus hello copy-pasting, try-and-check and
other counterproductive approaches.

- Then Vladimir pointed real-life case with signal inversion by handmade
level shifter. Although scope of this is likely limited to hw labs,
support for this is wanted and thus some way to override polarity in
chip user's dts be available.  Still, this should be optional, without
requiring dts to always define polarity of each gpio.


It becomes obvious that this topic has global scope, it is not something
to solve within hi8345 driver or within iio.  For patch in question,
possibilities are:
- revert the patch, restore situation with driver depending on wrong
statement in dts, maybe document that in bindings,
- replace patch with code assuming that device tree has correct
definition of reset gpio polarity; break existing device trees (all are
out-of-tree as of today),
- keep the patch, thus not break anything and still stop requiring
device tree to contain wrong statement, but make entire situation
somewhat hacky and loose support for board reverting signal between gpio
provider and hi8435's pin (hopefully no such board exists).

I don't know. Maintainer should decide.

Nikita


Re: [PATCH 4/4] iio: hi8435: cleanup reset gpio

2017-05-25 Thread Nikita Yushchenko
> Reset GPIO is active low.
>
> Currently driver uses gpiod_set_value(1) to clean reset, which depends
> on device tree to contain GPIO_ACTIVE_HIGH - that does not match reality.
>
> This fixes driver to use _raw version of gpiod_set_value() to enforce
> active-low semantics despite of what's written in device tree. Allowing
> device tree to override that only opens possibility for errors and does
> not add any value.
>
> Additionally, use _cansleep version to make things work with i2c-gpio
> and other sleeping gpio drivers.  
 The reset gpio comes from platform hence it should be handled by DTS.

 In driver the gpio should not be raw.

 Even the hi8435 is active low but platform may invert signal (f.e. by
 adding trigger on the circuit path).  
>>> I see.  However - isn't this pure theoretic?  Does such case exist?  
>> I assure you that this is frequently used.
>>
>> Simply search google for "simple voltage level shifter"
>> It might be on PNP or NPN transistor, hence logic might be inverted.
>>
>>>
>>> In vast majority of cases, GPIO polarity is chip-specific, not
>>> chip-use-specific.  Thus this knowlege belongs to driver and not to
>>> device tree describing particular chip usage.  Having this always
>>> defined at usage side is IMO major source of errors.  
>> GPIO comes from SoC then "circuit path" and finally chip reset input.
>>
>> What do you propose if h/w circuit path has simple voltage level shifter 
>> on transistor. How to differentiate PNP and NPN cases?
> 
> Hmm. Ah well, I clearly jumped too fast on this set and should have
> left it for a while longer (I rushed a little as I'm away next weekend
> and the cycle is moving towards rc3)
> 
> Sorry about that.
> 
> Anyhow, I am tempted to queue a revert of this patch.  The level
> shifting case hadn't occurred to me (oops).
> 
> Thoughts?

Well here is the full story.

- I found that chip's reset line is active low per datasheet, but device
tree for board I work with states it is active high

- I checked driver code and found that driver depends on this incorrect
setting, it won't work if device tree will state that gpio is active low

- I could revert values in driver code AND in device tree, this way make
device tree be correct (against reality) but make dtb files flashed into
existing systems incompatible with future kernels -  which I disliked

- Thus I thought that I can remove explicit definition of polarity from
device tree (replacing it with neutrally-looking zero), and change
driver to use _raw.  I assumed that there is no real gain to let device
tree override gpio polarity for signal that is per-datasheet always
active low

- Thinking further on this, I realized that for common case signal
polarity is something defined by chip, and thus this knowledge belongs
to chip's driver and not to chip user's device tree. Moreover, device
tree writer could easily be not aware of signal polarity (too many
datasheets are NDA-closed), thus hello copy-pasting, try-and-check and
other counterproductive approaches.

- Then Vladimir pointed real-life case with signal inversion by handmade
level shifter. Although scope of this is likely limited to hw labs,
support for this is wanted and thus some way to override polarity in
chip user's dts be available.  Still, this should be optional, without
requiring dts to always define polarity of each gpio.


It becomes obvious that this topic has global scope, it is not something
to solve within hi8345 driver or within iio.  For patch in question,
possibilities are:
- revert the patch, restore situation with driver depending on wrong
statement in dts, maybe document that in bindings,
- replace patch with code assuming that device tree has correct
definition of reset gpio polarity; break existing device trees (all are
out-of-tree as of today),
- keep the patch, thus not break anything and still stop requiring
device tree to contain wrong statement, but make entire situation
somewhat hacky and loose support for board reverting signal between gpio
provider and hi8435's pin (hopefully no such board exists).

I don't know. Maintainer should decide.

Nikita


Re: [PATCH/RFC] iio: hi8435: do not enable all events by default

2017-05-24 Thread Nikita Yushchenko


24.05.2017 22:27, Jonathan Cameron wrote:
> On Tue, 23 May 2017 11:08:30 +0300
> Nikita Yushchenko <nikita.yo...@cogentembedded.com> wrote:
> 
>> Having all events enabled by default is misleading.
>> Userspace should explicitly enable events they want to receive.
>>
>> Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
> I agree in principle, but this is a userspace ABI change.  Sadly we
> can't do it with out risking breaking userspace code...
> 
> One of those we should have caught in review, but now it's there
> we can't actually do anything about it unless we are absolutely
> sure no one will notice!

I see your point.

Still, isn't there subsystem-level default that all events are disabled
by default?  If such, then current hi8435 state breaks subsystem-level
rules, which is a [userspace-visible] bug.  I'm not sure how far should
we go in bug compatibility.

One crazy idea could be - make default selectable via device tree (with
default set to all-enabled to keep bug-compatibility).  But perhaps
that's over-reaction.


Re: [PATCH/RFC] iio: hi8435: do not enable all events by default

2017-05-24 Thread Nikita Yushchenko


24.05.2017 22:27, Jonathan Cameron wrote:
> On Tue, 23 May 2017 11:08:30 +0300
> Nikita Yushchenko  wrote:
> 
>> Having all events enabled by default is misleading.
>> Userspace should explicitly enable events they want to receive.
>>
>> Signed-off-by: Nikita Yushchenko 
> I agree in principle, but this is a userspace ABI change.  Sadly we
> can't do it with out risking breaking userspace code...
> 
> One of those we should have caught in review, but now it's there
> we can't actually do anything about it unless we are absolutely
> sure no one will notice!

I see your point.

Still, isn't there subsystem-level default that all events are disabled
by default?  If such, then current hi8435 state breaks subsystem-level
rules, which is a [userspace-visible] bug.  I'm not sure how far should
we go in bug compatibility.

One crazy idea could be - make default selectable via device tree (with
default set to all-enabled to keep bug-compatibility).  But perhaps
that's over-reaction.


Re: [PATCH] iio: hi8435: fix race between event enable and event generation

2017-05-24 Thread Nikita Yushchenko
>> Add locking to avoid interference between reading/processing current
>> sence in event enable and event generation paths.
>>
>> Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
> Make sense.  Could you give a little more detail on the seriousness
> of this bug?  I need to assess whether we just queue it up for the
> next merge window or push it forward quicker as a bug fix and
> whether to mark it for stable or not.
> 
> You probably have a better idea of how much it matters than I do!

Race was introduced by my previous patch, and noticed by Vladimir.
It is not in any released tree.

Possible race impact is loss of event or duplicate event.

Nikita


Re: [PATCH] iio: hi8435: fix race between event enable and event generation

2017-05-24 Thread Nikita Yushchenko
>> Add locking to avoid interference between reading/processing current
>> sence in event enable and event generation paths.
>>
>> Signed-off-by: Nikita Yushchenko 
> Make sense.  Could you give a little more detail on the seriousness
> of this bug?  I need to assess whether we just queue it up for the
> next merge window or push it forward quicker as a bug fix and
> whether to mark it for stable or not.
> 
> You probably have a better idea of how much it matters than I do!

Race was introduced by my previous patch, and noticed by Vladimir.
It is not in any released tree.

Possible race impact is loss of event or duplicate event.

Nikita


Re: [PATCH 4/4] iio: hi8435: cleanup reset gpio

2017-05-23 Thread Nikita Yushchenko
>> Reset GPIO is active low.
>>
>> Currently driver uses gpiod_set_value(1) to clean reset, which depends
>> on device tree to contain GPIO_ACTIVE_HIGH - that does not match reality.
>>
>> This fixes driver to use _raw version of gpiod_set_value() to enforce
>> active-low semantics despite of what's written in device tree. Allowing
>> device tree to override that only opens possibility for errors and does
>> not add any value.
>>
>> Additionally, use _cansleep version to make things work with i2c-gpio
>> and other sleeping gpio drivers.
> 
> The reset gpio comes from platform hence it should be handled by DTS.
> 
> In driver the gpio should not be raw.
> 
> Even the hi8435 is active low but platform may invert signal (f.e. by
> adding trigger on the circuit path).

I see.  However - isn't this pure theoretic?  Does such case exist?

In vast majority of cases, GPIO polarity is chip-specific, not
chip-use-specific.  Thus this knowlege belongs to driver and not to
device tree describing particular chip usage.  Having this always
defined at usage side is IMO major source of errors.

In this particular case, we already have device trees in the wild with
polarity set to active_high.  If we now change that to require
active_low, we break existing setups.  Not sure this is acceptable.

I'm unsure what is good way forward here. I believe it is at gpiolib
level, which perhaps should change how "logical value" is defined, such
that knowledge of chip-specific information is not forced to chip usage
scope.

Nikita


Re: [PATCH 4/4] iio: hi8435: cleanup reset gpio

2017-05-23 Thread Nikita Yushchenko
>> Reset GPIO is active low.
>>
>> Currently driver uses gpiod_set_value(1) to clean reset, which depends
>> on device tree to contain GPIO_ACTIVE_HIGH - that does not match reality.
>>
>> This fixes driver to use _raw version of gpiod_set_value() to enforce
>> active-low semantics despite of what's written in device tree. Allowing
>> device tree to override that only opens possibility for errors and does
>> not add any value.
>>
>> Additionally, use _cansleep version to make things work with i2c-gpio
>> and other sleeping gpio drivers.
> 
> The reset gpio comes from platform hence it should be handled by DTS.
> 
> In driver the gpio should not be raw.
> 
> Even the hi8435 is active low but platform may invert signal (f.e. by
> adding trigger on the circuit path).

I see.  However - isn't this pure theoretic?  Does such case exist?

In vast majority of cases, GPIO polarity is chip-specific, not
chip-use-specific.  Thus this knowlege belongs to driver and not to
device tree describing particular chip usage.  Having this always
defined at usage side is IMO major source of errors.

In this particular case, we already have device trees in the wild with
polarity set to active_high.  If we now change that to require
active_low, we break existing setups.  Not sure this is acceptable.

I'm unsure what is good way forward here. I believe it is at gpiolib
level, which perhaps should change how "logical value" is defined, such
that knowledge of chip-specific information is not forced to chip usage
scope.

Nikita


[PATCH/RFC] iio: hi8435: do not enable all events by default

2017-05-23 Thread Nikita Yushchenko
Having all events enabled by default is misleading.
Userspace should explicitly enable events they want to receive.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/iio/adc/hi8435.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index ef5c286c8e67..0331739f235c 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -506,8 +506,6 @@ static int hi8435_probe(struct spi_device *spi)
idev->channels  = hi8435_channels;
idev->num_channels  = ARRAY_SIZE(hi8435_channels);
 
-   /* unmask all events */
-   priv->event_scan_mask = ~(0);
/*
 * There is a restriction in the chip - the hysteresis can not be odd.
 * If the hysteresis is set to odd value then chip gets into lock state
-- 
2.11.0



[PATCH/RFC] iio: hi8435: do not enable all events by default

2017-05-23 Thread Nikita Yushchenko
Having all events enabled by default is misleading.
Userspace should explicitly enable events they want to receive.

Signed-off-by: Nikita Yushchenko 
---
 drivers/iio/adc/hi8435.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index ef5c286c8e67..0331739f235c 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -506,8 +506,6 @@ static int hi8435_probe(struct spi_device *spi)
idev->channels  = hi8435_channels;
idev->num_channels  = ARRAY_SIZE(hi8435_channels);
 
-   /* unmask all events */
-   priv->event_scan_mask = ~(0);
/*
 * There is a restriction in the chip - the hysteresis can not be odd.
 * If the hysteresis is set to odd value then chip gets into lock state
-- 
2.11.0



[PATCH] iio: hi8435: remote ampersands from hi8435_info definition

2017-05-23 Thread Nikita Yushchenko
C syntax allows apersands when initializing structures fields with
function pointers, but in Linux sources ampersands are normally not used
in thix context.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/iio/adc/hi8435.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index 28fc699f00f6..ef5c286c8e67 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -414,11 +414,11 @@ static const struct iio_chan_spec hi8435_channels[] = {
 static const struct iio_info hi8435_info = {
.driver_module = THIS_MODULE,
.read_raw = hi8435_read_raw,
-   .read_event_config = _read_event_config,
+   .read_event_config = hi8435_read_event_config,
.write_event_config = hi8435_write_event_config,
-   .read_event_value = _read_event_value,
-   .write_event_value = _write_event_value,
-   .debugfs_reg_access = _debugfs_reg_access,
+   .read_event_value = hi8435_read_event_value,
+   .write_event_value = hi8435_write_event_value,
+   .debugfs_reg_access = hi8435_debugfs_reg_access,
 };
 
 static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val)
-- 
2.11.0



[PATCH] iio: hi8435: remote ampersands from hi8435_info definition

2017-05-23 Thread Nikita Yushchenko
C syntax allows apersands when initializing structures fields with
function pointers, but in Linux sources ampersands are normally not used
in thix context.

Signed-off-by: Nikita Yushchenko 
---
 drivers/iio/adc/hi8435.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index 28fc699f00f6..ef5c286c8e67 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -414,11 +414,11 @@ static const struct iio_chan_spec hi8435_channels[] = {
 static const struct iio_info hi8435_info = {
.driver_module = THIS_MODULE,
.read_raw = hi8435_read_raw,
-   .read_event_config = _read_event_config,
+   .read_event_config = hi8435_read_event_config,
.write_event_config = hi8435_write_event_config,
-   .read_event_value = _read_event_value,
-   .write_event_value = _write_event_value,
-   .debugfs_reg_access = _debugfs_reg_access,
+   .read_event_value = hi8435_read_event_value,
+   .write_event_value = hi8435_write_event_value,
+   .debugfs_reg_access = hi8435_debugfs_reg_access,
 };
 
 static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val)
-- 
2.11.0



[PATCH] iio: hi8435: fix race between event enable and event generation

2017-05-23 Thread Nikita Yushchenko
Add locking to avoid interference between reading/processing current
sence in event enable and event generation paths.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/iio/adc/hi8435.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index ab59969b7c49..28fc699f00f6 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -144,6 +144,8 @@ static int hi8435_write_event_config(struct iio_dev *idev,
int ret;
u32 tmp;
 
+   mutex_lock(>lock);
+
if (state) {
ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
if (ret < 0)
@@ -157,6 +159,8 @@ static int hi8435_write_event_config(struct iio_dev *idev,
} else
priv->event_scan_mask &= ~BIT(chan->channel);
 
+   mutex_unlock(>lock);
+
return 0;
 }
 
@@ -449,12 +453,16 @@ static irqreturn_t hi8435_trigger_handler(int irq, void 
*private)
u32 val;
int ret;
 
+   mutex_lock(>lock);
+
ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
if (ret < 0)
goto err_read;
 
hi8435_iio_push_event(idev, val);
 
+   mutex_unlock(>lock);
+
 err_read:
iio_trigger_notify_done(idev->trig);
 
-- 
2.11.0



[PATCH] iio: hi8435: fix race between event enable and event generation

2017-05-23 Thread Nikita Yushchenko
Add locking to avoid interference between reading/processing current
sence in event enable and event generation paths.

Signed-off-by: Nikita Yushchenko 
---
 drivers/iio/adc/hi8435.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index ab59969b7c49..28fc699f00f6 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -144,6 +144,8 @@ static int hi8435_write_event_config(struct iio_dev *idev,
int ret;
u32 tmp;
 
+   mutex_lock(>lock);
+
if (state) {
ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
if (ret < 0)
@@ -157,6 +159,8 @@ static int hi8435_write_event_config(struct iio_dev *idev,
} else
priv->event_scan_mask &= ~BIT(chan->channel);
 
+   mutex_unlock(>lock);
+
return 0;
 }
 
@@ -449,12 +453,16 @@ static irqreturn_t hi8435_trigger_handler(int irq, void 
*private)
u32 val;
int ret;
 
+   mutex_lock(>lock);
+
ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
if (ret < 0)
goto err_read;
 
hi8435_iio_push_event(idev, val);
 
+   mutex_unlock(>lock);
+
 err_read:
iio_trigger_notify_done(idev->trig);
 
-- 
2.11.0



Re: [PATCH 2/4] iio: hi8435: avoid garbage event at first enable

2017-05-23 Thread Nikita Yushchenko
>> +int ret;
>> +u32 tmp;
>> +
>> +if (state) {
>> +ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
>> +if (ret < 0)
>> +return ret;
>> +if (tmp & BIT(chan->channel))
>> +priv->event_prev_val |= BIT(chan->channel);
>> +else
>> +priv->event_prev_val &= ~BIT(chan->channel);
>>   -priv->event_scan_mask &= ~BIT(chan->channel);
>> -if (state)
>>   priv->event_scan_mask |= BIT(chan->channel);
>> +} else
>> +priv->event_scan_mask &= ~BIT(chan->channel);
>>   
> 
> This will race with hi8435_iio_push_event for priv->event_scan_mask.

I was under impression that mutual-exclusion is provided by core. Now I
see it is not. Will submit a fix soon.

> Since you adding raw access then it is reasonable to initialize
> priv->event_prev_val in hi8435_read_raw.

This will cause complex interdependency between events and raw access.
E.g. should we generate event if change was discovered while processing
raw access from user space?  If we do, then we break semantics "events
generated only under trigger".  If we don't, we need complex state handling.

> Then use the following sequence for your application:
> 1. read raw value
> 2. enable events

So what if:
- one application calls read raw,
- then, far later, signal changes,
- then, far later, other application enables events?

Should second application get notification of change that happened long
before in enabled events?  I think no.

There is fundamental race between start-of-monitoring and
change-of-signal-near-start-of-monitoring. To avoid it, reading signal
must be either atomic with start of monitoring (which is not possible
with IIO API), or done after start of monitoring (which moves handling
of this race to user side).

Nikita


Re: [PATCH 2/4] iio: hi8435: avoid garbage event at first enable

2017-05-23 Thread Nikita Yushchenko
>> +int ret;
>> +u32 tmp;
>> +
>> +if (state) {
>> +ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
>> +if (ret < 0)
>> +return ret;
>> +if (tmp & BIT(chan->channel))
>> +priv->event_prev_val |= BIT(chan->channel);
>> +else
>> +priv->event_prev_val &= ~BIT(chan->channel);
>>   -priv->event_scan_mask &= ~BIT(chan->channel);
>> -if (state)
>>   priv->event_scan_mask |= BIT(chan->channel);
>> +} else
>> +priv->event_scan_mask &= ~BIT(chan->channel);
>>   
> 
> This will race with hi8435_iio_push_event for priv->event_scan_mask.

I was under impression that mutual-exclusion is provided by core. Now I
see it is not. Will submit a fix soon.

> Since you adding raw access then it is reasonable to initialize
> priv->event_prev_val in hi8435_read_raw.

This will cause complex interdependency between events and raw access.
E.g. should we generate event if change was discovered while processing
raw access from user space?  If we do, then we break semantics "events
generated only under trigger".  If we don't, we need complex state handling.

> Then use the following sequence for your application:
> 1. read raw value
> 2. enable events

So what if:
- one application calls read raw,
- then, far later, signal changes,
- then, far later, other application enables events?

Should second application get notification of change that happened long
before in enabled events?  I think no.

There is fundamental race between start-of-monitoring and
change-of-signal-near-start-of-monitoring. To avoid it, reading signal
must be either atomic with start of monitoring (which is not possible
with IIO API), or done after start of monitoring (which moves handling
of this race to user side).

Nikita


Re: [PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-23 Thread Nikita Yushchenko
>> However, hi8435 driver historically was coded using inverted values
>> passed to gpiolib calls.  And there are setups in the wild with device
>> trees containing GPIO_ACTIVE_HIGH that I'd prefer not breaking.
>>
>> To solve, I submitted a patch on hi8435 driver that changes to _raw()
>> gpio calls (thus making it independent of what is written in device
>> tree), and want [future] device trees not to contain explicitly written
>> gpio polarity.
> 
> So maybe add another #define, GPIO_ACTIVE_IGNORED, to make it clear
> that it does not matter what value you put there, it is ignored.

"Crap origin" here is that in vast majority of cases, polarity is
per-chip, not per-chip-use, knowledge. And proper location for per-chip
knowledge is chip's driver.  Moving this knowledge to per-chip-use
location in device trees only provides a source for errors, with little
gain.

Vladimir Barinov mentions possibility that signal can be inverted by
board between gpio provider and chip's pin ...   but do we have at least
one practical case of this?  And if we even do, it's quite uncommon, and
something special should be required in device tree for these special
cases and not for "normal" cases.




Re: [PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-23 Thread Nikita Yushchenko
>> However, hi8435 driver historically was coded using inverted values
>> passed to gpiolib calls.  And there are setups in the wild with device
>> trees containing GPIO_ACTIVE_HIGH that I'd prefer not breaking.
>>
>> To solve, I submitted a patch on hi8435 driver that changes to _raw()
>> gpio calls (thus making it independent of what is written in device
>> tree), and want [future] device trees not to contain explicitly written
>> gpio polarity.
> 
> So maybe add another #define, GPIO_ACTIVE_IGNORED, to make it clear
> that it does not matter what value you put there, it is ignored.

"Crap origin" here is that in vast majority of cases, polarity is
per-chip, not per-chip-use, knowledge. And proper location for per-chip
knowledge is chip's driver.  Moving this knowledge to per-chip-use
location in device trees only provides a source for errors, with little
gain.

Vladimir Barinov mentions possibility that signal can be inverted by
board between gpio provider and chip's pin ...   but do we have at least
one practical case of this?  And if we even do, it's quite uncommon, and
something special should be required in device tree for these special
cases and not for "normal" cases.




Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-22 Thread Nikita Yushchenko
Hi,

 Alternative solution could be - have separate write path for earlycon.
>>>
>>> It looks to me having the same issue with a separate write patch
>>> for earlycon as we still need distinguish Little or Big endian
>>> for Layerscape and IMX.
>>>
 At a glance, it is dozen lines of code.
>>>
>>> Would you please show some sample code?
>>
>> Do not reuse lpuart32_console_putchar() in earlycon code.
>>
>> Have two sets of early_setup/early_write/putchar - for BE and
>> defaut-endian earlycon. And in these putchar's do not use
>> lpuart_(read|write).
>>
> 
> Isn't that introducing another consistency break after fix one
> consistency break?
> 
> If doing that, we then have two register read/write APIs.
> One for normal driver operation by dynamically checking lpuart_is_be
> property to distinguish the endian difference problem.
> Another is specifically implemented for only early console read/write
> and use hardcoded way to read/write register directly instead of using
> the standard API lpuart32_read/write, like follows:
> e.g.
> lpuart32_le_console_write() {
>writel();
> }
> 
> lpuart32_be_console_write() {
>iowrite32be()
> }
> This also makes the driver a bit strange and ugly.
> 
> It looks to me both way are trade offs and the later one seems sacrifice
> more. And i doubt if it's really necessary for probably a no real gain
> purpose as the FPGA you mentioned is a theoretical case and less
> possibility to exist.
> 
> I'm still wondering how about keep using the exist way and adding more
> information in code to explain why use a global var?

I've checked other driver under drivers/tty/serial/, for examples of
similar cases.

Please look at serial8250_early_in() / serial8250_early_out() ?
These do handle different endian, via port->iotype

Another example is drivers/tty/serial/samsung.c, where
port->private_data is initialized and used.

Nikita


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-22 Thread Nikita Yushchenko
Hi,

 Alternative solution could be - have separate write path for earlycon.
>>>
>>> It looks to me having the same issue with a separate write patch
>>> for earlycon as we still need distinguish Little or Big endian
>>> for Layerscape and IMX.
>>>
 At a glance, it is dozen lines of code.
>>>
>>> Would you please show some sample code?
>>
>> Do not reuse lpuart32_console_putchar() in earlycon code.
>>
>> Have two sets of early_setup/early_write/putchar - for BE and
>> defaut-endian earlycon. And in these putchar's do not use
>> lpuart_(read|write).
>>
> 
> Isn't that introducing another consistency break after fix one
> consistency break?
> 
> If doing that, we then have two register read/write APIs.
> One for normal driver operation by dynamically checking lpuart_is_be
> property to distinguish the endian difference problem.
> Another is specifically implemented for only early console read/write
> and use hardcoded way to read/write register directly instead of using
> the standard API lpuart32_read/write, like follows:
> e.g.
> lpuart32_le_console_write() {
>writel();
> }
> 
> lpuart32_be_console_write() {
>iowrite32be()
> }
> This also makes the driver a bit strange and ugly.
> 
> It looks to me both way are trade offs and the later one seems sacrifice
> more. And i doubt if it's really necessary for probably a no real gain
> purpose as the FPGA you mentioned is a theoretical case and less
> possibility to exist.
> 
> I'm still wondering how about keep using the exist way and adding more
> information in code to explain why use a global var?

I've checked other driver under drivers/tty/serial/, for examples of
similar cases.

Please look at serial8250_early_in() / serial8250_early_out() ?
These do handle different endian, via port->iotype

Another example is drivers/tty/serial/samsung.c, where
port->private_data is initialized and used.

Nikita


Re: [PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-22 Thread Nikita Yushchenko
>> +hi8435@1 {
>> +compatible = "holt,hi8435";
>> +reg = <1>;
>> +spi-max-frequency = <2000>;
>> +gpios = < 3 0>;
> 
> Nit: GPIO_ACTIVE_HIGH instead of 0?

Gray area here.

Chip's reset input is active LOW.

However, hi8435 driver historically was coded using inverted values
passed to gpiolib calls.  And there are setups in the wild with device
trees containing GPIO_ACTIVE_HIGH that I'd prefer not breaking.

To solve, I submitted a patch on hi8435 driver that changes to _raw()
gpio calls (thus making it independent of what is written in device
tree), and want [future] device trees not to contain explicitly written
gpio polarity.

Far not ideal but better than device trees explicitly stating
GPIO_ACTIVE_HIGH while it is active low.

Nikita


Re: [PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-22 Thread Nikita Yushchenko
>> +hi8435@1 {
>> +compatible = "holt,hi8435";
>> +reg = <1>;
>> +spi-max-frequency = <2000>;
>> +gpios = < 3 0>;
> 
> Nit: GPIO_ACTIVE_HIGH instead of 0?

Gray area here.

Chip's reset input is active LOW.

However, hi8435 driver historically was coded using inverted values
passed to gpiolib calls.  And there are setups in the wild with device
trees containing GPIO_ACTIVE_HIGH that I'd prefer not breaking.

To solve, I submitted a patch on hi8435 driver that changes to _raw()
gpio calls (thus making it independent of what is written in device
tree), and want [future] device trees not to contain explicitly written
gpio polarity.

Far not ideal but better than device trees explicitly stating
GPIO_ACTIVE_HIGH while it is active low.

Nikita


[PATCH] spi: spi-fsl-dspi: ensure non-zero return on error path

2017-05-22 Thread Nikita Yushchenko
Propagate error return from dspi_request_dma() into probe routine's
return.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/spi/spi-fsl-dspi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 15201645bdc4..d89127f4a46d 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -1032,7 +1032,8 @@ static int dspi_probe(struct platform_device *pdev)
goto out_master_put;
 
if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
-   if (dspi_request_dma(dspi, res->start)) {
+   ret = dspi_request_dma(dspi, res->start);
+   if (ret < 0) {
dev_err(>dev, "can't get dma channels\n");
goto out_clk_put;
}
-- 
2.11.0



[PATCH] spi: spi-fsl-dspi: ensure non-zero return on error path

2017-05-22 Thread Nikita Yushchenko
Propagate error return from dspi_request_dma() into probe routine's
return.

Signed-off-by: Nikita Yushchenko 
---
 drivers/spi/spi-fsl-dspi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 15201645bdc4..d89127f4a46d 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -1032,7 +1032,8 @@ static int dspi_probe(struct platform_device *pdev)
goto out_master_put;
 
if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
-   if (dspi_request_dma(dspi, res->start)) {
+   ret = dspi_request_dma(dspi, res->start);
+   if (ret < 0) {
dev_err(>dev, "can't get dma channels\n");
goto out_clk_put;
}
-- 
2.11.0



[PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-22 Thread Nikita Yushchenko
ZII dev board rev B has a Holt Hi8435 connected to dspi2.
Add it to device tree.

ZII dev board rev C does not have that, so use rev-b dts file,
not common dtsi file.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts 
b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
index 37f95427616f..f433465c3a7c 100644
--- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@ -348,6 +348,25 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+ {
+   bus-num = <1>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_dspi2>;
+   status = "okay";
+   spi-num-chipselects = <2>;
+
+   hi8435@1 {
+   compatible = "holt,hi8435";
+   reg = <1>;
+   spi-max-frequency = <2000>;
+   gpios = < 3 0>;
+   };
+};
+
  {
clock-frequency = <10>;
pinctrl-names = "default";
-- 
2.11.0



[PATCH] ARM: dts: vf610-zii-dev-rev-b: add hi8435 device

2017-05-22 Thread Nikita Yushchenko
ZII dev board rev B has a Holt Hi8435 connected to dspi2.
Add it to device tree.

ZII dev board rev C does not have that, so use rev-b dts file,
not common dtsi file.

Signed-off-by: Nikita Yushchenko 
---
 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts 
b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
index 37f95427616f..f433465c3a7c 100644
--- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@ -348,6 +348,25 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+ {
+   bus-num = <1>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_dspi2>;
+   status = "okay";
+   spi-num-chipselects = <2>;
+
+   hi8435@1 {
+   compatible = "holt,hi8435";
+   reg = <1>;
+   spi-max-frequency = <2000>;
+   gpios = < 3 0>;
+   };
+};
+
  {
clock-frequency = <10>;
pinctrl-names = "default";
-- 
2.11.0



[PATCH 2/4] iio: hi8435: avoid garbage event at first enable

2017-05-19 Thread Nikita Yushchenko
Currently, driver generates events for channels if new reading differs
from previous one. This "previous value" is initialized to zero, which
results into event if value is constant-one.

Fix that by initializing "previous value" by reading at event enable
time.

This provides reliable sequence for userspace:
- enable event,
- AFTER THAT read current value,
- AFTER THAT each event will correspond to change.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/iio/adc/hi8435.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index cb8e6342eddf..45a92e3e8f2b 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -141,10 +141,21 @@ static int hi8435_write_event_config(struct iio_dev *idev,
 enum iio_event_direction dir, int state)
 {
struct hi8435_priv *priv = iio_priv(idev);
+   int ret;
+   u32 tmp;
+
+   if (state) {
+   ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
+   if (ret < 0)
+   return ret;
+   if (tmp & BIT(chan->channel))
+   priv->event_prev_val |= BIT(chan->channel);
+   else
+   priv->event_prev_val &= ~BIT(chan->channel);
 
-   priv->event_scan_mask &= ~BIT(chan->channel);
-   if (state)
priv->event_scan_mask |= BIT(chan->channel);
+   } else
+   priv->event_scan_mask &= ~BIT(chan->channel);
 
return 0;
 }
-- 
2.11.0



[PATCH 2/4] iio: hi8435: avoid garbage event at first enable

2017-05-19 Thread Nikita Yushchenko
Currently, driver generates events for channels if new reading differs
from previous one. This "previous value" is initialized to zero, which
results into event if value is constant-one.

Fix that by initializing "previous value" by reading at event enable
time.

This provides reliable sequence for userspace:
- enable event,
- AFTER THAT read current value,
- AFTER THAT each event will correspond to change.

Signed-off-by: Nikita Yushchenko 
---
 drivers/iio/adc/hi8435.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index cb8e6342eddf..45a92e3e8f2b 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -141,10 +141,21 @@ static int hi8435_write_event_config(struct iio_dev *idev,
 enum iio_event_direction dir, int state)
 {
struct hi8435_priv *priv = iio_priv(idev);
+   int ret;
+   u32 tmp;
+
+   if (state) {
+   ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
+   if (ret < 0)
+   return ret;
+   if (tmp & BIT(chan->channel))
+   priv->event_prev_val |= BIT(chan->channel);
+   else
+   priv->event_prev_val &= ~BIT(chan->channel);
 
-   priv->event_scan_mask &= ~BIT(chan->channel);
-   if (state)
priv->event_scan_mask |= BIT(chan->channel);
+   } else
+   priv->event_scan_mask &= ~BIT(chan->channel);
 
return 0;
 }
-- 
2.11.0



[PATCH 3/4] iio: hi8435: make in_voltage_sensing_mode_available visible

2017-05-19 Thread Nikita Yushchenko
Possible values of sensing_mode are encoded with strings and actual
atrings used are not obvious.

Provide a hint by enabling in_voltage_sensing_mode_available attribute.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/iio/adc/hi8435.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index 45a92e3e8f2b..d09cb6ff8044 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -356,6 +356,7 @@ static const struct iio_enum hi8435_sensing_mode = {
 
 static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
IIO_ENUM("sensing_mode", IIO_SEPARATE, _sensing_mode),
+   IIO_ENUM_AVAILABLE("sensing_mode", _sensing_mode),
{},
 };
 
-- 
2.11.0



[PATCH 3/4] iio: hi8435: make in_voltage_sensing_mode_available visible

2017-05-19 Thread Nikita Yushchenko
Possible values of sensing_mode are encoded with strings and actual
atrings used are not obvious.

Provide a hint by enabling in_voltage_sensing_mode_available attribute.

Signed-off-by: Nikita Yushchenko 
---
 drivers/iio/adc/hi8435.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index 45a92e3e8f2b..d09cb6ff8044 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -356,6 +356,7 @@ static const struct iio_enum hi8435_sensing_mode = {
 
 static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
IIO_ENUM("sensing_mode", IIO_SEPARATE, _sensing_mode),
+   IIO_ENUM_AVAILABLE("sensing_mode", _sensing_mode),
{},
 };
 
-- 
2.11.0



[PATCH 1/4] iio: hi8435: add raw access

2017-05-19 Thread Nikita Yushchenko
With current event-only driver, it is not possible for user space
application to know current senses if they don't change since
application starts.

Address that by adding raw access to channels.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/iio/adc/hi8435.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index 678e8c7ea763..cb8e6342eddf 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -105,6 +105,26 @@ static int hi8435_writew(struct hi8435_priv *priv, u8 reg, 
u16 val)
return spi_write(priv->spi, priv->reg_buffer, 3);
 }
 
+static int hi8435_read_raw(struct iio_dev *idev,
+  const struct iio_chan_spec *chan,
+  int *val, int *val2, long mask)
+{
+   struct hi8435_priv *priv = iio_priv(idev);
+   u32 tmp;
+   int ret;
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
+   if (ret < 0)
+   return ret;
+   *val = !!(tmp & BIT(chan->channel));
+   return IIO_VAL_INT;
+   default:
+   return -EINVAL;
+   }
+}
+
 static int hi8435_read_event_config(struct iio_dev *idev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
@@ -333,6 +353,7 @@ static const struct iio_chan_spec_ext_info 
hi8435_ext_info[] = {
.type = IIO_VOLTAGE,\
.indexed = 1,   \
.channel = num, \
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
.event_spec = hi8435_events,\
.num_event_specs = ARRAY_SIZE(hi8435_events),   \
.ext_info = hi8435_ext_info,\
@@ -376,6 +397,7 @@ static const struct iio_chan_spec hi8435_channels[] = {
 
 static const struct iio_info hi8435_info = {
.driver_module = THIS_MODULE,
+   .read_raw = hi8435_read_raw,
.read_event_config = _read_event_config,
.write_event_config = hi8435_write_event_config,
.read_event_value = _read_event_value,
-- 
2.11.0



[PATCH 1/4] iio: hi8435: add raw access

2017-05-19 Thread Nikita Yushchenko
With current event-only driver, it is not possible for user space
application to know current senses if they don't change since
application starts.

Address that by adding raw access to channels.

Signed-off-by: Nikita Yushchenko 
---
 drivers/iio/adc/hi8435.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index 678e8c7ea763..cb8e6342eddf 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -105,6 +105,26 @@ static int hi8435_writew(struct hi8435_priv *priv, u8 reg, 
u16 val)
return spi_write(priv->spi, priv->reg_buffer, 3);
 }
 
+static int hi8435_read_raw(struct iio_dev *idev,
+  const struct iio_chan_spec *chan,
+  int *val, int *val2, long mask)
+{
+   struct hi8435_priv *priv = iio_priv(idev);
+   u32 tmp;
+   int ret;
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   ret = hi8435_readl(priv, HI8435_SO31_0_REG, );
+   if (ret < 0)
+   return ret;
+   *val = !!(tmp & BIT(chan->channel));
+   return IIO_VAL_INT;
+   default:
+   return -EINVAL;
+   }
+}
+
 static int hi8435_read_event_config(struct iio_dev *idev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
@@ -333,6 +353,7 @@ static const struct iio_chan_spec_ext_info 
hi8435_ext_info[] = {
.type = IIO_VOLTAGE,\
.indexed = 1,   \
.channel = num, \
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
.event_spec = hi8435_events,\
.num_event_specs = ARRAY_SIZE(hi8435_events),   \
.ext_info = hi8435_ext_info,\
@@ -376,6 +397,7 @@ static const struct iio_chan_spec hi8435_channels[] = {
 
 static const struct iio_info hi8435_info = {
.driver_module = THIS_MODULE,
+   .read_raw = hi8435_read_raw,
.read_event_config = _read_event_config,
.write_event_config = hi8435_write_event_config,
.read_event_value = _read_event_value,
-- 
2.11.0



[PATCH 4/4] iio: hi8435: cleanup reset gpio

2017-05-19 Thread Nikita Yushchenko
Reset GPIO is active low.

Currently driver uses gpiod_set_value(1) to clean reset, which depends
on device tree to contain GPIO_ACTIVE_HIGH - that does not match reality.

This fixes driver to use _raw version of gpiod_set_value() to enforce
active-low semantics despite of what's written in device tree. Allowing
device tree to override that only opens possibility for errors and does
not add any value.

Additionally, use _cansleep version to make things work with i2c-gpio
and other sleeping gpio drivers.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/iio/adc/hi8435.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index d09cb6ff8044..ab59969b7c49 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -476,13 +476,15 @@ static int hi8435_probe(struct spi_device *spi)
priv->spi = spi;
 
reset_gpio = devm_gpiod_get(>dev, NULL, GPIOD_OUT_LOW);
-   if (IS_ERR(reset_gpio)) {
-   /* chip s/w reset if h/w reset failed */
+   if (!IS_ERR(reset_gpio)) {
+   /* need >=100ns low pulse to reset chip */
+   gpiod_set_raw_value_cansleep(reset_gpio, 0);
+   udelay(1);
+   gpiod_set_raw_value_cansleep(reset_gpio, 1);
+   } else {
+   /* s/w reset chip if h/w reset is not available */
hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST);
hi8435_writeb(priv, HI8435_CTRL_REG, 0);
-   } else {
-   udelay(5);
-   gpiod_set_value(reset_gpio, 1);
}
 
spi_set_drvdata(spi, idev);
-- 
2.11.0



[PATCH 4/4] iio: hi8435: cleanup reset gpio

2017-05-19 Thread Nikita Yushchenko
Reset GPIO is active low.

Currently driver uses gpiod_set_value(1) to clean reset, which depends
on device tree to contain GPIO_ACTIVE_HIGH - that does not match reality.

This fixes driver to use _raw version of gpiod_set_value() to enforce
active-low semantics despite of what's written in device tree. Allowing
device tree to override that only opens possibility for errors and does
not add any value.

Additionally, use _cansleep version to make things work with i2c-gpio
and other sleeping gpio drivers.

Signed-off-by: Nikita Yushchenko 
---
 drivers/iio/adc/hi8435.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index d09cb6ff8044..ab59969b7c49 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -476,13 +476,15 @@ static int hi8435_probe(struct spi_device *spi)
priv->spi = spi;
 
reset_gpio = devm_gpiod_get(>dev, NULL, GPIOD_OUT_LOW);
-   if (IS_ERR(reset_gpio)) {
-   /* chip s/w reset if h/w reset failed */
+   if (!IS_ERR(reset_gpio)) {
+   /* need >=100ns low pulse to reset chip */
+   gpiod_set_raw_value_cansleep(reset_gpio, 0);
+   udelay(1);
+   gpiod_set_raw_value_cansleep(reset_gpio, 1);
+   } else {
+   /* s/w reset chip if h/w reset is not available */
hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST);
hi8435_writeb(priv, HI8435_CTRL_REG, 0);
-   } else {
-   udelay(5);
-   gpiod_set_value(reset_gpio, 1);
}
 
spi_set_drvdata(spi, idev);
-- 
2.11.0



Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-17 Thread Nikita Yushchenko
Hi

My view of your statement is:
- you currently assume only a few cases for this driver - builtin UART
in vf610, ls1012a and imx7,
- in each of these cases, all lpuart instances share same endian, thus
having that in global var works for these cases,
- having that in global var makes it possible for you to write less
lines of code

My complain is:
- in Linux, we are trying to keep drivers generic,
- in Linux, having less lines of code has never been sufficient to break
basic data structure consistency,
- having driver to keep per-device capability in global var is a clear
case of breaking consistency.


>>> That's for special case, normally we wouldn't do that.
>>
>> For me this "special case" looks like "let's break data structure
>> consistency to reuse several lines of code".
>>
>> With code snippets you show, it looks even worse: you assign same global
>> variable in several places for different uses. 
> 
> If you mean lpuart_is_be, it's not for different uses.
> The purpose is the same to align the correct endian but in two places.

_probe() routine called for device X alters state already in use for
device Y.

> 
>> implicitly assuming that
>> it is for same device. Which can be true in your current system, but not
>> elsewhere (e.g. why not having lpuart programmed into fpga)?
>>
> 
> Sorry, What issues for fpga?

Connect FPGA to IMX7 based system and program LS1012a version of lpuart
core into it.  Have your console on system UART broken at time when
driver gets registered.


> 
>> Alternative solution could be - have separate write path for earlycon.
> 
> It looks to me having the same issue with a separate write patch
> for earlycon as we still need distinguish Little or Big endian
> for Layerscape and IMX.
> 
>> At a glance, it is dozen lines of code.
> 
> Would you please show some sample code?

Do not reuse lpuart32_console_putchar() in earlycon code.

Have two sets of early_setup/early_write/putchar - for BE and
defaut-endian earlycon. And in these putchar's do not use
lpuart_(read|write).


As far as I can see, fsl_lpuart.c already has two drivers in one -
there is separate set of routines for 8bit and 32bit cases.
And those routines that are common, have if blocks that separate cases.
I think these drivers will be cleaner if separated.
However that's completely different story.


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-17 Thread Nikita Yushchenko
Hi

My view of your statement is:
- you currently assume only a few cases for this driver - builtin UART
in vf610, ls1012a and imx7,
- in each of these cases, all lpuart instances share same endian, thus
having that in global var works for these cases,
- having that in global var makes it possible for you to write less
lines of code

My complain is:
- in Linux, we are trying to keep drivers generic,
- in Linux, having less lines of code has never been sufficient to break
basic data structure consistency,
- having driver to keep per-device capability in global var is a clear
case of breaking consistency.


>>> That's for special case, normally we wouldn't do that.
>>
>> For me this "special case" looks like "let's break data structure
>> consistency to reuse several lines of code".
>>
>> With code snippets you show, it looks even worse: you assign same global
>> variable in several places for different uses. 
> 
> If you mean lpuart_is_be, it's not for different uses.
> The purpose is the same to align the correct endian but in two places.

_probe() routine called for device X alters state already in use for
device Y.

> 
>> implicitly assuming that
>> it is for same device. Which can be true in your current system, but not
>> elsewhere (e.g. why not having lpuart programmed into fpga)?
>>
> 
> Sorry, What issues for fpga?

Connect FPGA to IMX7 based system and program LS1012a version of lpuart
core into it.  Have your console on system UART broken at time when
driver gets registered.


> 
>> Alternative solution could be - have separate write path for earlycon.
> 
> It looks to me having the same issue with a separate write patch
> for earlycon as we still need distinguish Little or Big endian
> for Layerscape and IMX.
> 
>> At a glance, it is dozen lines of code.
> 
> Would you please show some sample code?

Do not reuse lpuart32_console_putchar() in earlycon code.

Have two sets of early_setup/early_write/putchar - for BE and
defaut-endian earlycon. And in these putchar's do not use
lpuart_(read|write).


As far as I can see, fsl_lpuart.c already has two drivers in one -
there is separate set of routines for 8bit and 32bit cases.
And those routines that are common, have if blocks that separate cases.
I think these drivers will be cleaner if separated.
However that's completely different story.


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-17 Thread Nikita Yushchenko
>> Code should be consistent.
>>
> 
> Yes.
> 
>> There is no good reason to have sport->lpuart32 inside sport, but
>> lpuart_is_be outside of it. Both these values describe properties of
>> particular device, and thus should be in per-device structure.
>>
> 
> That's for special case, normally we wouldn't do that.

For me this "special case" looks like "let's break data structure
consistency to reuse several lines of code".

With code snippets you show, it looks even worse: you assign same global
variable in several places for different uses. implicitly assuming that
it is for same device. Which can be true in your current system, but not
elsewhere (e.g. why not having lpuart programmed into fpga)?

Alternative solution could be - have separate write path for earlycon.
At a glance, it is dozen lines of code.


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-17 Thread Nikita Yushchenko
>> Code should be consistent.
>>
> 
> Yes.
> 
>> There is no good reason to have sport->lpuart32 inside sport, but
>> lpuart_is_be outside of it. Both these values describe properties of
>> particular device, and thus should be in per-device structure.
>>
> 
> That's for special case, normally we wouldn't do that.

For me this "special case" looks like "let's break data structure
consistency to reuse several lines of code".

With code snippets you show, it looks even worse: you assign same global
variable in several places for different uses. implicitly assuming that
it is for same device. Which can be true in your current system, but not
elsewhere (e.g. why not having lpuart programmed into fpga)?

Alternative solution could be - have separate write path for earlycon.
At a glance, it is dozen lines of code.


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko
>  static u32 lpuart32_read(void __iomem *addr)
>  {
> - return ioread32be(addr);
> + return lpuart_is_be ? ioread32be(addr) : readl(addr);
>  }
>  
>  static void lpuart32_write(u32 val, void __iomem *addr)
>  {
> - iowrite32be(val, addr);
> + if (lpuart_is_be)
> + iowrite32be(val, addr);
> + else
> + writel(val, addr);
>  }

 What if this is ever executed on big endian system?

>>>
>>> Sorry, not catching the point...
>>>
>>> What issues will meet?
>>
>> Isn't writel() in host endian?
> 
> On big endian systems, it is supposed to run iowrite32be.

Your code states, "force BE if lpuart_is_be, don't care otherwise".
This semantics looks questionable for code reviewer.
If driver handles endian, should't it be explicit in both cases?
And if indeed driver means handling BE explicitly, but don't caring
otherwise, maybe variable name should suggest that (i.e. "force_be")?

Although driver maintainer could think differently. I won't insist on this.

Nikita


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko
>  static u32 lpuart32_read(void __iomem *addr)
>  {
> - return ioread32be(addr);
> + return lpuart_is_be ? ioread32be(addr) : readl(addr);
>  }
>  
>  static void lpuart32_write(u32 val, void __iomem *addr)
>  {
> - iowrite32be(val, addr);
> + if (lpuart_is_be)
> + iowrite32be(val, addr);
> + else
> + writel(val, addr);
>  }

 What if this is ever executed on big endian system?

>>>
>>> Sorry, not catching the point...
>>>
>>> What issues will meet?
>>
>> Isn't writel() in host endian?
> 
> On big endian systems, it is supposed to run iowrite32be.

Your code states, "force BE if lpuart_is_be, don't care otherwise".
This semantics looks questionable for code reviewer.
If driver handles endian, should't it be explicit in both cases?
And if indeed driver means handling BE explicitly, but don't caring
otherwise, maybe variable name should suggest that (i.e. "force_be")?

Although driver maintainer could think differently. I won't insist on this.

Nikita


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko
>>> @@ -2000,6 +2007,7 @@ static int lpuart_probe(struct platform_device *pdev)
>>> }
>>> sport->port.line = ret;
>>> sport->lpuart32 = sdata->is_32;
>>> +   lpuart_is_be = sdata->is_be;
>>
>> Setting a global variable in per-device routine is quite bad design.
>>
> 
> There is a reason for that we don't want to change the exist 
> lpuart32_read[write] API which is widely used in driver.
> Making a global lpuart_is_be is the simplest way to do it.
> 
> Any strong blocking reason?

Code should be consistent.

There is no good reason to have sport->lpuart32 inside sport, but
lpuart_is_be outside of it. Both these values describe properties of
particular device, and thus should be in per-device structure.

If that implies adding sport arg to lpuart32_(read|write), just do that.


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko
>>> @@ -2000,6 +2007,7 @@ static int lpuart_probe(struct platform_device *pdev)
>>> }
>>> sport->port.line = ret;
>>> sport->lpuart32 = sdata->is_32;
>>> +   lpuart_is_be = sdata->is_be;
>>
>> Setting a global variable in per-device routine is quite bad design.
>>
> 
> There is a reason for that we don't want to change the exist 
> lpuart32_read[write] API which is widely used in driver.
> Making a global lpuart_is_be is the simplest way to do it.
> 
> Any strong blocking reason?

Code should be consistent.

There is no good reason to have sport->lpuart32 inside sport, but
lpuart_is_be outside of it. Both these values describe properties of
particular device, and thus should be in per-device structure.

If that implies adding sport arg to lpuart32_(read|write), just do that.


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko


17.05.2017 06:39, Dong Aisheng wrote:
> On Tue, May 16, 2017 at 02:15:08PM +0300, Nikita Yushchenko wrote:
>>>  static u32 lpuart32_read(void __iomem *addr)
>>>  {
>>> -   return ioread32be(addr);
>>> +   return lpuart_is_be ? ioread32be(addr) : readl(addr);
>>>  }
>>>  
>>>  static void lpuart32_write(u32 val, void __iomem *addr)
>>>  {
>>> -   iowrite32be(val, addr);
>>> +   if (lpuart_is_be)
>>> +   iowrite32be(val, addr);
>>> +   else
>>> +   writel(val, addr);
>>>  }
>>
>> What if this is ever executed on big endian system?
>>
> 
> Sorry, not catching the point...
> 
> What issues will meet?

Isn't writel() in host endian?


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko


17.05.2017 06:39, Dong Aisheng wrote:
> On Tue, May 16, 2017 at 02:15:08PM +0300, Nikita Yushchenko wrote:
>>>  static u32 lpuart32_read(void __iomem *addr)
>>>  {
>>> -   return ioread32be(addr);
>>> +   return lpuart_is_be ? ioread32be(addr) : readl(addr);
>>>  }
>>>  
>>>  static void lpuart32_write(u32 val, void __iomem *addr)
>>>  {
>>> -   iowrite32be(val, addr);
>>> +   if (lpuart_is_be)
>>> +   iowrite32be(val, addr);
>>> +   else
>>> +   writel(val, addr);
>>>  }
>>
>> What if this is ever executed on big endian system?
>>
> 
> Sorry, not catching the point...
> 
> What issues will meet?

Isn't writel() in host endian?


Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko
>  static u32 lpuart32_read(void __iomem *addr)
>  {
> - return ioread32be(addr);
> + return lpuart_is_be ? ioread32be(addr) : readl(addr);
>  }
>  
>  static void lpuart32_write(u32 val, void __iomem *addr)
>  {
> - iowrite32be(val, addr);
> + if (lpuart_is_be)
> + iowrite32be(val, addr);
> + else
> + writel(val, addr);
>  }

What if this is ever executed on big endian system?



Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko
>  static u32 lpuart32_read(void __iomem *addr)
>  {
> - return ioread32be(addr);
> + return lpuart_is_be ? ioread32be(addr) : readl(addr);
>  }
>  
>  static void lpuart32_write(u32 val, void __iomem *addr)
>  {
> - iowrite32be(val, addr);
> + if (lpuart_is_be)
> + iowrite32be(val, addr);
> + else
> + writel(val, addr);
>  }

What if this is ever executed on big endian system?



Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko
> @@ -2000,6 +2007,7 @@ static int lpuart_probe(struct platform_device *pdev)
>   }
>   sport->port.line = ret;
>   sport->lpuart32 = sdata->is_32;
> + lpuart_is_be = sdata->is_be;

Setting a global variable in per-device routine is quite bad design.



Re: [V2, 2/6] tty: serial: lpuart: add little endian 32 bit register support

2017-05-16 Thread Nikita Yushchenko
> @@ -2000,6 +2007,7 @@ static int lpuart_probe(struct platform_device *pdev)
>   }
>   sport->port.line = ret;
>   sport->lpuart32 = sdata->is_32;
> + lpuart_is_be = sdata->is_be;

Setting a global variable in per-device routine is quite bad design.



Re: [PATCH] pinctrl: when claiming hog, skip maps not served by same device

2017-05-12 Thread Nikita Yushchenko
>> +/*
>> + * If pctldev is not null, we are claiming hog for it,
>> + * that means, setting that is served by pctldev by itself.
>> + *
>> + * Thus we must skip map that is for this device but is served
>> + * by other device.
>> + */
>> +if (pctldev &&
>> +strcmp(dev_name(pctldev->dev), map->ctrl_dev_name))
>> +continue;
>>  
>>  ret = add_setting(p, pctldev, map);
>>  /*
>> -- 
> 
> Maybe add a comment saying pctldev is NULL in the regular case
> and only exists in the hog case?

Isn't comment above saying exactly that?


Re: [PATCH] pinctrl: when claiming hog, skip maps not served by same device

2017-05-12 Thread Nikita Yushchenko
>> +/*
>> + * If pctldev is not null, we are claiming hog for it,
>> + * that means, setting that is served by pctldev by itself.
>> + *
>> + * Thus we must skip map that is for this device but is served
>> + * by other device.
>> + */
>> +if (pctldev &&
>> +strcmp(dev_name(pctldev->dev), map->ctrl_dev_name))
>> +continue;
>>  
>>  ret = add_setting(p, pctldev, map);
>>  /*
>> -- 
> 
> Maybe add a comment saying pctldev is NULL in the regular case
> and only exists in the hog case?

Isn't comment above saying exactly that?


[PATCH] pinctrl: when claiming hog, skip maps not served by same device

2017-05-11 Thread Nikita Yushchenko
When pinctrl device registers, it automatically claims hogs, that is,
maps that pinctrl device serves for itself.

It is possible that in addition to SoC's pinctrl device, other pinctrl
devices get registered. E.g. some gpio expander devies are registered
as pinctrl devices. For such devices, pinctrl maps could be defined
that set up SoC's pins (e.g. interrupt pin for gpio expander). Such
a map will have target device set to gpio expander.

Here is device tree snippet that causes this scenario:

 {
sx1503@20 {
compatible = "semtech,sx1503q";
pinctrl-names = "default";
pinctrl-0 = <_sx1503_20>;
...
};
};
...
 {
pinctrl_sx1503_20: pinctrl-sx1503-20 {
fsl,pins = <
VF610_PAD_PTB1__GPIO_23 0x219d
>;
};
};

Such a map will have target device set to gpio expander. However is not
a hog, it is a regular map that is claimed by core before gpio expander
device is probed.

Thus when looking for hogs, it is not enough to check that map's target
device is set to pinctrl device being registered. Need also check that
map's control device is also set to the same.

Signed-off-by: Nikita Yushchenko <nikita.yo...@cogentembedded.com>
---
 drivers/pinctrl/core.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 1653cbda6a82..682ebd360030 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -1038,6 +1038,16 @@ static struct pinctrl *create_pinctrl(struct device *dev,
/* Map must be for this device */
if (strcmp(map->dev_name, devname))
continue;
+   /*
+* If pctldev is not null, we are claiming hog for it,
+* that means, setting that is served by pctldev by itself.
+*
+* Thus we must skip map that is for this device but is served
+* by other device.
+*/
+   if (pctldev &&
+   strcmp(dev_name(pctldev->dev), map->ctrl_dev_name))
+   continue;
 
ret = add_setting(p, pctldev, map);
/*
-- 
2.11.0



[PATCH] pinctrl: when claiming hog, skip maps not served by same device

2017-05-11 Thread Nikita Yushchenko
When pinctrl device registers, it automatically claims hogs, that is,
maps that pinctrl device serves for itself.

It is possible that in addition to SoC's pinctrl device, other pinctrl
devices get registered. E.g. some gpio expander devies are registered
as pinctrl devices. For such devices, pinctrl maps could be defined
that set up SoC's pins (e.g. interrupt pin for gpio expander). Such
a map will have target device set to gpio expander.

Here is device tree snippet that causes this scenario:

 {
sx1503@20 {
compatible = "semtech,sx1503q";
pinctrl-names = "default";
pinctrl-0 = <_sx1503_20>;
...
};
};
...
 {
pinctrl_sx1503_20: pinctrl-sx1503-20 {
fsl,pins = <
VF610_PAD_PTB1__GPIO_23 0x219d
>;
};
};

Such a map will have target device set to gpio expander. However is not
a hog, it is a regular map that is claimed by core before gpio expander
device is probed.

Thus when looking for hogs, it is not enough to check that map's target
device is set to pinctrl device being registered. Need also check that
map's control device is also set to the same.

Signed-off-by: Nikita Yushchenko 
---
 drivers/pinctrl/core.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 1653cbda6a82..682ebd360030 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -1038,6 +1038,16 @@ static struct pinctrl *create_pinctrl(struct device *dev,
/* Map must be for this device */
if (strcmp(map->dev_name, devname))
continue;
+   /*
+* If pctldev is not null, we are claiming hog for it,
+* that means, setting that is served by pctldev by itself.
+*
+* Thus we must skip map that is for this device but is served
+* by other device.
+*/
+   if (pctldev &&
+   strcmp(dev_name(pctldev->dev), map->ctrl_dev_name))
+   continue;
 
ret = add_setting(p, pctldev, map);
/*
-- 
2.11.0



Re: pinctrl-sx150x.c broken in 4.11

2017-05-11 Thread Nikita Yushchenko
>>> Maybe create_pinctrl() could check if the pin controller device
>>> for a potential hog points to the device itself and bail out
>>> if that's not the case?
>>
>> Well that's exactly what patch from my first mail in this thread does.
>> This indeed fixes my case, but I don't know if it is correct in generic
>> case.
> 
> OK, yeah I just looked it up as I was not in cc.
> 
>> Should I submit it? Do you ack?
> 
> Yeah please submit a proper patch. I assume you already checked
> that this change only affects the pinctrl hogs only, not regular
> device pins? I'd assume so as it's in create_pinctrl()..

Regular device pins go via pinctrl_get() which calls create_pinctrl()
with second argument set to NULL.


Re: pinctrl-sx150x.c broken in 4.11

2017-05-11 Thread Nikita Yushchenko
>>> Maybe create_pinctrl() could check if the pin controller device
>>> for a potential hog points to the device itself and bail out
>>> if that's not the case?
>>
>> Well that's exactly what patch from my first mail in this thread does.
>> This indeed fixes my case, but I don't know if it is correct in generic
>> case.
> 
> OK, yeah I just looked it up as I was not in cc.
> 
>> Should I submit it? Do you ack?
> 
> Yeah please submit a proper patch. I assume you already checked
> that this change only affects the pinctrl hogs only, not regular
> device pins? I'd assume so as it's in create_pinctrl()..

Regular device pins go via pinctrl_get() which calls create_pinctrl()
with second argument set to NULL.


Re: pinctrl-sx150x.c broken in 4.11

2017-05-11 Thread Nikita Yushchenko
>>> Hmm maybe yeah. I don't quite follow the above the "pinctrl-0 property
>>> of sx150x device tree node, is misinterpreted as hog" part though.
>>
>> sx150x is i2c-gpio device.  It has 16 GPIO lines that are communicated
>> with via i2c bus, and an interrupt line.
>>
>> Interrupt line is typically connected to SoC's pin.
>> This pin has to be configured.
>> This is done by providing appropriate subnode in SoC's pinmux node, with
>> information with pin configuration, and pinctrl-0 property in sx150x's
>> node with phandle to that subnode:
>>
>> ...
>>  {
>>  sx1503@20 {
>>  compatible = "semtech,sx1503q";
>>  pinctrl-names = "default";
>>  pinctrl-0 = <_sx1503_20>;
>>  ...
>>  };
>> };
>> ...
>>  {
>>  pinctrl_sx1503_20: pinctrl-sx1503-20 {
>>  fsl,pins = <
>>  VF610_PAD_PTB1__GPIO_23 0x219d
>>  >;
>>  };
>> };
>>
>> This pin configuration is handled by driver core, i.e. before probe()
>> for sx150x is called, core applies pin configuration.
>>
>> However sx150x driver is currently implemented as a pinctrl driver.
>>
>> When it initializes, pinctrl searches for "hog", i.e. pin config that
>> should be applied at driver registration time.
>>
>> While doing so, core searches for any registered pinctrl_map for device
>> being register. Search loop is in create_pinctrl().
>>
>> In this case, this loop finds map that is defined above.
>>
>> This is *not* hog.  This is pin setting already applied in SoC's pinmux
>> controller for sx1503 device.
>>
>> However code in create_pinctrl() tries to apply it, and use sx1503's
>> methods to do so. Which is plain wrong and errors out.
> 
> Maybe create_pinctrl() could check if the pin controller device
> for a potential hog points to the device itself and bail out
> if that's not the case?

Well that's exactly what patch from my first mail in this thread does.
This indeed fixes my case, but I don't know if it is correct in generic
case.

Should I submit it? Do you ack?

Nikita


  1   2   3   4   >