Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | /* $Id: uctrl.c,v 1.2 1999/09/07 23:11:08 shadow Exp $ * uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3 * * Copyright 1999 Derrick J Brashear (shadow@dementia.org) */ #include <linux/config.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/malloc.h> #include <linux/ioport.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/mm.h> #include <asm/openprom.h> #include <asm/oplib.h> #include <asm/system.h> #include <asm/irq.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/sbus.h> #define UCTRL_MINOR 174 struct uctrl_driver { volatile u32 *regs; int irq; }; static struct uctrl_driver drv; static loff_t uctrl_llseek(struct file *file, loff_t offset, int type) { return -ESPIPE; } static int uctrl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { default: return -EINVAL; } return 0; } static int uctrl_open(struct inode *inode, struct file *file) { MOD_INC_USE_COUNT; return 0; } static int uctrl_release(struct inode *inode, struct file *file) { MOD_DEC_USE_COUNT; return 0; } void uctrl_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uctrl_driver *driver = (struct uctrl_driver *)dev_id; printk("in uctrl_interrupt\n"); } static struct file_operations uctrl_fops = { uctrl_llseek, NULL, /* read */ NULL, /* write */ NULL, /* readdir */ NULL, /* poll */ uctrl_ioctl, NULL, /* mmap */ uctrl_open, NULL, /* flush */ uctrl_release }; static struct miscdevice uctrl_dev = { UCTRL_MINOR, "uctrl", &uctrl_fops }; #ifdef MODULE int init_module(void) #else int __init uctrl_init(void) #endif { struct uctrl_driver *driver = &drv; int len; struct linux_prom_irqs tmp_irq[2]; unsigned int vaddr[2] = { 0, 0 }; int tmpnode, uctrlnode = prom_getchild(prom_root_node); tmpnode = prom_searchsiblings(uctrlnode, "obio"); if (tmpnode) uctrlnode = prom_getchild(tmpnode); uctrlnode = prom_searchsiblings(uctrlnode, "uctrl"); if (!uctrlnode) return -ENODEV; /* the prom mapped it for us */ len = prom_getproperty(uctrlnode, "address", (void *) vaddr, sizeof(vaddr)); driver->regs = vaddr[0]; len = prom_getproperty(uctrlnode, "intr", (char *) tmp_irq, sizeof(tmp_irq)); if(!driver->irq) driver->irq = tmp_irq[0].pri; request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver); enable_irq(driver->irq); if (misc_register(&uctrl_dev)) { printk("%s: unable to get misc minor %d\n", __FUNCTION__, uctrl_dev.minor); disable_irq(driver->irq); free_irq(driver->irq, driver); return -ENODEV; } printk(KERN_INFO, "uctrl: 0x%x (irq %d)\n", driver->regs, __irq_itoa(driver->irq)); return 0; } #ifdef MODULE void cleanup_module(void) { struct uctrl_driver *driver = &drv; misc_deregister(&uctrl_dev); if (driver->irq) { disable_irq(driver->irq); free_irq(driver->irq, driver); } if (driver->regs) driver->regs = 0; } #endif |