Re: [PATCH 12/32] MAINTAINERS: update lego,ev3-battery.yaml reference

2021-04-01 Thread David Lechner

On 4/1/21 7:17 AM, Mauro Carvalho Chehab wrote:

Changeset 3004e581d92a ("dt-bindings: power: supply: lego-ev3-battery: Convert to DT 
schema format")
renamed: Documentation/devicetree/bindings/power/supply/lego_ev3_battery.txt
to: Documentation/devicetree/bindings/power/supply/lego,ev3-battery.yaml.

Update its cross-reference accordingly.

Fixes: 3004e581d92a ("dt-bindings: power: supply: lego-ev3-battery: Convert to DT 
schema format")
Signed-off-by: Mauro Carvalho Chehab 
---


Reviewed-by: David Lechner 



Re: [PATCH v3 0/1] drm/tiny: add support for Waveshare 2inch LCD module

2021-03-30 Thread David Lechner

On 3/30/21 3:08 AM, Carlis wrote:

From: Xuezhi Zhang 

This adds a new module for the ST7789V controller with parameters for
the Waveshare 2inch LCD module.

Signed-off-by: Xuezhi Zhang 
---
v2:change compatible value.
v3:change author name.
---
  MAINTAINERS|   8 +
  drivers/gpu/drm/tiny/Kconfig   |  14 ++
  drivers/gpu/drm/tiny/Makefile  |   1 +
  drivers/gpu/drm/tiny/st7789v.c | 269 +
  4 files changed, 292 insertions(+)
  create mode 100644 drivers/gpu/drm/tiny/st7789v.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d92f85ca831d..df25e8e0deb1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5769,6 +5769,14 @@ T:   git git://anongit.freedesktop.org/drm/drm-misc
  F:Documentation/devicetree/bindings/display/sitronix,st7735r.yaml
  F:drivers/gpu/drm/tiny/st7735r.c
  
+DRM DRIVER FOR SITRONIX ST7789V PANELS

+M: David Lechner 


I should not be added here. I don't have one of these displays.


+M: Xuezhi Zhang 
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml
+F: drivers/gpu/drm/tiny/st7789v.c
+
  DRM DRIVER FOR SONY ACX424AKP PANELS
  M:Linus Walleij 
  S:Maintained


Re: [PATCHv2 19/38] dt-bindings: power: supply: lego-ev3-battery: Convert to DT schema format

2021-03-23 Thread David Lechner

On 3/17/21 8:48 AM, Sebastian Reichel wrote:

Convert the binding to DT schema format.

Cc: David Lechner 
Signed-off-by: Sebastian Reichel 
---


Reviewed-by: David Lechner 



Re: [PATCH 19/38] dt-bindings: power: supply: lego-ev3-battery: Convert to DT schema format

2021-03-12 Thread David Lechner

On 3/12/21 9:43 AM, Sebastian Reichel wrote:

Convert the binding to DT schema format.

Cc: David Lechner 
Signed-off-by: Sebastian Reichel 
---


Reviewed-by: David Lechner 


Re: [PATCH v8 20/22] counter: Implement events_queue_size sysfs attribute

2021-02-26 Thread David Lechner

On 2/25/21 6:03 PM, William Breathitt Gray wrote:

On Sun, Feb 21, 2021 at 03:51:40PM +, Jonathan Cameron wrote:

On Thu, 18 Feb 2021 19:32:16 +0900
William Breathitt Gray  wrote:


On Sun, Feb 14, 2021 at 06:11:46PM +, Jonathan Cameron wrote:

On Fri, 12 Feb 2021 21:13:44 +0900
William Breathitt Gray  wrote:
   

The events_queue_size sysfs attribute provides a way for users to
dynamically configure the Counter events queue size for the Counter
character device interface. The size is in number of struct
counter_event data structures. The number of elements will be rounded-up
to a power of 2 due to a requirement of the kfifo_alloc function called
during reallocation of the queue.

Cc: Oleksij Rempel 
Signed-off-by: William Breathitt Gray 
---
  Documentation/ABI/testing/sysfs-bus-counter |  8 +++
  drivers/counter/counter-chrdev.c| 23 +++
  drivers/counter/counter-chrdev.h|  2 ++
  drivers/counter/counter-sysfs.c | 25 +
  4 files changed, 58 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter 
b/Documentation/ABI/testing/sysfs-bus-counter
index 847e96f19d19..f6cb2a8b08a7 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -212,6 +212,14 @@ Description:
both edges:
Any state transition.
  
+What:		/sys/bus/counter/devices/counterX/events_queue_size

+KernelVersion: 5.13
+Contact:   linux-...@vger.kernel.org
+Description:
+   Size of the Counter events queue in number of struct
+   counter_event data structures. The number of elements will be
+   rounded-up to a power of 2.
+
  What: /sys/bus/counter/devices/counterX/name
  KernelVersion:5.2
  Contact:  linux-...@vger.kernel.org
diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c
index 16f02df7f73d..53eea894e13f 100644
--- a/drivers/counter/counter-chrdev.c
+++ b/drivers/counter/counter-chrdev.c
@@ -375,6 +375,29 @@ void counter_chrdev_remove(struct counter_device *const 
counter)
cdev_del(>chrdev);
  }
  
+int counter_chrdev_realloc_queue(struct counter_device *const counter,

+size_t queue_size)
+{
+   int err;
+   DECLARE_KFIFO_PTR(events, struct counter_event);
+   unsigned long flags;
+
+   /* Allocate new events queue */
+   err = kfifo_alloc(, queue_size, GFP_ATOMIC);


Is there any potential for losing events?


We take the events_list_lock down below so we're safe against missing an
event, but past events currently unread in the queue will be lost.

Shortening the size of the queue is inherently a destructive process if
we have more events in the current queue than can fit in the new queue.
Because we a liable to lose some events in such a case, I think it's
best to keep the behavior of this reallocation consistent and have it
provide a fresh empty queue every time, as opposed to sometimes dropping
events and sometimes not.

I also suspect an actual user would be setting the size of their queue
to the required amount before they begin watching events, rather than
adjusting it sporadically during a live operation.



Absolutely agree.   As such I wonder if you are better off enforcing this
behaviour?  If the cdev is open for reading, don't allow the fifo to be
resized.

Jonathan


I can't really think of a good reason not to, so let's enforce it: if
the cdev is open, then we'll return an EINVAL if the user attempts to
resize the queue.

What is a good way to check for this condition? Should I just call
kref_read() and see if it's greater than 1? For example, in
counter_chrdev_realloc_queue():

if (kref_read(>dev.kobj.kref) > 1)
return -EINVAL;

William Breathitt Gray



Wouldn't EBUSY make more sense?


Re: [PATCH v8 16/22] counter: Move counter enums to uapi header

2021-02-20 Thread David Lechner

On 2/12/21 6:13 AM, William Breathitt Gray wrote:

This is in preparation for a subsequent patch implementing a character
device interface for the Counter subsystem.

Signed-off-by: William Breathitt Gray 
---


Reviewed-by: David Lechner 




Re: [PATCH v8 13/22] counter: Internalize sysfs interface code

2021-02-20 Thread David Lechner

On 2/12/21 6:13 AM, William Breathitt Gray wrote:

This is a reimplementation of the Generic Counter driver interface.
There are no modifications to the Counter subsystem userspace interface,
so existing userspace applications should continue to run seamlessly.

The purpose of this patch is to internalize the sysfs interface code
among the various counter drivers into a shared module. Counter drivers
pass and take data natively (i.e. u8, u64, etc.) and the shared counter
module handles the translation between the sysfs interface and the
device drivers. This guarantees a standard userspace interface for all
counter drivers, and helps generalize the Generic Counter driver ABI in
order to support the Generic Counter chrdev interface (introduced in a
subsequent patch) without significant changes to the existing counter
drivers.

Note, Counter device registration is the same as before: drivers
populate a struct counter_device with components and callbacks, then
pass the structure to the devm_counter_register function. However,
what's different now is how the Counter subsystem code handles this
registration internally.

Whereas before callbacks would interact directly with sysfs data, this
interaction is now abstracted and instead callbacks interact with native
C data types. The counter_comp structure forms the basis for Counter
extensions.

The counter-sysfs.c file contains the code to parse through the
counter_device structure and register the requested components and
extensions. Attributes are created and populated based on type, with
respective translation functions to handle the mapping between sysfs and
the counter driver callbacks.

The translation performed for each attribute is straightforward: the
attribute type and data is parsed from the counter_attribute structure,
the respective counter driver read/write callback is called, and sysfs
I/O is handled before or after the driver read/write function is called.

Cc: Syed Nayyar Waris 
Cc: Patrick Havelange 
Cc: Kamel Bouhara 
Cc: Fabrice Gasnier 
Cc: Maxime Coquelin 
Cc: Alexandre Torgue 
Cc: David Lechner 
Cc: Dan Carpenter 
Signed-off-by: William Breathitt Gray 
---


For TI eQEP bits...

Reviewed-by: David Lechner 
Tested-by: David Lechner 


Re: [PATCH v8 12/22] counter: Rename counter_count_function to counter_function

2021-02-20 Thread David Lechner

On 2/14/21 11:13 AM, Jonathan Cameron wrote:

On Fri, 12 Feb 2021 21:13:36 +0900
William Breathitt Gray  wrote:


The phrase "Counter Count function" is verbose and unintentionally
implies that function is a Count extension. This patch adjusts the
Counter subsystem code to use the more direct "Counter function" phrase
to make the intent of this code clearer. The phrase "Count action" is
adjusted herein as well for the same reason.

Cc: Syed Nayyar Waris 
Cc: Patrick Havelange 
Cc: Kamel Bouhara 
Cc: Fabrice Gasnier 
Cc: Maxime Coquelin 
Cc: Alexandre Torgue 
Cc: David Lechner 
Signed-off-by: William Breathitt Gray 


I agree this makes sense in the counter core code, but in the drivers
it may not be quite so obvious we are talking about a counter function
given some of the bits of hardware do a number of other things.

I guess up to the various driver maintainers on whether they
think the new meaning is clear enough!

Jonathan



TBH, I think "counter count function" makes more sense to me.



Re: [PATCH v8 11/22] counter: Rename counter_signal_value to counter_signal_level

2021-02-20 Thread David Lechner

On 2/12/21 6:13 AM, William Breathitt Gray wrote:

Signal values will always be levels so let's be explicit it about it to
make the intent of the code clear.

Cc: Syed Nayyar Waris 
Cc: Kamel Bouhara 
Signed-off-by: William Breathitt Gray 
---


Reviewed-by: David Lechner 




Re: [PATCH v8 10/22] counter: Standardize to ERANGE for limit exceeded errors

2021-02-20 Thread David Lechner

On 2/12/21 6:13 AM, William Breathitt Gray wrote:

ERANGE is a semantically better error code to return when an argument
value falls outside the supported limit range of a device.

Cc: Syed Nayyar Waris 
Cc: Fabrice Gasnier 
Cc: Maxime Coquelin 
Cc: Alexandre Torgue 
Signed-off-by: William Breathitt Gray 
---


Reviewed-by: David Lechner 

(I agree with William's assessment that this use of ERANGE
is consistent with other uses in the kernel.)




Re: [PATCH v8 09/22] counter: Return error code on invalid modes

2021-02-20 Thread David Lechner

On 2/12/21 6:13 AM, William Breathitt Gray wrote:

Only a select set of modes (function, action, etc.) are valid for a
given device configuration. This patch ensures that invalid modes result
in a return -EINVAL. Such a situation should never occur in reality, but
it's good to define a default switch cases for the sake of making the
intent of the code clear.

Cc: Syed Nayyar Waris 
Cc: Kamel Bouhara 
Cc: Fabrice Gasnier 
Cc: Maxime Coquelin 
Cc: Alexandre Torgue 
Cc: David Lechner 
Signed-off-by: William Breathitt Gray 
---


Reviewed-by: David Lechner 

(In response to Jonathan's comment, I think this is fine rather than
adding more churn to change all of the breaks to returns - but will
keep that in mind for future changes.)



Re: [PATCH v8 03/22] counter: 104-quad-8: Return error when invalid mode during ceiling_write

2021-02-20 Thread David Lechner

On 2/12/21 6:13 AM, William Breathitt Gray wrote:

The 104-QUAD-8 only has two count modes where a ceiling value makes
sense: Range Limit and Modulo-N. Outside of these two modes, setting a
ceiling value is an invalid operation -- so let's report it as such by
returning -EINVAL.

Fixes: fc069262261c ("counter: 104-quad-8: Add lock guards - generic interface")
Cc: Syed Nayyar Waris 
Signed-off-by: William Breathitt Gray 
---
  drivers/counter/104-quad-8.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index 9691f8612be8..f0608b21196a 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -714,13 +714,14 @@ static ssize_t quad8_count_ceiling_write(struct 
counter_device *counter,
switch (priv->count_mode[count->id]) {
case 1:
case 3:
+   mutex_unlock(>lock);
quad8_preset_register_set(priv, count->id, ceiling);
-   break;
+   return len;
}
  
  	mutex_unlock(>lock);
  
-	return len;

+   return -EINVAL;
  }
  
  static ssize_t quad8_count_preset_enable_read(struct counter_device *counter,




What happens if the register is written to when in the wrong mode?

If it doesn't hurt anything, I would suggest always writing the register
instead so that users don't have to know worry about the fact that the mode
has to be set first.


Re: [PATCH v8 02/22] docs: counter: Fix spelling

2021-02-20 Thread David Lechner

On 2/12/21 6:13 AM, William Breathitt Gray wrote:

"Miscellaneous" is the correct spelling.

Signed-off-by: William Breathitt Gray 
---


Reviewed-by: David Lechner 



Re: [PATCH v8 01/22] docs: counter: Consolidate Counter sysfs attributes documentation

2021-02-20 Thread David Lechner

On 2/12/21 6:13 AM, William Breathitt Gray wrote:

Duplicate ABIs are not valid, so let's consolidate these sysfs
attributes into the main sysfs-bus-counter documentation file.

Cc: Patrick Havelange 
Signed-off-by: William Breathitt Gray 
---


Reviewed-by: David Lechner 



Re: [PATCH v7 5/5] counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8

2021-02-11 Thread David Lechner

On 2/11/21 5:56 PM, William Breathitt Gray wrote:

On Wed, Dec 30, 2020 at 11:36:45AM -0600, David Lechner wrote:

On 12/25/20 6:15 PM, William Breathitt Gray wrote:


diff --git a/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8 
b/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8
index eac32180c40d..0ecba24d43aa 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8
+++ b/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8
@@ -1,3 +1,28 @@
+What:  /sys/bus/counter/devices/counterX/countY/irq_trigger


Do we really need this sysfs attribute? Shouldn't interrupts be configured
_only_ by the chrdev interface?


I think this attribute can go away because we can implicitly figure out
the correct IRQ configuration from the struct counter_watch data when a
user executes a COUNTER_ADD_WATCH_IOCTL ioctl command.

However, I need some help deciding on an appropriate behavior for
conflicting counter_watch configurations. Let me give some context
first.

The 104-QUAD-8 features 8 channels (essentially 8 independent physical
counters on the device). Each channel can independently issue an event,
but any particular channel can only be set to a single kind of event
(COUNTER_EVENT_INDEX, COUNTER_EVENT_OVERFLOW, etc.).

The purpose of the irq_trigger sysfs attribute I introduced in this
patch is to allow the user to select the event configuration they want
for a particular channel. We can theoretically figure this out
implicitly from the struct counter_watch request, so this sysfs
attribute may not be necessary.

However, how do we handle the case where a user executes two
COUNTER_ADD_WATCH_IOCTL ioctl commands for the same channel but with
different event selections? I'm considering three possible behaviors:

* Fail the second ioctl call; event selection of the first struct
   counter_watch takes precedence and thus second is incompatible.
* Issue a dev_warn() indicating that the second struct counter_watch
   event selection will now be the event configuration for that channel.
* Don't notify the user, just silently reconfigure for the second struct
   counter_watch event selection.

I'm suspecting the first behavior I listed here (ioctl returning failed)
is the most appropriate as a user is explicitly made known of this
particular device's inability to support more than one type of event per
channel.

What do you think?



I agree that it should return an error instead of adding the watch.
I'm pretty sure that is how I implemented the TI eQEP driver already.



Re: [PATCH] remoteproc: pru: future-proof PRU ID matching

2021-01-28 Thread David Lechner

On 1/28/21 4:55 PM, Suman Anna wrote:

Hi David,

On 1/15/21 6:53 PM, Suman Anna wrote:

On 1/4/21 3:18 PM, David Lechner wrote:

  static int pru_rproc_probe(struct platform_device *pdev)
@@ -825,20 +808,28 @@ static int pru_rproc_remove(struct platform_device *pdev)
  
  static const struct pru_private_data pru_data = {

.type = PRU_TYPE_PRU,
+   .pru0_iram_offset = 0x4000,
+   .pru1_iram_offset = 0x8000,


The offsets for the PRU cores are actually 0x34000 and 0x38000 respectively from
the base of the PRUSS on non-Davinci SoCs.

If we were to use this static data approach, then we might as well continue to
use the current address masking logic with the appropriate masks for Davinci
(0x38000 and 0x3C000, not true offsets but as masks they would work). Davinci
PRUSS is the only one with its differences being the first PRUSS IP, and I would
prefer to keep the logic aligned to the IPs on all the recent SoCs on 3
different TI SoC families (OMAP, Keystone 2 and K3).

Let me know what you think.


I'm not too picky as long as it works. :-)

If keeping the static data to a minimum is really important, I suppose we could
introduce a new type = PRU_TYPE_PRU_V1 for these PRUSSs instead. It sounds like
this information might be useful elsewhere anyway.


Re: [PATCH 1/2] dt-bindings: soc: ti: ti,pruss: add ti,am1806-pruss

2021-01-16 Thread David Lechner

On 1/15/21 10:45 AM, Suman Anna wrote:

+ Sekhar and Bartosz

Hi David,

On 1/4/21 12:30 PM, David Lechner wrote:

This adds a "ti,am1806-pruss" compatible type for the PRUSS found in
TI AM18xx/OMAP-L138 SoCs.

Signed-off-by: David Lechner 
---
  Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml 
b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
index 037c51b2f972..a6ed23fdbc00 100644
--- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
+++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
@@ -61,6 +61,7 @@ properties:
  
compatible:

  enum:
+  - ti,am1806-pruss  # for AM18xx/OMAP-L138 SoC family


Almost all the drivers for these SoCs use the prefix "ti,da850-xxx" for the
compatibles. Can we switch to using those instead of ti,am1806?


I wasn't sure which chips exactly are "DA850". If someone can tell
me, I can look at the docs to see if they have a PRUSS.


Re: [PATCH 2/2] soc: ti: pruss: add support for AM18XX/OMAP-L138 PRUSS

2021-01-16 Thread David Lechner

On 1/15/21 6:52 PM, Suman Anna wrote:

Hi David,

On 1/4/21 12:30 PM, David Lechner wrote:

This adds support for the PRUSS found in AM18XX/OMAP-L138. This PRUSS
doesn't have a CFG register, so that is made optional as selected by
the device tree compatible string.

ARCH_DAVINCI is added in the Kconfig so that the driver can be selected
on that platform.

Signed-off-by: David Lechner 
---
  drivers/soc/ti/Kconfig |  2 +-
  drivers/soc/ti/pruss.c | 76 --
  2 files changed, 45 insertions(+), 33 deletions(-)

diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index 7e2fb1c16af1..7a692a21480a 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -85,7 +85,7 @@ config TI_K3_SOCINFO
  
  config TI_PRUSS

tristate "TI PRU-ICSS Subsystem Platform drivers"
-   depends on SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || ARCH_KEYSTONE || 
ARCH_K3
+   depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || 
ARCH_KEYSTONE || ARCH_K3
select MFD_SYSCON
help
  TI PRU-ICSS Subsystem platform specific support.
diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
index 5d6e7132a5c4..bfaf3ff74b01 100644
--- a/drivers/soc/ti/pruss.c
+++ b/drivers/soc/ti/pruss.c
@@ -24,10 +24,12 @@
   * struct pruss_private_data - PRUSS driver private data
   * @has_no_sharedram: flag to indicate the absence of PRUSS Shared Data RAM
   * @has_core_mux_clock: flag to indicate the presence of PRUSS core clock
+ * @has_cfg: flag to indicate the presence of PRUSS CFG registers


I recommend to change this to a negative flag as the Davinci platforms are the
only ones that don't have CFG (being the very first SoCs with a PRUSS IP)
sub-module.


Negative flags hurt my brain. :-)

I was actually thinking about submitting a patch to convert
has_no_sharedram to a positive flag as well. But I understand
the sentiment of only setting the flag true for the odd case
rather than the usual case.




   */
  struct pruss_private_data {
bool has_no_sharedram;
bool has_core_mux_clock;
+   bool has_cfg;
  };
  
  static void pruss_of_free_clk_provider(void *data)

@@ -239,42 +241,44 @@ static int pruss_probe(struct platform_device *pdev)
goto rpm_disable;
}
  


And use it here to skip all the cfg code parsing. All the below delta is just
for the additional indentation for the flag. If you don't like goto's in
non-error paths, then we can refactor the CFG parse code into a separate 
function.



Refactoring to a separate function sounds good to me.


Re: [PATCH] clocksource: davinci: move pr_fmt() before the includes

2021-01-11 Thread David Lechner

On 1/11/21 8:08 AM, Bartosz Golaszewski wrote:

From: Bartosz Golaszewski 

We no longer need to undef pr_fmt if we define our own before including
any headers.

Signed-off-by: Bartosz Golaszewski 
---


Acked-by: David Lechner 



Re: [PATCH] irqchip: Simplify the TI_PRUSS_INTC Kconfig

2021-01-08 Thread David Lechner

On 1/8/21 10:29 AM, Suman Anna wrote:

The TI PRUSS INTC irqchip driver handles the local interrupt controller
which is a child device of it's parent PRUSS/ICSSG device. The driver
was upstreamed in parallel with the PRUSS platform driver, and was
configurable independently previously. The PRUSS interrupt controller
is an integral part of the overall PRUSS software architecture, and is
not useful at all by itself.

Simplify the TI_PRUSS_INTC Kconfig dependencies by making it silent and
selected automatically when the TI_PRUSS platform driver is enabled.

Signed-off-by: Suman Anna 
---


Reviewed-by: David Lechner 



Re: [PATCH] irqchip/irq-pruss-intc: implement set_type() callback

2021-01-05 Thread David Lechner

On 1/5/21 2:47 AM, Marc Zyngier wrote:

On 2021-01-04 18:36, David Lechner wrote:

This implements the irqchip set_type() callback for the TI PRUSS
interrupt controller. This is needed for cases where an event needs
to be active low.

According to the technical reference manual, the polarity should always
be set to high, however in practice, the polarity needs to be set low
for the McASP Tx/Rx system event in conjunction with soft UART PRU
firmware for TI AM18XX SoCs, otherwise it doesn't work.


I remember asking about this when I reviewed the patch series, and
was told that there was no need to handle anything *but* level high.
As a consequence, the DT binding doesn't have any way to express
the trigger configuration.

Now this? What is going to drive the configuration?


I made it work by setting IRQF_TRIGGER_LOW in devm_request_irq().

I can try to see if there is a way to change the (10 year old)
firmware instead.

Hopefully someone from TI can shed more light on the subject?





Signed-off-by: David Lechner 
---
 drivers/irqchip/irq-pruss-intc.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
index 5409016e6ca0..f882af8a7ded 100644
--- a/drivers/irqchip/irq-pruss-intc.c
+++ b/drivers/irqchip/irq-pruss-intc.c
@@ -334,6 +334,32 @@ static void pruss_intc_irq_unmask(struct irq_data *data)
 pruss_intc_write_reg(intc, PRU_INTC_EISR, hwirq);
 }

+static int pruss_intc_irq_set_type(struct irq_data *data, unsigned int type)
+{
+    struct pruss_intc *intc = irq_data_get_irq_chip_data(data);
+    u32 reg, bit, val;
+
+    if (type & IRQ_TYPE_LEVEL_MASK) {
+    /* polarity register */
+    reg = PRU_INTC_SIPR(data->hwirq / 32);
+    bit = BIT(data->hwirq % 32);
+    val = pruss_intc_read_reg(intc, reg);
+
+    /*
+ * This check also ensures that IRQ_TYPE_DEFAULT will result
+ * in setting the level to high.
+ */
+    if (type & IRQ_TYPE_LEVEL_HIGH)
+    val |= bit;
+    else
+    val &= ~bit;
+
+    pruss_intc_write_reg(intc, reg, val);


RMW  of a shared register without locking?


+    }
+
+    return 0;


What happens when this is passed an edge configuration? It should at
least return an error.


This is probably a moot point if we are not going to allow
changing the type, but there is another register for selecting
edge or level. But the manual says similarly says it should
always be set to level.




+}
+
 static int pruss_intc_irq_reqres(struct irq_data *data)
 {
 if (!try_module_get(THIS_MODULE))
@@ -389,6 +415,7 @@ static struct irq_chip pruss_irqchip = {
 .irq_ack    = pruss_intc_irq_ack,
 .irq_mask    = pruss_intc_irq_mask,
 .irq_unmask    = pruss_intc_irq_unmask,
+    .irq_set_type    = pruss_intc_irq_set_type,
 .irq_request_resources    = pruss_intc_irq_reqres,
 .irq_release_resources    = pruss_intc_irq_relres,
 .irq_get_irqchip_state    = pruss_intc_irq_get_irqchip_state,


Thanks,

     M.




[PATCH] remoteproc: pru: future-proof PRU ID matching

2021-01-04 Thread David Lechner
Currently, to determine the ID (0 or 1) of a PRU core, the last 19 bits
of the physical address of the cores IRAM are compared to known values.
However, the PRUs on TI AM18XX have IRAM at 0x01c38000 and 0x01c3c000
respectively. The former conflicts with PRU1_IRAM_ADDR_MASK which could
cause PRU0 to be detected as PRU1. (The latter also conflicts with
TX_PRU1_IRAM_ADDR_MASK but it would still be correctly detected as
PRU1.)

This fixes the problem by moving the address matching offset values to
the device-specific data. This way the compatible string does half of
the work of narrowing down the addresses to two possibilities instead
of checking the address against all possible PRU types. This also lets
us narrow down the scope of the match from 19 bits to 16 bits for all
PRU types.

After this, the TI AM18XX PRUs will be able to be added without running
into the problems stated above.

We can also drop the local ret variable while touching this code.

Signed-off-by: David Lechner 
---
 drivers/remoteproc/pru_rproc.c | 49 ++
 1 file changed, 20 insertions(+), 29 deletions(-)

diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
index 2667919d76b3..94ce48df2f48 100644
--- a/drivers/remoteproc/pru_rproc.c
+++ b/drivers/remoteproc/pru_rproc.c
@@ -46,15 +46,6 @@
 #define PRU_DEBUG_GPREG(x) (0x + (x) * 4)
 #define PRU_DEBUG_CT_REG(x)(0x0080 + (x) * 4)
 
-/* PRU/RTU/Tx_PRU Core IRAM address masks */
-#define PRU_IRAM_ADDR_MASK 0x3
-#define PRU0_IRAM_ADDR_MASK0x34000
-#define PRU1_IRAM_ADDR_MASK0x38000
-#define RTU0_IRAM_ADDR_MASK0x4000
-#define RTU1_IRAM_ADDR_MASK0x6000
-#define TX_PRU0_IRAM_ADDR_MASK 0xa000
-#define TX_PRU1_IRAM_ADDR_MASK 0xc000
-
 /* PRU device addresses for various type of PRU RAMs */
 #define PRU_IRAM_DA0   /* Instruction RAM */
 #define PRU_PDRAM_DA   0   /* Primary Data RAM */
@@ -96,10 +87,14 @@ enum pru_type {
 /**
  * struct pru_private_data - device data for a PRU core
  * @type: type of the PRU core (PRU, RTU, Tx_PRU)
+ * @pru0_iram_offset: used to identify PRU core 0
+ * @pru1_iram_offset: used to identify PRU core 1
  * @is_k3: flag used to identify the need for special load handling
  */
 struct pru_private_data {
enum pru_type type;
+   u16 pru0_iram_offset;
+   u16 pru1_iram_offset;
unsigned int is_k3 : 1;
 };
 
@@ -693,33 +688,21 @@ static int pru_rproc_parse_fw(struct rproc *rproc, const 
struct firmware *fw)
 }
 
 /*
- * Compute PRU id based on the IRAM addresses. The PRU IRAMs are
+ * Compute PRU id based on the last 16 bits of IRAM addresses. The PRU IRAMs 
are
  * always at a particular offset within the PRUSS address space.
  */
 static int pru_rproc_set_id(struct pru_rproc *pru)
 {
-   int ret = 0;
-
-   switch (pru->mem_regions[PRU_IOMEM_IRAM].pa & PRU_IRAM_ADDR_MASK) {
-   case TX_PRU0_IRAM_ADDR_MASK:
-   fallthrough;
-   case RTU0_IRAM_ADDR_MASK:
-   fallthrough;
-   case PRU0_IRAM_ADDR_MASK:
+   u16 offset = pru->mem_regions[PRU_IOMEM_IRAM].pa;
+
+   if (offset == pru->data->pru0_iram_offset)
pru->id = 0;
-   break;
-   case TX_PRU1_IRAM_ADDR_MASK:
-   fallthrough;
-   case RTU1_IRAM_ADDR_MASK:
-   fallthrough;
-   case PRU1_IRAM_ADDR_MASK:
+   else if (offset == pru->data->pru1_iram_offset)
pru->id = 1;
-   break;
-   default:
-   ret = -EINVAL;
-   }
+   else
+   return -EINVAL;
 
-   return ret;
+   return 0;
 }
 
 static int pru_rproc_probe(struct platform_device *pdev)
@@ -825,20 +808,28 @@ static int pru_rproc_remove(struct platform_device *pdev)
 
 static const struct pru_private_data pru_data = {
.type = PRU_TYPE_PRU,
+   .pru0_iram_offset = 0x4000,
+   .pru1_iram_offset = 0x8000,
 };
 
 static const struct pru_private_data k3_pru_data = {
.type = PRU_TYPE_PRU,
+   .pru0_iram_offset = 0x4000,
+   .pru1_iram_offset = 0x8000,
.is_k3 = 1,
 };
 
 static const struct pru_private_data k3_rtu_data = {
.type = PRU_TYPE_RTU,
+   .pru0_iram_offset = 0x4000,
+   .pru1_iram_offset = 0x6000,
.is_k3 = 1,
 };
 
 static const struct pru_private_data k3_tx_pru_data = {
.type = PRU_TYPE_TX_PRU,
+   .pru0_iram_offset = 0xa000,
+   .pru1_iram_offset = 0xc000,
.is_k3 = 1,
 };
 
-- 
2.25.1



Re: [PATCH v2 2/5] remoteproc: pru: Add APIs to get and put the PRU cores

2021-01-04 Thread David Lechner





@@ -706,14 +824,14 @@ static int pru_rproc_set_id(struct pru_rproc *pru)
case RTU0_IRAM_ADDR_MASK:
fallthrough;
case PRU0_IRAM_ADDR_MASK:
-   pru->id = 0;
+   pru->id = PRUSS_PRU0;
break;
case TX_PRU1_IRAM_ADDR_MASK:
fallthrough;
case RTU1_IRAM_ADDR_MASK:
fallthrough;
case PRU1_IRAM_ADDR_MASK:
-   pru->id = 1;
+   pru->id = PRUSS_PRU1;
break;
default:
ret = -EINVAL;




There is a similar opportunity for using PRUSS_PRU1 in pru_d_da_to_va()


Re: [PATCH v2 0/5] Introduce PRU remoteproc consumer API

2021-01-04 Thread David Lechner




Please see the individual patches for exact changes in each patch, following is
the only change from v1:
 - Change the 'prus' property name to 'ti,prus' as suggested by Rob Herring,
 which influences patch #1 and patch #2


It looks like "soc: ti: pruss: Add pruss_{request, release}_mem_region() API"
was also dropped in v2. Was this intentional?


Re: [PATCH 1/5] dt-bindings: remoteproc: Add PRU consumer bindings

2021-01-04 Thread David Lechner




Also, I think you can get rid of 'ti,pruss-gp-mux-sel'. Can't it just
be an arg cell in 'ti,prus' entries?

Rob


+1 for using cells instead of a separate property.

FYI, we will have a similar issue with the PRUSSEVTSEL signal for the
interrupt controller on the AM18XX. I am still of the opinion (described
in more detail at [1]) that using a cell for this makes for both better
device tree bindings and easier driver implementation. So I am interested
to see what the resolution is here.

[1]: 
https://patchwork.kernel.org/project/linux-arm-kernel/patch/20190708035243.12170-5-s-a...@ti.com/


[PATCH] irqchip/irq-pruss-intc: implement set_type() callback

2021-01-04 Thread David Lechner
This implements the irqchip set_type() callback for the TI PRUSS
interrupt controller. This is needed for cases where an event needs
to be active low.

According to the technical reference manual, the polarity should always
be set to high, however in practice, the polarity needs to be set low
for the McASP Tx/Rx system event in conjunction with soft UART PRU
firmware for TI AM18XX SoCs, otherwise it doesn't work.

Signed-off-by: David Lechner 
---
 drivers/irqchip/irq-pruss-intc.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
index 5409016e6ca0..f882af8a7ded 100644
--- a/drivers/irqchip/irq-pruss-intc.c
+++ b/drivers/irqchip/irq-pruss-intc.c
@@ -334,6 +334,32 @@ static void pruss_intc_irq_unmask(struct irq_data *data)
pruss_intc_write_reg(intc, PRU_INTC_EISR, hwirq);
 }
 
+static int pruss_intc_irq_set_type(struct irq_data *data, unsigned int type)
+{
+   struct pruss_intc *intc = irq_data_get_irq_chip_data(data);
+   u32 reg, bit, val;
+
+   if (type & IRQ_TYPE_LEVEL_MASK) {
+   /* polarity register */
+   reg = PRU_INTC_SIPR(data->hwirq / 32);
+   bit = BIT(data->hwirq % 32);
+   val = pruss_intc_read_reg(intc, reg);
+
+   /*
+* This check also ensures that IRQ_TYPE_DEFAULT will result
+* in setting the level to high.
+*/
+   if (type & IRQ_TYPE_LEVEL_HIGH)
+   val |= bit;
+   else
+   val &= ~bit;
+
+   pruss_intc_write_reg(intc, reg, val);
+   }
+
+   return 0;
+}
+
 static int pruss_intc_irq_reqres(struct irq_data *data)
 {
if (!try_module_get(THIS_MODULE))
@@ -389,6 +415,7 @@ static struct irq_chip pruss_irqchip = {
.irq_ack= pruss_intc_irq_ack,
.irq_mask   = pruss_intc_irq_mask,
.irq_unmask = pruss_intc_irq_unmask,
+   .irq_set_type   = pruss_intc_irq_set_type,
.irq_request_resources  = pruss_intc_irq_reqres,
.irq_release_resources  = pruss_intc_irq_relres,
.irq_get_irqchip_state  = pruss_intc_irq_get_irqchip_state,
-- 
2.25.1



[PATCH 2/2] soc: ti: pruss: add support for AM18XX/OMAP-L138 PRUSS

2021-01-04 Thread David Lechner
This adds support for the PRUSS found in AM18XX/OMAP-L138. This PRUSS
doesn't have a CFG register, so that is made optional as selected by
the device tree compatible string.

ARCH_DAVINCI is added in the Kconfig so that the driver can be selected
on that platform.

Signed-off-by: David Lechner 
---
 drivers/soc/ti/Kconfig |  2 +-
 drivers/soc/ti/pruss.c | 76 --
 2 files changed, 45 insertions(+), 33 deletions(-)

diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index 7e2fb1c16af1..7a692a21480a 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -85,7 +85,7 @@ config TI_K3_SOCINFO
 
 config TI_PRUSS
tristate "TI PRU-ICSS Subsystem Platform drivers"
-   depends on SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || ARCH_KEYSTONE || 
ARCH_K3
+   depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || 
ARCH_KEYSTONE || ARCH_K3
select MFD_SYSCON
help
  TI PRU-ICSS Subsystem platform specific support.
diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
index 5d6e7132a5c4..bfaf3ff74b01 100644
--- a/drivers/soc/ti/pruss.c
+++ b/drivers/soc/ti/pruss.c
@@ -24,10 +24,12 @@
  * struct pruss_private_data - PRUSS driver private data
  * @has_no_sharedram: flag to indicate the absence of PRUSS Shared Data RAM
  * @has_core_mux_clock: flag to indicate the presence of PRUSS core clock
+ * @has_cfg: flag to indicate the presence of PRUSS CFG registers
  */
 struct pruss_private_data {
bool has_no_sharedram;
bool has_core_mux_clock;
+   bool has_cfg;
 };
 
 static void pruss_of_free_clk_provider(void *data)
@@ -239,42 +241,44 @@ static int pruss_probe(struct platform_device *pdev)
goto rpm_disable;
}
 
-   child = of_get_child_by_name(np, "cfg");
-   if (!child) {
-   dev_err(dev, "%pOF is missing its 'cfg' node\n", child);
-   ret = -ENODEV;
-   goto rpm_put;
-   }
+   if (data->has_cfg) {
+   child = of_get_child_by_name(np, "cfg");
+   if (!child) {
+   dev_err(dev, "%pOF is missing its 'cfg' node\n", child);
+   ret = -ENODEV;
+   goto rpm_put;
+   }
 
-   if (of_address_to_resource(child, 0, )) {
-   ret = -ENOMEM;
-   goto node_put;
-   }
+   if (of_address_to_resource(child, 0, )) {
+   ret = -ENOMEM;
+   goto node_put;
+   }
 
-   pruss->cfg_base = devm_ioremap(dev, res.start, resource_size());
-   if (!pruss->cfg_base) {
-   ret = -ENOMEM;
-   goto node_put;
-   }
+   pruss->cfg_base = devm_ioremap(dev, res.start, 
resource_size());
+   if (!pruss->cfg_base) {
+   ret = -ENOMEM;
+   goto node_put;
+   }
 
-   regmap_conf.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", child,
-(u64)res.start);
-   regmap_conf.max_register = resource_size() - 4;
-
-   pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base,
- _conf);
-   kfree(regmap_conf.name);
-   if (IS_ERR(pruss->cfg_regmap)) {
-   dev_err(dev, "regmap_init_mmio failed for cfg, ret = %ld\n",
-   PTR_ERR(pruss->cfg_regmap));
-   ret = PTR_ERR(pruss->cfg_regmap);
-   goto node_put;
-   }
+   regmap_conf.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", child,
+(u64)res.start);
+   regmap_conf.max_register = resource_size() - 4;
+
+   pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base,
+ _conf);
+   kfree(regmap_conf.name);
+   if (IS_ERR(pruss->cfg_regmap)) {
+   dev_err(dev, "regmap_init_mmio failed for cfg, ret = 
%ld\n",
+   PTR_ERR(pruss->cfg_regmap));
+   ret = PTR_ERR(pruss->cfg_regmap);
+   goto node_put;
+   }
 
-   ret = pruss_clk_init(pruss, child);
-   if (ret) {
-   dev_err(dev, "failed to setup coreclk-mux\n");
-   goto node_put;
+   ret = pruss_clk_init(pruss, child);
+   if (ret) {
+   dev_err(dev, "failed to setup coreclk-mux\n");
+   goto node_put;
+   }
}
 
ret = devm_of_platform_populate(dev);
@@ -309,19 +313,27 @@ static int pruss_remove(struct platform_device *pdev)
 }
 
 /* instance-specific driver private data */
+stat

[PATCH 0/2] Add support for TI AM18XX/OMAP-L138 PRUSS

2021-01-04 Thread David Lechner
This is the first step for adding support for the PRUSS on TI AM18XX/OMAP-L138
SoCs. This series adds support in the top-level PRUSS driver. (Patches for the
interrupt controller and individual PRUs are independent of this change and
will be submitted separately.)

David Lechner (2):
  dt-bindings: soc: ti: ti,pruss: add ti,am1806-pruss
  soc: ti: pruss: add support for AM18XX/OMAP-L138 PRUSS

 .../devicetree/bindings/soc/ti/ti,pruss.yaml  |  2 +
 drivers/soc/ti/Kconfig|  2 +-
 drivers/soc/ti/pruss.c| 76 +++
 3 files changed, 47 insertions(+), 33 deletions(-)

-- 
2.25.1



[PATCH 1/2] dt-bindings: soc: ti: ti,pruss: add ti,am1806-pruss

2021-01-04 Thread David Lechner
This adds a "ti,am1806-pruss" compatible type for the PRUSS found in
TI AM18xx/OMAP-L138 SoCs.

Signed-off-by: David Lechner 
---
 Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml 
b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
index 037c51b2f972..a6ed23fdbc00 100644
--- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
+++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
@@ -61,6 +61,7 @@ properties:
 
   compatible:
 enum:
+  - ti,am1806-pruss  # for AM18xx/OMAP-L138 SoC family
   - ti,am3356-pruss  # for AM335x SoC family
   - ti,am4376-pruss0 # for AM437x SoC family and PRUSS unit 0
   - ti,am4376-pruss1 # for AM437x SoC family and PRUSS unit 1
@@ -321,6 +322,7 @@ if:
 compatible:
   contains:
 enum:
+  - ti,am1806-pruss
   - ti,k2g-pruss
   - ti,am654-icssg
   - ti,j721e-icssg
-- 
2.25.1



[PATCH] ARM: dts: da850: add MMD SDIO interrupts

2020-12-31 Thread David Lechner
This adds the MMC SDIO interrupts to the MMC nodes in the device tree
for TI DA850/AM18XX/OMAP-L138.

The missing interrupts were causing the following error message to be
printed:

davinci_mmc 1c4.mmc: IRQ index 1 not found

Signed-off-by: David Lechner 
---
 arch/arm/boot/dts/da850.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 7cf31b6e48b7..d2c609e4da5b 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -537,7 +537,7 @@ mmc0: mmc@4 {
reg = <0x4 0x1000>;
cap-sd-highspeed;
cap-mmc-highspeed;
-   interrupts = <16>;
+   interrupts = <16>, <17>;
dmas = < 16 0>, < 17 0>;
dma-names = "rx", "tx";
clocks = < 5>;
@@ -567,7 +567,7 @@ mmc1: mmc@21b000 {
reg = <0x21b000 0x1000>;
cap-sd-highspeed;
cap-mmc-highspeed;
-   interrupts = <72>;
+   interrupts = <72>, <73>;
dmas = < 28 0>, < 29 0>;
dma-names = "rx", "tx";
clocks = < 18>;
-- 
2.25.1



Re: [PATCH v7 0/5] Introduce the Counter character device interface

2020-12-30 Thread David Lechner

On 12/25/20 6:15 PM, William Breathitt Gray wrote:

Changes in v7:
  - Implemented u32 enums; enum types can now be used directly for
callbacks and values
  - Fixed refcount underflow bug
  - Refactored all err check to check for err < 0; this should help
prevent future oversights on valid positive return valids
  - Use mutex instead of raw_spin_lock in counter_chrdev_read();
kifo_to_user() can now safely sleep
  - Renamed COUNTER_COMPONENT_DUMMY to COUNTER_COMPONENT_NONE to make
purpose more obvious
  - Introduced a watch_validate() callback
  - Consolidated the functionality to clear the watches to the
counter_clear_watches() function
  - Reimplemented counter_push_event() as a void function; on error,
errno is returned via struct counter_event so that it can be handled
by userspace (because interrupt handlers can't do much for this)
  - Renamed the events_config() callback to events_configure();
"events_config" could be confused as a read callback when this is
actually intended to configure the device for the requested events
  - Reimplemented 104-QUAD-8 driver to use events_configure() and
watch_validate() callbacks; irq_trigger_enable sysfs attribute
removed because events_configure() now serves this purpose

The changes for this revision were much simpler compared to the previous
revisions. I don't have any further questions for this patchset, so it's
really just a search for possible bugs or regressions now. Please test
and verify this patchset on your systems, and ACK appropriately.



I'll wait for the next round to give my Reviewed-By, Tested-By but I've
rebased my WIP TI eQEP changes[1] on this and I haven't ran into any
problems yet.

[1]: https://github.com/dlech/linux/commits/bone-counter



Re: [PATCH v7 1/5] counter: Internalize sysfs interface code

2020-12-30 Thread David Lechner

On 12/25/20 6:15 PM, William Breathitt Gray wrote:


diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index a60aee1a1a29..6c058b93dc98 100644
--- a/drivers/counter/ti-eqep.c
+++ b/drivers/counter/ti-eqep.c




-static ssize_t ti_eqep_position_floor_write(struct counter_device *counter,
-   struct counter_count *count,
-   void *ext_priv, const char *buf,
-   size_t len)
+static int ti_eqep_position_floor_write(struct counter_device *counter,
+   struct counter_count *count, u64 floor)
  {
struct ti_eqep_cnt *priv = counter->priv;
-   int err;
-   u32 res;
  
-	err = kstrtouint(buf, 0, );

-   if (err < 0)
-   return err;
+   if (floor != (u32)floor)
+   return -ERANGE;
  
-	regmap_write(priv->regmap32, QPOSINIT, res);

+   regmap_write(priv->regmap32, QPOSINIT, floor);
  
-	return len;

+   return 0;
  }


This will conflict with 2ba7b50893de "counter:ti-eqep: remove floor"
(in Jonathan's fixes-togreg branch) which removes these functions.




Re: [PATCH v7 3/5] counter: Add character device interface

2020-12-30 Thread David Lechner

On 12/25/20 6:15 PM, William Breathitt Gray wrote:


diff --git a/include/uapi/linux/counter.h b/include/uapi/linux/counter.h
new file mode 100644
index ..7585dc9db19d
--- /dev/null
+++ b/include/uapi/linux/counter.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Userspace ABI for Counter character devices
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#ifndef _UAPI_COUNTER_H_
+#define _UAPI_COUNTER_H_
+
+#include 
+#include 
+
+/* Component type definitions */
+enum counter_component_type {
+   COUNTER_COMPONENT_NONE,
+   COUNTER_COMPONENT_SIGNAL,
+   COUNTER_COMPONENT_COUNT,
+   COUNTER_COMPONENT_FUNCTION,
+   COUNTER_COMPONENT_SYNAPSE_ACTION,
+   COUNTER_COMPONENT_EXTENSION,
+};
+
+/* Component scope definitions */
+enum counter_scope {


Do we need COUNTER_SCOPE_NONE to go with COUNTER_COMPONENT_NONE?


+   COUNTER_SCOPE_DEVICE,
+   COUNTER_SCOPE_SIGNAL,
+   COUNTER_SCOPE_COUNT,
+};
+
+/**
+ * struct counter_component - Counter component identification
+ * @type: component type (Count, extension, etc.)


Instead of "Count, extension, etc.", it could be more helpful
to say one of enum counter_component_type.


+ * @scope: component scope (Device, Count, or Signal)


Same here. @scope must be one of enum counter_scope.


+ * @parent: parent component identification number
+ * @id: component identification number


It could be helpful to say that these id numbers match
the X/Y/Z in the sysfs paths as described in the sysfs
ABI.


+ */
+struct counter_component {
+   __u8 type;
+   __u8 scope;
+   __u8 parent;
+   __u8 id;
+};
+
+/* Event type definitions */
+enum counter_event_type {
+   COUNTER_EVENT_OVERFLOW,
+   COUNTER_EVENT_UNDERFLOW,
+   COUNTER_EVENT_OVERFLOW_UNDERFLOW,
+   COUNTER_EVENT_THRESHOLD,
+   COUNTER_EVENT_INDEX,
+};
+
+/**
+ * struct counter_watch - Counter component watch configuration
+ * @component: component to watch when event triggers
+ * @event: event that triggers


It would be helpful to say that @event must be one of
enum counter_event_type.


+ * @channel: event channel


It would be useful to say that @channel should be 0 unless
a component has more than one event of the same type.


+ */
+struct counter_watch {
+   struct counter_component component;
+   __u8 event;
+   __u8 channel;
+};
+
+/* ioctl commands */
+#define COUNTER_CLEAR_WATCHES_IOCTL _IO(0x3E, 0x00)
+#define COUNTER_ADD_WATCH_IOCTL _IOW(0x3E, 0x01, struct counter_watch)
+#define COUNTER_LOAD_WATCHES_IOCTL _IO(0x3E, 0x02)
+
+/**
+ * struct counter_event - Counter event data
+ * @timestamp: best estimate of time of event occurrence, in nanoseconds
+ * @value: component value
+ * @watch: component watch configuration
+ * @errno: system error number
+ */
+struct counter_event {
+   __aligned_u64 timestamp;
+   __aligned_u64 value;
+   struct counter_watch watch;
+   __u8 errno;


There are error codes larger than 255. Probably better
make this __u32.


+};
+
+/* Count direction values */
+enum counter_count_direction {
+   COUNTER_COUNT_DIRECTION_FORWARD,
+   COUNTER_COUNT_DIRECTION_BACKWARD,
+};
+
+/* Count mode values */
+enum counter_count_mode {
+   COUNTER_COUNT_MODE_NORMAL,
+   COUNTER_COUNT_MODE_RANGE_LIMIT,
+   COUNTER_COUNT_MODE_NON_RECYCLE,
+   COUNTER_COUNT_MODE_MODULO_N,
+};
+
+/* Count function values */
+enum counter_function {
+   COUNTER_FUNCTION_INCREASE,
+   COUNTER_FUNCTION_DECREASE,
+   COUNTER_FUNCTION_PULSE_DIRECTION,
+   COUNTER_FUNCTION_QUADRATURE_X1_A,
+   COUNTER_FUNCTION_QUADRATURE_X1_B,
+   COUNTER_FUNCTION_QUADRATURE_X2_A,
+   COUNTER_FUNCTION_QUADRATURE_X2_B,
+   COUNTER_FUNCTION_QUADRATURE_X4,
+};
+
+/* Signal values */
+enum counter_signal_level {
+   COUNTER_SIGNAL_LEVEL_LOW,
+   COUNTER_SIGNAL_LEVEL_HIGH,
+};
+
+/* Action mode values */
+enum counter_synapse_action {
+   COUNTER_SYNAPSE_ACTION_NONE,
+   COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+   COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
+   COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
+};
+
+#endif /* _UAPI_COUNTER_H_ */





Re: [PATCH v7 4/5] docs: counter: Document character device interface

2020-12-30 Thread David Lechner

On 12/25/20 6:15 PM, William Breathitt Gray wrote:


+Userspace
+-
+Userspace applications can configure Counter events via ioctl operations
+on the Counter character device node. There following ioctl codes are
+supported and provided by the `linux/counter.h` userspace header file:
+
+* COUNTER_CLEAR_WATCHES_IOCTL:
+  Clear all Counter watches from all events
+
+* COUNTER_ADD_WATCH_IOCTL:
+  Add a Counter watch for the specified event
+
+* COUNTER_LOAD_WATCHES_IOCTL:
+  Activates the Counter watches added earlier


Would it make more sense to call the last and first ones
COUNTER_ENABLE_EVENTS_IOCTL and COUNTER_DISABLE_EVENTS_IOCTL?
In any case, more explanation would be helpful.

* COUNTER_ADD_WATCH_IOCTL:
  Queues a Counter watch for the specified event. The queued watches
  will not be applied until COUNTER_ENABLE_EVENTS_IOCTL is called.

* COUNTER_ENABLE_EVENTS_IOCTL:
  Enables monitoring the events specified by the Counter watches that were
  queued by COUNTER_ADD_WATCH_IOCTL. If events are already enabled, the new
  set of watches replaces the old one. Calling this ioctl also has the
  effect of clearing the queue of watches added by COUNTER_ADD_WATCH_IOCTL.

* COUNTER_DISABLE_EVENTS_IOCTL:
  Stops monitoring the previously enabled events.


+
+To configure events to gather Counter data, users first populate a
+`struct counter_watch` with the relevant event id, event channel id, and
+the information for the desired Counter component from which to read,
+and then pass it via the `COUNTER_ADD_WATCH_IOCTL` ioctl command.


for restructured text, two backticks are needed for ``code`` formatting




Re: [PATCH v7 5/5] counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8

2020-12-30 Thread David Lechner

On 12/25/20 6:15 PM, William Breathitt Gray wrote:


diff --git a/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8 
b/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8
index eac32180c40d..0ecba24d43aa 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8
+++ b/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8
@@ -1,3 +1,28 @@
+What:  /sys/bus/counter/devices/counterX/countY/irq_trigger


Do we really need this sysfs attribute? Shouldn't interrupts be configured
_only_ by the chrdev interface?




Re: [PATCH v6 1/5] counter: Internalize sysfs interface code

2020-12-21 Thread David Lechner

On 12/20/20 4:11 PM, William Breathitt Gray wrote:

On Sun, Dec 13, 2020 at 05:15:00PM -0600, David Lechner wrote:

On 11/22/20 2:29 PM, William Breathitt Gray wrote:


   14 files changed, 1806 insertions(+), 2546 deletions(-)


It would be really nice if we could break this down into smaller
pieces and start getting it merged. It is really tough to keep
reviewing this much code in one patch over and over again.


Yes, this is a pretty massive patch. I could break this across the
individual files affected to make it simpler to review, but in the end
all those patches would need to end up squashed together before merge
again (for the sake of git bisect), so the effort feels somewhat moot.

Luckily, I don't think there will be much change in the next revision
since it's looking like it'll mainly be a few bug fixes; hopefully this
coming version 7 will be the final revision before merge.


Here are some initial findings from testing:



+static void counter_device_release(struct device *dev)
+{
+   struct counter_device *const counter = dev_get_drvdata(dev);
+
+   counter_chrdev_remove(counter);
+   ida_simple_remove(_ida, counter->id);
+}



I got the following error after `modprobe -r ti-eqep`:

[ 1186.045766] [ cut here ]
[ 1186.050647] WARNING: CPU: 0 PID: 2625 at lib/refcount.c:28 
counter_device_release+0x10/0x24 [counter]
[ 1186.059976] refcount_t: underflow; use-after-free.
[ 1186.064790] Modules linked in: aes_arm_bs(+) crypto_simd cryptd ccm 
usb_f_mass_storage usb_f_acm u_serial usb_f_ecm rfcomm usb_f_rndis u_ether 
libcomposite aes_arm aes_generic cmac bnep wl18xx wlcore mac80211 libarc4 
sha256_generic libsha256 sha256_arm cfg80211 ti_am335x_adc kfifo_buf 
omap_aes_driver omap_crypto omap_sham crypto_engine pm33xx ti_emif_sram 
hci_uart omap_rng btbcm rng_core ti_eqep(-) counter bluetooth c_can_platform 
c_can ecdh_generic bmp280_spi ecc can_dev libaes bmp280_i2c bmp280 industrialio 
omap_mailbox musb_dsps wlcore_sdio musb_hdrc udc_core usbcore wkup_m3_ipc at24 
omap_wdt phy_am335x watchdog phy_am335x_control ti_am335x_tscadc phy_generic 
wkup_m3_rproc usb_common cppi41 rtc_omap leds_gpio led_class cpufreq_dt 
pwm_tiehrpwm autofs4
[ 1186.132376] CPU: 0 PID: 2625 Comm: modprobe Not tainted 
5.10.0-rc7bone-counter+ #23
[ 1186.140070] Hardware name: Generic AM33XX (Flattened Device Tree)
[ 1186.146225] [] (unwind_backtrace) from [] 
(show_stack+0x10/0x14)
[ 1186.154017] [] (show_stack) from [] 
(dump_stack+0xc4/0xe4)
[ 1186.161285] [] (dump_stack) from [] (__warn+0xd8/0x100)
[ 1186.168284] [] (__warn) from [] 
(warn_slowpath_fmt+0x94/0xbc)
[ 1186.175814] [] (warn_slowpath_fmt) from [] 
(counter_device_release+0x10/0x24 [counter])
[ 1186.185632] [] (counter_device_release [counter]) from 
[] (device_release+0x30/0xa4)
[ 1186.195163] [] (device_release) from [] 
(kobject_put+0x94/0x104)
[ 1186.202944] [] (kobject_put) from [] 
(kobject_put+0x94/0x104)
[ 1186.210472] [] (kobject_put) from [] 
(ti_eqep_remove+0x10/0x30 [ti_eqep])
[ 1186.219047] [] (ti_eqep_remove [ti_eqep]) from [] 
(platform_drv_remove+0x24/0x3c)
[ 1186.228313] [] (platform_drv_remove) from [] 
(device_release_driver_internal+0xfc/0x1d0)
[ 1186.238187] [] (device_release_driver_internal) from [] 
(driver_detach+0x58/0xa8)
[ 1186.247456] [] (driver_detach) from [] 
(bus_remove_driver+0x4c/0xa0)
[ 1186.255594] [] (bus_remove_driver) from [] 
(sys_delete_module+0x180/0x264)
[ 1186.264250] [] (sys_delete_module) from [] 
(ret_fast_syscall+0x0/0x54)
[ 1186.272551] Exception stack(0xd247ffa8 to 0xd247fff0)
[ 1186.277629] ffa0:   004fb478 004fb478 004fb4b4 0800 
b3bfcf00 
[ 1186.285847] ffc0: 004fb478 004fb478 004fb478 0081  be974900 
be974a55 004fb478
[ 1186.294062] ffe0: 004f8f5c be97352c 004ddd97 b6d11d68
[ 1186.299253] ---[ end trace e1c61dea091f1078 ]---


I noticed that I'm calling counter_chrdev_remove() twice: once in
counter_unregister(), and again in counter_device_release(). I suspect
this is what's causing the refcount to underflow. I'll test and verify
that this is the culprit.

In fact, I don't think I need to define a counter_device_release()
callback at all, would I? These cleanup function calls could be moved to
counter_unregister() instead.


As long as a user program keeps a chrdev open, it holds a reference to
the device, so I think it needs to be the other way around. (Unless it
is impossible to call counter_unregister() before all references have
been released - but I don't think that is the case - not 100% sure.)


Re: [PATCH v6 0/5] Introduce the Counter character device interface

2020-12-21 Thread David Lechner

On 12/20/20 3:44 PM, William Breathitt Gray wrote:

On Sun, Dec 13, 2020 at 05:15:14PM -0600, David Lechner wrote:

On 11/22/20 2:29 PM, William Breathitt Gray wrote:


1. Should standard Counter component data types be defined as u8 or u32?

 Many standard Counter component types such COUNTER_COMP_SIGNAL_LEVEL
 have standard values defined (e.g. COUNTER_SIGNAL_LEVEL_LOW and
 COUNTER_SIGNAL_LEVEL_HIGH). These values are currently handled by the
 Counter subsystem code as u8 data types.

 If u32 is used for these values instead, C enum structures could be
 used by driver authors to implicitly cast these values via the driver
 callback parameters.

 This question is primarily addressed to David Lechner. I'm somewhat
 confused about how this setup would look in device drivers. I've gone
 ahead and refactored the code to support u32 enums, and pushed it to
 a separate branch on my repository called counter_chrdev_v6_u32_enum:
 https://gitlab.com/vilhelmgray/iio/-/tree/counter_chrdev_v6_u32_enum

 Please check it out and let me know what you think. Is this the
 support you had in mind? I'm curious to see an example of how would
 your driver callback functions would look in this case. If everything
 works out fine, then I'll submit this branch as v7 of this patchset.


I haven't had time to look at this in depth, but just superficially looking
at it, it is mostly there. The driver callback would just use the enum type
in place of u32. For example:

static int ti_eqep_function_write(struct counter_device *counter,
  struct counter_count *count,
  enum counter_function function)

and the COUNTER_FUNCTION_* constants would be defined as:

enum counter_function {
COUNTER_FUNCTION_INCREASE,
...
};

instead of using #define macros.

One advantage I see to using u8, at least in the user API data structures,
is that it increases the number of events that fit in the kfifo buffer by
a significant factor.

And that is not to say that we couldn't do both: have the user API structs
use u8 for enum values and still use u32/strong enum types internally in
the callback functions.


I'm including David Laight because he initially opposed enums in favor
of fixed size types when we discussed this in an earlier revision:
https://lkml.org/lkml/2020/5/3/159

However, there have been significant changes to this patchset so the
context now is different than those earlier discussions (i.e. we're no
longer discussing ioctl calls).

I think reimplementing these constants as enums as described could work.
If we do so, should the enum constants be given specific values? For
example:

enum counter_function {
COUNTER_FUNCTION_INCREASE = 0,
COUNTER_FUNCTION_DECREASE = 1,
...
};


I would say no on the explicit values since they don't have
any significant meaning.


Re: [PATCH] counter:ti-eqep: remove floor

2020-12-14 Thread David Lechner

On 12/14/20 5:46 AM, William Breathitt Gray wrote:

On Sun, Dec 13, 2020 at 06:09:27PM -0600, David Lechner wrote:

The hardware doesn't support this. QPOSINIT is an initialization value
that is triggered by other things. When the counter overflows, it
always wraps around to zero.

Fixes: f213729f6796 "counter: new TI eQEP driver"
Signed-off-by: David Lechner 


Is the QPOSINIT preprocessor define needed at all anymore, or should it also be
removed?


There are already many more defines for registers that are not
used, so I didn't remove it.



Acked-by: William Breathitt Gray 


---
  drivers/counter/ti-eqep.c | 35 ---
  1 file changed, 35 deletions(-)

diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index a60aee1a1a29..65df9ef5b5bc 100644
--- a/drivers/counter/ti-eqep.c
+++ b/drivers/counter/ti-eqep.c
@@ -235,36 +235,6 @@ static ssize_t ti_eqep_position_ceiling_write(struct 
counter_device *counter,
return len;
  }
  
-static ssize_t ti_eqep_position_floor_read(struct counter_device *counter,

-  struct counter_count *count,
-  void *ext_priv, char *buf)
-{
-   struct ti_eqep_cnt *priv = counter->priv;
-   u32 qposinit;
-
-   regmap_read(priv->regmap32, QPOSINIT, );
-
-   return sprintf(buf, "%u\n", qposinit);
-}
-
-static ssize_t ti_eqep_position_floor_write(struct counter_device *counter,
-   struct counter_count *count,
-   void *ext_priv, const char *buf,
-   size_t len)
-{
-   struct ti_eqep_cnt *priv = counter->priv;
-   int err;
-   u32 res;
-
-   err = kstrtouint(buf, 0, );
-   if (err < 0)
-   return err;
-
-   regmap_write(priv->regmap32, QPOSINIT, res);
-
-   return len;
-}
-
  static ssize_t ti_eqep_position_enable_read(struct counter_device *counter,
struct counter_count *count,
void *ext_priv, char *buf)
@@ -301,11 +271,6 @@ static struct counter_count_ext ti_eqep_position_ext[] = {
.read   = ti_eqep_position_ceiling_read,
.write  = ti_eqep_position_ceiling_write,
},
-   {
-   .name   = "floor",
-   .read   = ti_eqep_position_floor_read,
-   .write  = ti_eqep_position_floor_write,
-   },
{
.name   = "enable",
.read   = ti_eqep_position_enable_read,
--
2.25.1





[PATCH] counter:ti-eqep: remove floor

2020-12-13 Thread David Lechner
The hardware doesn't support this. QPOSINIT is an initialization value
that is triggered by other things. When the counter overflows, it
always wraps around to zero.

Fixes: f213729f6796 "counter: new TI eQEP driver"
Signed-off-by: David Lechner 
---
 drivers/counter/ti-eqep.c | 35 ---
 1 file changed, 35 deletions(-)

diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index a60aee1a1a29..65df9ef5b5bc 100644
--- a/drivers/counter/ti-eqep.c
+++ b/drivers/counter/ti-eqep.c
@@ -235,36 +235,6 @@ static ssize_t ti_eqep_position_ceiling_write(struct 
counter_device *counter,
return len;
 }
 
-static ssize_t ti_eqep_position_floor_read(struct counter_device *counter,
-  struct counter_count *count,
-  void *ext_priv, char *buf)
-{
-   struct ti_eqep_cnt *priv = counter->priv;
-   u32 qposinit;
-
-   regmap_read(priv->regmap32, QPOSINIT, );
-
-   return sprintf(buf, "%u\n", qposinit);
-}
-
-static ssize_t ti_eqep_position_floor_write(struct counter_device *counter,
-   struct counter_count *count,
-   void *ext_priv, const char *buf,
-   size_t len)
-{
-   struct ti_eqep_cnt *priv = counter->priv;
-   int err;
-   u32 res;
-
-   err = kstrtouint(buf, 0, );
-   if (err < 0)
-   return err;
-
-   regmap_write(priv->regmap32, QPOSINIT, res);
-
-   return len;
-}
-
 static ssize_t ti_eqep_position_enable_read(struct counter_device *counter,
struct counter_count *count,
void *ext_priv, char *buf)
@@ -301,11 +271,6 @@ static struct counter_count_ext ti_eqep_position_ext[] = {
.read   = ti_eqep_position_ceiling_read,
.write  = ti_eqep_position_ceiling_write,
},
-   {
-   .name   = "floor",
-   .read   = ti_eqep_position_floor_read,
-   .write  = ti_eqep_position_floor_write,
-   },
{
.name   = "enable",
.read   = ti_eqep_position_enable_read,
-- 
2.25.1



Re: [PATCH v6 3/5] counter: Add character device interface

2020-12-13 Thread David Lechner

On 11/22/20 2:29 PM, William Breathitt Gray wrote:

This patch introduces a character device interface for the Counter
subsystem. Device data is exposed through standard character device read
operations. Device data is gathered when a Counter event is pushed by
the respective Counter device driver. Configuration is handled via ioctl
operations on the respective Counter character device node.

Cc: David Lechner 
Cc: Gwendal Grignou 
Cc: Dan Carpenter 
Signed-off-by: William Breathitt Gray 
---





diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c
new file mode 100644
index ..96fa7fbeef92
--- /dev/null
+++ b/drivers/counter/counter-chrdev.c




+static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
+  size_t len, loff_t *f_ps)
+{
+   struct counter_device *const counter = filp->private_data;
+   int err;
+   unsigned long flags;
+   unsigned int copied;
+
+   if (len < sizeof(struct counter_event))
+   return -EINVAL;
+
+   do {
+   if (kfifo_is_empty(>events)) {
+   if (filp->f_flags & O_NONBLOCK)
+   return -EAGAIN;
+
+   err = wait_event_interruptible(counter->events_wait,
+   !kfifo_is_empty(>events));
+   if (err)
+   return err;
+   }
+
+   raw_spin_lock_irqsave(>events_lock, flags);


As mentioned in my previous review, I think it would be fine to use a
mutex here instead of disabling interrupts. In fact, I think copy_to_user()
might sleep, in which case we really don't want to call this with
interrupts disabled.


+   err = kfifo_to_user(>events, buf, len, );
+   raw_spin_unlock_irqrestore(>events_lock, flags);
+   if (err)
+   return err;
+   } while (!copied);
+
+   return copied;
+}
+




+static int counter_add_watch(struct counter_device *const counter,
+const unsigned long arg)
+{
+   void __user *const uwatch = (void __user *)arg;
+   struct counter_watch watch;
+   struct counter_comp_node comp_node = {0};
+   size_t parent, id;
+   struct counter_comp *ext;
+   size_t num_ext;
+
+   if (copy_from_user(, uwatch, sizeof(watch)))
+   return -EFAULT;
+
+   /* Dummy components can skip evaluation */
+   if (watch.component.type == COUNTER_COMPONENT_DUMMY)


I think "none" would be a better name than "dummy". Then it just
naturally makes sense why we would skip the evaluation.


+   goto dummy_component;
+
+   parent = watch.component.parent;
+
+   /* Configure parent component info for comp node */
+   switch (watch.component.scope) {
+   case COUNTER_SCOPE_DEVICE:
+   ext = counter->ext;
+   num_ext = counter->num_ext;
+   break;
+   case COUNTER_SCOPE_SIGNAL:
+   if (parent >= counter->num_signals)
+   return -EINVAL;
+   parent = array_index_nospec(parent, counter->num_signals);
+
+   comp_node.parent = counter->signals + parent;
+
+   ext = counter->signals[parent].ext;
+   num_ext = counter->signals[parent].num_ext;
+   break;
+   case COUNTER_SCOPE_COUNT:
+   if (parent >= counter->num_counts)
+   return -EINVAL;
+   parent = array_index_nospec(parent, counter->num_counts);
+
+   comp_node.parent = counter->counts + parent;
+
+   ext = counter->counts[parent].ext;
+   num_ext = counter->counts[parent].num_ext;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   id = watch.component.id;
+
+   /* Configure component info for comp node */
+   switch (watch.component.type) {
+   case COUNTER_COMPONENT_SIGNAL:
+   if (watch.component.scope != COUNTER_SCOPE_SIGNAL)
+   return -EINVAL;
+
+   comp_node.comp.type = COUNTER_COMP_SIGNAL_LEVEL;
+   comp_node.comp.signal_u8_read = counter->ops->signal_read;
+   break;
+   case COUNTER_COMPONENT_COUNT:
+   if (watch.component.scope != COUNTER_SCOPE_COUNT)
+   return -EINVAL;
+
+   comp_node.comp.type = COUNTER_COMP_U64;
+   comp_node.comp.count_u64_read = counter->ops->count_read;
+   break;
+   case COUNTER_COMPONENT_FUNCTION:
+   if (watch.component.scope != COUNTER_SCOPE_COUNT)
+   return -EINVAL;
+
+   comp_node.comp.type = COUNTER_COMP_FUNCTION;
+   comp_node.comp.count_u8

Re: [PATCH v6 0/5] Introduce the Counter character device interface

2020-12-13 Thread David Lechner

On 11/22/20 2:29 PM, William Breathitt Gray wrote:


1. Should standard Counter component data types be defined as u8 or u32?

Many standard Counter component types such COUNTER_COMP_SIGNAL_LEVEL
have standard values defined (e.g. COUNTER_SIGNAL_LEVEL_LOW and
COUNTER_SIGNAL_LEVEL_HIGH). These values are currently handled by the
Counter subsystem code as u8 data types.

If u32 is used for these values instead, C enum structures could be
used by driver authors to implicitly cast these values via the driver
callback parameters.

This question is primarily addressed to David Lechner. I'm somewhat
confused about how this setup would look in device drivers. I've gone
ahead and refactored the code to support u32 enums, and pushed it to
a separate branch on my repository called counter_chrdev_v6_u32_enum:
https://gitlab.com/vilhelmgray/iio/-/tree/counter_chrdev_v6_u32_enum

Please check it out and let me know what you think. Is this the
support you had in mind? I'm curious to see an example of how would
your driver callback functions would look in this case. If everything
works out fine, then I'll submit this branch as v7 of this patchset.


I haven't had time to look at this in depth, but just superficially looking
at it, it is mostly there. The driver callback would just use the enum type
in place of u32. For example:

static int ti_eqep_function_write(struct counter_device *counter,
  struct counter_count *count,
  enum counter_function function)

and the COUNTER_FUNCTION_* constants would be defined as:

enum counter_function {
COUNTER_FUNCTION_INCREASE,
...
};

instead of using #define macros.

One advantage I see to using u8, at least in the user API data structures,
is that it increases the number of events that fit in the kfifo buffer by
a significant factor.

And that is not to say that we couldn't do both: have the user API structs
use u8 for enum values and still use u32/strong enum types internally in
the callback functions.





2. How should we handle "raw" timestamps?

Ahmad Fatoum brought up the possibility of returning "raw" timestamps
similar to what the network stack offers (see the network stack
SOF_TIMESTAMPING_{RAW,SYS}_HARDWARE support).

I'm not very familiar with the networking stack code, but if I
understand correctly the SOF_TIMESTAMPING_RAW_HARDWARE timestamps are
values returned from the device. If so, I suspect we would be able to
support these "raw" timestamps by defining them as Counter Extensions
and returning them in struct counter_event elements similar to the
other Extension values.


Is nanosecond resolution good enough? In the TI eQEP driver I considered
returning the raw timer value, but quickly realized that it would not be
very nice to expect the user code to know the clock rate of the timer. It
was very easy to get the clock rate in the kernel and just convert the
timer value to nanoseconds before returning it to userspace.

So if there is some specialized case where it can be solved no other way
besides using raw timestamps, then sure, include it. Otherwise I think we
should stick with nanoseconds for time values when possible.


Re: [PATCH v6 1/5] counter: Internalize sysfs interface code

2020-12-13 Thread David Lechner

On 11/22/20 2:29 PM, William Breathitt Gray wrote:


  14 files changed, 1806 insertions(+), 2546 deletions(-)


It would be really nice if we could break this down into smaller
pieces and start getting it merged. It is really tough to keep
reviewing this much code in one patch over and over again.

Here are some initial findings from testing:



+static void counter_device_release(struct device *dev)
+{
+   struct counter_device *const counter = dev_get_drvdata(dev);
+
+   counter_chrdev_remove(counter);
+   ida_simple_remove(_ida, counter->id);
+}



I got the following error after `modprobe -r ti-eqep`:

[ 1186.045766] [ cut here ]
[ 1186.050647] WARNING: CPU: 0 PID: 2625 at lib/refcount.c:28 
counter_device_release+0x10/0x24 [counter]
[ 1186.059976] refcount_t: underflow; use-after-free.
[ 1186.064790] Modules linked in: aes_arm_bs(+) crypto_simd cryptd ccm 
usb_f_mass_storage usb_f_acm u_serial usb_f_ecm rfcomm usb_f_rndis u_ether 
libcomposite aes_arm aes_generic cmac bnep wl18xx wlcore mac80211 libarc4 
sha256_generic libsha256 sha256_arm cfg80211 ti_am335x_adc kfifo_buf 
omap_aes_driver omap_crypto omap_sham crypto_engine pm33xx ti_emif_sram 
hci_uart omap_rng btbcm rng_core ti_eqep(-) counter bluetooth c_can_platform 
c_can ecdh_generic bmp280_spi ecc can_dev libaes bmp280_i2c bmp280 industrialio 
omap_mailbox musb_dsps wlcore_sdio musb_hdrc udc_core usbcore wkup_m3_ipc at24 
omap_wdt phy_am335x watchdog phy_am335x_control ti_am335x_tscadc phy_generic 
wkup_m3_rproc usb_common cppi41 rtc_omap leds_gpio led_class cpufreq_dt 
pwm_tiehrpwm autofs4
[ 1186.132376] CPU: 0 PID: 2625 Comm: modprobe Not tainted 
5.10.0-rc7bone-counter+ #23
[ 1186.140070] Hardware name: Generic AM33XX (Flattened Device Tree)
[ 1186.146225] [] (unwind_backtrace) from [] 
(show_stack+0x10/0x14)
[ 1186.154017] [] (show_stack) from [] 
(dump_stack+0xc4/0xe4)
[ 1186.161285] [] (dump_stack) from [] (__warn+0xd8/0x100)
[ 1186.168284] [] (__warn) from [] 
(warn_slowpath_fmt+0x94/0xbc)
[ 1186.175814] [] (warn_slowpath_fmt) from [] 
(counter_device_release+0x10/0x24 [counter])
[ 1186.185632] [] (counter_device_release [counter]) from 
[] (device_release+0x30/0xa4)
[ 1186.195163] [] (device_release) from [] 
(kobject_put+0x94/0x104)
[ 1186.202944] [] (kobject_put) from [] 
(kobject_put+0x94/0x104)
[ 1186.210472] [] (kobject_put) from [] 
(ti_eqep_remove+0x10/0x30 [ti_eqep])
[ 1186.219047] [] (ti_eqep_remove [ti_eqep]) from [] 
(platform_drv_remove+0x24/0x3c)
[ 1186.228313] [] (platform_drv_remove) from [] 
(device_release_driver_internal+0xfc/0x1d0)
[ 1186.238187] [] (device_release_driver_internal) from [] 
(driver_detach+0x58/0xa8)
[ 1186.247456] [] (driver_detach) from [] 
(bus_remove_driver+0x4c/0xa0)
[ 1186.255594] [] (bus_remove_driver) from [] 
(sys_delete_module+0x180/0x264)
[ 1186.264250] [] (sys_delete_module) from [] 
(ret_fast_syscall+0x0/0x54)
[ 1186.272551] Exception stack(0xd247ffa8 to 0xd247fff0)
[ 1186.277629] ffa0:   004fb478 004fb478 004fb4b4 0800 
b3bfcf00 
[ 1186.285847] ffc0: 004fb478 004fb478 004fb478 0081  be974900 
be974a55 004fb478
[ 1186.294062] ffe0: 004f8f5c be97352c 004ddd97 b6d11d68
[ 1186.299253] ---[ end trace e1c61dea091f1078 ]---


+static ssize_t counter_comp_u8_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t len)
+{
+   const struct counter_attribute *const a = to_counter_attribute(attr);
+   struct counter_device *const counter = dev_get_drvdata(dev);
+   struct counter_count *const count = a->parent;
+   struct counter_synapse *const synapse = a->comp.priv;
+   const struct counter_available *const avail = a->comp.priv;
+   int err;
+   bool bool_data;
+   int idx;
+   u8 data;
+
+   switch (a->comp.type) {
+   case COUNTER_COMP_BOOL:
+   err = kstrtobool(buf, _data);
+   data = bool_data;
+   break;
+   case COUNTER_COMP_FUNCTION:
+   err = find_in_string_array(, count->functions_list,
+  count->num_functions, buf,
+  counter_function_str);
+   break;
+   case COUNTER_COMP_SYNAPSE_ACTION:
+   err = find_in_string_array(, synapse->actions_list,
+  synapse->num_actions, buf,
+  counter_synapse_action_str);
+   break;
+   case COUNTER_COMP_ENUM:
+   idx = __sysfs_match_string(avail->strs, avail->num_items, buf);
+   if (idx < 0)
+   return idx;
+   data = idx;
+   break;
+   case COUNTER_COMP_COUNT_MODE:
+   err = find_in_string_array(, avail->enums,
+  avail->num_items, buf,
+ 

Re: [PATCH 0/3] Enable eQEP counter driver on BeagleBone Blue

2020-11-16 Thread David Lechner

On 11/16/20 5:36 AM, Tony Lindgren wrote:

* David Lechner  [201013 00:13]:

This series adds device tree nodes for the eQEP portion of the PWMSS on AM33xx
and enables it on BeagleBone Blue.

I actually submitted these a year ago, but it looks like these patches never got
applied with the actual eQEP driver when it was merged.


Sorry if I dropped these earlier, I guess I though you're reposting the
series and untagged them.


No worries, I forgot about them too. :-)




For reference, there was some previous discussion about the clocks in "ARM: dts:
am33xx: Add nodes for eQEP". [1]

[1]: https://lore.kernel.org/linux-omap/20190723145100.gs5...@atomide.com/

I have also included a new patch to enable the eQEP driver in the defconfig.


Great, thanks applying these into omap-for-v5.11/dt and defconfig branches.

Regards,

Tony





[PATCH v2] counter/ti-eqep: Fix regmap max_register

2020-10-25 Thread David Lechner
The values given were the offset of the register after the last
register instead of the actual last register in each range. Fix
by using the correct last register of each range.

Fixes: f213729f6796 ("counter: new TI eQEP driver")
Signed-off-by: David Lechner 
Acked-by: William Breathitt Gray 
---

v2 changes:
* add Fixes: tag
* picked up Acked-by:

 drivers/counter/ti-eqep.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index 1ff07faef27f..5d6470968d2c 100644
--- a/drivers/counter/ti-eqep.c
+++ b/drivers/counter/ti-eqep.c
@@ -368,7 +368,7 @@ static const struct regmap_config ti_eqep_regmap32_config = 
{
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
-   .max_register = 0x24,
+   .max_register = QUPRD,
 };
 
 static const struct regmap_config ti_eqep_regmap16_config = {
@@ -376,7 +376,7 @@ static const struct regmap_config ti_eqep_regmap16_config = 
{
.reg_bits = 16,
.val_bits = 16,
.reg_stride = 2,
-   .max_register = 0x1e,
+   .max_register = QCPRDLAT,
 };
 
 static int ti_eqep_probe(struct platform_device *pdev)
-- 
2.25.1



Re: [PATCH v5 3/5] counter: Add character device interface

2020-10-25 Thread David Lechner




diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index e66ed99dd5ea..cefef61f170d 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c



Not sure why sysfs changes are in the chrdev patch. Are these
changes related somehow?


Sorry, I forgot to explain this in the cover letter. The changes here
are only useful for the character device interface. These changes
introduce the extensionZ_name and extensionZ_width sysfs attributes.

In the character device interface, extensions are selected by their id
number, and the value returned depends on the type of data. The new
sysfs attributes introduced here allow users to match the id of an
extension with its name, as well as the bit width of the value returned
so that the user knows whether to use the value_u8 or value_u64 union
member in struct counter_event.



Are we sure that all value types will always be CPU-endian unsigned
integers? Or should we make an enum to describe the data type instead
of just the width?


It should be safe to assume that the character device interface will
only ever return CPU-endian unsigned integers. The device driver should
handle the conversion of any strange endianness from the device before
the character device interface, while userspace is the one responsible
for interpreting the meaning of count in the context of the application.

Let's create a scenario for the sake of example. Suppose we want to use
a counter device to track the vertical position of a component moved by
a linear actuator. The operator considers some vertical position as the
horizon, where anything above would be a positive position and anything
below a negative position. The counter device stores its count in
big-endian format; but the system CPU expects little-endian.

The flow of data for this scenario would look like the following (where
BE = big-endian, LE = little-endian):

+--+ +---+  ++
| Raw data | - BE -> | Device driver | -> LE -> | chrdev | - u64 ->
+--+ +---+  ++

At this point, the userspace application would read the unsigned integer
from the character device and determine how to interpret the position --
whether the count be converted to a signed value to represent a negative
physical position.

Whether or not a position should be considered negative is dependent on
the user application and context. Because the character device does not
know the context of the user application, it should only provide
unsigned integers in order to ensure a standard interface for counter
devices; userspace will be responsible for interpreting those counts to
something meaningful for the context of their applications.

William Breathitt Gray



Sounds reasonable to me.


Re: [PATCH v5 3/5] counter: Add character device interface

2020-10-25 Thread David Lechner

On 10/25/20 8:18 AM, William Breathitt Gray wrote:

On Tue, Oct 20, 2020 at 11:06:42AM -0500, David Lechner wrote:

On 10/18/20 11:58 AM, William Breathitt Gray wrote:

On Wed, Oct 14, 2020 at 05:40:44PM -0500, David Lechner wrote:

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

+static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
+  size_t len, loff_t *f_ps)
+{
+   struct counter_device *const counter = filp->private_data;
+   int err;
+   unsigned long flags;
+   unsigned int copied;
+
+   if (len < sizeof(struct counter_event))
+   return -EINVAL;
+
+   do {
+   if (kfifo_is_empty(>events)) {
+   if (filp->f_flags & O_NONBLOCK)
+   return -EAGAIN;
+
+   err = wait_event_interruptible(counter->events_wait,
+   !kfifo_is_empty(>events));
+   if (err)
+   return err;
+   }
+
+   raw_spin_lock_irqsave(>events_lock, flags);
+   err = kfifo_to_user(>events, buf, len, );
+   raw_spin_unlock_irqrestore(>events_lock, flags);
+   if (err)
+   return err;
+   } while (!copied);
+
+   return copied;
+}


All other uses of kfifo_to_user() I saw use a mutex instead of spin
lock. I don't see a reason for disabling interrupts here.


The Counter character device interface is special in this case because
counter->events could be accessed from an interrupt context. This is
possible if counter_push_event() is called for an interrupt (as is the
case for the 104_quad_8 driver). In this case, we can't use mutex
because we can't sleep in an interrupt context, so our only option is to
use spin lock.




The way I understand it, locking is only needed for concurrent readers
and locking between reader and writer is not needed.


You're right, it does say in the kfifo.h comments that with only one
concurrent reader and one current write, we don't need extra locking to
use these macros. Because we only have one kfifo_to_user() operating on
counter->events, does that mean we don't need locking at all here for
the counter_chrdev_read() function?

William Breathitt Gray



Even if we have the policy that only one file handle to the chrdev
can be open at a time, it is still possible that the it could be
read from multiple threads. So it I think it makes sense to keep
it just to be safe.


Re: [PATCH v5 3/5] counter: Add character device interface

2020-10-20 Thread David Lechner

On 10/18/20 11:58 AM, William Breathitt Gray wrote:

On Wed, Oct 14, 2020 at 05:40:44PM -0500, David Lechner wrote:

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

+static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
+  size_t len, loff_t *f_ps)
+{
+   struct counter_device *const counter = filp->private_data;
+   int err;
+   unsigned long flags;
+   unsigned int copied;
+
+   if (len < sizeof(struct counter_event))
+   return -EINVAL;
+
+   do {
+   if (kfifo_is_empty(>events)) {
+   if (filp->f_flags & O_NONBLOCK)
+   return -EAGAIN;
+
+   err = wait_event_interruptible(counter->events_wait,
+   !kfifo_is_empty(>events));
+   if (err)
+   return err;
+   }
+
+   raw_spin_lock_irqsave(>events_lock, flags);
+   err = kfifo_to_user(>events, buf, len, );
+   raw_spin_unlock_irqrestore(>events_lock, flags);
+   if (err)
+   return err;
+   } while (!copied);
+
+   return copied;
+}


All other uses of kfifo_to_user() I saw use a mutex instead of spin
lock. I don't see a reason for disabling interrupts here.


The Counter character device interface is special in this case because
counter->events could be accessed from an interrupt context. This is
possible if counter_push_event() is called for an interrupt (as is the
case for the 104_quad_8 driver). In this case, we can't use mutex
because we can't sleep in an interrupt context, so our only option is to
use spin lock.




The way I understand it, locking is only needed for concurrent readers
and locking between reader and writer is not needed.


Re: [PATCH v5 3/5] counter: Add character device interface

2020-10-20 Thread David Lechner




+static long counter_chrdev_ioctl(struct file *filp, unsigned int cmd,
+unsigned long arg)
+{
+   struct counter_device *const counter = filp->private_data;
+   raw_spinlock_t *const events_lock = >events_lock;
+   unsigned long flags;
+   struct list_head *const events_list = >events_list;
+   struct list_head *const next_events_list = >next_events_list;
+
+   switch (cmd) {
+   case COUNTER_CLEAR_WATCHES_IOCTL:
+   raw_spin_lock_irqsave(events_lock, flags);
+   counter_events_list_free(events_list);
+   raw_spin_unlock_irqrestore(events_lock, flags);
+   counter_events_list_free(next_events_list);


I think this ioctl is doing too much. If we have to use it for both
stopping events and clearing the list accumulated by
COUNTER_SET_WATCH_IOCTL, then we have a race condition of no events
after clearing watches during the time we are adding new ones and
until we load the new ones.

It would probably make more sense to call this ioctl
COUNTER_STOP_WATCHES_IOCTL and move counter_events_list_free(
next_events_list) to the end of COUNTER_LOAD_WATCHES_IOCTL.


I don't think we will necessarily have a race condition here.
COUNTER_CLEAR_WATCHES_IOCTL is intended to just clear the watches; e.g.
bring us back to a clear state when some sort of job has completely
finished and the user is no longer going to watch events for a while
(maybe they're adjusting the conveyor for the next job or some similar
operation).

I think the scenario you're concerned about is when you need to swap
watches in the middle of a job without losing events. In this case, you
wouldn't need to use COUNTER_CLEAR_WATCHES_IOCTL at all. Instead, you
would just set up the watches via COUNTER_SET_WATCH_IOCTL, and then use
COUNTER_LOAD_WATCHES_IOCTL to perform the swap; after
COUNTER_LOAD_WATCHES_IOCTL completes, next_events_list is empty (thanks
to list_replace_init()) and you're ready for the next set of watches.



Got it. I think I missed the fact that list_replace_init() clears
next_events_list.


+
+static int counter_chrdev_release(struct inode *inode, struct file *filp)
+{
+   struct counter_device *const counter = filp->private_data;
+   unsigned long flags;
+
+   put_device(>dev);


put_device() should be at the end of the function in case it is the last
reference.


put_device() shouldn't affect the counter_device events members, so I
don't think there's a difference in this case if it's called at the
beginning or end of the counter_chrdev_release function.



It isn't possible the some memory allocated with devm_kalloc() could be
be referenced after calling put_device() now or in the future?


+}
+EXPORT_SYMBOL_GPL(counter_push_event);




diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index e66ed99dd5ea..cefef61f170d 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c



Not sure why sysfs changes are in the chrdev patch. Are these
changes related somehow?


Sorry, I forgot to explain this in the cover letter. The changes here
are only useful for the character device interface. These changes
introduce the extensionZ_name and extensionZ_width sysfs attributes.

In the character device interface, extensions are selected by their id
number, and the value returned depends on the type of data. The new
sysfs attributes introduced here allow users to match the id of an
extension with its name, as well as the bit width of the value returned
so that the user knows whether to use the value_u8 or value_u64 union
member in struct counter_event.



Are we sure that all value types will always be CPU-endian unsigned
integers? Or should we make an enum to describe the data type instead
of just the width?


Re: [PATCH v5 1/5] counter: Internalize sysfs interface code

2020-10-20 Thread David Lechner

On 10/18/20 9:49 AM, William Breathitt Gray wrote:

On Mon, Oct 12, 2020 at 09:15:00PM -0500, David Lechner wrote:

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

This is a reimplementation of the Generic Counter driver interface.


I'll follow up if I find any problems while testing but here are some
comments I had from looking over the patch.


diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
new file mode 100644
index ..987c6e8277eb
--- /dev/null
+++ b/drivers/counter/counter-core.c




+/**
+ * counter_register - register Counter to the system
+ * @counter:   pointer to Counter to register
+ *
+ * This function registers a Counter to the system. A sysfs "counter" directory
+ * will be created and populated with sysfs attributes correlating with the
+ * Counter Signals, Synapses, and Counts respectively.
+ */
+int counter_register(struct counter_device *const counter)
+{
+   struct device *const dev = >dev;
+   int err;
+
+   /* Acquire unique ID */
+   counter->id = ida_simple_get(_ida, 0, 0, GFP_KERNEL);
+   if (counter->id < 0)
+   return counter->id;
+
+   /* Configure device structure for Counter */
+   dev->type = _device_type;
+   dev->bus = _bus_type;
+   if (counter->parent) {
+   dev->parent = counter->parent;
+   dev->of_node = counter->parent->of_node;
+   }
+   dev_set_name(dev, "counter%d", counter->id);
+   device_initialize(dev);> +   dev_set_drvdata(dev, counter);
+
+   /* Add Counter sysfs attributes */
+   err = counter_sysfs_add(counter);
+   if (err)
+   goto err_free_id;
+
+   /* Add device to system */
+   err = device_add(dev);
+   if (err) {
+   put_device(dev);
+   goto err_free_id;
+   }
+
+   return 0;
+
+err_free_id:
+   /* get_device/put_device combo used to free managed resources */
+   get_device(dev);
+   put_device(dev);


I've never seen this in a driver before, so it makes me think this is
not the "right way" to do this. After device_initialize() is called, we
already should have a reference to dev, so only device_put() is needed.


I do admit this feels very hacky, but I'm not sure how to handle this
more elegantly. The problem is that device_initialize() is not enough by
itself -- it just initializes the structure, while device_add()
increments the reference count via a call to get_device().


add_device() also releases this reference by calling put_device() in all
return paths. The reference count is initialized to 1 in device_initialize().

device_initialize > kobject_init > kobject_init_internal > kref_init



So let's assume counter_sysfs_add() fails and we go to err_free_id
before device_add() is called; if we ignore get_device(), the reference
count will be 0 at this point. We then call put_device(), which calls
kobject_put(), kref_put(), and eventually refcount_dec_and_test().

The refcount_dec_and_test() function returns 0 at this point because the
reference count can't be decremented further (refcount is already 0), so
release() is never called and we end up leaking all the memory we
allocated in counter_sysfs_add().

Is my logic correct here?


Not quite. I think you missed a few things I mentioned above. So we never
have a ref count of 0 until the very last call to put_device().


[PATCH] counter/ti-eqep: Fix regmap max_register

2020-10-16 Thread David Lechner
The values given were the offset of the register after the last
register instead of the actual last register in each range. Fix
by using the correct last register of each range.

Signed-off-by: David Lechner 
---
 drivers/counter/ti-eqep.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index fe2c6bb22133..e60aec225541 100644
--- a/drivers/counter/ti-eqep.c
+++ b/drivers/counter/ti-eqep.c
@@ -798,7 +798,7 @@ static const struct regmap_config ti_eqep_regmap32_config = 
{
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
-   .max_register = 0x24,
+   .max_register = QUPRD,
 };
 
 static const struct regmap_config ti_eqep_regmap16_config = {
@@ -806,7 +806,7 @@ static const struct regmap_config ti_eqep_regmap16_config = 
{
.reg_bits = 16,
.val_bits = 16,
.reg_stride = 2,
-   .max_register = 0x1e,
+   .max_register = QCPRDLAT,
 };
 
 static int ti_eqep_probe(struct platform_device *pdev)
-- 
2.25.1



Re: [PATCH v5 1/5] counter: Internalize sysfs interface code

2020-10-14 Thread David Lechner

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

+static ssize_t counter_comp_u8_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t len)
+{
+   const struct counter_attribute *const a = to_counter_attribute(attr);
+   struct counter_device *const counter = dev_get_drvdata(dev);
+   struct counter_count *const count = a->parent;
+   struct counter_synapse *const synapse = a->comp.priv;
+   const struct counter_available *const avail = a->comp.priv;
+   int err;
+   bool bool_data;
+   u8 data;
+
+   switch (a->comp.type) {
+   case COUNTER_COMP_BOOL:
+   err = kstrtobool(buf, _data);
+   data = bool_data;
+   break;
+   case COUNTER_COMP_FUNCTION:
+   err = find_in_string_array(, count->functions_list,
+  count->num_functions, buf,
+  counter_function_str);
+   break;
+   case COUNTER_COMP_SYNAPSE_ACTION:
+   err = find_in_string_array(, synapse->actions_list,
+  synapse->num_actions, buf,
+  counter_synapse_action_str);
+   break;
+   case COUNTER_COMP_ENUM:
+   err = __sysfs_match_string(avail->strs, avail->num_items, buf);
+   data = err;
+   break;
+   case COUNTER_COMP_COUNT_MODE:
+   err = find_in_string_array(, avail->enums,
+  avail->num_items, buf,
+  counter_count_mode_str);
+   break;
+   default:
+   err = kstrtou8(buf, 0, );
+   break;
+   }


In this function, return values are not always errors. So it would make
sense to call the err variable ret instead and check for ret < 0 below.

Setting enums to a value with index > 0 fails currently because of this.


+   if (err)
+   return err;
+
+   switch (a->scope) {
+   case COUNTER_SCOPE_DEVICE:
+   err = a->comp.device_u8_write(counter, data);
+   break;
+   case COUNTER_SCOPE_SIGNAL:
+   err = a->comp.signal_u8_write(counter, a->parent, data);
+   break;
+   case COUNTER_SCOPE_COUNT:
+   if (a->comp.type == COUNTER_COMP_SYNAPSE_ACTION)
+   err = a->comp.action_write(counter, count, synapse,
+  data);
+   else
+   err = a->comp.count_u8_write(counter, count, data);
+   break;
+   }
+   if (err)
+   return err;
+
+   return len;
+}




Re: [PATCH v5 3/5] counter: Add character device interface

2020-10-14 Thread David Lechner

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

+static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
+  size_t len, loff_t *f_ps)
+{
+   struct counter_device *const counter = filp->private_data;
+   int err;
+   unsigned long flags;
+   unsigned int copied;
+
+   if (len < sizeof(struct counter_event))
+   return -EINVAL;
+
+   do {
+   if (kfifo_is_empty(>events)) {
+   if (filp->f_flags & O_NONBLOCK)
+   return -EAGAIN;
+
+   err = wait_event_interruptible(counter->events_wait,
+   !kfifo_is_empty(>events));
+   if (err)
+   return err;
+   }
+
+   raw_spin_lock_irqsave(>events_lock, flags);
+   err = kfifo_to_user(>events, buf, len, );
+   raw_spin_unlock_irqrestore(>events_lock, flags);
+   if (err)
+   return err;
+   } while (!copied);
+
+   return copied;
+}


All other uses of kfifo_to_user() I saw use a mutex instead of spin
lock. I don't see a reason for disabling interrupts here.

Example:


static ssize_t iio_event_chrdev_read(struct file *filep,
 char __user *buf,
 size_t count,
 loff_t *f_ps)
{
struct iio_dev *indio_dev = filep->private_data;
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
struct iio_event_interface *ev_int = iio_dev_opaque->event_interface;
unsigned int copied;
int ret;

if (!indio_dev->info)
return -ENODEV;

if (count < sizeof(struct iio_event_data))
return -EINVAL;

do {
if (kfifo_is_empty(_int->det_events)) {
if (filep->f_flags & O_NONBLOCK)
return -EAGAIN;

ret = wait_event_interruptible(ev_int->wait,
!kfifo_is_empty(_int->det_events) ||
indio_dev->info == NULL);
if (ret)
return ret;
if (indio_dev->info == NULL)
return -ENODEV;
}

if (mutex_lock_interruptible(_int->read_lock))
return -ERESTARTSYS;
ret = kfifo_to_user(_int->det_events, buf, count, );
mutex_unlock(_int->read_lock);

if (ret)
return ret;

/*
 * If we couldn't read anything from the fifo (a different
 * thread might have been faster) we either return -EAGAIN if
 * the file descriptor is non-blocking, otherwise we go back to
 * sleep and wait for more data to arrive.
 */
if (copied == 0 && (filep->f_flags & O_NONBLOCK))
return -EAGAIN;

} while (copied == 0);

return copied;
}


Re: [PATCH v5 3/5] counter: Add character device interface

2020-10-14 Thread David Lechner

On 10/14/20 2:05 PM, William Breathitt Gray wrote:

On Wed, Oct 14, 2020 at 12:43:08PM -0500, David Lechner wrote:

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c
new file mode 100644
index ..2be3846e4105
--- /dev/null
+++ b/drivers/counter/counter-chrdev.c




+/**
+ * counter_push_event - queue event for userspace reading
+ * @counter:   pointer to Counter structure
+ * @event: triggered event
+ * @channel:   event channel
+ *
+ * Note: If no one is watching for the respective event, it is silently
+ * discarded.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int counter_push_event(struct counter_device *const counter, const u8 event,
+  const u8 channel)
+{
+   struct counter_event ev = {0};
+   unsigned int copied = 0;
+   unsigned long flags;
+   struct counter_event_node *event_node;
+   struct counter_comp_node *comp_node;
+   int err;
+
+   ev.timestamp = ktime_get_ns();
+   ev.watch.event = event;
+   ev.watch.channel = channel;
+
+   raw_spin_lock_irqsave(>events_lock, flags);
+
+   /* Search for event in the list */
+   list_for_each_entry(event_node, >events_list, l)
+   if (event_node->event == event &&
+   event_node->channel == channel)
+   break;
+
+   /* If event is not in the list */
+   if (_node->l == >events_list)
+   goto exit_early;
+
+   /* Read and queue relevant comp for userspace */
+   list_for_each_entry(comp_node, _node->comp_list, l) {
+   err = counter_get_data(counter, comp_node, _u8);


Currently all counter devices are memory mapped devices so calling
counter_get_data() here with interrupts disabled is probably OK, but
if any counter drivers are added that use I2C/SPI/etc. that will take
a long time to read, it would cause problems leaving interrupts
disabled here.

Brainstorming: Would it make sense to separate the event from the
component value being read? As I mentioned in one of my previous
reviews, I think there are some cases where we would just want to
know when an event happened and not read any additional data anyway.
In the case of a slow communication bus, this would also let us
queue the event in the kfifo and notify poll right away and then
defer the reads in a workqueue for later.


I don't see any problems with reporting just an event without any
component value attached (e.g. userspace could handle the component
reads via sysfs at a later point). We would just need a way to inform
userspace that the struct counter_component in the struct counter_watch
returned should be ignored.

Perhaps we can add an additional member to struct counter_watch
indicating whether it's an empty watch; or alternatively, add a new
component scope define to differentiate between an actual component and
an empty one (e.g. COUNTER_SCOPE_EVENT). What do you think?

William Breathitt Gray



I made the same suggestion in one of my other replies - except
I called it COUNTER_SCOPE_NONE.


Re: [PATCH v5 3/5] counter: Add character device interface

2020-10-14 Thread David Lechner

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c
new file mode 100644
index ..2be3846e4105
--- /dev/null
+++ b/drivers/counter/counter-chrdev.c




+/**
+ * counter_push_event - queue event for userspace reading
+ * @counter:   pointer to Counter structure
+ * @event: triggered event
+ * @channel:   event channel
+ *
+ * Note: If no one is watching for the respective event, it is silently
+ * discarded.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int counter_push_event(struct counter_device *const counter, const u8 event,
+  const u8 channel)
+{
+   struct counter_event ev = {0};
+   unsigned int copied = 0;
+   unsigned long flags;
+   struct counter_event_node *event_node;
+   struct counter_comp_node *comp_node;
+   int err;
+
+   ev.timestamp = ktime_get_ns();
+   ev.watch.event = event;
+   ev.watch.channel = channel;
+
+   raw_spin_lock_irqsave(>events_lock, flags);
+
+   /* Search for event in the list */
+   list_for_each_entry(event_node, >events_list, l)
+   if (event_node->event == event &&
+   event_node->channel == channel)
+   break;
+
+   /* If event is not in the list */
+   if (_node->l == >events_list)
+   goto exit_early;
+
+   /* Read and queue relevant comp for userspace */
+   list_for_each_entry(comp_node, _node->comp_list, l) {
+   err = counter_get_data(counter, comp_node, _u8);


Currently all counter devices are memory mapped devices so calling
counter_get_data() here with interrupts disabled is probably OK, but
if any counter drivers are added that use I2C/SPI/etc. that will take
a long time to read, it would cause problems leaving interrupts
disabled here.

Brainstorming: Would it make sense to separate the event from the
component value being read? As I mentioned in one of my previous
reviews, I think there are some cases where we would just want to
know when an event happened and not read any additional data anyway.
In the case of a slow communication bus, this would also let us
queue the event in the kfifo and notify poll right away and then
defer the reads in a workqueue for later.




+   if (err)
+   goto err_counter_get_data;
+
+   ev.watch.component = comp_node->component;
+
+   copied += kfifo_put(>events, ev);
+   }
+
+   if (copied)
+   wake_up_poll(>events_wait, EPOLLIN);
+
+exit_early:
+   raw_spin_unlock_irqrestore(>events_lock, flags);
+
+   return 0;
+
+err_counter_get_data:
+   raw_spin_unlock_irqrestore(>events_lock, flags);
+   return err;
+}




Re: [PATCH v5 3/5] counter: Add character device interface

2020-10-13 Thread David Lechner

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

This patch introduces a character device interface for the Counter
subsystem. Device data is exposed through standard character device read
operations. Device data is gathered when a Counter event is pushed by
the respective Counter device driver. Configuration is handled via ioctl
operations on the respective Counter character device node.



Probably don't need to duplicate the full documentation in the commit
message.



diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c
new file mode 100644
index ..2be3846e4105
--- /dev/null
+++ b/drivers/counter/counter-chrdev.c




+
+static int counter_set_event_node(struct counter_device *const counter,
+ struct counter_watch *const watch,
+ const struct counter_comp_node *const cfg)
+{
+   struct counter_event_node *event_node;
+   int err;
+   struct counter_comp_node *comp_node;
+
+   /* Search for event in the list */
+   list_for_each_entry(event_node, >next_events_list, l)
+   if (event_node->event == watch->event &&
+   event_node->channel == watch->channel)
+   break;
+
+   /* If event is not already in the list */
+   if (_node->l == >next_events_list) {
+   /* Allocate new event node */
+   event_node = kmalloc(sizeof(*event_node), GFP_ATOMIC);
+   if (!event_node)
+   return -ENOMEM;
+
+   /* Configure event node and add to the list */
+   event_node->event = watch->event;
+   event_node->channel = watch->channel;
+   INIT_LIST_HEAD(_node->comp_list);
+   list_add(_node->l, >next_events_list);
+   }
+
+   /* Check if component watch has already been set before */
+   list_for_each_entry(comp_node, _node->comp_list, l)
+   if (comp_node->parent == cfg->parent &&
+   comp_node->comp.count_u8_read == cfg->comp.count_u8_read)
+   return -EINVAL;


There are already enough things that could cause EINVAL, we could
probably skip this duplicate check to make troubleshooting easier.


+
+   /* Allocate component node */
+   comp_node = kmalloc(sizeof(*comp_node), GFP_ATOMIC);
+   if (!comp_node) {
+   err = -ENOMEM;
+   goto err_comp_node;


Since there is only one goto, we could just handle the error and
return here instead.


+   }
+   *comp_node = *cfg;
+
+   /* Add component node to event node */
+   list_add_tail(_node->l, _node->comp_list);
+
+   return 0;
+
+err_comp_node:


A comment explaining the list_empty() check would be nice.
It makes sense if you think about it, but it is not super
obvious.


+   if (list_empty(_node->comp_list)) {
+   list_del(_node->l);
+   kfree(event_node);
+   }
+   return err;
+}
+
+static int counter_set_watch(struct counter_device *const counter,
+const unsigned long arg)
+{
+   void __user *const uwatch = (void __user *)arg;
+   struct counter_watch watch;
+   struct counter_comp_node comp_node;
+   size_t parent, id;
+   struct counter_comp *ext;
+   size_t num_ext;
+
+   if (copy_from_user(, uwatch, sizeof(watch)))
+   return -EFAULT;
+   parent = watch.component.parent;
+   id = watch.component.id;
+
+   /* Configure parent component info for comp node */
+   switch (watch.component.scope) {
+   case COUNTER_SCOPE_DEVICE:
+   comp_node.parent = NULL;
+
+   ext = counter->ext;
+   num_ext = counter->num_ext;
+   break;
+   case COUNTER_SCOPE_SIGNAL:
+   if (counter->num_signals < parent + 1)


I think it would be more conventional this way:

if (parent >= counter->num_signals)


+   return -EINVAL;
+
+   comp_node.parent = counter->signals + parent;
+
+   ext = counter->signals[parent].ext;
+   num_ext = counter->signals[parent].num_ext;
+   break;
+   case COUNTER_SCOPE_COUNT:
+   if (counter->num_counts < parent + 1)


Same here.


+   return -EINVAL;
+
+   comp_node.parent = counter->counts + parent;
+
+   ext = counter->counts[parent].ext;
+   num_ext = counter->counts[parent].num_ext;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   /* Configure component info for comp node */
+   switch (watch.component.type) {
+   case COUNTER_COMPONENT_SIGNAL:
+   if (watch.component.scope != COUNTER_SCOPE_SIGNAL)
+   return -EINVAL;
+
+   comp_node.comp.type = COUNTER_COMP_SIGNAL_LEVEL;
+   comp_node.comp.signal_u8_read = 

Re: [PATCH v5 5/5] counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8

2020-10-13 Thread David Lechner

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

+static irqreturn_t quad8_irq_handler(int irq, void *quad8iio)
+{
+   struct quad8_iio *const priv = quad8iio;
+   const unsigned long base = priv->base;
+   unsigned long irq_status;
+   unsigned long channel;
+   u8 event;
+   int err;
+
+   irq_status = inb(base + QUAD8_REG_INTERRUPT_STATUS);
+   if (!irq_status)
+   return IRQ_NONE;
+
+   for_each_set_bit(channel, _status, QUAD8_NUM_COUNTERS) {
+   switch (priv->irq_trigger[channel]) {
+   case 0:
+   event = COUNTER_EVENT_OVERFLOW;
+   break;
+   case 1:
+   event = COUNTER_EVENT_THRESHOLD;
+   break;
+   case 2:
+   event = COUNTER_EVENT_OVERFLOW_UNDERFLOW;
+   break;
+   case 3:
+   event = COUNTER_EVENT_INDEX;
+   break;
+   default:
+   /* We should never reach here */
+   return -EINVAL;


This is not a valid return value for an IRQ handler. Maybe WARN_ONCE instead?


+   }
+   err = counter_push_event(>counter, event, channel);
+   if (err)
+   return err;


Same here. Otherwise, I think we could end up with interrupts in an endless
loop since the interrupt would never be cleared.


+   }
+
+   /* Clear pending interrupts on device */
+   outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
+
+   return IRQ_HANDLED;
+}
+




Re: [PATCH v5 4/5] docs: counter: Document character device interface

2020-10-13 Thread David Lechner

On 10/13/20 1:58 PM, William Breathitt Gray wrote:

On Mon, Oct 12, 2020 at 12:04:10PM -0500, David Lechner wrote:

On 10/8/20 7:28 AM, William Breathitt Gray wrote:

On Thu, Oct 08, 2020 at 10:09:09AM +0200, Pavel Machek wrote:

Hi!


+int main(void)
+{
+struct pollfd pfd = { .events = POLLIN };
+struct counter_event event_data[2];
+
+pfd.fd = open("/dev/counter0", O_RDWR);
+
+ioctl(pfd.fd, COUNTER_SET_WATCH_IOCTL, watches);
+ioctl(pfd.fd, COUNTER_SET_WATCH_IOCTL, watches + 1);
+ioctl(pfd.fd, COUNTER_LOAD_WATCHES_IOCTL);
+
+for (;;) {
+poll(, 1, -1);


Why do poll, when you are doing blocking read?


+read(pfd.fd, event_data,  sizeof(event_data));


Does your new chrdev always guarantee returning complete buffer?

If so, should it behave like that?

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


I suppose you're right: a poll() should be redundant now with this
version of the character device implementation because buffers will
always return complete; so a blocking read() should achieve the same
behavior that a poll() with read() would.

I'll give some more time for additional feedback to come in for this
version of the patchset, and then likely remove support for poll() in
the v6 submission.

William Breathitt Gray



I hope that you mean that you will just remove it from the example
and not from the chardev. Otherwise it won't be possible to
integrate this with an event loop.


Would you elaborate a bit further on this? My thought process is that
because users must set the Counter Events they want to watch, and only
those Counter Events show up in the character device node, a blocking
read() would effectively behave the same as poll() with read(); if none
of the Counter Events occur, the read() just blocks until one does, thus
making the use of a poll() call redundant.

William Breathitt Gray



If the counter device was the only file descriptor being read, then yes
it wouldn't matter. But if we are using this in combination with other
file descriptors, then it is common to poll all of the file descriptors
using a single syscall to see which one is ready to read rather than
doing a non-blocking read on all of the file descriptors, which would
result in many unnecessary syscalls.


Re: [PATCH v5 1/5] counter: Internalize sysfs interface code

2020-10-12 Thread David Lechner

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

This is a reimplementation of the Generic Counter driver interface.


I'll follow up if I find any problems while testing but here are some
comments I had from looking over the patch.


diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
new file mode 100644
index ..987c6e8277eb
--- /dev/null
+++ b/drivers/counter/counter-core.c




+/**
+ * counter_register - register Counter to the system
+ * @counter:   pointer to Counter to register
+ *
+ * This function registers a Counter to the system. A sysfs "counter" directory
+ * will be created and populated with sysfs attributes correlating with the
+ * Counter Signals, Synapses, and Counts respectively.
+ */
+int counter_register(struct counter_device *const counter)
+{
+   struct device *const dev = >dev;
+   int err;
+
+   /* Acquire unique ID */
+   counter->id = ida_simple_get(_ida, 0, 0, GFP_KERNEL);
+   if (counter->id < 0)
+   return counter->id;
+
+   /* Configure device structure for Counter */
+   dev->type = _device_type;
+   dev->bus = _bus_type;
+   if (counter->parent) {
+   dev->parent = counter->parent;
+   dev->of_node = counter->parent->of_node;
+   }
+   dev_set_name(dev, "counter%d", counter->id);
+   device_initialize(dev);> +   dev_set_drvdata(dev, counter);
+
+   /* Add Counter sysfs attributes */
+   err = counter_sysfs_add(counter);
+   if (err)
+   goto err_free_id;
+
+   /* Add device to system */
+   err = device_add(dev);
+   if (err) {
+   put_device(dev);
+   goto err_free_id;
+   }
+
+   return 0;
+
+err_free_id:
+   /* get_device/put_device combo used to free managed resources */
+   get_device(dev);
+   put_device(dev);


I've never seen this in a driver before, so it makes me think this is
not the "right way" to do this. After device_initialize() is called, we
already should have a reference to dev, so only device_put() is needed.



+   ida_simple_remove(_ida, counter->id);


In the case of error after device_initialize() is called, won't this
result in ida_simple_remove() being called twice, once here and once in
the release callback?


+   return err;
+}
+EXPORT_SYMBOL_GPL(counter_register);
+
+/**
+ * counter_unregister - unregister Counter from the system
+ * @counter:   pointer to Counter to unregister
+ *
+ * The Counter is unregistered from the system; all allocated memory is freed.
+ */
+void counter_unregister(struct counter_device *const counter)
+{
+   if (!counter)
+   return;
+
+   device_unregister(>dev);
+}
+EXPORT_SYMBOL_GPL(counter_unregister);
+
+static void devm_counter_unreg(struct device *dev, void *res)


To be consistent, it would be nice to spell out unregister.


+{
+   counter_unregister(*(struct counter_device **)res);
+}
+



diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
new file mode 100644
index ..e66ed99dd5ea
--- /dev/null
+++ b/drivers/counter/counter-sysfs.c



+/**
+ * counter_sysfs_add - Adds Counter sysfs attributes to the device structure
+ * @counter:   Pointer to the Counter device structure
+ *
+ * Counter sysfs attributes are created and added to the respective device
+ * structure for later registration to the system. Resource-managed memory
+ * allocation is performed by this function, and this memory should be freed
+ * when no longer needed (automatically by a device_unregister call, or
+ * manually by a devres_release_all call).
+ */
+int counter_sysfs_add(struct counter_device *const counter)
+{
+   struct device *const dev = >dev;
+   const size_t num_groups = counter->num_signals + counter->num_counts +
+ 1;


It is OK to go past 80 columns, especially for just for a few characters.


+   struct counter_attribute_group *groups;
+   size_t i, j;
+   int err;
+   struct attribute_group *group;
+   struct counter_attribute *p;
+
+   /* Allocate space for attribute groups (signals, counts, and ext) */
+   groups = devm_kcalloc(dev, num_groups, sizeof(*groups), GFP_KERNEL);
+   if (!groups)
+   return -ENOMEM;
+
+   /* Initialize attribute lists */
+   for (i = 0; i < num_groups; i++)
+   INIT_LIST_HEAD([i].attr_list);
+
+   /* Register Counter device attributes */
+   err = counter_device_register(counter, groups);


This function name is a bit misleading. At first I though we were registering
a new counter device (struct device). Maybe counter_sysfs_create_attrs()
would be a better name? (I wouldn't mind having all functions in this
file having a "counter_sysfs_" prefix for that matter.)



diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index 1ff07faef27f..938085dead80 100644
--- a/drivers/counter/ti-eqep.c
+++ 

Re: [PATCH v5 0/5] Introduce the Counter character device interface

2020-10-12 Thread David Lechner

On 9/26/20 9:18 PM, William Breathitt Gray wrote:

The following are some questions I have about this patchset:

1. Should standard Counter component data types be defined as u8 or u32?

Many standard Counter component types such COUNTER_COMP_SIGNAL_LEVEL
have standard values defined (e.g. COUNTER_SIGNAL_LEVEL_LOW and
COUNTER_SIGNAL_LEVEL_HIGH). These values are currently handled by the
Counter subsystem code as u8 data types.

If u32 is used for these values instead, C enum structures could be
used by driver authors to implicit cast these values via the driver
callback parameters; userspace would still use u32 with no issue.

In theory this can work because GCC will treat enums are having a
32-bit size; but I worry about the possibility of build targets that
have -fshort-enums enabled, resulting in enums having a size less
than 32 bits. Would this be a problem?


We shouldn't have to worry about userspace programs using -fshort-enums
since that would break all kernel interfaces that use enums, not just
these - so no one should be using that compiler flag.

So I am in favor of using strongly typed enums with u32 as the
"generic" enum member type.



2. Should I have reserved members in the userspace structures?

The structures in include/uapi/linux/counter.h are available to
userspace applications. Should I reserve space in these structures
for future additions and usage? Will endianess and packing be a
concern here?


Since there doesn't seem to be a large number of counter devices
this probably isn't critical. Are there any aspects of counter
devices in general that couldn't be described with the proposed
structures? For example, could there be components more than two
levels deep (i.e. it would need id, parent id and grandparent id
to describe fully)?


[PATCH 3/3] ARM: omap2plus_defconfig: Enable TI eQEP counter driver

2020-10-12 Thread David Lechner
This enables the TI eQEP counter driver that is used by BeagleBone Blue.

Signed-off-by: David Lechner 
---
 arch/arm/configs/omap2plus_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/omap2plus_defconfig 
b/arch/arm/configs/omap2plus_defconfig
index fe383f5a92fb..71b1a8f4c241 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -524,6 +524,8 @@ CONFIG_PHY_DM816X_USB=m
 CONFIG_OMAP_USB2=m
 CONFIG_TI_PIPE3=y
 CONFIG_TWL4030_USB=m
+CONFIG_COUNTER=m
+CONFIG_TI_EQEP=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS_SECURITY=y
-- 
2.25.1



[PATCH 1/3] ARM: dts: am33xx: Add nodes for eQEP

2020-10-12 Thread David Lechner
This adds new nodes for the Texas Instruments Enhanced Quadrature
Encoder Pulse (eQEP) module in the PWM subsystem on AM33XX.

Signed-off-by: David Lechner 
---
 arch/arm/boot/dts/am33xx-l4.dtsi | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi
index b88d0caa4b2d..17910268df82 100644
--- a/arch/arm/boot/dts/am33xx-l4.dtsi
+++ b/arch/arm/boot/dts/am33xx-l4.dtsi
@@ -1924,6 +1924,15 @@ ecap0: ecap@100 {
status = "disabled";
};
 
+   eqep0: counter@180 {
+   compatible = "ti,am3352-eqep";
+   reg = <0x180 0x80>;
+   clocks = <_gclk>;
+   clock-names = "sysclkout";
+   interrupts = <79>;
+   status = "disabled";
+   };
+
ehrpwm0: pwm@200 {
compatible = "ti,am3352-ehrpwm",
 "ti,am33xx-ehrpwm";
@@ -1976,6 +1985,15 @@ ecap1: ecap@100 {
status = "disabled";
};
 
+   eqep1: counter@180 {
+   compatible = "ti,am3352-eqep";
+   reg = <0x180 0x80>;
+   clocks = <_gclk>;
+   clock-names = "sysclkout";
+   interrupts = <88>;
+   status = "disabled";
+   };
+
ehrpwm1: pwm@200 {
compatible = "ti,am3352-ehrpwm",
 "ti,am33xx-ehrpwm";
@@ -2028,6 +2046,15 @@ ecap2: ecap@100 {
status = "disabled";
};
 
+   eqep2: counter@180 {
+   compatible = "ti,am3352-eqep";
+   reg = <0x180 0x80>;
+   clocks = <_gclk>;
+   clock-names = "sysclkout";
+   interrupts = <89>;
+   status = "disabled";
+   };
+
ehrpwm2: pwm@200 {
compatible = "ti,am3352-ehrpwm",
 "ti,am33xx-ehrpwm";
-- 
2.25.1



[PATCH 0/3] Enable eQEP counter driver on BeagleBone Blue

2020-10-12 Thread David Lechner
This series adds device tree nodes for the eQEP portion of the PWMSS on AM33xx
and enables it on BeagleBone Blue.

I actually submitted these a year ago, but it looks like these patches never got
applied with the actual eQEP driver when it was merged.

For reference, there was some previous discussion about the clocks in "ARM: dts:
am33xx: Add nodes for eQEP". [1]

[1]: https://lore.kernel.org/linux-omap/20190723145100.gs5...@atomide.com/

I have also included a new patch to enable the eQEP driver in the defconfig.


David Lechner (3):
  ARM: dts: am33xx: Add nodes for eQEP
  ARM: dts: am335x-boneblue: Enable eQEP
  ARM: omap2plus_defconfig: Enable TI eQEP counter driver

 arch/arm/boot/dts/am335x-boneblue.dts | 54 +++
 arch/arm/boot/dts/am33xx-l4.dtsi  | 27 ++
 arch/arm/configs/omap2plus_defconfig  |  2 +
 3 files changed, 83 insertions(+)

-- 
2.25.1



[PATCH 2/3] ARM: dts: am335x-boneblue: Enable eQEP

2020-10-12 Thread David Lechner
This enables the Enhanced Quadrature Encoder Pulse (eQEP) module for
connectors E1, E2 and E3 on BeagleBone Blue.

Signed-off-by: David Lechner 
---
 arch/arm/boot/dts/am335x-boneblue.dts | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-boneblue.dts 
b/arch/arm/boot/dts/am335x-boneblue.dts
index c696d57cf364..69acaf4ea0f3 100644
--- a/arch/arm/boot/dts/am335x-boneblue.dts
+++ b/arch/arm/boot/dts/am335x-boneblue.dts
@@ -241,6 +241,30 @@ AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_OUTPUT, 
MUX_MODE2)   /* (E18) uart0_cts
AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_OUTPUT, 
MUX_MODE7) /* (M16) gmii1_rxd0.gpio2[21] */
>;
};
+
+   /* E1 */
+   eqep0_pins: pinmux_eqep0_pins {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_INPUT, 
MUX_MODE1)/* (B12) mcasp0_aclkr.eQEP0A_in */
+   AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_INPUT, 
MUX_MODE1) /* (C13) mcasp0_fsr.eQEP0B_in */
+   >;
+   };
+
+   /* E2 */
+   eqep1_pins: pinmux_eqep1_pins {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_INPUT, 
MUX_MODE2) /* (V2) lcd_data12.eQEP1A_in */
+   AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_INPUT, 
MUX_MODE2) /* (V3) lcd_data13.eQEP1B_in */
+   >;
+   };
+
+   /* E3 */
+   eqep2_pins: pinmux_eqep2_pins {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_INPUT, 
MUX_MODE4)  /* (T12) gpmc_ad12.eQEP2A_in */
+   AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT, 
MUX_MODE4)  /* (R12) gpmc_ad13.eQEP2B_in */
+   >;
+   };
 };
 
  {
@@ -419,3 +443,33 @@ ls_buf_en {
line-name = "LS_BUF_EN";
};
 };
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "okay";
+};
-- 
2.25.1



Re: [PATCH v5 4/5] docs: counter: Document character device interface

2020-10-12 Thread David Lechner

On 10/8/20 7:28 AM, William Breathitt Gray wrote:

On Thu, Oct 08, 2020 at 10:09:09AM +0200, Pavel Machek wrote:

Hi!


+int main(void)
+{
+struct pollfd pfd = { .events = POLLIN };
+struct counter_event event_data[2];
+
+pfd.fd = open("/dev/counter0", O_RDWR);
+
+ioctl(pfd.fd, COUNTER_SET_WATCH_IOCTL, watches);
+ioctl(pfd.fd, COUNTER_SET_WATCH_IOCTL, watches + 1);
+ioctl(pfd.fd, COUNTER_LOAD_WATCHES_IOCTL);
+
+for (;;) {
+poll(, 1, -1);


Why do poll, when you are doing blocking read?


+read(pfd.fd, event_data,  sizeof(event_data));


Does your new chrdev always guarantee returning complete buffer?

If so, should it behave like that?

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


I suppose you're right: a poll() should be redundant now with this
version of the character device implementation because buffers will
always return complete; so a blocking read() should achieve the same
behavior that a poll() with read() would.

I'll give some more time for additional feedback to come in for this
version of the patchset, and then likely remove support for poll() in
the v6 submission.

William Breathitt Gray



I hope that you mean that you will just remove it from the example
and not from the chardev. Otherwise it won't be possible to
integrate this with an event loop.



[tip: irq/core] irqchip/irq-pruss-intc: Implement irq_{get, set}_irqchip_state ops

2020-10-11 Thread tip-bot2 for David Lechner
The following commit has been merged into the irq/core branch of tip:

Commit-ID: b1026e8a95e430e615579f14f0f73c94f9690468
Gitweb:
https://git.kernel.org/tip/b1026e8a95e430e615579f14f0f73c94f9690468
Author:David Lechner 
AuthorDate:Wed, 16 Sep 2020 18:36:37 +02:00
Committer: Marc Zyngier 
CommitterDate: Thu, 17 Sep 2020 12:20:32 +01:00

irqchip/irq-pruss-intc: Implement irq_{get, set}_irqchip_state ops

This implements the irq_get_irqchip_state and irq_set_irqchip_state
callbacks for the TI PRUSS INTC driver. The set callback can be used
by drivers to "kick" a PRU by injecting a PRU system event.

Co-developed-by: Suman Anna 
Co-developed-by: Grzegorz Jaszczyk 
Signed-off-by: Suman Anna 
Signed-off-by: David Lechner 
Signed-off-by: Grzegorz Jaszczyk 
Reviewed-by: Lee Jones 
Signed-off-by: Marc Zyngier 
---
 drivers/irqchip/irq-pruss-intc.c | 40 +++-
 1 file changed, 40 insertions(+)

diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
index e7ba358..bfe529a 100644
--- a/drivers/irqchip/irq-pruss-intc.c
+++ b/drivers/irqchip/irq-pruss-intc.c
@@ -12,6 +12,7 @@
  * Copyright (C) 2019 David Lechner 
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -323,6 +324,43 @@ static void pruss_intc_irq_relres(struct irq_data *data)
module_put(THIS_MODULE);
 }
 
+static int pruss_intc_irq_get_irqchip_state(struct irq_data *data,
+   enum irqchip_irq_state which,
+   bool *state)
+{
+   struct pruss_intc *intc = irq_data_get_irq_chip_data(data);
+   u32 reg, mask, srsr;
+
+   if (which != IRQCHIP_STATE_PENDING)
+   return -EINVAL;
+
+   reg = PRU_INTC_SRSR(data->hwirq / 32);
+   mask = BIT(data->hwirq % 32);
+
+   srsr = pruss_intc_read_reg(intc, reg);
+
+   *state = !!(srsr & mask);
+
+   return 0;
+}
+
+static int pruss_intc_irq_set_irqchip_state(struct irq_data *data,
+   enum irqchip_irq_state which,
+   bool state)
+{
+   struct pruss_intc *intc = irq_data_get_irq_chip_data(data);
+
+   if (which != IRQCHIP_STATE_PENDING)
+   return -EINVAL;
+
+   if (state)
+   pruss_intc_write_reg(intc, PRU_INTC_SISR, data->hwirq);
+   else
+   pruss_intc_write_reg(intc, PRU_INTC_SICR, data->hwirq);
+
+   return 0;
+}
+
 static struct irq_chip pruss_irqchip = {
.name   = "pruss-intc",
.irq_ack= pruss_intc_irq_ack,
@@ -330,6 +368,8 @@ static struct irq_chip pruss_irqchip = {
.irq_unmask = pruss_intc_irq_unmask,
.irq_request_resources  = pruss_intc_irq_reqres,
.irq_release_resources  = pruss_intc_irq_relres,
+   .irq_get_irqchip_state  = pruss_intc_irq_get_irqchip_state,
+   .irq_set_irqchip_state  = pruss_intc_irq_set_irqchip_state,
 };
 
 static int pruss_intc_validate_mapping(struct pruss_intc *intc, int event,


Re: [PATCH 15/18] counter: use semicolons rather than commas to separate statements

2020-09-28 Thread David Lechner

On 9/27/20 2:12 PM, Julia Lawall wrote:

Replace commas with semicolons.  What is done is essentially described by
the following Coccinelle semantic patch (http://coccinelle.lip6.fr/):

// 
@@ expression e1,e2; @@
e1
-,
+;
e2
... when any
// 

Signed-off-by: Julia Lawall 

---

Reviewed-by: David Lechner 



Re: [PATCH 09/10] clk: davinci: Add missing kerneldoc

2020-09-02 Thread David Lechner

On 9/2/20 10:03 AM, Krzysztof Kozlowski wrote:

Add missing kerneldoc to fix compile warning:

   drivers/clk/davinci/da8xx-cfgchip.c:578: warning: Function parameter or 
member 'dev' not described in 'da8xx_cfgchip_register_usb1_clk48'

Signed-off-by: Krzysztof Kozlowski 
---


Reviewed-by: David Lechner 



Re: [PATCH 10/10] clk: davinci: Simplify with dev_err_probe()

2020-09-02 Thread David Lechner

On 9/2/20 10:03 AM, Krzysztof Kozlowski wrote:

Common pattern of handling deferred probe can be simplified with
dev_err_probe().  Less code and the error value gets printed.

Signed-off-by: Krzysztof Kozlowski 
---


Reviewed-by: David Lechner 



Re: [PATCH 5/5] power: supply: lego_ev3: Simplify with dev_err_probe()

2020-08-26 Thread David Lechner

On 8/26/20 9:48 AM, Krzysztof Kozlowski wrote:

Common pattern of handling deferred probe can be simplified with
dev_err_probe().  Less code and also it prints the error value.

Signed-off-by: Krzysztof Kozlowski 
---


Reviewed-by: David Lechner 



Re: [PATCH] power: supply: Add dependency to lego-ev3-battery Kconfig options

2020-08-17 Thread David Lechner

On 8/17/20 12:43 PM, Alex Dewar wrote:

On Wed, Aug 12, 2020 at 02:12:57PM -0500, David Lechner wrote:

On 8/12/20 2:02 PM, Alex Dewar wrote:

On Wed, Aug 12, 2020 at 10:24:30AM -0500, David Lechner wrote:

On 8/12/20 8:37 AM, Alex Dewar wrote:

On Tue, Aug 11, 2020 at 09:24:10AM -0500, David Lechner wrote:

On 8/9/20 1:54 PM, Alex Dewar wrote:

This battery appears only to be used by a single board (DA850), so it
makes sense to add this to the Kconfig file so that users don't build
the module unnecessarily. It currently seems to be built for the x86
Arch Linux kernel where it's probably not doing much good.


It would probably also make sense to add "default n" since it only
applies to one board in the entire arch.


Ah ok. That makes sense. Would you like me to send a follow-on patch for
this?


You can just send a v2 patch that includes the change below and the
additional change.


I've just had a look at the documentation[1] and it seems that as there's
no "default y" there it'll default to n anyway. Have I got that right?

[1] 
https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html#menu-attributes



Yes, that seems right. That makes me wonder why this would have been enabled in
the Arch Linux kernel for x86 then.


Not sure, maybe the Arch devs like Lego? ;-)

Are you happy to give an Acked-by for this anyhoo?


Yup.

Acked-by: David Lechner 



@Sebastian, are you happy to pick up this patch?

Best,
Alex





Re: [PATCH] power: supply: Add dependency to lego-ev3-battery Kconfig options

2020-08-12 Thread David Lechner

On 8/12/20 2:02 PM, Alex Dewar wrote:

On Wed, Aug 12, 2020 at 10:24:30AM -0500, David Lechner wrote:

On 8/12/20 8:37 AM, Alex Dewar wrote:

On Tue, Aug 11, 2020 at 09:24:10AM -0500, David Lechner wrote:

On 8/9/20 1:54 PM, Alex Dewar wrote:

This battery appears only to be used by a single board (DA850), so it
makes sense to add this to the Kconfig file so that users don't build
the module unnecessarily. It currently seems to be built for the x86
Arch Linux kernel where it's probably not doing much good.


It would probably also make sense to add "default n" since it only
applies to one board in the entire arch.


Ah ok. That makes sense. Would you like me to send a follow-on patch for
this?


You can just send a v2 patch that includes the change below and the
additional change.


I've just had a look at the documentation[1] and it seems that as there's
no "default y" there it'll default to n anyway. Have I got that right?

[1] 
https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html#menu-attributes



Yes, that seems right. That makes me wonder why this would have been enabled in
the Arch Linux kernel for x86 then.


Re: [PATCH] clk: davinci: Use the correct size when allocating memory

2020-08-12 Thread David Lechner

On 8/9/20 9:49 AM, Christophe JAILLET wrote:

'sizeof(*pllen)' should be used in place of 'sizeof(*pllout)' to avoid a
small over-allocation.

Fixes: 2d1726915159 ("clk: davinci: New driver for davinci PLL clocks")
Signed-off-by: Christophe JAILLET 
---


Reviewed-by: David Lechner 


Re: [PATCH] power: supply: Add dependency to lego-ev3-battery Kconfig options

2020-08-12 Thread David Lechner

On 8/12/20 8:37 AM, Alex Dewar wrote:

On Tue, Aug 11, 2020 at 09:24:10AM -0500, David Lechner wrote:

On 8/9/20 1:54 PM, Alex Dewar wrote:

This battery appears only to be used by a single board (DA850), so it
makes sense to add this to the Kconfig file so that users don't build
the module unnecessarily. It currently seems to be built for the x86
Arch Linux kernel where it's probably not doing much good.


It would probably also make sense to add "default n" since it only
applies to one board in the entire arch.


Ah ok. That makes sense. Would you like me to send a follow-on patch for
this?


You can just send a v2 patch that includes the change below and the
additional change.



Alex



BATTERY_LEGO_EV3 is already explicitly set to "m" in the appropriate
defconfig file, so I don't think it would break anything.



Signed-off-by: Alex Dewar 
---
   drivers/power/supply/Kconfig | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index faf2830aa1527..9f76e2f47ac6d 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -164,7 +164,7 @@ config BATTERY_DS2782
   config BATTERY_LEGO_EV3
tristate "LEGO MINDSTORMS EV3 battery"
-   depends on OF && IIO && GPIOLIB
+   depends on OF && IIO && GPIOLIB && (ARCH_DAVINCI_DA850 || COMPILE_TEST)
help
  Say Y here to enable support for the LEGO MINDSTORMS EV3 battery.







Re: [PATCH] power: supply: Add dependency to lego-ev3-battery Kconfig options

2020-08-11 Thread David Lechner

On 8/9/20 1:54 PM, Alex Dewar wrote:

This battery appears only to be used by a single board (DA850), so it
makes sense to add this to the Kconfig file so that users don't build
the module unnecessarily. It currently seems to be built for the x86
Arch Linux kernel where it's probably not doing much good.


It would probably also make sense to add "default n" since it only
applies to one board in the entire arch.

BATTERY_LEGO_EV3 is already explicitly set to "m" in the appropriate
defconfig file, so I don't think it would break anything.



Signed-off-by: Alex Dewar 
---
  drivers/power/supply/Kconfig | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index faf2830aa1527..9f76e2f47ac6d 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -164,7 +164,7 @@ config BATTERY_DS2782
  
  config BATTERY_LEGO_EV3

tristate "LEGO MINDSTORMS EV3 battery"
-   depends on OF && IIO && GPIOLIB
+   depends on OF && IIO && GPIOLIB && (ARCH_DAVINCI_DA850 || COMPILE_TEST)
help
  Say Y here to enable support for the LEGO MINDSTORMS EV3 battery.
  





Re: [PATCH v4 3/5] counter: Add character device interface

2020-08-10 Thread David Lechner

On 8/9/20 9:51 AM, William Breathitt Gray wrote:

On Tue, Jul 28, 2020 at 07:20:03PM -0500, David Lechner wrote:

On 7/21/20 2:35 PM, William Breathitt Gray wrote:

This patch introduces a character device interface for the Counter
subsystem. Device data is exposed through standard character device read
operations. Device data is gathered when a Counter event is pushed by
the respective Counter device driver. Configuration is handled via ioctl
operations on the respective Counter character device node.


This sounds similar to triggers and buffers in the iio subsystem. And
I can see how it might be useful in some cases. But I think it would not
give the desired results when performance is important.

Thinking through a few cases here...

Suppose there was a new counter device that used the I2C bus. This would
either have to be periodically polled for events or it might have a
separate GPIO line to notify the MCU. In any case, with the proposed
implementation, there would be a separate I2C transaction for each data
point for that event. So none of the data for that event would actually
be from the same point in time. And with I2C, this time difference could
be significant.

With the TI eQEP I have been working with, there are special latched
registers for some events. To make use of these with events, we would have
add extensions for each one we want to use (and expose it in sysfs). But
really, the fact that we are using a latched register should be an
implementation detail in the driver and not something userspace should have
to know about.

So, I'm wondering if it would make sense to keep things simpler and have
events like the input subsystem where the event value is directly tied
to the event. It would probably be rare for an event to have more than
one or two values. And error events probably would not have a value at
all.

For example, with the TI eQEP, there is a unit timer time out event.
This latches the position count, the timer count and the timer period.
To translate this to an event data structure, the latched time would
be the event timestamp and the position count would be the event value.
The timer period should already be known since we would have configured
the timer ourselves. There is also a count event that works similarly.
In this case, the latched time would be the event timestamp and the
latched timer period would be the event value. We would know the count
already since we get an event for each count (and a separate direction
change event if the direction changes).


There are use-cases where it would be useful to have the extension reads
occur as close to the event trigger as possible (e.g. multiple-axes
positioning with boundary sensor flags) so I don't think this
functionality should be completely abadoned, but I think your argument
for standard event types makes sense.

We could treat those extensions reads as an optional feature that can be
enabled and configured by ioctls. However, the use-case you are
concerned with, we can redesign Counter events to return specific data
based on the specific event type.

For example, we could have a COUNTER_EVENT_INDEX which occurs when an
Index signal edge is detected, and the return data is the Count value
for that channel; we can also have a COUNTER_EVENT_TIMEOUT which occurs
when a unit timer times out, and returns the data you mentioned you are
interested in seeing.

These Counter event types would be standard, so user applications
wouldn't need to know driver/device implementation details, but instead
just follow the API to get the data they expect for that particular
event type. Would this kind of design work for your needs?



Yes. After trying (and failing) to implement my suggestions here, I
came to the conclusion that it was not sufficient to only have one
value per event. And it doesn't seem as obvious as I initially thought
which should be the "standard" value for an event in some cases.



When `counter_push_event(counter, 1)` is called for example, it will go
down the list for Event 1 and execute the read callbacks for Signal 0,
Signal 0 Extension 0, and Extension 4 -- the data returned for each is
pushed to a kfifo as a `struct counter_event`, which userspace can
retrieve via a standard read operation on the respective character
device node.

Userspace
-
Userspace applications can configure Counter events via ioctl operations
on the Counter character device node. There following ioctl codes are
supported and provided by the `linux/counter.h` userspace header file:

* COUNTER_CLEAR_WATCHES_IOCTL:
Clear all Counter watches from all events

* COUNTER_SET_WATCH_IOCTL:
Set a Counter watch on the specified event

To configure events to gather Counter data, users first populate a
`struct counter_watch` with the relevant event id and the information
for the desired Counter component from which to read, and then pass it
via the `COUNTER_SET_WATCH_IOCTL` ioctl command.

Userspace applications can then execu

Re: [PATCH v4 1/5] counter: Internalize sysfs interface code

2020-08-10 Thread David Lechner




CPMAC ETHERNET DRIVER

M:  Florian Fainelli 
diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index 78766b6ec271..0f20920073d6 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -621,7 +621,7 @@ static const struct iio_chan_spec quad8_channels[] = {
};

static int quad8_signal_read(struct counter_device *counter,

-   struct counter_signal *signal, enum counter_signal_value *val)
+struct counter_signal *signal, u8 *val)


I'm not a fan of replacing enum types with u8 everywhere in this patch.
But if we have to for technical reasons (e.g. causes compiler error if
we don't) then it would be helpful to add comments giving the enum type
everywhere like this instance where u8 is actually an enum value.

If we use u32 as the generic type for enums instead of u8, I think the
compiler will happlily let us use enum type and u32 interchangeably and
not complain.


I switched to fixed-width types after the suggestion by David Laight:
https://lkml.org/lkml/2020/5/3/159. I'll CC David Laight just in case he
wants to chime in again.

Enum types would be nice for making the valid values explicit, but there
is one benefit I have appreciated from the move to fixed-width types:
there has been a significant reduction of duplicate code; before, we had
a different read function for each different enum type, but now we use a
single function to handle them all.


Yes, what I was trying to explain is that by using u32 instead of u8, I
think we can actually do both.

The function pointers in struct counter_device *counter would use u32 as a
generic enum value in the declaration, but then the actual implementations
could still use the proper enum type.


Oh, I see what you mean now. So for example:

 int (*signal_read)(struct counter_device *counter,
struct counter_signal *signal, u8 *val)

This will become instead:

 int (*signal_read)(struct counter_device *counter,
struct counter_signal *signal, u32 *val)

Then in the driver callback implementation we use the enum type we need:

 enum counter_signal_level signal_level = COUNTER_SIGNAL_HIGH;
 ...
 *val = signal_level;

Is that what you have in mind?



Yes.

Additionally, if we have...


  int (*x_write)(struct counter_device *counter,
 ..., u32 val)
 
We should be able to define the implementation as:


static int my_driver_x_write(struct counter_device *counter,
 ..., enum some_type val)
{
...
}

Not sure if it works if val is a pointer though. Little-
endian systems would probably be fine, but maybe not big-
endian combined with -fshort-enums compiler flag.


  int (*x_read)(struct counter_device *counter,
..., u32 *val)
 


static int my_driver_x_read(struct counter_device *counter,
..., enum some_type *val)
{
...
}



Re: [PATCH v4 1/5] counter: Internalize sysfs interface code

2020-08-03 Thread David Lechner

On 8/2/20 4:04 PM, William Breathitt Gray wrote:

On Tue, Jul 28, 2020 at 05:45:53PM -0500, David Lechner wrote:

On 7/21/20 2:35 PM, William Breathitt Gray wrote:

This is a reimplementation of the Generic Counter driver interface.


...


-F: include/linux/counter_enum.h
+F: include/uapi/linux/counter.h


Seems odd to be introducing a uapi header here since this patch doesn't
make any changes to userspace.


These defines are needed by userspace for the character device
interface, but I see your point that at this point in the patchset they
don't need to be exposed yet.

I could create temporary include/linux/counter_types.h to house these
defines, and then later move them to include/uapi/linux/counter.h in the
character device interface introduction patch. Do you think I should do
so?


Since this patch is independent of the chardev changes and probably ready
to merge after one more round of review, I would say it probably makes
sense to just leave them in counter.h for now and move them to uapi when
the chardev interface is finalized. This way, we can just merge this patch
as soon as it is ready.



   
   CPMAC ETHERNET DRIVER

   M:   Florian Fainelli 
diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index 78766b6ec271..0f20920073d6 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -621,7 +621,7 @@ static const struct iio_chan_spec quad8_channels[] = {
   };
   
   static int quad8_signal_read(struct counter_device *counter,

-   struct counter_signal *signal, enum counter_signal_value *val)
+struct counter_signal *signal, u8 *val)


I'm not a fan of replacing enum types with u8 everywhere in this patch.
But if we have to for technical reasons (e.g. causes compiler error if
we don't) then it would be helpful to add comments giving the enum type
everywhere like this instance where u8 is actually an enum value.

If we use u32 as the generic type for enums instead of u8, I think the
compiler will happlily let us use enum type and u32 interchangeably and
not complain.


I switched to fixed-width types after the suggestion by David Laight:
https://lkml.org/lkml/2020/5/3/159. I'll CC David Laight just in case he
wants to chime in again.

Enum types would be nice for making the valid values explicit, but there
is one benefit I have appreciated from the move to fixed-width types:
there has been a significant reduction of duplicate code; before, we had
a different read function for each different enum type, but now we use a
single function to handle them all.


Yes, what I was trying to explain is that by using u32 instead of u8, I
think we can actually do both.

The function pointers in struct counter_device *counter would use u32 as a
generic enum value in the declaration, but then the actual implementations
could still use the proper enum type.




+   device_del(>dev);
+   counter_sysfs_free(counter);


Should sysfs be freed before deleting device? I think sysfs might be
using dev still.


I think it's the other way around isn't it? The Counter sysfs memory
should stay alive for the lifetime of the device. Once the device is
deleted, there's nothing left to access those struct attributes, so that
memory can now be freed. Correct me if my reasoning is wrong here.


I think you are right. I was thinking that device_del() would free
memory, but it doesn't. It also looks like other drivers call
device_put() after this, so maybe needed here too?


+static ssize_t counter_data_u8_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   const struct counter_attribute *const a = to_counter_attribute(attr);
+   struct counter_device *const counter = dev_get_drvdata(dev);
+   const struct counter_available *const avail = a->data.priv;
+   int err;
+   u8 data;
+
+   switch (a->type) {


I don't understand the use of the word "owner" here. What is being "owned"?

Perhaps "component" would be a better choice?


I wasn't too set on calling this "owner" either, but I'm not sure if
"component" would make sense either because I wouldn't label a device
attribute as belonging to any particular component (in fact it's quite
the opposite).

Perhaps the word "scope" would be better. What do you think? Or would
that be too vague as well.


"scope" makes sense to me.


-/**
- * struct counter_signal_ext - Counter Signal extensions
- * @name:  attribute name
- * @read:  read callback for this attribute; may be NULL
- * @write: write callback for this attribute; may be NULL
- * @priv:  data private to the driver
- */
-struct counter_signal_ext {
+enum counter_data_type {
+   COUNTER_DATA_TYPE_U8,
+   COUNTER_DATA_TYPE_U64,
+   COUNTER_DATA_TYPE_BOOL,
+   COUNTER_DATA_TYPE_SIGNAL,


Does this mean signal name?


This repre

Re: [PATCH v4 4/5] irqchip/irq-pruss-intc: Implement irq_{get,set}_irqchip_state ops

2020-07-31 Thread David Lechner

On 7/31/20 7:28 AM, Grzegorz Jaszczyk wrote:

On Wed, 29 Jul 2020 at 21:23, David Lechner  wrote:


On 7/28/20 4:18 AM, Grzegorz Jaszczyk wrote:

From: David Lechner 

This implements the irq_get_irqchip_state and irq_set_irqchip_state
callbacks for the TI PRUSS INTC driver. The set callback can be used
by drivers to "kick" a PRU by injecting a PRU system event.

Example:


We could improve this example by showing a device tree node of a
firmware-defined device implemented in the PRU:

 /* Software-defined UART in PRU */
 pru_uart: serial@ {
 compatible = "ti,pru-uart";
 ...
 interrupt-parent = <_intc>;
 /* PRU system event 31, channel 0, host event 0 */
 interrupts = <31 0 0>, ...;
 interrupt-names = "kick", ...;
 ...
 },

Then driver would request the IRQ during probe:

 data->kick_irq = of_irq_get_byname(dev, "kick");
 if (data->kick_irq < 0)
 ...


And later the driver would use the IRQ to kick the PRU:

 irq_set_irqchip_state(data->kick_irq, IRQCHIP_STATE_PENDING, true);




We could but I am not sure if this kind of complex example should land
in the commit log.
Marc could you please comment how you want to see this?

Thank you,
Grzegorz



Based on the discussion in the device tree binding patch, the expanded
example I gave is incorrect, so we can just drop it.


Re: [PATCH v4 1/5] dt-bindings: irqchip: Add PRU-ICSS interrupt controller bindings

2020-07-31 Thread David Lechner

On 7/31/20 6:48 AM, Grzegorz Jaszczyk wrote:

On Wed, 29 Jul 2020 at 19:34, David Lechner  wrote:

It is not clear what the meaning of each cell is. Looking at later patches, it
looks like the first cell is the PRU system event number, the second cell is the
channel and the third cell is the host event number.


Ok, how about updating above description like this:
Client users shall use the PRU System event number (the interrupt source
that the client is interested in) [cell 1], PRU channel [cell 2] and PRU
host_intr (target) [cell 3] as the value of the interrupts property in their
node.  The system events can be mapped to some output host interrupts through 2
levels of many-to-one mapping i.e. events to channel mapping and channels to
host interrupts so through this property entire mapping is provided.


Cell 3 is host_intr0-7? How would we map to other host events?


Re: [PATCH v4 3/5] counter: Add character device interface

2020-07-30 Thread David Lechner

On 7/28/20 7:20 PM, David Lechner wrote:

On 7/21/20 2:35 PM, William Breathitt Gray wrote:

This patch introduces a character device interface for the Counter
subsystem. Device data is exposed through standard character device read
operations. Device data is gathered when a Counter event is pushed by
the respective Counter device driver. Configuration is handled via ioctl
operations on the respective Counter character device node.


This sounds similar to triggers and buffers in the iio subsystem. And
I can see how it might be useful in some cases. But I think it would not
give the desired results when performance is important.



By the way, I really appreciate the work you have done here. When reviewing
code, it is easy to point out what is wrong or we don't like and to not
mention all the parts that are good. And there is a lot of really good work
here already.

I've been working on this all week to try out some of my suggestions and
I'm not getting very far. This is a very difficult problem to solve!

I just wanted to mention this since I responded to this patch series
already but I am still learning and trying things. So I may have more/
different feedback in the future and I may decide some of my suggestions
are not so good. :-)

And one more thing, there was a nice talk at the Embedded Linux
Conference last month about lessons learned from designing a userspace
API for the GPIO subsystem [1]. Unfortunately, there is no video yet,
but the slides might have some helpful ideas about mistakes to avoid.

[1]: https://elinux.org/ELC_2020_Presentations



Re: [PATCH v4 5/5] irqchip/irq-pruss-intc: Add support for ICSSG INTC on K3 SoCs

2020-07-29 Thread David Lechner

On 7/28/20 4:18 AM, Grzegorz Jaszczyk wrote:

From: Suman Anna 

The K3 AM65x and J721E SoCs have the next generation of the PRU-ICSS IP,
commonly called ICSSG. The PRUSS INTC present within the ICSSG supports
more System Events (160 vs 64), more Interrupt Channels and Host Interrupts
(20 vs 10) compared to the previous generation PRUSS INTC instances. The
first 2 and the last 10 of these host interrupt lines are used by the
PRU and other auxiliary cores and sub-modules within the ICSSG, with 8
host interrupts connected to MPU. The host interrupts 5, 6, 7 are also
connected to the other ICSSG instances within the SoC and can be
partitioned as per system integration through the board dts files.

Enhance the PRUSS INTC driver to add support for this ICSSG INTC
instance.

Signed-off-by: Suman Anna 
Signed-off-by: Grzegorz Jaszczyk 
---


There is not much left in this patch. Might as well squash this into
"irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts".


Re: [PATCH v4 4/5] irqchip/irq-pruss-intc: Implement irq_{get,set}_irqchip_state ops

2020-07-29 Thread David Lechner

On 7/28/20 4:18 AM, Grzegorz Jaszczyk wrote:

From: David Lechner 

This implements the irq_get_irqchip_state and irq_set_irqchip_state
callbacks for the TI PRUSS INTC driver. The set callback can be used
by drivers to "kick" a PRU by injecting a PRU system event.

Example:


We could improve this example by showing a device tree node of a
firmware-defined device implemented in the PRU:

/* Software-defined UART in PRU */
pru_uart: serial@ {
compatible = "ti,pru-uart";
...
interrupt-parent = <_intc>;
/* PRU system event 31, channel 0, host event 0 */
interrupts = <31 0 0>, ...;
interrupt-names = "kick", ...;
...
},

Then driver would request the IRQ during probe:

data->kick_irq = of_irq_get_byname(dev, "kick");
if (data->kick_irq < 0)
...


And later the driver would use the IRQ to kick the PRU:

irq_set_irqchip_state(data->kick_irq, IRQCHIP_STATE_PENDING, true);



  irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, true);

Signed-off-by: David Lechner 
Signed-off-by: Suman Anna 
Signed-off-by: Grzegorz Jaszczyk 
Reviewed-by: Lee Jones 
---


Re: [PATCH v4 3/5] irqchip/irq-pruss-intc: Add logic for handling reserved interrupts

2020-07-29 Thread David Lechner

On 7/28/20 4:18 AM, Grzegorz Jaszczyk wrote:

From: Suman Anna 

The PRUSS INTC has a fixed number of output interrupt lines that are
connected to a number of processors or other PRUSS instances or other
devices (like DMA) on the SoC. The output interrupt lines 2 through 9
are usually connected to the main Arm host processor and are referred
to as host interrupts 0 through 7 from ARM/MPU perspective.

All of these 8 host interrupts are not always exclusively connected
to the Arm interrupt controller. Some SoCs have some interrupt lines
not connected to the Arm interrupt controller at all, while a few others
have the interrupt lines connected to multiple processors in which they
need to be partitioned as per SoC integration needs. For example, AM437x
and 66AK2G SoCs have 2 PRUSS instances each and have the host interrupt 5
connected to the other PRUSS, while AM335x has host interrupt 0 shared
between MPU and TSC_ADC and host interrupts 6 & 7 shared between MPU and
a DMA controller.

Add logic to the PRUSS INTC driver to ignore both these shared and
invalid interrupts.


If a person wanted to use DMA with a PRU what will handle the mapping
of a PRU event to host interrupt 6 or 7 if they are being ignored here?



Signed-off-by: Suman Anna 
Signed-off-by: Grzegorz Jaszczyk 
---
v3->v4:
- Due to changes in DT bindings which converts irqs-reserved
   property from uint8-array to bitmask requested by Rob introduce
   relevant changes in the driver.
- Merge the irqs-reserved and irqs-shared to one property since they
   can be handled by one logic (relevant change was introduced to DT
   binding).
- Update commit message.
v2->v3:
- Extra checks for (intc->irqs[i]) in error/remove path was moved from
   "irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS
   interrupts" to this patch
v1->v2:
- https://patchwork.kernel.org/patch/11069757/
---
  drivers/irqchip/irq-pruss-intc.c | 29 -
  1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
index 45b966a..cf9a59b 100644
--- a/drivers/irqchip/irq-pruss-intc.c
+++ b/drivers/irqchip/irq-pruss-intc.c
@@ -474,7 +474,7 @@ static int pruss_intc_probe(struct platform_device *pdev)
struct pruss_intc *intc;
struct pruss_host_irq_data *host_data[MAX_NUM_HOST_IRQS] = { NULL };
int i, irq, ret;
-   u8 max_system_events;
+   u8 max_system_events, invalid_intr = 0;
  
  	data = of_device_get_match_data(dev);

if (!data)
@@ -496,6 +496,16 @@ static int pruss_intc_probe(struct platform_device *pdev)
return PTR_ERR(intc->base);
}
  
+	ret = of_property_read_u8(dev->of_node, "ti,irqs-reserved",

+ _intr);


Why not make the variable name match the property name?


+
+   /*
+* The irqs-reserved is used only for some SoC's therefore not having
+* this property is still valid
+*/
+   if (ret < 0 && ret != -EINVAL)
+   return ret;
+
pruss_intc_init(intc);
  
  	mutex_init(>lock);

@@ -506,6 +516,9 @@ static int pruss_intc_probe(struct platform_device *pdev)
return -ENOMEM;
  
  	for (i = 0; i < MAX_NUM_HOST_IRQS; i++) {

+   if (invalid_intr & BIT(i))
+   continue;
+
irq = platform_get_irq_byname(pdev, irq_names[i]);
if (irq <= 0) {
dev_err(dev, "platform_get_irq_byname failed for %s : 
%d\n",
@@ -533,8 +546,11 @@ static int pruss_intc_probe(struct platform_device *pdev)
return 0;
  
  fail_irq:

-   while (--i >= 0)
-   irq_set_chained_handler_and_data(intc->irqs[i], NULL, NULL);
+   while (--i >= 0) {
+   if (intc->irqs[i])
+   irq_set_chained_handler_and_data(intc->irqs[i], NULL,
+NULL);
+   }
  
  	irq_domain_remove(intc->domain);
  
@@ -548,8 +564,11 @@ static int pruss_intc_remove(struct platform_device *pdev)

unsigned int hwirq;
int i;
  
-	for (i = 0; i < MAX_NUM_HOST_IRQS; i++)

-   irq_set_chained_handler_and_data(intc->irqs[i], NULL, NULL);
+   for (i = 0; i < MAX_NUM_HOST_IRQS; i++) {
+   if (intc->irqs[i])
+   irq_set_chained_handler_and_data(intc->irqs[i], NULL,
+NULL);
+   }
  
  	for (hwirq = 0; hwirq < max_system_events; hwirq++)

irq_dispose_mapping(irq_find_mapping(intc->domain, hwirq));





Re: [PATCH v4 2/5] irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts

2020-07-29 Thread David Lechner

On 7/28/20 4:18 AM, Grzegorz Jaszczyk wrote:

The Programmable Real-Time Unit Subsystem (PRUSS) contains a local
interrupt controller (INTC) that can handle various system input events
and post interrupts back to the device-level initiators. The INTC can
support upto 64 input events with individual control configuration and
hardware prioritization. These events are mapped onto 10 output interrupt
lines through two levels of many-to-one mapping support. Different
interrupt lines are routed to the individual PRU cores or to the host
CPU, or to other devices on the SoC. Some of these events are sourced
from peripherals or other sub-modules within that PRUSS, while a few
others are sourced from SoC-level peripherals/devices.

The PRUSS INTC platform driver manages this PRUSS interrupt controller
and implements an irqchip driver to provide a Linux standard way for
the PRU client users to enable/disable/ack/re-trigger a PRUSS system
event. The system events to interrupt channels and output interrupts
relies on the mapping configuration provided either through the PRU
firmware blob (for interrupts routed to PRU cores) or via the PRU
application's device tree node (for interrupt routed to the main CPU).
In the first case the mappings will be programmed on PRU remoteproc
driver demand (via irq_create_fwspec_mapping) during the boot of a PRU
core and cleaned up after the PRU core is stopped.

Reference counting is used to allow multiple system events to share a
single channel and to allow multiple channels to share a single host
event.

The PRUSS INTC module is reference counted during the interrupt
setup phase through the irqchip's irq_request_resources() and
irq_release_resources() ops. This restricts the module from being
removed as long as there are active interrupt users.

The driver currently supports and can be built for OMAP architecture
based AM335x, AM437x and AM57xx SoCs; Keystone2 architecture based
66AK2G SoCs and Davinci architecture based OMAP-L13x/AM18x/DA850 SoCs.
All of these SoCs support 64 system events, 10 interrupt channels and
10 output interrupt lines per PRUSS INTC with a few SoC integration
differences.

NOTE:
Each PRU-ICSS's INTC on AM57xx SoCs is preceded by a Crossbar that
enables multiple external events to be routed to a specific number
of input interrupt events. Any non-default external interrupt event
directed towards PRUSS needs this crossbar to be setup properly.

Signed-off-by: Suman Anna 
Signed-off-by: Andrew F. Davis 
Signed-off-by: Roger Quadros 
Signed-off-by: Grzegorz Jaszczyk 
---


It looks like this patch also includes code that I wrote [1] so:

Signed-off-by: David Lechner 


[1]: 
https://lore.kernel.org/lkml/124b03b8-f8e7-682b-8767-13a739329...@lechnology.com/



diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
new file mode 100644
index 000..45b966a
--- /dev/null
+++ b/drivers/irqchip/irq-pruss-intc.c
@@ -0,0 +1,591 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PRU-ICSS INTC IRQChip driver for various TI SoCs
+ *
+ * Copyright (C) 2016-2020 Texas Instruments Incorporated - http://www.ti.com/
+ * Andrew F. Davis 
+ * Suman Anna 


Please add:

+ * Copyright (C) 2019 David Lechner 


+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Number of host interrupts reaching the main MPU sub-system. Note that this
+ * is not the same as the total number of host interrupts supported by the 
PRUSS
+ * INTC instance
+ */
+#define MAX_NUM_HOST_IRQS  8
+
+/* minimum starting host interrupt number for MPU */
+#define MIN_PRU_HOST_INT   2


nit: "First" might be a better word choice than "minimum"


+
+/* PRU_ICSS_INTC registers */
+#define PRU_INTC_REVID 0x
+#define PRU_INTC_CR0x0004
+#define PRU_INTC_GER   0x0010
+#define PRU_INTC_GNLR  0x001c
+#define PRU_INTC_SISR  0x0020
+#define PRU_INTC_SICR  0x0024
+#define PRU_INTC_EISR  0x0028
+#define PRU_INTC_EICR  0x002c
+#define PRU_INTC_HIEISR0x0034
+#define PRU_INTC_HIDISR0x0038
+#define PRU_INTC_GPIR  0x0080
+#define PRU_INTC_SRSR(x)   (0x0200 + (x) * 4)
+#define PRU_INTC_SECR(x)   (0x0280 + (x) * 4)
+#define PRU_INTC_ESR(x)(0x0300 + (x) * 4)
+#define PRU_INTC_ECR(x)(0x0380 + (x) * 4)
+#define PRU_INTC_CMR(x)(0x0400 + (x) * 4)
+#define PRU_INTC_HMR(x)(0x0800 + (x) * 4)
+#define PRU_INTC_HIPIR(x)  (0x0900 + (x) * 4)
+#define PRU_INTC_SIPR(x)   (0x0d00 + (x) * 4)
+#define PRU_INTC_SITR(x)   (0x0d80 + (x) * 4)
+#define PRU_INTC_HINLR(x)  (0x1100 + (x) * 4)
+#define PRU_INTC_HIER  0x1500
+
+/* CMR register bit-field macros */
+#define CMR_EVT_MAP_MASK   0xf
+#define CMR_EVT_MAP_BITS   8
+#define CMR_EVT_PER_REG4
+
+/* HMR register bit-field macros */
+#define HMR_CH_MAP_MASK0xf
+#de

Re: [PATCH v4 1/5] dt-bindings: irqchip: Add PRU-ICSS interrupt controller bindings

2020-07-29 Thread David Lechner

On 7/28/20 4:18 AM, Grzegorz Jaszczyk wrote:

From: Suman Anna 

The Programmable Real-Time Unit and Industrial Communication Subsystem
(PRU-ICSS or simply PRUSS) contains an interrupt controller (INTC) that
can handle various system input events and post interrupts back to the
device-level initiators. The INTC can support upto 64 input events on


nit: "up to" is two separate words


most SoCs with individual control configuration and h/w prioritization.
These events are mapped onto 10 output interrupt lines through two levels
of many-to-one mapping support. Different interrupt lines are routed to
the individual PRU cores or to the host CPU or to other PRUSS instances.

The K3 AM65x and J721E SoCs have the next generation of the PRU-ICSS IP,
commonly called ICSSG. The ICSSG interrupt controller on K3 SoCs provide
a higher number of host interrupts (20 vs 10) and can handle an increased
number of input events (160 vs 64) from various SoC interrupt sources.

Add the bindings document for these interrupt controllers on all the
applicable SoCs. It covers the OMAP architecture SoCs - AM33xx, AM437x
and AM57xx; the Keystone 2 architecture based 66AK2G SoC; the Davinci
architecture based OMAPL138 SoCs, and the K3 architecture based AM65x
and J721E SoCs.

Signed-off-by: Suman Anna 
Signed-off-by: Andrew F. Davis 
Signed-off-by: Roger Quadros 
Signed-off-by: Grzegorz Jaszczyk 
---
v3->v4:
- Drop allOf references to interrupt-controller.yaml and
   interrupts.yaml.
- Drop items descriptions and use only maxItems: 1 as suggested by Rob.
- Convert irqs-reserved property from uint8-array to bitmask.
- Minor descriptions updates.
- Change interrupt-cells to 3 in order to provide 2-level mapping
   description for interrupts routed to the main CPU (as Marc requested).
- Merge the irqs-reserved and irqs-shared to one property since they
   can be handled by one logic.
- Drop reviewed-by due to introduced changes.
- Add another example illustrating irqs-reserved property usage.
v2->v3:
- Convert dt-binding to YAML
v1->v2:
- https://patchwork.kernel.org/patch/11069767/
---
  .../interrupt-controller/ti,pruss-intc.yaml| 157 +
  1 file changed, 157 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml

diff --git 
a/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml 
b/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
new file mode 100644
index 000..7336b11
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
@@ -0,0 +1,157 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/ti,pruss-intc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI PRU-ICSS Local Interrupt Controller
+
+maintainers:
+  - Suman Anna 
+
+description: |
+  Each PRU-ICSS has a single interrupt controller instance that is common
+  to all the PRU cores. Most interrupt controllers can route 64 input events
+  which are then mapped to 10 possible output interrupts through two levels
+  of mapping. The input events can be triggered by either the PRUs and/or
+  various other PRUSS internal and external peripherals. The first 2 output
+  interrupts (0, 1) are fed exclusively to the internal PRU cores, with the
+  remaining 8 (2 through 9) connected to external interrupt controllers
+  including the MPU and/or other PRUSS instances, DSPs or devices.
+
+  The property "ti,irqs-reserved" is used for denoting the connection
+  differences on the output interrupts 2 through 9. If this property is not
+  defined, it implies that all the PRUSS INTC output interrupts 2 through 9
+  (host_intr0 through host_intr7) are connected exclusively to the Arm 
interrupt
+  controller.
+
+  The K3 family of SoCs can handle 160 input events that can be mapped to 20
+  different possible output interrupts. The additional output interrupts (10
+  through 19) are connected to new sub-modules within the ICSSG instances.
+
+  This interrupt-controller node should be defined as a child node of the
+  corresponding PRUSS node. The node should be named "interrupt-controller".
+
+properties:
+  compatible:
+enum:
+  - ti,pruss-intc
+  - ti,icssg-intc
+description: |
+  Use "ti,pruss-intc" for OMAP-L13x/AM18x/DA850 SoCs,
+  AM335x family of SoCs,
+  AM437x family of SoCs,
+  AM57xx family of SoCs
+  66AK2G family of SoCs
+  Use "ti,icssg-intc" for K3 AM65x & J721E family of SoCs
+
+  reg:
+maxItems: 1
+
+  interrupts:
+minItems: 1
+maxItems: 8
+description: |
+  All the interrupts generated towards the main host processor in the SoC.
+  A shared interrupt can be skipped if the desired destination and usage is
+  by a different processor/device.



Re: [PATCH v4 3/5] counter: Add character device interface

2020-07-28 Thread David Lechner
   .component.owner_id = 1,
 .component.type = COUNTER_COMPONENT_TYPE_COUNT,
 },
 };

 int main(void)
 {
 struct pollfd pfd = { .events = POLLIN };
 struct counter_event event_data[2];

 pfd.fd = open("/dev/counter0", O_RDWR);

 ioctl(pfd.fd, COUNTER_SET_WATCH_IOCTL, watches);
 ioctl(pfd.fd, COUNTER_SET_WATCH_IOCTL, watches + 1);


What enables events? If an event is enabled for each of these ioctls,
then we have a race condition where events events from the first watch
can start to be queued before the second watch is added. So we would
have to flush the chardev first before polling, otherwise the assumption
that event_data[0] is owner_id=0 and event_data[1] is owner_id=1 is
not true.

This is also racy if we want to clear watches and set up new watches
at runtime. There would be a period of time where there were no watches
and we could miss events.

With my suggested changes of having fixed values per event and generic
events, we could just have a single ioctl to enable and disable events.
This would probably need to take an array of event descriptors as an
argument where event descriptors contain the component type/id and the
event to enable.



 for (;;) {
 poll(, 1, -1);

 read(pfd.fd, event_data, sizeof(event_data));

 printf("Timestamp 0: %llu\nCount 0: %llu\n"
"Timestamp 1: %llu\nCount 1: %llu\n",
(unsigned long long)event_data[0].timestamp,
(unsigned long long)event_data[0].value_u64,
(unsigned long long)event_data[1].timestamp,
(unsigned long long)event_data[1].value_u64);
     }

 return 0;
 }

Cc: David Lechner 
Cc: Gwendal Grignou 
Signed-off-by: William Breathitt Gray 
---




Re: [PATCH][next] clk: davinci: Use fallthrough pseudo-keyword

2020-07-27 Thread David Lechner

On 7/27/20 3:11 PM, Gustavo A. R. Silva wrote:

Replace the existing /* fall through */ comments and its variants with
the new pseudo-keyword macro fallthrough[1].

[1] 
https://www.kernel.org/doc/html/v5.7/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through

Signed-off-by: Gustavo A. R. Silva 


Reviewed-by: David Lechner 


Re: [PATCH v3 3/4] counter: Add character device interface

2020-06-27 Thread David Lechner

On 6/27/20 1:17 PM, William Breathitt Gray wrote:

On Mon, Jun 22, 2020 at 09:08:48AM -0500, David Lechner wrote:

On 6/21/20 2:53 PM, William Breathitt Gray wrote:

For example, in the dual-axes positioning table scenario, a user
application would likely want to know the exact X and Y position at the
time of a given event -- that means an event should provide two Count
values (and possibly associated device flags) when it occurs. I'm not
sure yet how the struct counter_event should be defined in order to
support this; we will need to indicate the format of data as well as
provide the data itself. Perhaps, we can handle this by providing an
unique id field so that only a single datum (e.g. a single count value)
is provided via the value field, but subsequent struct counter_event
items share the same id so that the user knows that a particular datum
is part of a larger group of data for a specific event.


The timestamp could act as the "id" to correlate multiple values of a
single event.


Okay, I see how that can work. So the /dev/counterX character nodes
would return a stream of data structures that look something like this:

struct counter_event {
/**
 * Best approximation of when event occurred in nanoseconds.
 * Same timestamp value indicates data is part of same event.
 */
struct timeval time;
/**
 * Type of event that triggered. This would correlate with the
 * IRQ set up for the device.
 */
__u16 type;
/**
 * Type of data represented by the value member. This enables
 * the user to extract the right datatype from the value field.
 */
__u16 code;
/** The value recorded when the event fired. */
__u64 value;
};

In fact, this data structure looks a lot like struct input_event; would
it make sense to use that for this? I suppose we can't because we need
to support 64-bit value for our use cases.


Yes, since counter is its own subsystem, it makes sense to have its own
data types.



Userspace also requires a way to enable the events and configure them to
report the data it wants. So perhaps the following sysfs attributes
would accomplish such:

* /sys/bus/devices/counterX/eventY_enable:
   Users can enable/disable event Y.
* /sys/bus/devices/counterX/eventY_config:
   Data to get when event Y is triggered (e.g. Counts, extensions, etc.).


This is one of the questions I had too that I don't have a good answer to.

If we want to allow the use case of multiple "consumers" for a single
chardev where each consumer wants different events (e.g program X opens
/dev/counter0 and wants only events A and B while program Y opens the
same /dev/counter0 and wants only events A and C) then it would make
sense to use an ioctl for configuration of events so that each open
file descriptor could be configured differently.

But if we only want to allow one user of a counter, then configuring
via sysfs as you have suggested is probably fine.

I think I might make sense to us an ioctl in any case though if we are
going to use the same code values to configure the event.



Here's another concern for latency-sensitive applications: should we
handle writing data to the devices? While we have real-life examples of
latency-sensitive read operations, I'm not sure if a user will ever need
to write to a counter device within some realtime critical deadline --
I think write operations are primarily done for the purpose of
configuring the device for operation rather than during it. So perhaps
we don't need to worry about this use case because users can write data
via the existing sysfs interface.


Agreed.


Re: [PATCH v3 3/4] counter: Add character device interface

2020-06-22 Thread David Lechner

On 6/21/20 2:53 PM, William Breathitt Gray wrote:

Synapses simply indicate a change in a Count value


Ah, ok. I understand now that synapse is the wrong term for things like
the change in direction event or error events.


For example, in the dual-axes positioning table scenario, a user
application would likely want to know the exact X and Y position at the
time of a given event -- that means an event should provide two Count
values (and possibly associated device flags) when it occurs. I'm not
sure yet how the struct counter_event should be defined in order to
support this; we will need to indicate the format of data as well as
provide the data itself. Perhaps, we can handle this by providing an
unique id field so that only a single datum (e.g. a single count value)
is provided via the value field, but subsequent struct counter_event
items share the same id so that the user knows that a particular datum
is part of a larger group of data for a specific event.


The timestamp could act as the "id" to correlate multiple values of a
single event.


Re: [PATCH v3 3/4] counter: Add character device interface

2020-06-20 Thread David Lechner

On 6/16/20 8:40 PM, William Breathitt Gray wrote:

This patch introduces a character device interface for the Counter
subsystem. Device control is exposed through standard character device
read and write operations.

A /sys/bus/counter/devices/counterX/chrdev_format sysfs attribute is
introduced to expose the character device data format:

* Users may write to this sysfs attribute to select the components they
   want to interface -- the layout can be determined as well from the
   order. For example:

   # echo "C0 C3 C2" > /sys/bus/counter/devices/counter0/chrdev_format

   This would select Counts 0, 3, and 2 (in that order) to be available
   in the /dev/counter0 node as a contiguous memory region.

   You can select extensions in a similar fashion:

   # echo "C4E2 S1E0" > /sys/bus/counter/devices/counter0/chrdev_format

   This would select extension 2 from Count 4, and extension 0 from
   Signal 1.

* Users may read from this chrdev_format sysfs attribute in order to see
   the currently configured format of the character device.

* Users may perform read/write operations on the /dev/counterX node
   directly; the layout of the data is what they user has configured via
   the chrdev_format sysfs attribute. For example:

   # echo "C0 C1 S0 S1" > /sys/bus/counter/devices/counter0/chrdev_format

   Yields the following /dev/counter0 memory layout:

   +-+--+--+--+
   | Byte 0 - Byte 7 | Byte 8 - Byte 15 | Byte 16  | Byte 17  |
   +-+--+--+--+
   | Count 0 | Count 1  | Signal 0 | Signal 2 |
   +-+--+--+--+

   The number of bytes allotted for each component or extension is
   determined by its respective data type: u8 will have 1 byte allotted,
   u64 will have 8 bytes allotted, etc.



Instead of the proposed character device, I would really rather have one
that gives past events instead of the current state.

I have thought about some of the suggestions from previous version of
this patch series and I'm starting to think something similar to the
input and gpio subsystems would work fairly well.


There would have to be a fixed size event data structure:

struct counter_event {
/** Best approximation of when event occurred in nanoseconds. */
__u64 timestamp;
/**
 * Description of the synapse that triggered the event and the
 * signal/counter that the value represents.
 */
__u64 descriptor;
/** The signal/counter value recorded when the synapse fired. */
__u64 value;
};

The descriptor field would actually probably be a union of __u64 and a
struct with its own fields to describe the synapse and signal or count.

If a synapse involves more than one signal or count, then there would
be multiple events with identical timestamps.

Userspace programs should be able to enable only the events/synapses they
are interested in and then the poll() the character device to wait for
events in an efficient way instead of having to constantly read - which
could still miss events.

---

Real world use case - measuring the speed of a motor:

At low speeds it is more accurate to measure the time difference between
count events. In this case we would want events from two synapses. One
triggered by the rising and falling edges of signal A and one triggered
by the direction signal. The magnitude of the speed is calculated by
taking the difference in timestamps between signal A events and the +/-
sign is determined by the direction signal.

At high speeds a different configuration is needed. Assuming the counter
has a timer clock signal a synapse would be configured to fire every 10
or 20 milliseconds. This would trigger an event that contains the count.
The speed is calculated as the difference in counts divided by the fixed
time interval.

Some applications may need to do both and be able to change the
configuration at runtime. It may start out in the low speed configuration,
but as the speed increases, events triggered by the change in count will
need to be disabled to prevent being overwhelmed with too many count
events. But if the speed drops low again, the count events will need to
be turned back on.

---

Regarding the implementation, the character device can be backed by a
kfifo. Interrupts from the counter hardware push events to the kfifo
and reading from the character device drains the kfifo.

drivers/gpio/gpiolib.c could be a good example to follow.

If we only want to allow one consumer to open the chardev at a time,
then enabling/disabling events via sysfs would probably be fine since
we are already sort of doing that anyway to enable/disable counters.
But if we need to allow multiple consumers per chardev that would each
want different events, then configuring via ioctl would be required so
that per-file descriptor configuration could be done (each call to open()
would create a 

Re: [PATCH v2 0/4] Introduce the Counter character device interface

2020-06-02 Thread David Lechner

On 5/31/20 12:14 PM, William Breathitt Gray wrote:

Yielding the following /dev/counter0 memory layout:

++-++---+
| Byte 0 | Byte 1 - Byte 8 | Byte 9 | Byte 10 - Byte 17 |
++-++---+
| Boundary 0 | Count 0 | Boundary 1 | Count 1   |
++-++---+


A potential pitfall with this sort of packing is that some platforms
do not support unaligned access, so data would have to be "unpacked"
before it could be used.


Re: [PATCH 0/4] Introduce the Counter character device interface

2020-04-29 Thread David Lechner

On 4/29/20 1:11 PM, William Breathitt Gray wrote:

Over the past couple years we have noticed some shortcomings with the
Counter sysfs interface. Although useful in the majority of situations,
there are certain use-cases where interacting through sysfs attributes
can become cumbersome and inefficient. A desire to support more advanced
functionality such as timestamps, multi-axis positioning tables, and
other such latency-sensitive applications, has motivated a reevaluation
of the Counter subsystem. I believe a character device interface will be
helpful for this more niche area of counter device use.


Nice to see some progress being made. :-)



Interaction with Counter character devices occurs via ioctl commands.
This allows userspace applications to access and set counter data using
native C datatypes rather than working through string translations.


For most aspects of the counter subsystem, this is not an issue since
configuring a counter is not a time-sensitive operation. Instead of
ioctls, I was expecting to just be able to read the character device
and receive counter events or poll to wait for events similar to how
the input subsystem works or how buffers work in the iio subsystem.

I'm afraid I don't really see much use in having ioctls that do
exactly what sysfs already does. And my intuition tells me that the
extra work needed to maintain it will probably cost more than any
benefit gained. (Maybe other have a different experience that leads
to a different conclusion?)


Re: [PATCH v4 2/2] docs: driver-api: generic-counter: Update Count and Signal data types

2019-10-06 Thread David Lechner

On 10/6/19 11:03 AM, William Breathitt Gray wrote:

Count data is now always represented as an unsigned integer, while
Signal data is either SIGNAL_LOW or SIGNAL_HIGH.

Signed-off-by: William Breathitt Gray 
---
  Documentation/driver-api/generic-counter.rst | 22 +++-
  1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/Documentation/driver-api/generic-counter.rst 
b/Documentation/driver-api/generic-counter.rst
index 8382f01a53e3..161652fc1025 100644
--- a/Documentation/driver-api/generic-counter.rst
+++ b/Documentation/driver-api/generic-counter.rst
@@ -39,10 +39,7 @@ There are three core components to a counter:
  COUNT
  -
  A Count represents the count data for a set of Signals. The Generic
-Counter interface provides the following available count data types:
-
-* COUNT_POSITION:
-  Unsigned integer value representing position.
+Counter interface represents the count data as an unsigned integer.


The previous patch looks like it is using unsigned long instead of
unsigned integer.




Re: [PATCH v4 1/2] counter: Simplify the count_read and count_write callbacks

2019-10-06 Thread David Lechner

On 10/6/19 11:03 AM, William Breathitt Gray wrote:

The count_read and count_write callbacks are simplified to pass val as
unsigned long rather than as an opaque data structure. The opaque
counter_count_read_value and counter_count_write_value structures,
counter_count_value_type enum, and relevant counter_count_read_value_set
and counter_count_write_value_get functions, are removed as they are no
longer used.

Cc: David Lechner 
Cc: Patrick Havelange 
Acked-by: Fabrice Gasnier 
Signed-off-by: William Breathitt Gray 
---


Acked-by: David Lechner 



Re: [PATCH v3 0/6] counter: new TI eQEP driver

2019-09-02 Thread David Lechner

On 9/1/19 5:58 PM, David Lechner wrote:

This series adds device tree bindings and a new counter driver for the Texas
Instruments Enhanced Quadrature Encoder Pulse (eQEP).



...


David Lechner (6):
   bus/ti-pwmss: move TI PWMSS driver from PWM to bus subsystem
   dt-bindings: counter: new bindings for TI eQEP
   counter: new TI eQEP driver
   ARM: dts: am33xx: Add nodes for eQEP
   ARM: dts: am335x-boneblue: Enable eQEP
   ARM: dts: am335x-boneblue: Use of am335x-osd335x-common.dtsi



In case anyone notices, this series only has 5 patches, not 6. "ARM: dts:
am335x-boneblue: Use of am335x-osd335x-common.dtsi" is unrelated and was
submitted separately.


Re: [PATCH] counter: fix devm_platform_ioremap_resource.cocci warnings

2019-09-01 Thread David Lechner

On 8/9/19 4:41 AM, Julia Lawall wrote:

From: kbuild test robot 

  Use devm_platform_ioremap_resource helper which wraps
  platform_get_resource() and devm_ioremap_resource() together.

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

Fixes: 78958c294246 ("counter: new TI eQEP driver")
Signed-off-by: kbuild test robot 
Signed-off-by: Julia Lawall 
---



Included this change in v2 of the "counter: new TI eQEP driver" series.

Thanks.


[PATCH v3 2/6] dt-bindings: counter: new bindings for TI eQEP

2019-09-01 Thread David Lechner
This documents device tree binding for the Texas Instruments Enhanced
Quadrature Encoder Pulse (eQEP) Module found in various TI SoCs.

Signed-off-by: David Lechner 
---

v3 changes:
- fixed style issues
- fixed generic node name
- (was suggested to drop descriptions since there is only one interrupt and one
  clock, but I opted to keep them anyway)
v2 changes:
- convert to .yaml format
- rename clock to "sysclkout"

 .../devicetree/bindings/counter/ti-eqep.yaml  | 50 +++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/counter/ti-eqep.yaml

diff --git a/Documentation/devicetree/bindings/counter/ti-eqep.yaml 
b/Documentation/devicetree/bindings/counter/ti-eqep.yaml
new file mode 100644
index ..85f1ff83afe7
--- /dev/null
+++ b/Documentation/devicetree/bindings/counter/ti-eqep.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/counter/ti-eqep.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments Enhanced Quadrature Encoder Pulse (eQEP) Module
+
+maintainers:
+  - David Lechner 
+
+properties:
+  compatible:
+const: ti,am3352-eqep
+
+  reg:
+maxItems: 1
+
+  interrupts:
+description: The eQEP event interrupt
+maxItems: 1
+
+  clocks:
+description: The clock that determines the SYSCLKOUT rate for the eQEP
+  peripheral.
+maxItems: 1
+
+  clock-names:
+const: sysclkout
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+eqep0: counter@180 {
+compatible = "ti,am3352-eqep";
+reg = <0x180 0x80>;
+clocks = <_gclk>;
+clock-names = "sysclkout";
+interrupts = <79>;
+};
+
+...
-- 
2.17.1



[PATCH v3 1/6] bus/ti-pwmss: move TI PWMSS driver from PWM to bus subsystem

2019-09-01 Thread David Lechner
The TI PWMSS driver is a simple bus driver for providing power
power management for the PWM peripherals on TI AM33xx SoCs, namely
eCAP, eHRPWM and eQEP. The eQEP is a counter rather than a PWM, so
it does not make sense to have the bus driver in the PWM subsystem
since the PWMSS is not exclusive to PWM devices.

Signed-off-by: David Lechner 
---

v3 changes:
- none
v2 changes:
- new patch

 drivers/bus/Kconfig   | 9 +
 drivers/bus/Makefile  | 1 +
 drivers/{pwm/pwm-tipwmss.c => bus/ti-pwmss.c} | 0
 drivers/pwm/Kconfig   | 9 -
 drivers/pwm/Makefile  | 1 -
 5 files changed, 10 insertions(+), 10 deletions(-)
 rename drivers/{pwm/pwm-tipwmss.c => bus/ti-pwmss.c} (100%)

diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 1851112ccc29..4eeb15839ce0 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -140,6 +140,15 @@ config TEGRA_GMI
  Driver for the Tegra Generic Memory Interface bus which can be used
  to attach devices such as NOR, UART, FPGA and more.
 
+config  TI_PWMSS
+   bool
+   default y if (ARCH_OMAP2PLUS) && (PWM_TIECAP || PWM_TIEHRPWM)
+   help
+ PWM Subsystem driver support for AM33xx SOC.
+
+ PWM submodules require PWM config space access from submodule
+ drivers and require common parent driver support.
+
 config TI_SYSC
bool "TI sysc interconnect target module driver"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index ca300b1914ce..a2d13cf4a877 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_SUNXI_RSB)   += sunxi-rsb.o
 obj-$(CONFIG_SIMPLE_PM_BUS)+= simple-pm-bus.o
 obj-$(CONFIG_TEGRA_ACONNECT)   += tegra-aconnect.o
 obj-$(CONFIG_TEGRA_GMI)+= tegra-gmi.o
+obj-$(CONFIG_TI_PWMSS) += ti-pwmss.o
 obj-$(CONFIG_TI_SYSC)  += ti-sysc.o
 obj-$(CONFIG_TS_NBUS)  += ts-nbus.o
 obj-$(CONFIG_UNIPHIER_SYSTEM_BUS)  += uniphier-system-bus.o
diff --git a/drivers/pwm/pwm-tipwmss.c b/drivers/bus/ti-pwmss.c
similarity index 100%
rename from drivers/pwm/pwm-tipwmss.c
rename to drivers/bus/ti-pwmss.c
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index a7e57516959e..300396564769 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -497,15 +497,6 @@ config  PWM_TIEHRPWM
  To compile this driver as a module, choose M here: the module
  will be called pwm-tiehrpwm.
 
-config  PWM_TIPWMSS
-   bool
-   default y if (ARCH_OMAP2PLUS) && (PWM_TIECAP || PWM_TIEHRPWM)
-   help
- PWM Subsystem driver support for AM33xx SOC.
-
- PWM submodules require PWM config space access from submodule
- drivers and require common parent driver support.
-
 config PWM_TWL
tristate "TWL4030/6030 PWM support"
depends on TWL4030_CORE
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 76b555b51887..f67eb6e9294d 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_PWM_SUN4I)   += pwm-sun4i.o
 obj-$(CONFIG_PWM_TEGRA)+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)   += pwm-tiecap.o
 obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
-obj-$(CONFIG_PWM_TIPWMSS)  += pwm-tipwmss.o
 obj-$(CONFIG_PWM_TWL)  += pwm-twl.o
 obj-$(CONFIG_PWM_TWL_LED)  += pwm-twl-led.o
 obj-$(CONFIG_PWM_VT8500)   += pwm-vt8500.o
-- 
2.17.1



[PATCH v3 0/6] counter: new TI eQEP driver

2019-09-01 Thread David Lechner
This series adds device tree bindings and a new counter driver for the Texas
Instruments Enhanced Quadrature Encoder Pulse (eQEP).

As mentioned in one of the commit messages, to start with, the driver only
supports reading the current counter value and setting the min/max values.
Other features can be added as the counter subsystem gains support for them.

v3 changes:
- Minor changes to device tree bindings (style and generic node name)
- Drop action in initializer
- Fix ordering of pm runtime disable
v2 changes:
- New patch to move TI PWMSS driver from drivers/pwm/ to drivers/bus/
- Device tree bindings converted to .yaml format
- Device tree clock renamed from "fck" to "sysclkout"
- Dropped unused index and strobe signals from counter driver
- Added synapses and actions to counter driver
- Fixed base in of kstrtouint()
- Clarifications in commit messages

This series has been tested on a BeagleBone Blue with the following script:

#!/usr/bin/env python3

from os import path
from time import sleep

COUNTER_PATH = '/sys/bus/counter/devices'
COUNTERS = ['counter0', 'counter1', 'counter2']
COUNT0 = 'count0'
COUNT = 'count'
FUNCTION = 'function'
CEILING = 'ceiling'
FLOOR = 'floor'
ENABLE = 'enable'

cnts = []

for c in COUNTERS:
function_path = path.join(COUNTER_PATH, c, COUNT0, FUNCTION)
with open(function_path, 'w') as f:
f.write('quadrature x4')
floor_path = path.join(COUNTER_PATH, c, COUNT0, FLOOR)
with open(floor_path, 'w') as f:
f.write(str(0))
ceiling_path = path.join(COUNTER_PATH, c, COUNT0, CEILING)
with open(ceiling_path, 'w') as f:
f.write(str(0x))
enable_path = path.join(COUNTER_PATH, c, COUNT0, ENABLE)
with open(enable_path, 'w') as f:
f.write('1')

cnt_path = path.join(COUNTER_PATH, c, COUNT0, COUNT)
cnts.append(open(cnt_path, 'r'))

while True:
for c in cnts:
c.seek(0)
val = int(c.read())
if val >= 0x8000:
val -= 0x1
print(val, end=' ')
    print()
sleep(1)

David Lechner (6):
  bus/ti-pwmss: move TI PWMSS driver from PWM to bus subsystem
  dt-bindings: counter: new bindings for TI eQEP
  counter: new TI eQEP driver
  ARM: dts: am33xx: Add nodes for eQEP
  ARM: dts: am335x-boneblue: Enable eQEP
  ARM: dts: am335x-boneblue: Use of am335x-osd335x-common.dtsi

 .../devicetree/bindings/counter/ti-eqep.yaml  |  50 ++
 MAINTAINERS   |   6 +
 arch/arm/boot/dts/am335x-boneblue.dts | 146 +++---
 arch/arm/boot/dts/am33xx-l4.dtsi  |  27 +
 drivers/bus/Kconfig   |   9 +
 drivers/bus/Makefile  |   1 +
 drivers/{pwm/pwm-tipwmss.c => bus/ti-pwmss.c} |   0
 drivers/counter/Kconfig   |  11 +
 drivers/counter/Makefile  |   1 +
 drivers/counter/ti-eqep.c | 473 ++
 drivers/pwm/Kconfig   |   9 -
 drivers/pwm/Makefile  |   1 -
 12 files changed, 634 insertions(+), 100 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/counter/ti-eqep.yaml
 rename drivers/{pwm/pwm-tipwmss.c => bus/ti-pwmss.c} (100%)
 create mode 100644 drivers/counter/ti-eqep.c

-- 
2.17.1



[PATCH v3 5/6] ARM: dts: am335x-boneblue: Enable eQEP

2019-09-01 Thread David Lechner
This enables the Enhanced Quadrature Encoder Pulse (eQEP) module for
connectors E1, E2 and E3 on BeagleBone Blue.

Signed-off-by: David Lechner 
---

v3 changes:
- none
v2 changes:
- none

 arch/arm/boot/dts/am335x-boneblue.dts | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-boneblue.dts 
b/arch/arm/boot/dts/am335x-boneblue.dts
index 0257576d5d16..df3978ce061c 100644
--- a/arch/arm/boot/dts/am335x-boneblue.dts
+++ b/arch/arm/boot/dts/am335x-boneblue.dts
@@ -258,6 +258,30 @@
AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_OUTPUT, 
MUX_MODE7) /* (M16) gmii1_rxd0.gpio2[21] */
>;
};
+
+   /* E1 */
+   eqep0_pins: pinmux_eqep0_pins {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_INPUT, 
MUX_MODE1)/* (B12) mcasp0_aclkr.eQEP0A_in */
+   AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_INPUT, 
MUX_MODE1) /* (C13) mcasp0_fsr.eQEP0B_in */
+   >;
+   };
+
+   /* E2 */
+   eqep1_pins: pinmux_eqep1_pins {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_INPUT, 
MUX_MODE2) /* (V2) lcd_data12.eQEP1A_in */
+   AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_INPUT, 
MUX_MODE2) /* (V3) lcd_data13.eQEP1B_in */
+   >;
+   };
+
+   /* E3 */
+   eqep2_pins: pinmux_eqep2_pins {
+   pinctrl-single,pins = <
+   AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_INPUT, 
MUX_MODE4)  /* (T12) gpmc_ad12.eQEP2A_in */
+   AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT, 
MUX_MODE4)  /* (R12) gpmc_ad13.eQEP2B_in */
+   >;
+   };
 };
 
  {
@@ -530,3 +554,33 @@
line-name = "LS_BUF_EN";
};
 };
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+};
-- 
2.17.1



  1   2   3   4   5   6   7   8   9   10   >