Re: [PATCH v2 1/4] clock: Add ClockEvent parameter to callbacks

2021-02-11 Thread Philippe Mathieu-Daudé
Hi Peter,

On 2/9/21 2:20 PM, Peter Maydell wrote:
> The Clock framework allows users to specify a callback which is
> called after the clock's period has been updated.  Some users need to
> also have a callback which is called before the clock period is
> updated.
> 
> As the first step in adding support for notifying Clock users on
> pre-update events, add an argument to the ClockCallback to specify
> what event is being notified, and add an argument to the various
> functions for registering a callback to specify which events are
> of interest to that callback.
> 
> Note that the documentation update renders correct the previously
> incorrect claim in 'Adding a new clock' that callbacks "will be
> explained in a following section".
> 
> Signed-off-by: Peter Maydell 
> ---
> v1->v2: (suggested by Luc) instead of making callback functions check
> whether 'event' is one they are interested in, specify mask of
> interesting events at callback registration time.
> ---
>  docs/devel/clocks.rst| 52 +++-
>  include/hw/clock.h   | 21 +++--
>  include/hw/qdev-clock.h  | 17 ---
>  hw/adc/npcm7xx_adc.c |  2 +-
>  hw/arm/armsse.c  |  9 +++---
>  hw/char/cadence_uart.c   |  4 +--
>  hw/char/ibex_uart.c  |  4 +--
>  hw/char/pl011.c  |  5 +--
>  hw/core/clock.c  | 20 +---
>  hw/core/qdev-clock.c |  8 +++--
>  hw/mips/cps.c|  2 +-
>  hw/misc/bcm2835_cprman.c | 23 --
>  hw/misc/npcm7xx_clk.c| 26 +---
>  hw/misc/npcm7xx_pwm.c|  2 +-
>  hw/misc/zynq_slcr.c  |  5 +--
>  hw/timer/cmsdk-apb-dualtimer.c   |  5 +--
>  hw/timer/cmsdk-apb-timer.c   |  4 +--
>  hw/timer/npcm7xx_timer.c |  2 +-
>  hw/watchdog/cmsdk-apb-watchdog.c |  5 +--
>  target/mips/cpu.c|  2 +-
>  20 files changed, 160 insertions(+), 58 deletions(-)

> diff --git a/include/hw/clock.h b/include/hw/clock.h
> index e5f45e2626d..5c73b4e7ae9 100644
> --- a/include/hw/clock.h
> +++ b/include/hw/clock.h
> @@ -22,7 +22,17 @@
>  #define TYPE_CLOCK "clock"
>  OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK)
>  
> -typedef void ClockCallback(void *opaque);
> +/*
> + * Argument to ClockCallback functions indicating why the callback
> + * has been called. A mask of these values logically ORed together
> + * is used to specify which events are interesting when the callback
> + * is registered, so these values must all be different bit values.
> + */
> +typedef enum ClockEvent {
> +ClockUpdate = 1, /* Clock period has just updated */

Just wondering loudly (QEMU doesn't have enum naming conventions),
maybe rename  ClockUpdate -> ClockUpdateEvent to clarify.

> +} ClockEvent;
> +
> +typedef void ClockCallback(void *opaque, ClockEvent event);
>  
>  /*
>   * clock store a value representing the clock's period in 2^-32ns unit.
> @@ -50,6 +60,7 @@ typedef void ClockCallback(void *opaque);
>   * @canonical_path: clock path string cache (used for trace purpose)
>   * @callback: called when clock changes
>   * @callback_opaque: argument for @callback
> + * @callback_events: mask of events when callback should be called
>   * @source: source (or parent in clock tree) of the clock
>   * @children: list of clocks connected to this one (it is their source)
>   * @sibling: structure used to form a clock list
> @@ -67,6 +78,7 @@ struct Clock {
>  char *canonical_path;
>  ClockCallback *callback;
>  void *callback_opaque;
> +int callback_events;

Isn't "unsigned" recommended for bit mask?

Otherwise (minor Hao Wu's NULL remark):
Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v2 1/4] clock: Add ClockEvent parameter to callbacks

2021-02-11 Thread Luc Michel
On 13:20 Tue 09 Feb , Peter Maydell wrote:
> The Clock framework allows users to specify a callback which is
> called after the clock's period has been updated.  Some users need to
> also have a callback which is called before the clock period is
> updated.
> 
> As the first step in adding support for notifying Clock users on
> pre-update events, add an argument to the ClockCallback to specify
> what event is being notified, and add an argument to the various
> functions for registering a callback to specify which events are
> of interest to that callback.
> 
> Note that the documentation update renders correct the previously
> incorrect claim in 'Adding a new clock' that callbacks "will be
> explained in a following section".
> 
> Signed-off-by: Peter Maydell 

With Hao's comment addressed:

Reviewed-by: Luc Michel 

> ---
> v1->v2: (suggested by Luc) instead of making callback functions check
> whether 'event' is one they are interested in, specify mask of
> interesting events at callback registration time.
> ---
>  docs/devel/clocks.rst| 52 +++-
>  include/hw/clock.h   | 21 +++--
>  include/hw/qdev-clock.h  | 17 ---
>  hw/adc/npcm7xx_adc.c |  2 +-
>  hw/arm/armsse.c  |  9 +++---
>  hw/char/cadence_uart.c   |  4 +--
>  hw/char/ibex_uart.c  |  4 +--
>  hw/char/pl011.c  |  5 +--
>  hw/core/clock.c  | 20 +---
>  hw/core/qdev-clock.c |  8 +++--
>  hw/mips/cps.c|  2 +-
>  hw/misc/bcm2835_cprman.c | 23 --
>  hw/misc/npcm7xx_clk.c| 26 +---
>  hw/misc/npcm7xx_pwm.c|  2 +-
>  hw/misc/zynq_slcr.c  |  5 +--
>  hw/timer/cmsdk-apb-dualtimer.c   |  5 +--
>  hw/timer/cmsdk-apb-timer.c   |  4 +--
>  hw/timer/npcm7xx_timer.c |  2 +-
>  hw/watchdog/cmsdk-apb-watchdog.c |  5 +--
>  target/mips/cpu.c|  2 +-
>  20 files changed, 160 insertions(+), 58 deletions(-)
> 
> diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
> index c54bbb82409..cd344e3fe5d 100644
> --- a/docs/devel/clocks.rst
> +++ b/docs/devel/clocks.rst
> @@ -80,11 +80,12 @@ Adding clocks to a device must be done during the init 
> method of the Device
>  instance.
>  
>  To add an input clock to a device, the function ``qdev_init_clock_in()``
> -must be used.  It takes the name, a callback and an opaque parameter
> -for the callback (this will be explained in a following section).
> +must be used.  It takes the name, a callback, an opaque parameter
> +for the callback and a mask of events when the callback should be
> +called (this will be explained in a following section).
>  Output is simpler; only the name is required. Typically::
>  
> -qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev);
> +qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev, 
> ClockUpdate);
>  qdev_init_clock_out(DEVICE(dev), "clk_out");
>  
>  Both functions return the created Clock pointer, which should be saved in the
> @@ -113,7 +114,7 @@ output.
>   * callback for the input clock (see "Callback on input clock
>   * change" section below for more information).
>   */
> -static void clk_in_callback(void *opaque);
> +static void clk_in_callback(void *opaque, ClockEvent event);
>  
>  /*
>   * static array describing clocks:
> @@ -124,7 +125,7 @@ output.
>   *   the clk_out field of a MyDeviceState structure.
>   */
>  static const ClockPortInitArray mydev_clocks = {
> -QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback),
> +QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback, ClockUpdate),
>  QDEV_CLOCK_OUT(MyDeviceState, clk_out),
>  QDEV_CLOCK_END
>  };
> @@ -153,6 +154,40 @@ nothing else to do. This value will be propagated to 
> other clocks when
>  connecting the clocks together and devices will fetch the right value during
>  the first reset.
>  
> +Clock callbacks
> +---
> +
> +You can give a clock a callback function in several ways:
> +
> + * by passing it as an argument to ``qdev_init_clock_in()``
> + * as an argument to the ``QDEV_CLOCK_IN()`` macro initializing an
> +   array to be passed to ``qdev_init_clocks()``
> + * by directly calling the ``clock_set_callback()`` function
> +
> +The callback function must be of this type:
> +
> +.. code-block:: c
> +
> +   typedef void ClockCallback(void *opaque, ClockEvent event);
> +
> +The ``opaque`` argument is the pointer passed to ``qdev_init_clock_in()``
> +or ``clock_set_callback()``; for ``qdev_init_clocks()`` it is the
> +``dev`` device pointer.
> +
> +The ``event`` argument specifies why the callback has been called.
> +When you register the callback you specify a mask of ClockEvent values
> +that you are interested in. The callback will only be called for those
> +events.
> +
> +The events currently 

Re: [PATCH v2 1/4] clock: Add ClockEvent parameter to callbacks

2021-02-10 Thread Peter Maydell
On Wed, 10 Feb 2021 at 20:53, Hao Wu  wrote:
>
>
>
> On Tue, Feb 9, 2021 at 5:24 AM Peter Maydell  wrote:
>> diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
>> index 870a6d50c27..573f4876dc6 100644
>> --- a/hw/adc/npcm7xx_adc.c
>> +++ b/hw/adc/npcm7xx_adc.c
>> @@ -238,7 +238,7 @@ static void npcm7xx_adc_init(Object *obj)
>>  memory_region_init_io(>iomem, obj, _adc_ops, s,
>>TYPE_NPCM7XX_ADC, 4 * KiB);
>>  sysbus_init_mmio(sbd, >iomem);
>> -s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
>> +s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 
>> ClockUpdate);
>
> Since there's no callback here should it be
>  s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
> ?

Yes; thanks for the catch. (The function ignores the events argument
if there's no callback function specified, but 0 makes more sense.)

-- PMM



Re: [PATCH v2 1/4] clock: Add ClockEvent parameter to callbacks

2021-02-10 Thread Hao Wu
On Tue, Feb 9, 2021 at 5:24 AM Peter Maydell 
wrote:

> The Clock framework allows users to specify a callback which is
> called after the clock's period has been updated.  Some users need to
> also have a callback which is called before the clock period is
> updated.
>
> As the first step in adding support for notifying Clock users on
> pre-update events, add an argument to the ClockCallback to specify
> what event is being notified, and add an argument to the various
> functions for registering a callback to specify which events are
> of interest to that callback.
>
> Note that the documentation update renders correct the previously
> incorrect claim in 'Adding a new clock' that callbacks "will be
> explained in a following section".
>
> Signed-off-by: Peter Maydell 
> ---
> v1->v2: (suggested by Luc) instead of making callback functions check
> whether 'event' is one they are interested in, specify mask of
> interesting events at callback registration time.
> ---
>  docs/devel/clocks.rst| 52 +++-
>  include/hw/clock.h   | 21 +++--
>  include/hw/qdev-clock.h  | 17 ---
>  hw/adc/npcm7xx_adc.c |  2 +-
>  hw/arm/armsse.c  |  9 +++---
>  hw/char/cadence_uart.c   |  4 +--
>  hw/char/ibex_uart.c  |  4 +--
>  hw/char/pl011.c  |  5 +--
>  hw/core/clock.c  | 20 +---
>  hw/core/qdev-clock.c |  8 +++--
>  hw/mips/cps.c|  2 +-
>  hw/misc/bcm2835_cprman.c | 23 --
>  hw/misc/npcm7xx_clk.c| 26 +---
>  hw/misc/npcm7xx_pwm.c|  2 +-
>  hw/misc/zynq_slcr.c  |  5 +--
>  hw/timer/cmsdk-apb-dualtimer.c   |  5 +--
>  hw/timer/cmsdk-apb-timer.c   |  4 +--
>  hw/timer/npcm7xx_timer.c |  2 +-
>  hw/watchdog/cmsdk-apb-watchdog.c |  5 +--
>  target/mips/cpu.c|  2 +-
>  20 files changed, 160 insertions(+), 58 deletions(-)
>
> diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
> index c54bbb82409..cd344e3fe5d 100644
> --- a/docs/devel/clocks.rst
> +++ b/docs/devel/clocks.rst
> @@ -80,11 +80,12 @@ Adding clocks to a device must be done during the init
> method of the Device
>  instance.
>
>  To add an input clock to a device, the function ``qdev_init_clock_in()``
> -must be used.  It takes the name, a callback and an opaque parameter
> -for the callback (this will be explained in a following section).
> +must be used.  It takes the name, a callback, an opaque parameter
> +for the callback and a mask of events when the callback should be
> +called (this will be explained in a following section).
>  Output is simpler; only the name is required. Typically::
>
> -qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev);
> +qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev,
> ClockUpdate);
>  qdev_init_clock_out(DEVICE(dev), "clk_out");
>
>  Both functions return the created Clock pointer, which should be saved in
> the
> @@ -113,7 +114,7 @@ output.
>   * callback for the input clock (see "Callback on input clock
>   * change" section below for more information).
>   */
> -static void clk_in_callback(void *opaque);
> +static void clk_in_callback(void *opaque, ClockEvent event);
>
>  /*
>   * static array describing clocks:
> @@ -124,7 +125,7 @@ output.
>   *   the clk_out field of a MyDeviceState structure.
>   */
>  static const ClockPortInitArray mydev_clocks = {
> -QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback),
> +QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback,
> ClockUpdate),
>  QDEV_CLOCK_OUT(MyDeviceState, clk_out),
>  QDEV_CLOCK_END
>  };
> @@ -153,6 +154,40 @@ nothing else to do. This value will be propagated to
> other clocks when
>  connecting the clocks together and devices will fetch the right value
> during
>  the first reset.
>
> +Clock callbacks
> +---
> +
> +You can give a clock a callback function in several ways:
> +
> + * by passing it as an argument to ``qdev_init_clock_in()``
> + * as an argument to the ``QDEV_CLOCK_IN()`` macro initializing an
> +   array to be passed to ``qdev_init_clocks()``
> + * by directly calling the ``clock_set_callback()`` function
> +
> +The callback function must be of this type:
> +
> +.. code-block:: c
> +
> +   typedef void ClockCallback(void *opaque, ClockEvent event);
> +
> +The ``opaque`` argument is the pointer passed to ``qdev_init_clock_in()``
> +or ``clock_set_callback()``; for ``qdev_init_clocks()`` it is the
> +``dev`` device pointer.
> +
> +The ``event`` argument specifies why the callback has been called.
> +When you register the callback you specify a mask of ClockEvent values
> +that you are interested in. The callback will only be called for those
> +events.
> +
> +The events currently supported are:
> +
> + * ``ClockUpdate`` : called after the