Changeset 9904


Ignore:
Timestamp:
2007-12-25T01:35:00+01:00 (9 years ago)
Author:
blogic
Message:

add gpio fixes and reset button supportÂ

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/ifxmips/files/drivers/char/ifxmips_gpio.c

    r9826 r9904  
    2525#include <linux/init.h> 
    2626#include <linux/ioctl.h> 
     27#include <linux/timer.h> 
     28#include <linux/module.h> 
     29#include <linux/timer.h> 
     30#include <linux/interrupt.h> 
     31#include <linux/kobject.h> 
     32#include <linux/workqueue.h> 
     33#include <linux/skbuff.h> 
     34#include <linux/netlink.h> 
     35#include <net/sock.h> 
     36#include <asm/uaccess.h> 
    2737#include <asm/semaphore.h> 
    2838#include <asm/uaccess.h> 
     
    3545static unsigned int ifxmips_gpio_major = 0; 
    3646 
     47#ifdef CONFIG_IFXMIPS_GPIO_RST_BTN 
     48#define IFXMIPS_RST_PIN 15 
     49#define IFXMIPS_RST_PORT 1 
     50 
     51static struct timer_list rst_button_timer;  
     52 
     53extern struct sock *uevent_sock; 
     54extern u64 uevent_next_seqnum(void); 
     55static unsigned long seen; 
     56static int pressed = 0; 
     57 
     58struct event_t { 
     59        struct work_struct wq; 
     60        int set; 
     61        unsigned long jiffies; 
     62}; 
     63#endif 
     64 
    3765/* TODO do we need this ? */ 
    3866static struct semaphore port_sem; 
     
    6593{ 
    6694        IFXMIPS_GPIO_SANITY; 
    67         writel(readl(IFXMIPS_GPIO_P0_OD + (port * 0x30)) | (1 << pin), IFXMIPS_GPIO_P0_OD); 
     95        writel(readl(IFXMIPS_GPIO_P0_OD + (port * 0xC)) | (1 << pin), IFXMIPS_GPIO_P0_OD + (port * 0xC)); 
    6896 
    6997        return 0; 
     
    75103{ 
    76104        IFXMIPS_GPIO_SANITY; 
    77         writel(readl(IFXMIPS_GPIO_P0_OD + (port * 0x30)) & ~(1 << pin), IFXMIPS_GPIO_P0_OD); 
     105        writel(readl(IFXMIPS_GPIO_P0_OD + (port * 0xC)) & ~(1 << pin), IFXMIPS_GPIO_P0_OD + (port * 0xC)); 
    78106 
    79107        return 0; 
     
    85113{ 
    86114    IFXMIPS_GPIO_SANITY; 
    87         writel(readl(IFXMIPS_GPIO_P0_PUDSEL + (port * 0x30)) | (1 << pin), IFXMIPS_GPIO_P0_PUDSEL); 
     115        writel(readl(IFXMIPS_GPIO_P0_PUDSEL + (port * 0xC)) | (1 << pin), IFXMIPS_GPIO_P0_PUDSEL + (port * 0xC)); 
    88116 
    89117        return 0; 
     
    95123{ 
    96124    IFXMIPS_GPIO_SANITY; 
    97         writel(readl(IFXMIPS_GPIO_P0_PUDSEL + (port * 0x30)) & ~(1 << pin), IFXMIPS_GPIO_P0_PUDSEL); 
     125        writel(readl(IFXMIPS_GPIO_P0_PUDSEL + (port * 0xC)) & ~(1 << pin), IFXMIPS_GPIO_P0_PUDSEL + (port * 0xC)); 
    98126 
    99127        return 0; 
     
    105133{ 
    106134    IFXMIPS_GPIO_SANITY; 
    107         writel(readl(IFXMIPS_GPIO_P0_PUDEN + (port * 0x30)) | (1 << pin), IFXMIPS_GPIO_P0_PUDEN); 
     135        writel(readl(IFXMIPS_GPIO_P0_PUDEN + (port * 0xC)) | (1 << pin), IFXMIPS_GPIO_P0_PUDEN + (port * 0xC)); 
    108136 
    109137        return 0; 
     
    115143{ 
    116144    IFXMIPS_GPIO_SANITY; 
    117         writel(readl(IFXMIPS_GPIO_P0_PUDEN + (port * 0x30)) & ~(1 << pin), IFXMIPS_GPIO_P0_PUDEN); 
     145        writel(readl(IFXMIPS_GPIO_P0_PUDEN + (port * 0xC)) & ~(1 << pin), IFXMIPS_GPIO_P0_PUDEN + (port * 0xC)); 
    118146 
    119147        return 0; 
     
    125153{ 
    126154    IFXMIPS_GPIO_SANITY; 
    127         writel(readl(IFXMIPS_GPIO_P0_STOFF + (port * 0x30)) | (1 << pin), IFXMIPS_GPIO_P0_STOFF); 
     155        writel(readl(IFXMIPS_GPIO_P0_STOFF + (port * 0xC)) | (1 << pin), IFXMIPS_GPIO_P0_STOFF + (port * 0xC)); 
    128156 
    129157        return 0; 
     
    135163{ 
    136164    IFXMIPS_GPIO_SANITY; 
    137         writel(readl(IFXMIPS_GPIO_P0_STOFF + (port * 0x30)) & ~(1 << pin), IFXMIPS_GPIO_P0_STOFF); 
     165        writel(readl(IFXMIPS_GPIO_P0_STOFF + (port * 0xC)) & ~(1 << pin), IFXMIPS_GPIO_P0_STOFF + (port * 0xC)); 
    138166 
    139167        return 0; 
     
    145173{ 
    146174    IFXMIPS_GPIO_SANITY; 
    147         writel(readl(IFXMIPS_GPIO_P0_DIR + (port * 0x30)) | (1 << pin), IFXMIPS_GPIO_P0_DIR); 
     175        writel(readl(IFXMIPS_GPIO_P0_DIR + (port * 0xC)) | (1 << pin), IFXMIPS_GPIO_P0_DIR + (port * 0xC)); 
    148176 
    149177        return 0; 
     
    155183{ 
    156184    IFXMIPS_GPIO_SANITY; 
    157         writel(readl(IFXMIPS_GPIO_P0_DIR + (port * 0x30)) & ~(1 << pin), IFXMIPS_GPIO_P0_DIR); 
     185        writel(readl(IFXMIPS_GPIO_P0_DIR + (port * 0xC)) & ~(1 << pin), IFXMIPS_GPIO_P0_DIR + (port * 0xC)); 
    158186 
    159187        return 0; 
     
    165193{ 
    166194    IFXMIPS_GPIO_SANITY; 
    167         writel(readl(IFXMIPS_GPIO_P0_OUT + (port * 0x30)) | (1 << pin), IFXMIPS_GPIO_P0_OUT); 
     195        writel(readl(IFXMIPS_GPIO_P0_OUT + (port * 0xC)) | (1 << pin), IFXMIPS_GPIO_P0_OUT + (port * 0xC)); 
    168196 
    169197        return 0; 
     
    175203{ 
    176204    IFXMIPS_GPIO_SANITY; 
    177         writel(readl(IFXMIPS_GPIO_P0_OUT + (port * 0x30)) & ~(1 << pin), IFXMIPS_GPIO_P0_OUT); 
     205        writel(readl(IFXMIPS_GPIO_P0_OUT + (port * 0xC)) & ~(1 << pin), IFXMIPS_GPIO_P0_OUT + (port * 0xC)); 
    178206 
    179207        return 0; 
     
    186214    IFXMIPS_GPIO_SANITY; 
    187215 
    188         if (readl(IFXMIPS_GPIO_P0_IN + (port * 0x30)) & (1 << pin)) 
     216        if (readl(IFXMIPS_GPIO_P0_IN + (port * 0xC)) & (1 << pin)) 
    189217                return 0; 
    190218        else 
     
    197225{ 
    198226    IFXMIPS_GPIO_SANITY; 
    199         writel(readl(IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0x30)) | (1 << pin), IFXMIPS_GPIO_P0_ALTSEL0); 
     227        writel(readl(IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0xC)) | (1 << pin), IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0xC)); 
    200228 
    201229        return 0; 
     
    207235{ 
    208236    IFXMIPS_GPIO_SANITY; 
    209         writel(readl(IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0x30)) & ~(1 << pin), IFXMIPS_GPIO_P0_ALTSEL0); 
     237        writel(readl(IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0xC)) & ~(1 << pin), IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0xC)); 
    210238 
    211239        return 0; 
     
    217245{ 
    218246    IFXMIPS_GPIO_SANITY; 
    219         writel(readl(IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0x30)) | (1 << pin), IFXMIPS_GPIO_P0_ALTSEL1); 
     247        writel(readl(IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0xC)) | (1 << pin), IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0xC)); 
    220248 
    221249        return 0; 
     
    227255{ 
    228256    IFXMIPS_GPIO_SANITY; 
    229         writel(readl(IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0x30)) & ~(1 << pin), IFXMIPS_GPIO_P0_ALTSEL1); 
     257        writel(readl(IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0xC)) & ~(1 << pin), IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0xC)); 
    230258 
    231259        return 0; 
    232260} 
    233261EXPORT_SYMBOL(ifxmips_port_clear_altsel1); 
     262 
     263#ifdef CONFIG_IFXMIPS_GPIO_RST_BTN 
     264static inline void add_msg(struct sk_buff *skb, char *msg) 
     265{ 
     266        char *scratch; 
     267        scratch = skb_put(skb, strlen(msg) + 1); 
     268        sprintf(scratch, msg); 
     269} 
     270 
     271static void hotplug_button(struct work_struct *wq) 
     272{ 
     273        struct sk_buff *skb; 
     274        struct event_t *event; 
     275        size_t len; 
     276        char *scratch, *s; 
     277        char buf[128]; 
     278 
     279        event = container_of(wq, struct event_t, wq); 
     280        if (!uevent_sock) 
     281                goto done; 
     282 
     283        /* allocate message with the maximum possible size */ 
     284        s = event->set ? "pressed" : "released"; 
     285        len = strlen(s) + 2; 
     286        skb = alloc_skb(len + 2048, GFP_KERNEL); 
     287        if (!skb) 
     288                goto done; 
     289 
     290        /* add header */ 
     291        scratch = skb_put(skb, len); 
     292        sprintf(scratch, "%s@",s); 
     293 
     294        /* copy keys to our continuous event payload buffer */ 
     295        add_msg(skb, "HOME=/"); 
     296        add_msg(skb, "PATH=/sbin:/bin:/usr/sbin:/usr/bin"); 
     297        add_msg(skb, "SUBSYSTEM=button"); 
     298        add_msg(skb, "BUTTON=reset"); 
     299        add_msg(skb, (event->set ? "ACTION=pressed" : "ACTION=released")); 
     300        sprintf(buf, "SEEN=%ld", (event->jiffies - seen)/HZ); 
     301        add_msg(skb, buf); 
     302        snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum()); 
     303        add_msg(skb, buf); 
     304 
     305        NETLINK_CB(skb).dst_group = 1; 
     306        netlink_broadcast(uevent_sock, skb, 0, 1, GFP_KERNEL); 
     307 
     308done: 
     309        kfree(event); 
     310} 
     311 
     312static void reset_button_poll(unsigned long unused) 
     313{ 
     314        struct event_t *event; 
     315         
     316        rst_button_timer.expires = jiffies + HZ; 
     317        add_timer(&rst_button_timer); 
     318         
     319        if (pressed != ifxmips_port_get_input(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN)) 
     320        { 
     321                if(pressed) 
     322                        pressed = 0; 
     323                else 
     324                        pressed = 1; 
     325                printk("button was %s\n", (pressed ? "pressed" : "released")); 
     326                event = (struct event_t *) kzalloc(sizeof(struct event_t), GFP_ATOMIC); 
     327                if (!event) 
     328                { 
     329                        printk("Could not alloc hotplug event\n"); 
     330                        return; 
     331                } 
     332                event->set = pressed; 
     333                event->jiffies = jiffies; 
     334                INIT_WORK(&event->wq, (void *)(void *)hotplug_button); 
     335                schedule_work(&event->wq); 
     336                seen = jiffies; 
     337        } 
     338} 
     339#endif 
    234340 
    235341long ifxmips_port_read_procmem_helper(char* tag, u32* in_reg, char *buf) 
     
    426532                                ifxmips_port_read_procmem, NULL); 
    427533 
     534#ifdef CONFIG_IFXMIPS_GPIO_RST_BTN 
     535        ifxmips_port_set_open_drain(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN); 
     536        ifxmips_port_clear_altsel0(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN); 
     537        ifxmips_port_clear_altsel1(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN); 
     538        ifxmips_port_set_dir_in(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN); 
     539         
     540        seen = jiffies; 
     541 
     542        init_timer(&rst_button_timer); 
     543        rst_button_timer.function = reset_button_poll; 
     544        rst_button_timer.expires = jiffies + HZ; 
     545        add_timer(&rst_button_timer); 
     546#endif 
     547 
    428548        printk("registered ifxmips gpio driver\n"); 
    429549 
     
    435555ifxmips_gpio_exit (void) 
    436556{ 
     557#ifdef CONFIG_IFXMIPS_GPIO_RST_BTN 
     558        del_timer_sync(&rst_button_timer); 
     559#endif 
    437560        unregister_chrdev(ifxmips_gpio_major, "ifxmips_gpio"); 
    438561        remove_proc_entry("ifxmips_gpio", NULL); 
Note: See TracChangeset for help on using the changeset viewer.