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 ar531x_boarddata *bcfg;
|
||||||
|
static struct timer_list rst_button_timer;
|
||||||
|
|
||||||
extern struct sock *uevent_sock;
|
extern struct sock *uevent_sock;
|
||||||
extern u64 uevent_next_seqnum(void);
|
extern u64 uevent_next_seqnum(void);
|
||||||
|
@ -71,6 +72,37 @@ done:
|
||||||
kfree(event);
|
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 irqreturn_t button_handler(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
static int pressed = 0;
|
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);
|
gpio &= 1 << (irq - AR531X_GPIO_IRQ_BASE);
|
||||||
|
|
||||||
event->set = gpio;
|
event->set = gpio;
|
||||||
|
if(!event->set)
|
||||||
|
no_release_workaround = 0;
|
||||||
|
|
||||||
event->jiffies = jiffies;
|
event->jiffies = jiffies;
|
||||||
|
|
||||||
INIT_WORK(&event->wq, (void *)(void *)hotplug_button);
|
INIT_WORK(&event->wq, (void *)(void *)hotplug_button);
|
||||||
schedule_work(&event->wq);
|
schedule_work(&event->wq);
|
||||||
|
|
||||||
seen = jiffies;
|
seen = jiffies;
|
||||||
|
if(event->set && no_release_workaround)
|
||||||
|
{
|
||||||
|
rst_button_timer.expires = jiffies + (HZ / 4);
|
||||||
|
add_timer(&rst_button_timer);
|
||||||
|
}
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +149,11 @@ int __init ar531x_init_reset(void)
|
||||||
|
|
||||||
seen = jiffies;
|
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);
|
request_irq(AR531X_RESET_GPIO_IRQ, &button_handler, IRQF_SAMPLE_RANDOM, "ar531x_reset", NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue