diff options
Diffstat (limited to 'package/kernel/broadcom-diag/src/diag.c')
-rw-r--r-- | package/kernel/broadcom-diag/src/diag.c | 234 |
1 files changed, 126 insertions, 108 deletions
diff --git a/package/kernel/broadcom-diag/src/diag.c b/package/kernel/broadcom-diag/src/diag.c index ccbaee2..849a843 100644 --- a/package/kernel/broadcom-diag/src/diag.c +++ b/package/kernel/broadcom-diag/src/diag.c @@ -44,6 +44,21 @@ static int fill_event(struct event_t *); static unsigned int gpiomask = 0; module_param(gpiomask, int, 0644); +extern char *nvram_get(char *str); + +static void register_leds(struct led_t *l); +static void unregister_leds(struct led_t *l); +static void led_flash(unsigned long dummy); + +static struct platform_t platform; + +static struct timer_list led_timer = TIMER_INITIALIZER(&led_flash, 0, 0); + +static struct proc_dir_entry *diag, *leds; + +static struct prochandler_t proc_model = { .type = PROC_MODEL }; +static struct prochandler_t proc_gpiomask = { .type = PROC_GPIOMASK }; + enum { /* Linksys */ WAP54GV1, @@ -1381,41 +1396,6 @@ static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *)) } } -static void register_buttons(struct button_t *b) -{ - for (; b->name; b++) - platform.button_mask |= b->gpio; - - platform.button_mask &= ~gpiomask; - - bcm47xx_gpio_outen(platform.button_mask, 0); - bcm47xx_gpio_control(platform.button_mask, 0); - platform.button_polarity = bcm47xx_gpio_in(~0) & platform.button_mask; - bcm47xx_gpio_polarity(platform.button_mask, platform.button_polarity); - bcm47xx_gpio_intmask(platform.button_mask, platform.button_mask); - - gpio_set_irqenable(1, button_handler); -} - -static void unregister_buttons(struct button_t *b) -{ - bcm47xx_gpio_intmask(platform.button_mask, 0); - - gpio_set_irqenable(0, button_handler); -} - - -static void add_msg(struct event_t *event, char *msg, int argv) -{ - char *s; - - if (argv) - return; - - s = skb_put(event->skb, strlen(msg) + 1); - strcpy(s, msg); -} - static void hotplug_button(struct work_struct *work) { struct event_t *event = container_of(work, struct event_t, wq); @@ -1433,27 +1413,6 @@ static void hotplug_button(struct work_struct *work) kfree(event); } - -static int fill_event (struct event_t *event) -{ - static char buf[128]; - - add_msg(event, "HOME=/", 0); - add_msg(event, "PATH=/sbin:/bin:/usr/sbin:/usr/bin", 0); - add_msg(event, "SUBSYSTEM=button", 0); - snprintf(buf, 128, "ACTION=%s", event->action); - add_msg(event, buf, 0); - snprintf(buf, 128, "BUTTON=%s", event->name); - add_msg(event, buf, 0); - snprintf(buf, 128, "SEEN=%ld", event->seen); - add_msg(event, buf, 0); - snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum()); - add_msg(event, buf, 0); - - return 0; -} - - static irqreturn_t button_handler(int irq, void *dev_id) { struct button_t *b; @@ -1486,71 +1445,58 @@ static irqreturn_t button_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static void register_leds(struct led_t *l) +static void register_buttons(struct button_t *b) { - struct proc_dir_entry *p; - u32 mask = 0; - u32 oe_mask = 0; - u32 val = 0; - - leds = proc_mkdir("led", diag); - if (!leds) - return; + for (; b->name; b++) + platform.button_mask |= b->gpio; - for(; l->name; l++) { - if (l->gpio & gpiomask) - continue; + platform.button_mask &= ~gpiomask; - switch (l->gpio & GPIO_TYPE_MASK) { - case GPIO_TYPE_EXTIF: - l->state = 0; - set_led_extif(l); - break; - case GPIO_TYPE_SHIFT: - mask |= (SHIFTREG_DATA | SHIFTREG_CLK); - oe_mask |= (SHIFTREG_DATA | SHIFTREG_CLK); - l->state = (l->polarity != NORMAL); - set_led_shift(l); - break; - case GPIO_TYPE_NORMAL: - default: - if (l->polarity != INPUT) oe_mask |= l->gpio; - mask |= l->gpio; - val |= (l->polarity == NORMAL)?0:l->gpio; - break; - } + bcm47xx_gpio_outen(platform.button_mask, 0); + bcm47xx_gpio_control(platform.button_mask, 0); + platform.button_polarity = bcm47xx_gpio_in(~0) & platform.button_mask; + bcm47xx_gpio_polarity(platform.button_mask, platform.button_polarity); + bcm47xx_gpio_intmask(platform.button_mask, platform.button_mask); - if (l->polarity == INPUT) continue; + gpio_set_irqenable(1, button_handler); +} - if ((p = create_proc_entry(l->name, S_IRUSR, leds))) { - l->proc.type = PROC_LED; - l->proc.ptr = l; - p->data = (void *) &l->proc; - p->proc_fops = &diag_proc_fops; - } - } +static void unregister_buttons(struct button_t *b) +{ + bcm47xx_gpio_intmask(platform.button_mask, 0); - bcm47xx_gpio_outen(mask, oe_mask); - bcm47xx_gpio_control(mask, 0); - bcm47xx_gpio_out(mask, val); - bcm47xx_gpio_intmask(mask, 0); + gpio_set_irqenable(0, button_handler); } -static void unregister_leds(struct led_t *l) + +static void add_msg(struct event_t *event, char *msg, int argv) { - for(; l->name; l++) - remove_proc_entry(l->name, leds); + char *s; - remove_proc_entry("led", diag); + if (argv) + return; + + s = skb_put(event->skb, strlen(msg) + 1); + strcpy(s, msg); } -static void set_led_extif(struct led_t *led) +static int fill_event (struct event_t *event) { - volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (led->gpio & ~GPIO_TYPE_MASK); - if (led->state) - *addr = 0xFF; - else - *addr; + static char buf[128]; + + add_msg(event, "HOME=/", 0); + add_msg(event, "PATH=/sbin:/bin:/usr/sbin:/usr/bin", 0); + add_msg(event, "SUBSYSTEM=button", 0); + snprintf(buf, 128, "ACTION=%s", event->action); + add_msg(event, buf, 0); + snprintf(buf, 128, "BUTTON=%s", event->name); + add_msg(event, buf, 0); + snprintf(buf, 128, "SEEN=%ld", event->seen); + add_msg(event, buf, 0); + snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum()); + add_msg(event, buf, 0); + + return 0; } /* @@ -1592,6 +1538,15 @@ static void set_led_shift(struct led_t *led) } } +static void set_led_extif(struct led_t *led) +{ + volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (led->gpio & ~GPIO_TYPE_MASK); + if (led->state) + *addr = 0xFF; + else + *addr; +} + static void led_flash(unsigned long dummy) { struct led_t *l; @@ -1744,6 +1699,69 @@ static ssize_t diag_proc_write(struct file *file, const char *buf, size_t count, return ret; } +static struct file_operations diag_proc_fops = { + read: diag_proc_read, + write: diag_proc_write +}; + +static void register_leds(struct led_t *l) +{ + struct proc_dir_entry *p; + u32 mask = 0; + u32 oe_mask = 0; + u32 val = 0; + + leds = proc_mkdir("led", diag); + if (!leds) + return; + + for(; l->name; l++) { + if (l->gpio & gpiomask) + continue; + + switch (l->gpio & GPIO_TYPE_MASK) { + case GPIO_TYPE_EXTIF: + l->state = 0; + set_led_extif(l); + break; + case GPIO_TYPE_SHIFT: + mask |= (SHIFTREG_DATA | SHIFTREG_CLK); + oe_mask |= (SHIFTREG_DATA | SHIFTREG_CLK); + l->state = (l->polarity != NORMAL); + set_led_shift(l); + break; + case GPIO_TYPE_NORMAL: + default: + if (l->polarity != INPUT) oe_mask |= l->gpio; + mask |= l->gpio; + val |= (l->polarity == NORMAL)?0:l->gpio; + break; + } + + if (l->polarity == INPUT) continue; + + if ((p = create_proc_entry(l->name, S_IRUSR, leds))) { + l->proc.type = PROC_LED; + l->proc.ptr = l; + p->data = (void *) &l->proc; + p->proc_fops = &diag_proc_fops; + } + } + + bcm47xx_gpio_outen(mask, oe_mask); + bcm47xx_gpio_control(mask, 0); + bcm47xx_gpio_out(mask, val); + bcm47xx_gpio_intmask(mask, 0); +} + +static void unregister_leds(struct led_t *l) +{ + for(; l->name; l++) + remove_proc_entry(l->name, leds); + + remove_proc_entry("led", diag); +} + static int __init diag_init(void) { static struct proc_dir_entry *p; |