Re: [PATCH 0/6] Generic PWM API implementation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Nov 23, 2009 at 7:12 AM, Bill Gatliff <bgat@xxxxxxxxxxxxxxx> wrote:
> Grant Likely wrote:
>> I'm talking about discrete controllable entities.
>
> At the extreme, I see discrete, single-pin GPIO as being a degenerate
> case of PWM: only 0% or 100% duty cycle e.g. one-bit granularity, a
> single output, and no dependencies with any other channels or pins.

yes

> But the perspectives of the two groups of users are completely
> different, so I don't see any advantage to having a combined user-facing
> API.

... for the control API; yes.  ie, the functions that set the GPIO pin
state or the PWM duty cycle.  There is no overlap here (except for the
degenerate case of using a PWM as an output only GPIO... which is
useful.  Board designers do crazy things).

>> I'm talking about the management code to obtain a reference to
>> the pin your interested in.  There is a non-trivial amount of code
>> associated with getting a reference to a pin and the behaviour
>> required is largely identical between GPIO and PWM.
>
> True, but anything involving pins has to be dealt with at the platform
> level.

Not exactly true.  GPIO pins do not have to be dealt with at the
platform level when GPIO lib is used.  I've got several platforms
where the routing of GPIOs is specified in the device tree data, and
platform code never touches them.  When the driver probes a device
implemented via GPIOs, it reads the data and requests the GPIO numbers
that it needs.

*however* I do agree that it is the responsibility of platform code to
set up chip-internal pin muxing and routing.  Actually, further than
that, I think it is actually firmware's responsibility to set up chip
internal pin muxing because it leads to more common platform code in
the kernel (less board specific fixups), but the kernel can fix it up
in a pinch.  But I'm not arguing about the pin (hardware) setup code.

>  And the general approach for that so far is that the board's
> startup code sets the pins how it wants them, and the peripheral drivers
> more or less assume that things are as they should be when it comes time
> to activate the peripherals themselves.  Anything more sophisticated
> than that and you prevent the kind of reuse that's taking place now
> between AVR32 and AT91, for example.
>
> Maybe that's an opportunity for improvement: an API for pin reservation,
> that GPIO, PWM and other platform-oriented drivers could use to request
> the pins that they want.  A kind of common version of the OMAP mux
> management code, if you will.

Perhaps.  But that's not what I'm taking issue with.

> But I don't think such an API would be all that useful for GPIO- and
> PWM-related scenarios.  Out of necessity, PWM and GPIO are very specific
> to the board hardware, and on-the-fly pin configuration changes aren't
> possible: either the hardware needs that pin to be an output, or it
> doesn't.  You can't make that decision at runtime because you'd probably
> have to swap out or add resistors, drivers, etc.  The software to do
> *that* would be.... tricky.  :)
>
>
>> I don't want to see a new subsystem that largely does the exact same job, but is
>> different in subtle ways.  I think it should either be a unified
>> PWM/GPIO pin management subsystem, or a common library used by each.
>
> Where is there overlap?  My PWM code is totally pin-agnostic, at least
> for the drivers I've worked with so far.  And I'm not aware of any GPIO
> chip drivers that deal with pin multiplexing, either.  Not saying there
> aren't any, only that I haven't seen them.

The overlap is in the management of registered pins.  I do not take
issue with the API.  In fact, I don't take issue with the code that
you've written either.  It appears to be well written.  I take issue
with all the common code behind the API to make it work and to allow
GPIOs or PWMs to be registered at runtime.  The overlap is the code
and behaviour used to register pins and to obtain a reference to a
pin.

On the PWM side; it's the code backing pwm_register().
pwm_unregister(), pwm_request(), pwm_free(), and the sysfs hooks.

For GPIO; it's gpiochip_add(), gpiochip_remove(), gpio_request(),
gpio_free(), the sysfs hooks, and the device tree bindings.

They perform exactly the same task.  The difference is that PWM
devices implement the PWM API and GPIO devices implement the GPIO API;
but the behaviour needed to manage them is identical.  I don't like
the fact that it will be implemented twice with subtle differences
between them.

The argument has been made that the split is appropriate because the
use case between GPIO and PWM is considerably different, and to a
point I agree.  The PWM use case definitely requires a different API.
However, the argument also makes the assumption that what is a GPIO
and what is a PWM can easily be pinned down.  For example, I've got
output only GPIOs, input only GPIOs, and a device that implements both
PWM and GPIO behaviour (not pin muxing).  And, as you say, the
degenerate of PWM behaviour is analogous to GPIO output.  The range of
behaviour supported by a PWM or GPIO device is entirely dependent on
what the hardware designer chooses to implement, and there isn't a
canonical definition of either GPIO or PWM.  If a hard distinction is
made now to manage GPIO and PWM pins separately, what then do we do
with other similar-yet-different pin controllers?  What about a
multi-voltage output GPIO pin?  Or a Frequency generator pin?  Is it
appropriate to create a new subsystem for managing each one?  And then
have devices that implement more than one common-case api to register
against each subsystem?

What an API can do is capture the common use cases, but it can never
capture the full range of behaviour implemented by a particular
device.  What I see as important to driver writers (PWM/GPIO users) is
the ability to obtain and use a reference to a controllable pin.  Then
it can either use a common-case API, or if it needs to, call device
specific extra hooks to do something funky, like hardware triggering.

For pin controller driver writers, the need is to export as much
behaviour as possible via a common-case API so that the device can
easily be reused by things the driver author hasn't even conceived of.
 Some behaviors won't fit, and some devices don't support behaviour
exposed by the API.  It is perfectly valid for a pin controller driver
to only implement the ops supported by the device and use -EINVAL if
an unsupported op is attempted.

I say that it is better to have a single pin-controller subsystem (and
again, not talking about pin-mux, that is something different) for
registering pins to, and leave it up to the drivers to choose which
ops to implement.  It can implement just the PWM ops, or just the GPIO
ops, or both.  A pin user will use the same mechanism to obtain a
reference to the pin regardless of the pin type, and can use that
reference to call the common case apis (gpio_get/set_value(),
pwm_config(), etc), or can use the reference when calling into a
driver-specific hook.  When new capabilities are identified, the list
of implementable ops can be extended without impact on existing
drivers.  Drivers can take advantage of the new behaviour by
implementing the new ops.

> It's a nice idea in the abstract, but I sure don't see how to make it
> work well enough in practice to be worth the effort.  I'm not saying it
> can't be done, just that it isn't my focus.  Yours?  :)

The problem that I have is that it shifts the maintenance burden from
the time of development (ie. now) to code maintenance time.  By
duplicating the infrastructure it doubles the code to be maintained.
It means there are differences between how a GPIO/PWM controllers
register their pins, and differences in how other drivers obtain and
use them.  It also establishes a pattern of writing new subsystems to
handle similar-yet-different pin controllers.  To me that is a
non-trivial cost.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
--
To unsubscribe from this list: send the line "unsubscribe linux-embedded" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Gstreamer Embedded]     [Linux MMC Devel]     [U-Boot V2]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux ARM Kernel]     [Linux OMAP]     [Linux SCSI]

  Powered by Linux