Port-arm archive

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

Re: Raspberry Pi ACT LED

Finally I found how this is done in Linux. I looked at the
raspberry/linux repository on github. Linux has a led subsystem which
allows you to manually control LEDs or assign a certain type of
trigger. The MMC driver provides such a trigger and is assigned to the
ACT LED as default. The magic happens in drivers/mmc/core/core.c:

static void
mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
led_trigger_event(host->led, LED_FULL);

void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) {
led_trigger_event(host->led, LED_OFF);

So one could turn off the LED from the driver or, as Greg suggested,
from a timer (a callout?).

2015-04-21 23:24 GMT+02:00 Jared McNeill <jmcneill%invisible.ca@localhost>:
> I would do this:
>  - Add bcm2835gpio_function_write to bcm2835_gpio_subr.[ch]
>  - Pass the gpio pin from rpi_device_register to the mmc driver as a
>    device property.
>  - In the MMC driver, if the pin property is set, use it to toggle the LED
>    state. You've selected the right place to do it.
> Since this is all MD code (and we don't have a MI KPI for gpio access,
> unfortunately) this approach should be fine.
> On Tue, 21 Apr 2015, Stephan wrote:
>> Okay, LED_ON() and LED_OFF() is pseudo-code and should have indicated
>> the place to put the control functions in. The next question would be
>> how to control the LED - for example by utilizing the GPIO framework
>> or driver, which might be too much overhead. Another way could be
>> writing directly to the corresponding register. I guess the given code
>> snipped runs in process context and waits on a CV which gets signalled
>> from the interrupt context?!
>> Either way, it might be good to know how it is impleneted in Linux but
>> I couldn?t find the appropriate place yet. The ultra-fragmented nature
>> of Linux isn?t very helpful with finding things.
>> 2015-04-21 14:24 GMT+02:00 Greg Troxel <gdt%ir.bbn.com@localhost>:
>>> Stephan <stephanwib%googlemail.com@localhost> writes:
>>>> bcm_dmac_transfer(sc->sc_dmac);
>>>> LED_ON();
>>>>    while (sc->sc_state == EMMC_DMA_STATE_BUSY) {
>>>>    error = cv_timedwait(&sc->sc_cv, &sc->sc_lock, hz * 10);
>>>>    if (error == EWOULDBLOCK) {
>>>>    device_printf(sc->sc.sc_dev, "transfer timeout!\n");
>>>>    bcm_dmac_halt(sc->sc_dmac);
>>>>    sc->sc_state = EMMC_DMA_STATE_IDLE;
>>>>    error = ETIMEDOUT;
>>>>    break;
>>>>    }
>>>> }
>>>> LED_OFF();
>>>> mutex_exit(&sc->sc_lock);
>>>> This also needs to be put in an #ifdef to be only included in a Pi
>>>> build.
>>>> Comments / hints / better ideas?
>>> I wonder if it makes sense to generalize this, to have a bunch of naemd
>>> (#define?) notification types, and macros to on/off, so that they get
>>> defined to empty on systems where it doesn't make sense, and to
>>> something sensible on various systems that have indicators.   Surely the
>>> RPI B isn't the only device where this makes sense, and there's probably
>>> a lot different.
>>> There was a comment about calling these "during the transfer" which was
>>> too vague to be really helpful, but you might want to check the
>>> locking/sleeping rules - generally one cannot call things that might
>>> sleep from interrupts, etc.   But given that the code is already calling
>>> cv_timedwait, sleeping isn't really an issue (and I don't know what's
>>> behind LED_ON()).
>>> (A tangent: More generally, one of the harder things to figure out in
>>> NetBSD (or anything) is what the locking/etc. rules are, and I think it
>>> would help to have more explicit comments in each procedure about
>>> assumptions.)

Home | Main Index | Thread Index | Old Index