add proper uci/hotplug based button handling on atheros and work around boards, where the gpio release irq does not fire correctly
SVN-Revision: 12179
This commit is contained in:
parent
af76ae2cb5
commit
5e5cc5a7c8
3 changed files with 86 additions and 1 deletions
17
target/linux/atheros/base-files/etc/config/system
Normal file
17
target/linux/atheros/base-files/etc/config/system
Normal file
|
@ -0,0 +1,17 @@
|
|||
config system
|
||||
option hostname OpenWrt
|
||||
option timezone UTC
|
||||
|
||||
config button
|
||||
option button reset
|
||||
option action released
|
||||
option handler "logger reboot"
|
||||
option min 0
|
||||
option max 4
|
||||
|
||||
config button
|
||||
option button reset
|
||||
option action released
|
||||
option handler "logger factory default"
|
||||
option min 5
|
||||
option max 30
|
|
@ -0,0 +1,24 @@
|
|||
. /etc/functions.sh
|
||||
do_button () {
|
||||
local button
|
||||
local action
|
||||
local handler
|
||||
local min
|
||||
local max
|
||||
|
||||
config_get button $1 button
|
||||
config_get action $1 action
|
||||
config_get handler $1 handler
|
||||
config_get min $1 min
|
||||
config_get max $1 max
|
||||
|
||||
[ "$ACTION" = "$action" -a "$BUTTON" = "$button" -a -n "$handler" ] && {
|
||||
[ -z "$min" -o -z "$max" ] && eval $handler
|
||||
[ -n "$min" -a -n "$max" ] && {
|
||||
[ $min -le $SEEN -a $max -ge $SEEN ] && eval $handler
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config_load system
|
||||
config_foreach do_button button
|
|
@ -18,6 +18,7 @@ struct event_t {
|
|||
};
|
||||
|
||||
static struct ar531x_boarddata *bcfg;
|
||||
static struct timer_list rst_button_timer;
|
||||
|
||||
extern struct sock *uevent_sock;
|
||||
extern u64 uevent_next_seqnum(void);
|
||||
|
@ -71,6 +72,37 @@ done:
|
|||
kfree(event);
|
||||
}
|
||||
|
||||
static int no_release_workaround = 1;
|
||||
|
||||
static void
|
||||
reset_button_poll(unsigned long unused)
|
||||
{
|
||||
struct event_t *event;
|
||||
int gpio = ~0;
|
||||
|
||||
if(!no_release_workaround)
|
||||
return;
|
||||
|
||||
DO_AR5315(gpio = sysRegRead(AR5315_GPIO_DI);)
|
||||
gpio &= 1 << (AR531X_RESET_GPIO_IRQ - AR531X_GPIO_IRQ_BASE);
|
||||
if(gpio)
|
||||
{
|
||||
rst_button_timer.expires = jiffies + (HZ / 4);
|
||||
add_timer(&rst_button_timer);
|
||||
} else {
|
||||
event = (struct event_t *) kzalloc(sizeof(struct event_t), GFP_ATOMIC);
|
||||
if (!event)
|
||||
{
|
||||
printk("Could not alloc hotplug event\n");
|
||||
return;
|
||||
}
|
||||
event->set = 0;
|
||||
event->jiffies = jiffies;
|
||||
INIT_WORK(&event->wq, (void *)(void *)hotplug_button);
|
||||
schedule_work(&event->wq);
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t button_handler(int irq, void *dev_id)
|
||||
{
|
||||
static int pressed = 0;
|
||||
|
@ -87,13 +119,20 @@ static irqreturn_t button_handler(int irq, void *dev_id)
|
|||
gpio &= 1 << (irq - AR531X_GPIO_IRQ_BASE);
|
||||
|
||||
event->set = gpio;
|
||||
if(!event->set)
|
||||
no_release_workaround = 0;
|
||||
|
||||
event->jiffies = jiffies;
|
||||
|
||||
INIT_WORK(&event->wq, (void *)(void *)hotplug_button);
|
||||
schedule_work(&event->wq);
|
||||
|
||||
seen = jiffies;
|
||||
|
||||
if(event->set && no_release_workaround)
|
||||
{
|
||||
rst_button_timer.expires = jiffies + (HZ / 4);
|
||||
add_timer(&rst_button_timer);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -110,6 +149,11 @@ int __init ar531x_init_reset(void)
|
|||
|
||||
seen = jiffies;
|
||||
|
||||
init_timer(&rst_button_timer);
|
||||
rst_button_timer.function = reset_button_poll;
|
||||
rst_button_timer.expires = jiffies + HZ / 50;
|
||||
add_timer(&rst_button_timer);
|
||||
|
||||
request_irq(AR531X_RESET_GPIO_IRQ, &button_handler, IRQF_SAMPLE_RANDOM, "ar531x_reset", NULL);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue