static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info_82c700 = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &optidma_port_ops }; static const struct ata_port_info info_82c700_udma = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, .port_ops = &optiplus_port_ops }; const struct ata_port_info *ppi[] = { &info_82c700, NULL }; static int printed_version; int rc; if (!printed_version++) dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); rc = pcim_enable_device(dev); if (rc) return rc; /* Fixed location chipset magic */ inw(0x1F1); inw(0x1F1); pci_clock = inb(0x1F5) & 1; /* 0 = 33Mhz, 1 = 25Mhz */ if (optiplus_with_udma(dev)) ppi[0] = &info_82c700_udma; return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL); } static const struct pci_device_id optidma[] = { { PCI_VDEVICE(OPTI, 0xD568), }, /* Opti 82C700 */ { }, }; static struct pci_driver optidma_pci_driver = { .name = DRV_NAME, .id_table = optidma, .probe = optidma_init_one, .remove = ata_pci_remove_one, #ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, #endif }; static int __init optidma_init(void) { return pci_register_driver(&optidma_pci_driver); } static void __exit optidma_exit(void) { pci_unregister_driver(&optidma_pci_driver); } MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("low-level driver for Opti Firestar/Firestar Plus"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, optidma); MODULE_VERSION(DRV_VERSION); module_init(optidma_init); module_exit(optidma_exit);
static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "ALiM7101", }; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { wdt_turnoff(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { wdt_startup(); retval = 0; } return retval; } case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; case WDIOC_SETTIMEOUT: { int new_timeout; if (get_user(new_timeout, p)) return -EFAULT; /* arbitrary upper limit */ if (new_timeout < 1 || new_timeout > 3600) return -EINVAL; timeout = new_timeout; wdt_keepalive(); /* Fall through */ } case WDIOC_GETTIMEOUT: return put_user(timeout, p); default: return -ENOTTY; } } static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, .unlocked_ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wdt_fops, }; static int wdt_restart_handle(struct notifier_block *this, unsigned long mode, void *cmd) { /* * Cobalt devices have no way of rebooting themselves other * than getting the watchdog to pull reset, so we restart the * watchdog on reboot with no heartbeat. */ wdt_change(WDT_ENABLE); /* loop until the watchdog fires */ while (true) ; return NOTIFY_DONE; } static struct notifier_block wdt_restart_handler = { .notifier_call = wdt_restart_handle, .priority = 128, }; /* * Notifier for system down */ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) wdt_turnoff(); return NOTIFY_DONE; } /* * The WDT needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; static void __exit alim7101_wdt_unload(void) { wdt_turnoff(); /* Deregister */ misc_deregister(&wdt_miscdev); unregister_reboot_notifier(&wdt_notifier); unregister_restart_handler(&wdt_restart_handler); pci_dev_put(alim7101_pmu); } static int __init alim7101_wdt_init(void) { int rc = -EBUSY; struct pci_dev *ali1543_south; char tmp; pr_info("Steve Hill <*****@*****.**>\n"); alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); if (!alim7101_pmu) { pr_info("ALi M7101 PMU not present - WDT not set\n"); return -EBUSY; } /* Set the WDT in the PMU to 1 second */ pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02); ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!ali1543_south) { pr_info("ALi 1543 South-Bridge not present - WDT not set\n"); goto err_out; } pci_read_config_byte(ali1543_south, 0x5e, &tmp); pci_dev_put(ali1543_south); if ((tmp & 0x1e) == 0x00) { if (!use_gpio) { pr_info("Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); goto err_out; } nowayout = 1; } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { pr_info("ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); goto err_out; } if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ timeout = WATCHDOG_TIMEOUT; pr_info("timeout value must be 1 <= x <= 3600, using %d\n", timeout); } rc = register_reboot_notifier(&wdt_notifier); if (rc) { pr_err("cannot register reboot notifier (err=%d)\n", rc); goto err_out; } rc = register_restart_handler(&wdt_restart_handler); if (rc) { pr_err("cannot register restart handler (err=%d)\n", rc); goto err_out_reboot; } rc = misc_register(&wdt_miscdev); if (rc) { pr_err("cannot register miscdev on minor=%d (err=%d)\n", wdt_miscdev.minor, rc); goto err_out_restart; } if (nowayout) __module_get(THIS_MODULE); pr_info("WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", timeout, nowayout); return 0; err_out_restart: unregister_restart_handler(&wdt_restart_handler); err_out_reboot: unregister_reboot_notifier(&wdt_notifier); err_out: pci_dev_put(alim7101_pmu); return rc; } module_init(alim7101_wdt_init); module_exit(alim7101_wdt_unload); static const struct pci_device_id alim7101_pci_tbl[] __used = { { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533) }, { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) }, { } }; MODULE_DEVICE_TABLE(pci, alim7101_pci_tbl); MODULE_AUTHOR("Steve Hill"); MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver"); MODULE_LICENSE("GPL");
static int sblock_thread(void *data) { struct sblock_mgr *sblock = data; struct smsg mcmd, mrecv; int rval; int recovery = 0; struct sched_param param = {.sched_priority = 90}; /*set the thread as a real time thread, and its priority is 90*/ sched_setscheduler(current, SCHED_RR, ¶m); /* since the channel open may hang, we call it in the sblock thread */ rval = smsg_ch_open(sblock->dst, sblock->channel, -1); if (rval != 0) { printk(KERN_ERR "Failed to open channel %d\n", sblock->channel); /* assign NULL to thread poniter as failed to open channel */ sblock->thread = NULL; return rval; } /* handle the sblock events */ while (!kthread_should_stop()) { /* monitor sblock recv smsg */ smsg_set(&mrecv, sblock->channel, 0, 0, 0); rval = smsg_recv(sblock->dst, &mrecv, -1); if (rval == -EIO || rval == -ENODEV) { /* channel state is FREE */ msleep(5); continue; } pr_debug("sblock thread recv msg: dst=%d, channel=%d, " "type=%d, flag=0x%04x, value=0x%08x\n", sblock->dst, sblock->channel, mrecv.type, mrecv.flag, mrecv.value); switch (mrecv.type) { case SMSG_TYPE_OPEN: /* handle channel recovery */ if (recovery) { if (sblock->handler) { sblock->handler(SBLOCK_NOTIFY_CLOSE, sblock->data); } sblock_recover(sblock->dst, sblock->channel); } smsg_open_ack(sblock->dst, sblock->channel); break; case SMSG_TYPE_CLOSE: /* handle channel recovery */ smsg_close_ack(sblock->dst, sblock->channel); if (sblock->handler) { sblock->handler(SBLOCK_NOTIFY_CLOSE, sblock->data); } sblock->state = SBLOCK_STATE_IDLE; break; case SMSG_TYPE_CMD: /* respond cmd done for sblock init */ WARN_ON(mrecv.flag != SMSG_CMD_SBLOCK_INIT); smsg_set(&mcmd, sblock->channel, SMSG_TYPE_DONE, SMSG_DONE_SBLOCK_INIT, sblock->smem_addr); smsg_send(sblock->dst, &mcmd, -1); if (sblock->handler) { sblock->handler(SBLOCK_NOTIFY_OPEN, sblock->data); } sblock->state = SBLOCK_STATE_READY; recovery = 1; break; case SMSG_TYPE_EVENT: /* handle sblock send/release events */ switch (mrecv.flag) { case SMSG_EVENT_SBLOCK_SEND: wake_up_interruptible_all(&sblock->ring->recvwait); if (sblock->handler) { sblock->handler(SBLOCK_NOTIFY_RECV, sblock->data); } break; case SMSG_EVENT_SBLOCK_RELEASE: wake_up_interruptible_all(&(sblock->ring->getwait)); if (sblock->handler) { sblock->handler(SBLOCK_NOTIFY_GET, sblock->data); } break; default: rval = 1; break; } break; default: rval = 1; break; }; if (rval) { printk(KERN_WARNING "non-handled sblock msg: %d-%d, %d, %d, %d\n", sblock->dst, sblock->channel, mrecv.type, mrecv.flag, mrecv.value); rval = 0; } } printk(KERN_WARNING "sblock %d-%d thread stop", sblock->dst, sblock->channel); return rval; } int sblock_create(uint8_t dst, uint8_t channel, uint32_t txblocknum, uint32_t txblocksize, uint32_t rxblocknum, uint32_t rxblocksize) { struct sblock_mgr *sblock = NULL; volatile struct sblock_ring_header *ringhd = NULL; volatile struct sblock_ring_header *poolhd = NULL; uint32_t hsize; int i, result; sblock = kzalloc(sizeof(struct sblock_mgr) , GFP_KERNEL); if (!sblock) { return -ENOMEM; } sblock->state = SBLOCK_STATE_IDLE; sblock->dst = dst; sblock->channel = channel; sblock->txblksz = txblocksize; sblock->rxblksz = rxblocksize; sblock->txblknum = txblocknum; sblock->rxblknum = rxblocknum; /* allocate smem */ hsize = sizeof(struct sblock_header); sblock->smem_size = hsize + /* for header*/ txblocknum * txblocksize + rxblocknum * rxblocksize + /* for blks */ (txblocknum + rxblocknum) * sizeof(struct sblock_blks) + /* for ring*/ (txblocknum + rxblocknum) * sizeof(struct sblock_blks); /* for pool*/ sblock->smem_addr = smem_alloc(sblock->smem_size); if (!sblock->smem_addr) { printk(KERN_ERR "Failed to allocate smem for sblock\n"); kfree(sblock); return -ENOMEM; } sblock->smem_virt = ioremap(sblock->smem_addr, sblock->smem_size); if (!sblock->smem_virt) { printk(KERN_ERR "Failed to map smem for sblock\n"); smem_free(sblock->smem_addr, sblock->smem_size); kfree(sblock); return -EFAULT; } /* initialize ring and header */ sblock->ring = kzalloc(sizeof(struct sblock_ring), GFP_KERNEL); if (!sblock->ring) { printk(KERN_ERR "Failed to allocate ring for sblock\n"); iounmap(sblock->smem_virt); smem_free(sblock->smem_addr, sblock->smem_size); kfree(sblock); return -ENOMEM; } ringhd = (volatile struct sblock_ring_header *)(sblock->smem_virt); ringhd->txblk_addr = sblock->smem_addr + hsize; ringhd->txblk_count = txblocknum; ringhd->txblk_size = txblocksize; ringhd->txblk_rdptr = 0; ringhd->txblk_wrptr = 0; ringhd->txblk_blks = sblock->smem_addr + hsize + txblocknum * txblocksize + rxblocknum * rxblocksize; ringhd->rxblk_addr = ringhd->txblk_addr + txblocknum * txblocksize; ringhd->rxblk_count = rxblocknum; ringhd->rxblk_size = rxblocksize; ringhd->rxblk_rdptr = 0; ringhd->rxblk_wrptr = 0; ringhd->rxblk_blks = ringhd->txblk_blks + txblocknum * sizeof(struct sblock_blks); poolhd = (volatile struct sblock_ring_header *)(sblock->smem_virt + sizeof(struct sblock_ring_header)); poolhd->txblk_addr = sblock->smem_addr + hsize; poolhd->txblk_count = txblocknum; poolhd->txblk_size = txblocksize; poolhd->txblk_rdptr = 0; poolhd->txblk_wrptr = 0; poolhd->txblk_blks = ringhd->rxblk_blks + rxblocknum * sizeof(struct sblock_blks); poolhd->rxblk_addr = ringhd->txblk_addr + txblocknum * txblocksize; poolhd->rxblk_count = rxblocknum; poolhd->rxblk_size = rxblocksize; poolhd->rxblk_rdptr = 0; poolhd->rxblk_wrptr = 0; poolhd->rxblk_blks = poolhd->txblk_blks + txblocknum * sizeof(struct sblock_blks); sblock->ring->txrecord = kzalloc(sizeof(int) * txblocknum, GFP_KERNEL); if (!sblock->ring->txrecord) { printk(KERN_ERR "Failed to allocate memory for txrecord\n"); iounmap(sblock->smem_virt); smem_free(sblock->smem_addr, sblock->smem_size); kfree(sblock->ring); kfree(sblock); return -ENOMEM; } sblock->ring->rxrecord = kzalloc(sizeof(int) * rxblocknum, GFP_KERNEL); if (!sblock->ring->rxrecord) { printk(KERN_ERR "Failed to allocate memory for rxrecord\n"); iounmap(sblock->smem_virt); smem_free(sblock->smem_addr, sblock->smem_size); kfree(sblock->ring->txrecord); kfree(sblock->ring); kfree(sblock); return -ENOMEM; } sblock->ring->header = sblock->smem_virt; sblock->ring->txblk_virt = sblock->smem_virt + (ringhd->txblk_addr - sblock->smem_addr); sblock->ring->r_txblks = sblock->smem_virt + (ringhd->txblk_blks - sblock->smem_addr); sblock->ring->rxblk_virt = sblock->smem_virt + (ringhd->rxblk_addr - sblock->smem_addr); sblock->ring->r_rxblks = sblock->smem_virt + (ringhd->rxblk_blks - sblock->smem_addr); sblock->ring->p_txblks = sblock->smem_virt + (poolhd->txblk_blks - sblock->smem_addr); sblock->ring->p_rxblks = sblock->smem_virt + (poolhd->rxblk_blks - sblock->smem_addr); for (i = 0; i < txblocknum; i++) { sblock->ring->p_txblks[i].addr = poolhd->txblk_addr + i * txblocksize; sblock->ring->p_txblks[i].length = txblocksize; sblock->ring->txrecord[i] = SBLOCK_BLK_STATE_DONE; poolhd->txblk_wrptr++; } for (i = 0; i < rxblocknum; i++) { sblock->ring->p_rxblks[i].addr = poolhd->rxblk_addr + i * rxblocksize; sblock->ring->p_rxblks[i].length = rxblocksize; sblock->ring->rxrecord[i] = SBLOCK_BLK_STATE_DONE; poolhd->rxblk_wrptr++; } init_waitqueue_head(&sblock->ring->getwait); init_waitqueue_head(&sblock->ring->recvwait); spin_lock_init(&sblock->ring->r_txlock); spin_lock_init(&sblock->ring->r_rxlock); spin_lock_init(&sblock->ring->p_txlock); spin_lock_init(&sblock->ring->p_rxlock); sblock->thread = kthread_create(sblock_thread, sblock, "sblock-%d-%d", dst, channel); if (IS_ERR(sblock->thread)) { printk(KERN_ERR "Failed to create kthread: sblock-%d-%d\n", dst, channel); iounmap(sblock->smem_virt); smem_free(sblock->smem_addr, sblock->smem_size); kfree(sblock->ring->txrecord); kfree(sblock->ring->rxrecord); kfree(sblock->ring); result = PTR_ERR(sblock->thread); kfree(sblock); return result; } sblocks[dst][channel]=sblock; wake_up_process(sblock->thread); return 0; } void sblock_destroy(uint8_t dst, uint8_t channel) { struct sblock_mgr *sblock = sblocks[dst][channel]; if (sblock == NULL) { return; } sblock->state = SBLOCK_STATE_IDLE; smsg_ch_close(dst, channel, -1); /* stop sblock thread if it's created successfully and still alive */ if (!IS_ERR_OR_NULL(sblock->thread)) { kthread_stop(sblock->thread); } if (sblock->ring) { wake_up_interruptible_all(&sblock->ring->recvwait); wake_up_interruptible_all(&sblock->ring->getwait); if (sblock->ring->txrecord) { kfree(sblock->ring->txrecord); } if (sblock->ring->rxrecord) { kfree(sblock->ring->rxrecord); } kfree(sblock->ring); } if (sblock->smem_virt) { iounmap(sblock->smem_virt); } smem_free(sblock->smem_addr, sblock->smem_size); kfree(sblock); sblocks[dst][channel]=NULL; } int sblock_register_notifier(uint8_t dst, uint8_t channel, void (*handler)(int event, void *data), void *data) { struct sblock_mgr *sblock = sblocks[dst][channel]; if (!sblock) { printk(KERN_ERR "sblock-%d-%d not ready!\n", dst, channel); return -ENODEV; } #ifndef CONFIG_SIPC_WCN if (sblock->handler) { printk(KERN_ERR "sblock handler already registered\n"); return -EBUSY; } #endif sblock->handler = handler; sblock->data = data; return 0; } int sblock_get(uint8_t dst, uint8_t channel, struct sblock *blk, int timeout) { struct sblock_mgr *sblock = (struct sblock_mgr *)sblocks[dst][channel]; struct sblock_ring *ring = NULL; volatile struct sblock_ring_header *ringhd = NULL; volatile struct sblock_ring_header *poolhd = NULL; int txpos, index; int rval = 0; unsigned long flags; if (!sblock || sblock->state != SBLOCK_STATE_READY) { printk(KERN_ERR "sblock-%d-%d not ready!\n", dst, channel); return sblock ? -EIO : -ENODEV; } ring = sblock->ring; ringhd = (volatile struct sblock_ring_header *)(&ring->header->ring); poolhd = (volatile struct sblock_ring_header *)(&ring->header->pool); if (poolhd->txblk_rdptr == poolhd->txblk_wrptr) { if (timeout == 0) { /* no wait */ printk(KERN_WARNING "sblock_get %d-%d is empty!\n", dst, channel); rval = -ENODATA; } else if (timeout < 0) { /* wait forever */ rval = wait_event_interruptible(ring->getwait, poolhd->txblk_rdptr != poolhd->txblk_wrptr || sblock->state == SBLOCK_STATE_IDLE); if (rval < 0) { printk(KERN_WARNING "sblock_get wait interrupted!\n"); } if (sblock->state == SBLOCK_STATE_IDLE) { printk(KERN_ERR "sblock_get sblock state is idle!\n"); rval = -EIO; } } else { /* wait timeout */ rval = wait_event_interruptible_timeout(ring->getwait, poolhd->txblk_rdptr != poolhd->txblk_wrptr || sblock == SBLOCK_STATE_IDLE, timeout); if (rval < 0) { printk(KERN_WARNING "sblock_get wait interrupted!\n"); } else if (rval == 0) { printk(KERN_WARNING "sblock_get wait timeout!\n"); rval = -ETIME; } if(sblock->state == SBLOCK_STATE_IDLE) { printk(KERN_ERR "sblock_get sblock state is idle!\n"); rval = -EIO; } } } if (rval < 0) { return rval; } /* multi-gotter may cause got failure */ spin_lock_irqsave(&ring->p_txlock, flags); if (poolhd->txblk_rdptr != poolhd->txblk_wrptr && sblock->state == SBLOCK_STATE_READY) { txpos = sblock_get_ringpos(poolhd->txblk_rdptr, poolhd->txblk_count); blk->addr = sblock->smem_virt + (ring->p_txblks[txpos].addr - sblock->smem_addr); blk->length = poolhd->txblk_size; poolhd->txblk_rdptr = poolhd->txblk_rdptr + 1; index = sblock_get_index((blk->addr - ring->txblk_virt), sblock->txblksz); ring->txrecord[index] = SBLOCK_BLK_STATE_PENDING; } else { rval = sblock->state == SBLOCK_STATE_READY ? -EAGAIN : -EIO; } spin_unlock_irqrestore(&ring->p_txlock, flags); return rval; } static int sblock_send_ex(uint8_t dst, uint8_t channel, struct sblock *blk, bool yell) { struct sblock_mgr *sblock = (struct sblock_mgr *)sblocks[dst][channel]; struct sblock_ring *ring; volatile struct sblock_ring_header *ringhd; struct smsg mevt; int txpos, index; int rval = 0; unsigned long flags; if (!sblock || sblock->state != SBLOCK_STATE_READY) { printk(KERN_ERR "sblock-%d-%d not ready!\n", dst, channel); return sblock ? -EIO : -ENODEV; } pr_debug("sblock_send: dst=%d, channel=%d, addr=%p, len=%d\n", dst, channel, blk->addr, blk->length); ring = sblock->ring; ringhd = (volatile struct sblock_ring_header *)(&ring->header->ring); spin_lock_irqsave(&ring->r_txlock, flags); txpos = sblock_get_ringpos(ringhd->txblk_wrptr, ringhd->txblk_count); ring->r_txblks[txpos].addr = blk->addr - sblock->smem_virt + sblock->smem_addr; ring->r_txblks[txpos].length = blk->length; pr_debug("sblock_send: channel=%d, wrptr=%d, txpos=%d, addr=%x\n", channel, ringhd->txblk_wrptr, txpos, ring->r_txblks[txpos].addr); ringhd->txblk_wrptr = ringhd->txblk_wrptr + 1; if (yell && sblock->state == SBLOCK_STATE_READY) { smsg_set(&mevt, channel, SMSG_TYPE_EVENT, SMSG_EVENT_SBLOCK_SEND, 0); rval = smsg_send(dst, &mevt, 0); } index = sblock_get_index((blk->addr - ring->txblk_virt), sblock->txblksz); ring->txrecord[index] = SBLOCK_BLK_STATE_DONE; spin_unlock_irqrestore(&ring->r_txlock, flags); return rval ; } int sblock_send(uint8_t dst, uint8_t channel, struct sblock *blk) { return sblock_send_ex(dst, channel, blk, true); } int sblock_send_prepare(uint8_t dst, uint8_t channel, struct sblock *blk) { return sblock_send_ex(dst, channel, blk, false); } int sblock_send_finish(uint8_t dst, uint8_t channel) { struct sblock_mgr *sblock = (struct sblock_mgr *)sblocks[dst][channel]; struct sblock_ring *ring; volatile struct sblock_ring_header *ringhd; struct smsg mevt; int rval; if (!sblock || sblock->state != SBLOCK_STATE_READY) { printk(KERN_ERR "sblock-%d-%d not ready!\n", dst, channel); return sblock ? -EIO : -ENODEV; } ring = sblock->ring; ringhd = (volatile struct sblock_ring_header *)(&ring->header->ring); if (ringhd->txblk_wrptr != ringhd->txblk_rdptr) { smsg_set(&mevt, channel, SMSG_TYPE_EVENT, SMSG_EVENT_SBLOCK_SEND, 0); rval = smsg_send(dst, &mevt, 0); } return rval; } int sblock_receive(uint8_t dst, uint8_t channel, struct sblock *blk, int timeout) { struct sblock_mgr *sblock = sblocks[dst][channel]; struct sblock_ring *ring; volatile struct sblock_ring_header *ringhd; int rxpos, index, rval = 0; unsigned long flags; if (!sblock || sblock->state != SBLOCK_STATE_READY) { printk(KERN_ERR "sblock-%d-%d not ready!\n", dst, channel); return sblock ? -EIO : -ENODEV; } ring = sblock->ring; ringhd = (volatile struct sblock_ring_header *)(&ring->header->ring); pr_debug("sblock_receive: dst=%d, channel=%d, timeout=%d\n", dst, channel, timeout); pr_debug("sblock_receive: channel=%d, wrptr=%d, rdptr=%d", channel, ringhd->rxblk_wrptr, ringhd->rxblk_rdptr); if (ringhd->rxblk_wrptr == ringhd->rxblk_rdptr) { if (timeout == 0) { /* no wait */ pr_debug("sblock_receive %d-%d is empty!\n", dst, channel); rval = -ENODATA; } else if (timeout < 0) { /* wait forever */ rval = wait_event_interruptible(ring->recvwait, ringhd->rxblk_wrptr != ringhd->rxblk_rdptr); if (rval < 0) { printk(KERN_WARNING "sblock_receive wait interrupted!\n"); } if (sblock->state == SBLOCK_STATE_IDLE) { printk(KERN_ERR "sblock_receive sblock state is idle!\n"); rval = -EIO; } } else { /* wait timeout */ rval = wait_event_interruptible_timeout(ring->recvwait, ringhd->rxblk_wrptr != ringhd->rxblk_rdptr, timeout); if (rval < 0) { printk(KERN_WARNING "sblock_receive wait interrupted!\n"); } else if (rval == 0) { printk(KERN_WARNING "sblock_receive wait timeout!\n"); rval = -ETIME; } if (sblock->state == SBLOCK_STATE_IDLE) { printk(KERN_ERR "sblock_receive sblock state is idle!\n"); rval = -EIO; } } } if (rval < 0) { return rval; } /* multi-receiver may cause recv failure */ spin_lock_irqsave(&ring->r_rxlock, flags); if (ringhd->rxblk_wrptr != ringhd->rxblk_rdptr && sblock->state == SBLOCK_STATE_READY) { rxpos = sblock_get_ringpos(ringhd->rxblk_rdptr, ringhd->rxblk_count); blk->addr = ring->r_rxblks[rxpos].addr - sblock->smem_addr + sblock->smem_virt; blk->length = ring->r_rxblks[rxpos].length; ringhd->rxblk_rdptr = ringhd->rxblk_rdptr + 1; pr_debug("sblock_receive: channel=%d, rxpos=%d, addr=%p, len=%d\n", channel, rxpos, blk->addr, blk->length); index = sblock_get_index((blk->addr - ring->rxblk_virt), sblock->rxblksz); ring->rxrecord[index] = SBLOCK_BLK_STATE_PENDING; } else { rval = sblock->state == SBLOCK_STATE_READY ? -EAGAIN : -EIO; } spin_unlock_irqrestore(&ring->r_rxlock, flags); return rval; } int sblock_get_free_count(uint8_t dst, uint8_t channel) { struct sblock_mgr *sblock = (struct sblock_mgr *)sblocks[dst][channel]; struct sblock_ring *ring = NULL; volatile struct sblock_ring_header *poolhd = NULL; int blk_count = 0; unsigned long flags; if (!sblock || sblock->state != SBLOCK_STATE_READY) { printk(KERN_ERR "sblock-%d-%d not ready!\n", dst, channel); return -ENODEV; } ring = sblock->ring; poolhd = (volatile struct sblock_ring_header *)(&ring->header->pool); spin_lock_irqsave(&ring->p_txlock, flags); blk_count = (int)(poolhd->txblk_wrptr - poolhd->txblk_rdptr); spin_unlock_irqrestore(&ring->p_txlock, flags); return blk_count; } int sblock_release(uint8_t dst, uint8_t channel, struct sblock *blk) { struct sblock_mgr *sblock = (struct sblock_mgr *)sblocks[dst][channel]; struct sblock_ring *ring = NULL; volatile struct sblock_ring_header *ringhd = NULL; volatile struct sblock_ring_header *poolhd = NULL; struct smsg mevt; unsigned long flags; int rxpos; int index; if (!sblock || sblock->state != SBLOCK_STATE_READY) { printk(KERN_ERR "sblock-%d-%d not ready!\n", dst, channel); return -ENODEV; } pr_debug("sblock_release: dst=%d, channel=%d, addr=%p, len=%d\n", dst, channel, blk->addr, blk->length); ring = sblock->ring; ringhd = (volatile struct sblock_ring_header *)(&ring->header->ring); poolhd = (volatile struct sblock_ring_header *)(&ring->header->pool); spin_lock_irqsave(&ring->p_rxlock, flags); rxpos = sblock_get_ringpos(poolhd->rxblk_wrptr, poolhd->rxblk_count); ring->p_rxblks[rxpos].addr = blk->addr - sblock->smem_virt + sblock->smem_addr; ring->p_rxblks[rxpos].length = poolhd->rxblk_size; poolhd->rxblk_wrptr = poolhd->rxblk_wrptr + 1; pr_debug("sblock_release: addr=%x\n", ring->p_rxblks[rxpos].addr); if((int)(poolhd->rxblk_wrptr - poolhd->rxblk_rdptr) == 1 && sblock->state == SBLOCK_STATE_READY) { /* send smsg to notify the peer side */ smsg_set(&mevt, channel, SMSG_TYPE_EVENT, SMSG_EVENT_SBLOCK_RELEASE, 0); smsg_send(dst, &mevt, -1); } index = sblock_get_index((blk->addr - ring->rxblk_virt), sblock->rxblksz); ring->rxrecord[index] = SBLOCK_BLK_STATE_DONE; spin_unlock_irqrestore(&ring->p_rxlock, flags); return 0; } #if defined(CONFIG_DEBUG_FS) static int sblock_debug_show(struct seq_file *m, void *private) { struct sblock_mgr *sblock = NULL; struct sblock_ring *ring = NULL; volatile struct sblock_ring_header *ringhd = NULL; volatile struct sblock_ring_header *poolhd = NULL; int i, j; for (i = 0; i < SIPC_ID_NR; i++) { for (j=0; j < SMSG_CH_NR; j++) { sblock = sblocks[i][j]; if (!sblock) { continue; } ring = sblock->ring; ringhd = (volatile struct sblock_ring_header *)(&sblock->ring->header->ring); poolhd = (volatile struct sblock_ring_header *)(&sblock->ring->header->pool); seq_printf(m, "sblock dst 0x%0x, channel: 0x%0x, state: %d, smem_virt: 0x%0x, smem_addr: 0x%0x, smem_size: 0x%0x, txblksz: %d, rxblksz: %d \n", sblock->dst, sblock->channel, sblock->state, (uint32_t)sblock->smem_virt, sblock->smem_addr, sblock->smem_size, sblock->txblksz, sblock->rxblksz ); seq_printf(m, "sblock ring: txblk_virt :0x%0x, rxblk_virt :0x%0x \n", (uint32_t)ring->txblk_virt, (uint32_t)ring->rxblk_virt); seq_printf(m, "sblock ring header: rxblk_addr :0x%0x, rxblk_rdptr :0x%0x, rxblk_wrptr :0x%0x, rxblk_size :%d, rxblk_count :%d, rxblk_blks: 0x%0x \n", ringhd->rxblk_addr, ringhd->rxblk_rdptr, ringhd->rxblk_wrptr, ringhd->rxblk_size, ringhd->rxblk_count, ringhd->rxblk_blks); seq_printf(m, "sblock ring header: txblk_addr :0x%0x, txblk_rdptr :0x%0x, txblk_wrptr :0x%0x, txblk_size :%d, txblk_count :%d, txblk_blks: 0x%0x \n", ringhd->txblk_addr, ringhd->txblk_rdptr, ringhd->txblk_wrptr, ringhd->txblk_size, ringhd->txblk_count, ringhd->txblk_blks ); seq_printf(m, "sblock pool header: rxblk_addr :0x%0x, rxblk_rdptr :0x%0x, rxblk_wrptr :0x%0x, rxblk_size :%d, rxpool_count :%d, rxblk_blks: 0x%0x \n", poolhd->rxblk_addr, poolhd->rxblk_rdptr, poolhd->rxblk_wrptr, poolhd->rxblk_size, (int)(poolhd->rxblk_wrptr - poolhd->rxblk_rdptr), poolhd->rxblk_blks); seq_printf(m, "sblock pool header: txblk_addr :0x%0x, txblk_rdptr :0x%0x, txblk_wrptr :0x%0x, txblk_size :%d, txpool_count :%d, txblk_blks: 0x%0x \n", poolhd->txblk_addr, poolhd->txblk_rdptr, poolhd->txblk_wrptr, poolhd->txblk_size, (int)(poolhd->txblk_wrptr - poolhd->txblk_rdptr), poolhd->txblk_blks ); } } return 0; } static int sblock_debug_open(struct inode *inode, struct file *file) { return single_open(file, sblock_debug_show, inode->i_private); } static const struct file_operations sblock_debug_fops = { .open = sblock_debug_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; int sblock_init_debugfs(void *root ) { if (!root) return -ENXIO; debugfs_create_file("sblock", S_IRUGO, (struct dentry *)root, NULL, &sblock_debug_fops); return 0; } #endif /* CONFIG_DEBUG_FS */ EXPORT_SYMBOL(sblock_put); EXPORT_SYMBOL(sblock_create); EXPORT_SYMBOL(sblock_destroy); EXPORT_SYMBOL(sblock_register_notifier); EXPORT_SYMBOL(sblock_get); EXPORT_SYMBOL(sblock_send); EXPORT_SYMBOL(sblock_send_prepare); EXPORT_SYMBOL(sblock_send_finish); EXPORT_SYMBOL(sblock_receive); EXPORT_SYMBOL(sblock_get_free_count); EXPORT_SYMBOL(sblock_release); MODULE_AUTHOR("Chen Gaopeng"); MODULE_DESCRIPTION("SIPC/SBLOCK driver"); MODULE_LICENSE("GPL");
static int axp20x_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); const struct regulator_desc *regulators; struct regulator_config config = { .dev = pdev->dev.parent, .regmap = axp20x->regmap, .driver_data = axp20x, }; int ret, i, nregulators; u32 workmode; const char *axp22x_dc1_name = axp22x_regulators[AXP22X_DCDC1].name; const char *axp22x_dc5_name = axp22x_regulators[AXP22X_DCDC5].name; switch (axp20x->variant) { case AXP202_ID: case AXP209_ID: regulators = axp20x_regulators; nregulators = AXP20X_REG_ID_MAX; break; case AXP221_ID: case AXP223_ID: regulators = axp22x_regulators; nregulators = AXP22X_REG_ID_MAX; break; default: dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n", axp20x->variant); return -EINVAL; } /* This only sets the dcdc freq. Ignore any errors */ axp20x_regulator_parse_dt(pdev); for (i = 0; i < nregulators; i++) { const struct regulator_desc *desc = ®ulators[i]; struct regulator_desc *new_desc; /* * Regulators DC1SW and DC5LDO are connected internally, * so we have to handle their supply names separately. * * We always register the regulators in proper sequence, * so the supply names are correctly read. See the last * part of this loop to see where we save the DT defined * name. */ if (regulators == axp22x_regulators) { if (i == AXP22X_DC1SW) { new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL); *new_desc = regulators[i]; new_desc->supply_name = axp22x_dc1_name; desc = new_desc; } else if (i == AXP22X_DC5LDO) { new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL); *new_desc = regulators[i]; new_desc->supply_name = axp22x_dc5_name; desc = new_desc; } } rdev = devm_regulator_register(&pdev->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "Failed to register %s\n", regulators[i].name); return PTR_ERR(rdev); } ret = of_property_read_u32(rdev->dev.of_node, "x-powers,dcdc-workmode", &workmode); if (!ret) { if (axp20x_set_dcdc_workmode(rdev, i, workmode)) dev_err(&pdev->dev, "Failed to set workmode on %s\n", rdev->desc->name); } /* * Save AXP22X DCDC1 / DCDC5 regulator names for later. */ if (regulators == axp22x_regulators) { /* Can we use rdev->constraints->name instead? */ if (i == AXP22X_DCDC1) of_property_read_string(rdev->dev.of_node, "regulator-name", &axp22x_dc1_name); else if (i == AXP22X_DCDC5) of_property_read_string(rdev->dev.of_node, "regulator-name", &axp22x_dc5_name); } } return 0; } static struct platform_driver axp20x_regulator_driver = { .probe = axp20x_regulator_probe, .driver = { .name = "axp20x-regulator", }, }; module_platform_driver(axp20x_regulator_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Carlo Caione <*****@*****.**>"); MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC"); MODULE_ALIAS("platform:axp20x-regulator");
static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) { const struct pm8xxx_keypad_platform_data *pdata = dev_get_platdata(&pdev->dev); const struct matrix_keymap_data *keymap_data; struct pmic8xxx_kp *kp; int rc; u8 ctrl_val; struct device *sec_key; struct pm_gpio kypd_drv = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_LOW, .function = PM_GPIO_FUNC_1, .inv_int_pol = 1, }; struct pm_gpio kypd_sns = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_31P5, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_NO, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 1, }; if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8XXX_MAX_COLS || pdata->num_rows > PM8XXX_MAX_ROWS || pdata->num_cols < PM8XXX_MIN_COLS) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } if (!pdata->scan_delay_ms || pdata->scan_delay_ms > MAX_SCAN_DELAY || pdata->scan_delay_ms < MIN_SCAN_DELAY || !is_power_of_2(pdata->scan_delay_ms)) { dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); return -EINVAL; } if (!pdata->row_hold_ns || pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); return -EINVAL; } if (!pdata->debounce_ms || ((pdata->debounce_ms % 5) != 0) || pdata->debounce_ms > MAX_DEBOUNCE_TIME || pdata->debounce_ms < MIN_DEBOUNCE_TIME) { dev_err(&pdev->dev, "invalid debounce time supplied\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data supplied\n"); return -EINVAL; } kp = kzalloc(sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; platform_set_drvdata(pdev, kp); kp->pdata = pdata; kp->dev = &pdev->dev; kp->input = input_allocate_device(); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); rc = -ENOMEM; goto err_alloc_device; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); rc = -ENXIO; goto err_get_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); rc = -ENXIO; goto err_get_irq; } kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; kp->input->dev.parent = &pdev->dev; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->evbit[0] = BIT_MASK(EV_KEY); if (pdata->rep) __set_bit(EV_REP, kp->input->evbit); kp->input->keycode = kp->keycodes; kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; kp->input->keycodesize = sizeof(kp->keycodes); kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, kp->input->keycode, kp->input->keybit); get_volumekey_matrix(keymap_data, &volup_matrix, &voldown_matrix); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8xxx_kpd_init(kp); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); goto err_get_irq; } rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, pdata->num_cols, kp, &kypd_sns); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); goto err_gpio_config; } rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, pdata->num_rows, kp, &kypd_drv); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); goto err_gpio_config; } rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); goto err_get_irq; } rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); goto err_req_stuck_irq; } rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); goto err_pmic_reg_read; } rc = request_threaded_irq(MSM_GPIO_KEY_VOLUP_IRQ , NULL, pmic8058_volume_up_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "vol_up", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request vol_up irq\n"); goto err_req_sense_irq; } rc = request_threaded_irq(MSM_GPIO_KEY_VOLDOWN_IRQ , NULL, pmic8058_volume_down_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "vol_down", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request vol_down irq\n"); goto err_req_sense_irq; } kp->ctrl_reg = ctrl_val; #if defined CONFIG_MACH_VITAL2REFRESH gpio_tlmm_config(GPIO_CFG(MSM_HALL_IC, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); input_set_capability(kp->input, EV_SW, SW_LID); if (gpio_get_value(MSM_HALL_IC)) { input_report_switch(kp->input, SW_LID, 1); } else { input_report_switch(kp->input, SW_LID, 0); } input_sync(kp->input); printk(KERN_INFO "[input_report_switch] slide_int - !gpio_hall_ic %s\n", gpio_get_value(MSM_HALL_IC) == 0 ? "OPEN" : "CLOSE"); rc = request_threaded_irq(MSM_GPIO_TO_INT(MSM_HALL_IC), NULL, hall_ic_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "hall_ic", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request hall_ic irq\n"); goto err_hall_ic_irq; } #endif rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); goto err_pmic_reg_read; } sec_key = device_create(sec_class, NULL, 0, NULL, "sec_key"); if (IS_ERR(sec_key)) pr_err("Failed to create device(sec_key)!\n"); rc = device_create_file(sec_key, &dev_attr_sec_key_pressed); if (rc) { pr_err("Failed to create device file - pressed(%s), err(%d)!\n", dev_attr_sec_key_pressed.attr.name, rc); } dev_set_drvdata(sec_key, kp); device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; err_pmic_reg_read: free_irq(kp->key_stuck_irq, kp); err_req_stuck_irq: free_irq(kp->key_sense_irq, kp); #if defined CONFIG_MACH_VITAL2REFRESH err_hall_ic_irq: #endif err_req_sense_irq: err_gpio_config: err_get_irq: input_free_device(kp->input); err_alloc_device: platform_set_drvdata(pdev, NULL); kfree(kp); return rc; } static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) { struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); device_init_wakeup(&pdev->dev, 0); free_irq(kp->key_stuck_irq, kp); free_irq(kp->key_sense_irq, kp); input_unregister_device(kp->input); kfree(kp); platform_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM_SLEEP static int pmic8xxx_kp_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { enable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); #if defined CONFIG_MACH_VITAL2REFRESH enable_irq_wake(MSM_GPIO_TO_INT(MSM_HALL_IC)); /* to wakeup in case of sleep */ #endif if (input_dev->users) pmic8xxx_kp_disable(kp); mutex_unlock(&input_dev->mutex); } return 0; } static int pmic8xxx_kp_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { disable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); #if defined CONFIG_MACH_VITAL2REFRESH disable_irq_wake(MSM_GPIO_TO_INT(MSM_HALL_IC)); /* to match irq pair */ #endif if (input_dev->users) pmic8xxx_kp_enable(kp); mutex_unlock(&input_dev->mutex); } return 0; } #endif static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, pmic8xxx_kp_suspend, pmic8xxx_kp_resume); static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .remove = __devexit_p(pmic8xxx_kp_remove), .driver = { .name = PM8XXX_KEYPAD_DEV_NAME, .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, }, }; static int __init pmic8xxx_kp_init(void) { return platform_driver_register(&pmic8xxx_kp_driver); } module_init(pmic8xxx_kp_init); static void __exit pmic8xxx_kp_exit(void) { platform_driver_unregister(&pmic8xxx_kp_driver); } module_exit(pmic8xxx_kp_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("PMIC8XXX keypad driver"); MODULE_VERSION("1.0"); MODULE_ALIAS("platform:pmic8xxx_keypad"); MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
/* * keypad controller should be initialized in the following sequence * only, otherwise it might get into FSM stuck state. * * - Initialize keypad control parameters, like no. of rows, columns, * timing values etc., * - configure rows and column gpios pull up/down. * - set irq edge type. * - enable the keypad controller. */ static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) { const struct pm8xxx_keypad_platform_data *pdata = dev_get_platdata(&pdev->dev); const struct matrix_keymap_data *keymap_data; struct pmic8xxx_kp *kp; int rc; u8 ctrl_val; struct pm_gpio kypd_drv = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_LOW, .function = PM_GPIO_FUNC_1, .inv_int_pol = 1, }; struct pm_gpio kypd_sns = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_31P5, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_NO, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 1, }; if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8XXX_MAX_COLS || pdata->num_rows > PM8XXX_MAX_ROWS || pdata->num_cols < PM8XXX_MIN_COLS) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } if (!pdata->scan_delay_ms || pdata->scan_delay_ms > MAX_SCAN_DELAY || pdata->scan_delay_ms < MIN_SCAN_DELAY || !is_power_of_2(pdata->scan_delay_ms)) { dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); return -EINVAL; } if (!pdata->row_hold_ns || pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); return -EINVAL; } if (!pdata->debounce_ms || ((pdata->debounce_ms % 5) != 0) || pdata->debounce_ms > MAX_DEBOUNCE_TIME || pdata->debounce_ms < MIN_DEBOUNCE_TIME) { dev_err(&pdev->dev, "invalid debounce time supplied\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data supplied\n"); return -EINVAL; } kp = kzalloc(sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; platform_set_drvdata(pdev, kp); kp->pdata = pdata; kp->dev = &pdev->dev; kp->input = input_allocate_device(); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); rc = -ENOMEM; goto err_alloc_device; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); rc = -ENXIO; goto err_get_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); rc = -ENXIO; goto err_get_irq; } kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; kp->input->dev.parent = &pdev->dev; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->evbit[0] = BIT_MASK(EV_KEY); if (pdata->rep) __set_bit(EV_REP, kp->input->evbit); kp->input->keycode = kp->keycodes; kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; kp->input->keycodesize = sizeof(kp->keycodes); kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, kp->input->keycode, kp->input->keybit); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8xxx_kpd_init(kp); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); goto err_get_irq; } rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, pdata->num_cols, kp, &kypd_sns); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); goto err_gpio_config; } rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, pdata->num_rows, kp, &kypd_drv); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); goto err_gpio_config; } rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); goto err_get_irq; } rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); goto err_req_stuck_irq; } rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); goto err_pmic_reg_read; } kp->ctrl_reg = ctrl_val; rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); goto err_pmic_reg_read; } device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; err_pmic_reg_read: free_irq(kp->key_stuck_irq, kp); err_req_stuck_irq: free_irq(kp->key_sense_irq, kp); err_gpio_config: err_get_irq: input_free_device(kp->input); err_alloc_device: platform_set_drvdata(pdev, NULL); kfree(kp); return rc; } static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) { struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); device_init_wakeup(&pdev->dev, 0); free_irq(kp->key_stuck_irq, kp); free_irq(kp->key_sense_irq, kp); input_unregister_device(kp->input); kfree(kp); platform_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM_SLEEP static int pmic8xxx_kp_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { enable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); if (input_dev->users) pmic8xxx_kp_disable(kp); mutex_unlock(&input_dev->mutex); } return 0; } static int pmic8xxx_kp_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { disable_irq_wake(kp->key_sense_irq); pmic8xxx_kp_enable(kp); } else { mutex_lock(&input_dev->mutex); if (input_dev->users) pmic8xxx_kp_enable(kp); mutex_unlock(&input_dev->mutex); } return 0; } #endif static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, pmic8xxx_kp_suspend, pmic8xxx_kp_resume); static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .remove = __devexit_p(pmic8xxx_kp_remove), .driver = { .name = PM8XXX_KEYPAD_DEV_NAME, .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, }, }; static int __init pmic8xxx_kp_init(void) { return platform_driver_register(&pmic8xxx_kp_driver); } module_init(pmic8xxx_kp_init); static void __exit pmic8xxx_kp_exit(void) { platform_driver_unregister(&pmic8xxx_kp_driver); } module_exit(pmic8xxx_kp_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("PMIC8XXX keypad driver"); MODULE_VERSION("1.0"); MODULE_ALIAS("platform:pmic8xxx_keypad"); MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA5, .port_ops = &marvell_ops, }; static const struct ata_port_info info_sata = { /* Slave possible as its magically mapped not real */ .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA6, .port_ops = &marvell_ops, }; const struct ata_port_info *ppi[] = { &info, &info_sata }; if (pdev->device == 0x6101) ppi[1] = &ata_dummy_port_info; return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL); } static const struct pci_device_id marvell_pci_tbl[] = { { PCI_DEVICE(0x11AB, 0x6101), }, { PCI_DEVICE(0x11AB, 0x6121), }, { PCI_DEVICE(0x11AB, 0x6123), }, { PCI_DEVICE(0x11AB, 0x6145), }, { } /* terminate list */ }; static struct pci_driver marvell_pci_driver = { .name = DRV_NAME, .id_table = marvell_pci_tbl, .probe = marvell_init_one, .remove = ata_pci_remove_one, #ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, #endif }; static int __init marvell_init(void) { return pci_register_driver(&marvell_pci_driver); } static void __exit marvell_exit(void) { pci_unregister_driver(&marvell_pci_driver); } module_init(marvell_init); module_exit(marvell_exit); MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("SCSI low-level driver for Marvell ATA in legacy mode"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, marvell_pci_tbl); MODULE_VERSION(DRV_VERSION);
static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "Acquire WDT", }; switch(cmd) { case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: acq_ping(); return 0; case WDIOC_GETTIMEOUT: return put_user(WATCHDOG_TIMEOUT, (int *)arg); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; if (get_user(options, (int *)arg)) return -EFAULT; if (options & WDIOS_DISABLECARD) { acq_stop(); retval = 0; } if (options & WDIOS_ENABLECARD) { acq_ping(); retval = 0; } return retval; } default: return -ENOIOCTLCMD; } } static int acq_open(struct inode *inode, struct file *file) { if (test_and_set_bit(0, &acq_is_open)) return -EBUSY; if (nowayout) __module_get(THIS_MODULE); /* Activate */ acq_ping(); return 0; } static int acq_close(struct inode *inode, struct file *file) { if (expect_close == 42) { acq_stop(); } else { printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); acq_ping(); } clear_bit(0, &acq_is_open); expect_close = 0; return 0; } /* * Notifier for system down */ static int acq_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if(code==SYS_DOWN || code==SYS_HALT) { /* Turn the WDT off */ acq_stop(); } return NOTIFY_DONE; } /* * Kernel Interfaces */ static struct file_operations acq_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = acq_write, .ioctl = acq_ioctl, .open = acq_open, .release = acq_close, }; static struct miscdevice acq_miscdev= { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &acq_fops, }; /* * The WDT card needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block acq_notifier = { .notifier_call = acq_notify_sys, .next = NULL, .priority = 0, }; static int __init acq_init(void) { int ret; printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); if (wdt_stop != wdt_start) { if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", wdt_stop); ret = -EIO; goto out; } } if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", wdt_start); ret = -EIO; goto unreg_stop; } ret = register_reboot_notifier(&acq_notifier); if (ret != 0) { printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); goto unreg_regions; } ret = misc_register(&acq_miscdev); if (ret != 0) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto unreg_reboot; } printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", nowayout); out: return ret; unreg_reboot: unregister_reboot_notifier(&acq_notifier); unreg_regions: release_region(wdt_start, 1); unreg_stop: if (wdt_stop != wdt_start) release_region(wdt_stop, 1); goto out; } static void __exit acq_exit(void) { misc_deregister(&acq_miscdev); unregister_reboot_notifier(&acq_notifier); if(wdt_stop != wdt_start) release_region(wdt_stop,1); release_region(wdt_start,1); } module_init(acq_init); module_exit(acq_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Unkown"); MODULE_DESCRIPTION("Acquire Single Board Computer Watchdog Timer driver");
static int omap_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int new_margin; static struct watchdog_info ident = { .identity = "OMAP Watchdog", .options = WDIOF_SETTIMEOUT, .firmware_version = 0, }; switch (cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info __user *)arg, &ident, sizeof(ident)); case WDIOC_GETSTATUS: return put_user(0, (int __user *)arg); case WDIOC_GETBOOTSTATUS: if (cpu_is_omap16xx()) return put_user(omap_readw(ARM_SYSST), (int __user *)arg); if (cpu_is_omap24xx()) return put_user(omap_prcm_get_reset_sources(), (int __user *)arg); case WDIOC_KEEPALIVE: omap_wdt_ping(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_margin, (int __user *)arg)) return -EFAULT; omap_wdt_adjust_timeout(new_margin); omap_wdt_disable(); omap_wdt_set_timeout(); omap_wdt_enable(); omap_wdt_ping(); /* Fall */ case WDIOC_GETTIMEOUT: return put_user(timer_margin, (int __user *)arg); } } static const struct file_operations omap_wdt_fops = { .owner = THIS_MODULE, .write = omap_wdt_write, .ioctl = omap_wdt_ioctl, .open = omap_wdt_open, .release = omap_wdt_release, }; static struct miscdevice omap_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &omap_wdt_fops }; static int __init omap_wdt_probe(struct platform_device *pdev) { struct resource *res, *mem; int ret; /* reserve static register mappings */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; mem = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (mem == NULL) return -EBUSY; platform_set_drvdata(pdev, mem); omap_wdt_users = 0; if (cpu_is_omap16xx()) { armwdt_ck = clk_get(&pdev->dev, "armwdt_ck"); if (IS_ERR(armwdt_ck)) { ret = PTR_ERR(armwdt_ck); armwdt_ck = NULL; goto fail; } } if (cpu_is_omap24xx()) { mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick"); if (IS_ERR(mpu_wdt_ick)) { ret = PTR_ERR(mpu_wdt_ick); mpu_wdt_ick = NULL; goto fail; } mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck"); if (IS_ERR(mpu_wdt_fck)) { ret = PTR_ERR(mpu_wdt_fck); mpu_wdt_fck = NULL; goto fail; } } omap_wdt_disable(); omap_wdt_adjust_timeout(timer_margin); omap_wdt_miscdev.parent = &pdev->dev; ret = misc_register(&omap_wdt_miscdev); if (ret) goto fail; pr_info("OMAP Watchdog Timer: initial timeout %d sec\n", timer_margin); /* autogate OCP interface clock */ omap_writel(0x01, OMAP_WATCHDOG_SYS_CONFIG); return 0; fail: if (armwdt_ck) clk_put(armwdt_ck); if (mpu_wdt_ick) clk_put(mpu_wdt_ick); if (mpu_wdt_fck) clk_put(mpu_wdt_fck); release_resource(mem); return ret; } static void omap_wdt_shutdown(struct platform_device *pdev) { omap_wdt_disable(); } static int omap_wdt_remove(struct platform_device *pdev) { struct resource *mem = platform_get_drvdata(pdev); misc_deregister(&omap_wdt_miscdev); release_resource(mem); if (armwdt_ck) clk_put(armwdt_ck); if (mpu_wdt_ick) clk_put(mpu_wdt_ick); if (mpu_wdt_fck) clk_put(mpu_wdt_fck); return 0; } #ifdef CONFIG_PM /* REVISIT ... not clear this is the best way to handle system suspend; and * it's very inappropriate for selective device suspend (e.g. suspending this * through sysfs rather than by stopping the watchdog daemon). Also, this * may not play well enough with NOWAYOUT... */ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state) { if (omap_wdt_users) omap_wdt_disable(); return 0; } static int omap_wdt_resume(struct platform_device *pdev) { if (omap_wdt_users) { omap_wdt_enable(); omap_wdt_ping(); } return 0; } #else #define omap_wdt_suspend NULL #define omap_wdt_resume NULL #endif static struct platform_driver omap_wdt_driver = { .probe = omap_wdt_probe, .remove = omap_wdt_remove, .shutdown = omap_wdt_shutdown, .suspend = omap_wdt_suspend, .resume = omap_wdt_resume, .driver = { .owner = THIS_MODULE, .name = "omap_wdt", }, }; static int __init omap_wdt_init(void) { return platform_driver_register(&omap_wdt_driver); } static void __exit omap_wdt_exit(void) { platform_driver_unregister(&omap_wdt_driver); } module_init(omap_wdt_init); module_exit(omap_wdt_exit); MODULE_AUTHOR("George G. Davis"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
int __init i2c_dev_init(void) { int res; printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE); i2cdev_initialized = 0; #ifdef CONFIG_DEVFS_FS if (devfs_register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops)) { #else if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) { #endif printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n", I2C_MAJOR); return -EIO; } #ifdef CONFIG_DEVFS_FS devfs_handle = devfs_mk_dir(NULL, "i2c", NULL); #endif i2cdev_initialized ++; if ((res = i2c_add_driver(&i2cdev_driver))) { printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n"); i2cdev_cleanup(); return res; } i2cdev_initialized ++; return 0; } int i2cdev_cleanup(void) { int res; if (i2cdev_initialized >= 2) { if ((res = i2c_del_driver(&i2cdev_driver))) { printk("i2c-dev.o: Driver deregistration failed, " "module not removed.\n"); return res; } i2cdev_initialized --; } if (i2cdev_initialized >= 1) { #ifdef CONFIG_DEVFS_FS devfs_unregister(devfs_handle); if ((res = devfs_unregister_chrdev(I2C_MAJOR, "i2c"))) { #else if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) { #endif printk("i2c-dev.o: unable to release major %d for i2c bus\n", I2C_MAJOR); return res; } i2cdev_initialized --; } return 0; } EXPORT_NO_SYMBOLS; #ifdef MODULE MODULE_AUTHOR("Frodo Looijaard <*****@*****.**> and Simon G. Vogl <*****@*****.**>"); MODULE_DESCRIPTION("I2C /dev entries driver"); MODULE_LICENSE("GPL"); int init_module(void) { return i2c_dev_init(); } int cleanup_module(void) { return i2cdev_cleanup(); }
static int tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_police *police = to_police(a); struct tc_police opt = { .index = police->tcf_index, .action = police->tcf_action, .mtu = police->tcfp_mtu, .burst = PSCHED_NS2TICKS(police->tcfp_burst), .refcnt = police->tcf_refcnt - ref, .bindcnt = police->tcf_bindcnt - bind, }; struct tcf_t t; if (police->rate_present) psched_ratecfg_getrate(&opt.rate, &police->rate); if (police->peak_present) psched_ratecfg_getrate(&opt.peakrate, &police->peak); if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) goto nla_put_failure; if (police->tcfp_result && nla_put_u32(skb, TCA_POLICE_RESULT, police->tcfp_result)) goto nla_put_failure; if (police->tcfp_ewma_rate && nla_put_u32(skb, TCA_POLICE_AVRATE, police->tcfp_ewma_rate)) goto nla_put_failure; t.install = jiffies_to_clock_t(jiffies - police->tcf_tm.install); t.lastuse = jiffies_to_clock_t(jiffies - police->tcf_tm.lastuse); t.firstuse = jiffies_to_clock_t(jiffies - police->tcf_tm.firstuse); t.expires = jiffies_to_clock_t(police->tcf_tm.expires); if (nla_put_64bit(skb, TCA_POLICE_TM, sizeof(t), &t, TCA_POLICE_PAD)) goto nla_put_failure; return skb->len; nla_put_failure: nlmsg_trim(skb, b); return -1; } static int tcf_police_search(struct net *net, struct tc_action **a, u32 index, struct netlink_ext_ack *extack) { struct tc_action_net *tn = net_generic(net, police_net_id); return tcf_idr_search(tn, a, index); } MODULE_AUTHOR("Alexey Kuznetsov"); MODULE_DESCRIPTION("Policing actions"); MODULE_LICENSE("GPL"); static struct tc_action_ops act_police_ops = { .kind = "police", .type = TCA_ID_POLICE, .owner = THIS_MODULE, .act = tcf_act_police, .dump = tcf_act_police_dump, .init = tcf_act_police_init, .walk = tcf_act_police_walker, .lookup = tcf_police_search, .size = sizeof(struct tcf_police), }; static __net_init int police_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, police_net_id); return tc_action_net_init(tn, &act_police_ops); } static void __net_exit police_exit_net(struct list_head *net_list) { tc_action_net_exit(net_list, police_net_id); } static struct pernet_operations police_net_ops = { .init = police_init_net, .exit_batch = police_exit_net, .id = &police_net_id, .size = sizeof(struct tc_action_net), }; static int __init police_init_module(void) { return tcf_register_action(&act_police_ops, &police_net_ops); } static void __exit police_cleanup_module(void) { tcf_unregister_action(&act_police_ops, &police_net_ops); } module_init(police_init_module); module_exit(police_cleanup_module);
static int cdfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { return get_sb_bdev(fs_type, flags, dev_name, data, cdfs_fill_super, mnt); #else static struct super_block *cdfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { return get_sb_bdev(fs_type, flags, dev_name, data, cdfs_fill_super); #endif } static struct file_system_type cdfs_fs_type = { .owner = THIS_MODULE, .name = "cdfs", .get_sb = cdfs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV }; #endif /******************************************************/ MODULE_AUTHOR("Michiel Ronsse ([email protected])"); MODULE_DESCRIPTION("CDfs: a CD filesystem"); MODULE_LICENSE("GPL"); #ifdef OLD_KERNEL EXPORT_NO_SYMBOLS; #endif /******************************************************************/ static int __init cdfs_init(void) { int err; PRINT("init_module (insmod)\n"); printk(FSNAME" "VERSION" loaded.\n"); // register file system err = register_filesystem(&cdfs_fs_type); if (err < 0) return err; // register /proc entry if ((cdfs_proc_entry = create_proc_entry(FSNAME, 0, NULL ))) cdfs_proc_entry->proc_fops = &proc_cdfs_operations; cdfs_proc_cd=NULL; // start kernel thread if ((kcdfsd_pid = kernel_thread(kcdfsd_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND)) >0 ) { return 0; } else { printk(FSNAME" kernel_thread failed.\n"); if (cdfs_proc_entry) remove_proc_entry(FSNAME, NULL); unregister_filesystem(&cdfs_fs_type); return -1; } } /******************************************************************/ static void __exit cdfs_exit(void) { PRINT("cleanup_module (rmmod)\n"); kcdfsd_cleanup_thread(); if (cdfs_proc_entry) remove_proc_entry(FSNAME, NULL); unregister_filesystem(&cdfs_fs_type); }
static int mxc_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int new_margin; int bootr; static struct watchdog_info ident = { .identity = "MXC Watchdog", .options = WDIOF_SETTIMEOUT, .firmware_version = 0, }; switch (cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info __user *)arg, &ident, sizeof(ident)); case WDIOC_GETSTATUS: return put_user(0, (int __user *)arg); case WDIOC_GETBOOTSTATUS: bootr = mxc_wdt_get_bootreason(wdt_base_reg); return put_user(bootr, (int __user *)arg); case WDIOC_KEEPALIVE: mxc_wdt_ping(wdt_base_reg); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_margin, (int __user *)arg)) return -EFAULT; mxc_wdt_adjust_timeout(new_margin); mxc_wdt_disable(wdt_base_reg); mxc_wdt_set_timeout(wdt_base_reg); mxc_wdt_enable(wdt_base_reg); mxc_wdt_ping(wdt_base_reg); return 0; case WDIOC_GETTIMEOUT: mxc_wdt_ping(wdt_base_reg); new_margin = mxc_wdt_get_timeout(wdt_base_reg); return put_user(new_margin, (int __user *)arg); } } static struct file_operations mxc_wdt_fops = { .owner = THIS_MODULE, .write = mxc_wdt_write, .ioctl = mxc_wdt_ioctl, .open = mxc_wdt_open, .release = mxc_wdt_release, }; static struct miscdevice mxc_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &mxc_wdt_fops }; static int __init mxc_wdt_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct resource *res, *mem; int ret; /* reserve static register mappings */ res = platform_get_resource(pdev, IORESOURCE_MEM, dev_num); if (!res) return -ENOENT; mem = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (mem == NULL) return -EBUSY; dev_set_drvdata(dev, mem); wdt_base_reg = IO_ADDRESS(res->start); mxc_wdt_disable(wdt_base_reg); mxc_wdt_adjust_timeout(timer_margin); mxc_wdt_users = 0; mxc_wdt_miscdev.dev = dev; ret = misc_register(&mxc_wdt_miscdev); if (ret) goto fail; pr_info("MXC Watchdog # %d Timer: initial timeout %d sec\n", dev_num, timer_margin); return 0; fail: release_resource(mem); pr_info("MXC Watchdog Probe failed\n"); return ret; } static void mxc_wdt_shutdown(struct device *dev) { struct resource *res = dev_get_drvdata(dev); mxc_wdt_disable(res->start); pr_info("MXC Watchdog # %d shutdown\n", dev_num); } static int __exit mxc_wdt_remove(struct device *dev) { struct resource *mem = dev_get_drvdata(dev); misc_deregister(&mxc_wdt_miscdev); release_resource(mem); pr_info("MXC Watchdog # %d removed\n", dev_num); return 0; } #ifdef CONFIG_PM /* REVISIT ... not clear this is the best way to handle system suspend; and * it's very inappropriate for selective device suspend (e.g. suspending this * through sysfs rather than by stopping the watchdog daemon). Also, this * may not play well enough with NOWAYOUT... */ static int mxc_wdt_suspend(struct device *dev, u32 state, u32 level) { struct resource *res = dev_get_drvdata(dev); if (level == SUSPEND_POWER_DOWN && mxc_wdt_users) mxc_wdt_disable(res->start); return 0; } static int mxc_wdt_resume(struct device *dev, u32 level) { struct resource *res = dev_get_drvdata(dev); if (level == RESUME_POWER_ON && mxc_wdt_users) { mxc_wdt_enable(res->start); mxc_wdt_ping(res->start); } return 0; } #else #define mxc_wdt_suspend NULL #define mxc_wdt_resume NULL #endif static struct device_driver mxc_wdt_driver = { .name = "mxc_wdt", .bus = &platform_bus_type, .probe = mxc_wdt_probe, .shutdown = mxc_wdt_shutdown, .remove = __exit_p(mxc_wdt_remove), .suspend = mxc_wdt_suspend, .resume = mxc_wdt_resume, }; static int __init mxc_wdt_init(void) { pr_info("MXC WatchDog Driver %s\n", DVR_VER); if ((timer_margin < TIMER_MARGIN_MIN) || (timer_margin > TIMER_MARGIN_MAX)) { pr_info("MXC watchdog error. wrong timer_margin %d\n", timer_margin); pr_info(" Range: %d to %d seconds\n", TIMER_MARGIN_MIN, TIMER_MARGIN_MAX); return -EINVAL; } return driver_register(&mxc_wdt_driver); } static void __exit mxc_wdt_exit(void) { driver_unregister(&mxc_wdt_driver); pr_info("MXC WatchDog Driver removed\n"); } module_init(mxc_wdt_init); module_exit(mxc_wdt_exit); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_defact *d = to_defact(a); struct tc_defact opt = { .index = d->tcf_index, .refcnt = d->tcf_refcnt - ref, .bindcnt = d->tcf_bindcnt - bind, .action = d->tcf_action, }; struct tcf_t t; if (nla_put(skb, TCA_DEF_PARMS, sizeof(opt), &opt) || nla_put_string(skb, TCA_DEF_DATA, d->tcfd_defdata)) goto nla_put_failure; tcf_tm_dump(&t, &d->tcf_tm); if (nla_put_64bit(skb, TCA_DEF_TM, sizeof(t), &t, TCA_DEF_PAD)) goto nla_put_failure; return skb->len; nla_put_failure: nlmsg_trim(skb, b); return -1; } static int tcf_simp_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, const struct tc_action_ops *ops) { struct tc_action_net *tn = net_generic(net, simp_net_id); return tcf_generic_walker(tn, skb, cb, type, ops); } static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, simp_net_id); return tcf_hash_search(tn, a, index); } static struct tc_action_ops act_simp_ops = { .kind = "simple", .type = TCA_ACT_SIMP, .owner = THIS_MODULE, .act = tcf_simp, .dump = tcf_simp_dump, .cleanup = tcf_simp_release, .init = tcf_simp_init, .walk = tcf_simp_walker, .lookup = tcf_simp_search, .size = sizeof(struct tcf_defact), }; static __net_init int simp_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, simp_net_id); return tc_action_net_init(tn, &act_simp_ops, SIMP_TAB_MASK); } static void __net_exit simp_exit_net(struct net *net) { struct tc_action_net *tn = net_generic(net, simp_net_id); tc_action_net_exit(tn); } static struct pernet_operations simp_net_ops = { .init = simp_init_net, .exit = simp_exit_net, .id = &simp_net_id, .size = sizeof(struct tc_action_net), }; MODULE_AUTHOR("Jamal Hadi Salim(2005)"); MODULE_DESCRIPTION("Simple example action"); MODULE_LICENSE("GPL"); static int __init simp_init_module(void) { int ret = tcf_register_action(&act_simp_ops, &simp_net_ops); if (!ret) pr_info("Simple TC action Loaded\n"); return ret; } static void __exit simp_cleanup_module(void) { tcf_unregister_action(&act_simp_ops, &simp_net_ops); } module_init(simp_init_module); module_exit(simp_cleanup_module);
static long wb_smsc_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int new_timeout; union { struct watchdog_info __user *ident; int __user *i; } uarg; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 0, .identity = "SMsC 37B787 Watchdog", }; uarg.i = (int __user *)arg; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: return put_user(wb_smsc_wdt_status(), uarg.i); case WDIOC_GETBOOTSTATUS: return put_user(0, uarg.i); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; if (get_user(options, uarg.i)) return -EFAULT; if (options & WDIOS_DISABLECARD) { wb_smsc_wdt_disable(); retval = 0; } if (options & WDIOS_ENABLECARD) { wb_smsc_wdt_enable(); retval = 0; } return retval; } case WDIOC_KEEPALIVE: wb_smsc_wdt_reset_timer(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_timeout, uarg.i)) return -EFAULT; /* the API states this is given in secs */ if (unit == UNIT_MINUTE) new_timeout /= 60; if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) return -EINVAL; timeout = new_timeout; wb_smsc_wdt_set_timeout(timeout); /* fall through - and return the new timeout... */ case WDIOC_GETTIMEOUT: new_timeout = timeout; if (unit == UNIT_MINUTE) new_timeout *= 60; return put_user(new_timeout, uarg.i); default: return -ENOTTY; } } /* -- Notifier funtions -----------------------------------------*/ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) { /* set timeout to 0, to avoid possible race-condition */ timeout = 0; wb_smsc_wdt_disable(); } return NOTIFY_DONE; } /* -- Module's structures ---------------------------------------*/ static const struct file_operations wb_smsc_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = wb_smsc_wdt_write, .unlocked_ioctl = wb_smsc_wdt_ioctl, .open = wb_smsc_wdt_open, .release = wb_smsc_wdt_release, }; static struct notifier_block wb_smsc_wdt_notifier = { .notifier_call = wb_smsc_wdt_notify_sys, }; static struct miscdevice wb_smsc_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wb_smsc_wdt_fops, }; /* -- Module init functions -------------------------------------*/ /* module's "constructor" */ static int __init wb_smsc_wdt_init(void) { int ret; pr_info("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { pr_err("Unable to register IO port %#x\n", IOPORT); ret = -EBUSY; goto out_pnp; } /* set new maximum, if it's too big */ if (timeout > MAX_TIMEOUT) timeout = MAX_TIMEOUT; /* init the watchdog timer */ wb_smsc_wdt_initialize(); ret = register_reboot_notifier(&wb_smsc_wdt_notifier); if (ret) { pr_err("Unable to register reboot notifier err = %d\n", ret); goto out_io; } ret = misc_register(&wb_smsc_wdt_miscdev); if (ret) { pr_err("Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); goto out_rbt; } /* output info */ pr_info("Timeout set to %d %s\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); pr_info("Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); out_clean: return ret; out_rbt: unregister_reboot_notifier(&wb_smsc_wdt_notifier); out_io: release_region(IOPORT, IOPORT_SIZE); out_pnp: goto out_clean; } /* module's "destructor" */ static void __exit wb_smsc_wdt_exit(void) { /* Stop the timer before we leave */ if (!nowayout) { wb_smsc_wdt_shutdown(); pr_info("Watchdog disabled\n"); } misc_deregister(&wb_smsc_wdt_miscdev); unregister_reboot_notifier(&wb_smsc_wdt_notifier); release_region(IOPORT, IOPORT_SIZE); pr_info("SMsC 37B787 watchdog component driver removed\n"); } module_init(wb_smsc_wdt_init); module_exit(wb_smsc_wdt_exit); MODULE_AUTHOR("Sven Anders <*****@*****.**>"); MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); MODULE_LICENSE("GPL"); #ifdef SMSC_SUPPORT_MINUTES module_param(unit, int, 0); MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); #endif module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, .port_ops = &cs5530_port_ops }; /* The docking connector doesn't do UDMA, and it seems not MWDMA */ static const struct ata_port_info info_palmax_secondary = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .port_ops = &cs5530_port_ops }; const struct ata_port_info *ppi[] = { &info, NULL }; int rc; rc = pcim_enable_device(pdev); if (rc) return rc; /* Chip initialisation */ if (cs5530_init_chip()) return -ENODEV; if (cs5530_is_palmax()) ppi[1] = &info_palmax_secondary; /* Now kick off ATA set up */ return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL); } #ifdef CONFIG_PM static int cs5530_reinit_one(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); int rc; rc = ata_pci_device_do_resume(pdev); if (rc) return rc; /* If we fail on resume we are doomed */ if (cs5530_init_chip()) return -EIO; ata_host_resume(host); return 0; } #endif /* CONFIG_PM */ static const struct pci_device_id cs5530[] = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), }, { }, }; static struct pci_driver cs5530_pci_driver = { .name = DRV_NAME, .id_table = cs5530, .probe = cs5530_init_one, .remove = ata_pci_remove_one, #ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = cs5530_reinit_one, #endif }; static int __init cs5530_init(void) { return pci_register_driver(&cs5530_pci_driver); } static void __exit cs5530_exit(void) { pci_unregister_driver(&cs5530_pci_driver); } MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, cs5530); MODULE_VERSION(DRV_VERSION); module_init(cs5530_init); module_exit(cs5530_exit);
/* * sysfs hook function */ static ssize_t madc_read(struct device *dev, struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct twl4030_madc_request req = { .channels = 1 << attr->index, .method = TWL4030_MADC_SW2, .type = TWL4030_MADC_WAIT, }; long val; val = twl4030_madc_conversion(&req); if (val < 0) return val; return sprintf(buf, "%d\n", req.rbuf[attr->index]); } /* sysfs nodes to read individual channels from user side */ static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, madc_read, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, madc_read, NULL, 1); static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, madc_read, NULL, 2); static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, madc_read, NULL, 3); static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, madc_read, NULL, 4); static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, madc_read, NULL, 5); static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, madc_read, NULL, 6); static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, madc_read, NULL, 7); static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, madc_read, NULL, 8); static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, madc_read, NULL, 9); static SENSOR_DEVICE_ATTR(curr10_input, S_IRUGO, madc_read, NULL, 10); static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, madc_read, NULL, 11); static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12); static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15); static struct attribute *twl4030_madc_attrs[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_in2_input.dev_attr.attr, &sensor_dev_attr_in3_input.dev_attr.attr, &sensor_dev_attr_in4_input.dev_attr.attr, &sensor_dev_attr_in5_input.dev_attr.attr, &sensor_dev_attr_in6_input.dev_attr.attr, &sensor_dev_attr_in7_input.dev_attr.attr, &sensor_dev_attr_in8_input.dev_attr.attr, &sensor_dev_attr_in9_input.dev_attr.attr, &sensor_dev_attr_curr10_input.dev_attr.attr, &sensor_dev_attr_in11_input.dev_attr.attr, &sensor_dev_attr_in12_input.dev_attr.attr, &sensor_dev_attr_in15_input.dev_attr.attr, NULL }; ATTRIBUTE_GROUPS(twl4030_madc); static int twl4030_madc_hwmon_probe(struct platform_device *pdev) { struct device *hwmon; hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "twl4030_madc", NULL, twl4030_madc_groups); return PTR_ERR_OR_ZERO(hwmon); } static struct platform_driver twl4030_madc_hwmon_driver = { .probe = twl4030_madc_hwmon_probe, .driver = { .name = "twl4030_madc_hwmon", .owner = THIS_MODULE, }, }; module_platform_driver(twl4030_madc_hwmon_driver); MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("J Keerthy"); MODULE_ALIAS("platform:twl4030_madc_hwmon");
int __init usb_mdc800_init (void) { /* Allocate Memory */ try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL)); memset(mdc800, 0, sizeof(struct mdc800_data)); mdc800->dev=0; mdc800->open=0; mdc800->state=NOT_CONNECTED; spin_lock_init (&mdc800->io_lock); init_waitqueue_head (&mdc800->irq_wait); init_waitqueue_head (&mdc800->write_wait); init_waitqueue_head (&mdc800->download_wait); try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL)); try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL)); try (mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL)); try (mdc800->irq_urb=usb_alloc_urb (0)); try (mdc800->download_urb=usb_alloc_urb (0)); try (mdc800->write_urb=usb_alloc_urb (0)); /* Register the driver */ if (usb_register (&mdc800_usb_driver) < 0) goto cleanup_on_fail; info ("Mustek Digital Camera Driver " VERSION " (MDC800)"); info (RELEASE_DATE " Henning Zabel <*****@*****.**>"); return 0; /* Clean driver up, when something fails */ cleanup_on_fail: if (mdc800 != 0) { err ("can't alloc memory!"); try_free_mem (mdc800->download_urb_buffer); try_free_mem (mdc800->write_urb_buffer); try_free_mem (mdc800->irq_urb_buffer); try_free_urb (mdc800->write_urb); try_free_urb (mdc800->download_urb); try_free_urb (mdc800->irq_urb); kfree (mdc800); } mdc800=0; return -1; } void __exit usb_mdc800_cleanup (void) { usb_deregister (&mdc800_usb_driver); usb_free_urb (mdc800->irq_urb); usb_free_urb (mdc800->download_urb); usb_free_urb (mdc800->write_urb); kfree (mdc800->irq_urb_buffer); kfree (mdc800->write_urb_buffer); kfree (mdc800->download_urb_buffer); kfree (mdc800); mdc800=0; } MODULE_AUTHOR ("Henning Zabel <*****@*****.**>"); MODULE_DESCRIPTION ("USB Driver for Mustek MDC800 Digital Camera"); module_init (usb_mdc800_init); module_exit (usb_mdc800_cleanup);
static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; u32 value; static const struct watchdog_info ident = { .options = WDIOF_CARDRESET, .identity = "RDC321x WDT", }; unsigned long flags; switch (cmd) { case WDIOC_KEEPALIVE: rdc321x_wdt_reset(); break; case WDIOC_GETSTATUS: /* Read the value from the DATA register */ spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); pci_read_config_dword(rdc321x_wdt_device.sb_pdev, rdc321x_wdt_device.base_reg, &value); spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); if (copy_to_user(argp, &value, sizeof(u32))) return -EFAULT; break; case WDIOC_GETSUPPORT: if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_SETOPTIONS: if (copy_from_user(&value, argp, sizeof(int))) return -EFAULT; switch (value) { case WDIOS_ENABLECARD: rdc321x_wdt_start(); break; case WDIOS_DISABLECARD: return rdc321x_wdt_stop(); default: return -EINVAL; } break; default: return -ENOTTY; } return 0; } static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if (!count) return -EIO; rdc321x_wdt_reset(); return count; } static const struct file_operations rdc321x_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .unlocked_ioctl = rdc321x_wdt_ioctl, .open = rdc321x_wdt_open, .write = rdc321x_wdt_write, .release = rdc321x_wdt_release, }; static struct miscdevice rdc321x_wdt_misc = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &rdc321x_wdt_fops, }; static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) { int err; struct resource *r; struct rdc321x_wdt_pdata *pdata; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data supplied\n"); return -ENODEV; } r = platform_get_resource_byname(pdev, IORESOURCE_IO, "wdt-reg"); if (!r) { dev_err(&pdev->dev, "failed to get wdt-reg resource\n"); return -ENODEV; } rdc321x_wdt_device.sb_pdev = pdata->sb_pdev; rdc321x_wdt_device.base_reg = r->start; err = misc_register(&rdc321x_wdt_misc); if (err < 0) { dev_err(&pdev->dev, "misc_register failed\n"); return err; } spin_lock_init(&rdc321x_wdt_device.lock); /* Reset the watchdog */ pci_write_config_dword(rdc321x_wdt_device.sb_pdev, rdc321x_wdt_device.base_reg, RDC_WDT_RST); init_completion(&rdc321x_wdt_device.stop); rdc321x_wdt_device.queue = 0; clear_bit(0, &rdc321x_wdt_device.inuse); setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0); rdc321x_wdt_device.default_ticks = ticks; dev_info(&pdev->dev, "watchdog init success\n"); return 0; } static int __devexit rdc321x_wdt_remove(struct platform_device *pdev) { if (rdc321x_wdt_device.queue) { rdc321x_wdt_device.queue = 0; wait_for_completion(&rdc321x_wdt_device.stop); } misc_deregister(&rdc321x_wdt_misc); return 0; } static struct platform_driver rdc321x_wdt_driver = { .probe = rdc321x_wdt_probe, .remove = __devexit_p(rdc321x_wdt_remove), .driver = { .owner = THIS_MODULE, .name = "rdc321x-wdt", }, }; module_platform_driver(rdc321x_wdt_driver); MODULE_AUTHOR("Florian Fainelli <*****@*****.**>"); MODULE_DESCRIPTION("RDC321x watchdog driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int asr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .identity = "IBM ASR" }; void __user *argp = (void __user *)arg; int __user *p = argp; int heartbeat; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: asr_toggle(); return 0; /* * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT * and WDIOC_GETTIMEOUT always returns 256. */ case WDIOC_GETTIMEOUT: heartbeat = 256; return put_user(heartbeat, p); case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { asr_disable(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { asr_enable(); asr_toggle(); retval = 0; } return retval; } } return -ENOIOCTLCMD; } static int asr_open(struct inode *inode, struct file *file) { if(test_and_set_bit(0, &asr_is_open)) return -EBUSY; asr_toggle(); asr_enable(); return nonseekable_open(inode, file); } static int asr_release(struct inode *inode, struct file *file) { if (asr_expect_close == 42) asr_disable(); else { printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); asr_toggle(); } clear_bit(0, &asr_is_open); asr_expect_close = 0; return 0; } static struct file_operations asr_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = asr_write, .ioctl = asr_ioctl, .open = asr_open, .release = asr_release, }; static struct miscdevice asr_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &asr_fops, }; struct ibmasr_id { const char *desc; int type; }; static struct ibmasr_id __initdata ibmasr_id_table[] = { { "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ }, { "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL }, { "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER }, { "IBM Automatic Server Restart - Machine Type 8482", ASMTYPE_JUNIPER }, { "IBM Automatic Server Restart - Machine Type 8648", ASMTYPE_SPRUCE }, { NULL } }; static int __init ibmasr_init(void) { struct ibmasr_id *id; int rc; for (id = ibmasr_id_table; id->desc; id++) { if (dmi_find_device(DMI_DEV_TYPE_OTHER, id->desc, NULL)) { asr_type = id->type; break; } } if (!asr_type) return -ENODEV; rc = misc_register(&asr_miscdev); if (rc < 0) { printk(KERN_ERR PFX "failed to register misc device\n"); return rc; } rc = asr_get_base_address(); if (rc) { misc_deregister(&asr_miscdev); return rc; } return 0; } static void __exit ibmasr_exit(void) { if (!nowayout) asr_disable(); misc_deregister(&asr_miscdev); release_region(asr_base, asr_length); } module_init(ibmasr_init); module_exit(ibmasr_exit); module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); MODULE_AUTHOR("Andrey Panin"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int timeout; static struct watchdog_info info = { .options = WDIOF_KEEPALIVEPING, .firmware_version = 0, .identity = "MPC8xx watchdog", }; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user((void *)arg, &info, sizeof(info))) return -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: if (put_user(wdt_status, (int *)arg)) return -EFAULT; wdt_status &= ~WDIOF_KEEPALIVEPING; break; case WDIOC_GETTEMP: return -EOPNOTSUPP; case WDIOC_SETOPTIONS: return -EOPNOTSUPP; case WDIOC_KEEPALIVE: m8xx_wdt_reset(); wdt_status |= WDIOF_KEEPALIVEPING; break; case WDIOC_SETTIMEOUT: return -EOPNOTSUPP; case WDIOC_GETTIMEOUT: timeout = m8xx_wdt_get_timeout(); if (put_user(timeout, (int *)arg)) return -EFAULT; break; default: return -ENOIOCTLCMD; } return 0; } static const struct file_operations mpc8xx_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = mpc8xx_wdt_write, .ioctl = mpc8xx_wdt_ioctl, .open = mpc8xx_wdt_open, .release = mpc8xx_wdt_release, }; static struct miscdevice mpc8xx_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &mpc8xx_wdt_fops, }; static int __init mpc8xx_wdt_init(void) { return misc_register(&mpc8xx_wdt_miscdev); } static void __exit mpc8xx_wdt_exit(void) { misc_deregister(&mpc8xx_wdt_miscdev); m8xx_wdt_reset(); mpc8xx_wdt_handler_enable(); } module_init(mpc8xx_wdt_init); module_exit(mpc8xx_wdt_exit); MODULE_AUTHOR("Florian Schirmer <*****@*****.**>"); MODULE_DESCRIPTION("MPC8xx watchdog driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_gact *gact = a->priv; struct tcf_t t; struct tc_gact opt = { .index = gact->tcf_index, .refcnt = gact->tcf_refcnt - ref, .bindcnt = gact->tcf_bindcnt - bind, .action = gact->tcf_action, }; NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt); #ifdef CONFIG_GACT_PROB if (gact->tcfg_ptype) { struct tc_gact_p p_opt = { .paction = gact->tcfg_paction, .pval = gact->tcfg_pval, .ptype = gact->tcfg_ptype, }; NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt); } #endif t.install = jiffies_to_clock_t(jiffies - gact->tcf_tm.install); t.lastuse = jiffies_to_clock_t(jiffies - gact->tcf_tm.lastuse); t.expires = jiffies_to_clock_t(gact->tcf_tm.expires); NLA_PUT(skb, TCA_GACT_TM, sizeof(t), &t); return skb->len; nla_put_failure: nlmsg_trim(skb, b); return -1; } static struct tc_action_ops act_gact_ops = { .kind = "gact", .hinfo = &gact_hash_info, .type = TCA_ACT_GACT, .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_gact, .dump = tcf_gact_dump, .cleanup = tcf_gact_cleanup, .lookup = tcf_hash_search, .init = tcf_gact_init, .walk = tcf_generic_walker }; MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); MODULE_DESCRIPTION("Generic Classifier actions"); MODULE_LICENSE("GPL"); static int __init gact_init_module(void) { #ifdef CONFIG_GACT_PROB printk("GACT probability on\n"); #else printk("GACT probability NOT on\n"); #endif return tcf_register_action(&act_gact_ops); } static void __exit gact_cleanup_module(void) { tcf_unregister_action(&act_gact_ops); } module_init(gact_init_module); module_exit(gact_cleanup_module);
static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "SC520", }; switch(cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if(get_user(new_options, p)) return -EFAULT; if(new_options & WDIOS_DISABLECARD) { wdt_turnoff(); retval = 0; } if(new_options & WDIOS_ENABLECARD) { wdt_startup(); retval = 0; } return retval; } case WDIOC_SETTIMEOUT: { int new_timeout; if(get_user(new_timeout, p)) return -EFAULT; if(wdt_set_heartbeat(new_timeout)) return -EINVAL; wdt_keepalive(); /* Fall through */ } case WDIOC_GETTIMEOUT: return put_user(timeout, p); } } static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, .ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wdt_fops, }; /* * Notifier for system down */ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if(code==SYS_DOWN || code==SYS_HALT) wdt_turnoff(); return NOTIFY_DONE; } /* * The WDT needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; static void __exit sc520_wdt_unload(void) { if (!nowayout) wdt_turnoff(); /* Deregister */ misc_deregister(&wdt_miscdev); unregister_reboot_notifier(&wdt_notifier); iounmap(wdtmrctl); } static int __init sc520_wdt_init(void) { int rc = -EBUSY; spin_lock_init(&wdt_spinlock); init_timer(&timer); timer.function = wdt_timer_ping; timer.data = 0; /* Check that the timeout value is within it's range ; if not reset to the default */ if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); printk(KERN_INFO PFX "timeout value must be 1<=timeout<=3600, using %d\n", WATCHDOG_TIMEOUT); } wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); if (!wdtmrctl) { printk(KERN_ERR PFX "Unable to remap memory\n"); rc = -ENOMEM; goto err_out_region2; } rc = register_reboot_notifier(&wdt_notifier); if (rc) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", rc); goto err_out_ioremap; } rc = misc_register(&wdt_miscdev); if (rc) { printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, rc); goto err_out_notifier; } printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", timeout,nowayout); return 0; err_out_notifier: unregister_reboot_notifier(&wdt_notifier); err_out_ioremap: iounmap(wdtmrctl); err_out_region2: return rc; } module_init(sc520_wdt_init); module_exit(sc520_wdt_unload); MODULE_AUTHOR("Scott and Bill Jennings"); MODULE_DESCRIPTION("Driver for watchdog timer in AMD \"Elan\" SC520 uProcessor"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_sample *s = to_sample(a); struct tc_sample opt = { .index = s->tcf_index, .action = s->tcf_action, .refcnt = s->tcf_refcnt - ref, .bindcnt = s->tcf_bindcnt - bind, }; struct tcf_t t; if (nla_put(skb, TCA_SAMPLE_PARMS, sizeof(opt), &opt)) goto nla_put_failure; tcf_tm_dump(&t, &s->tcf_tm); if (nla_put_64bit(skb, TCA_SAMPLE_TM, sizeof(t), &t, TCA_SAMPLE_PAD)) goto nla_put_failure; if (nla_put_u32(skb, TCA_SAMPLE_RATE, s->rate)) goto nla_put_failure; if (s->truncate) if (nla_put_u32(skb, TCA_SAMPLE_TRUNC_SIZE, s->trunc_size)) goto nla_put_failure; if (nla_put_u32(skb, TCA_SAMPLE_PSAMPLE_GROUP, s->psample_group_num)) goto nla_put_failure; return skb->len; nla_put_failure: nlmsg_trim(skb, b); return -1; } static int tcf_sample_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, const struct tc_action_ops *ops) { struct tc_action_net *tn = net_generic(net, sample_net_id); return tcf_generic_walker(tn, skb, cb, type, ops); } static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, sample_net_id); return tcf_hash_search(tn, a, index); } static struct tc_action_ops act_sample_ops = { .kind = "sample", .type = TCA_ACT_SAMPLE, .owner = THIS_MODULE, .act = tcf_sample_act, .dump = tcf_sample_dump, .init = tcf_sample_init, .cleanup = tcf_sample_cleanup, .walk = tcf_sample_walker, .lookup = tcf_sample_search, .size = sizeof(struct tcf_sample), }; static __net_init int sample_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, sample_net_id); return tc_action_net_init(tn, &act_sample_ops, SAMPLE_TAB_MASK); } static void __net_exit sample_exit_net(struct net *net) { struct tc_action_net *tn = net_generic(net, sample_net_id); tc_action_net_exit(tn); } static struct pernet_operations sample_net_ops = { .init = sample_init_net, .exit = sample_exit_net, .id = &sample_net_id, .size = sizeof(struct tc_action_net), }; static int __init sample_init_module(void) { return tcf_register_action(&act_sample_ops, &sample_net_ops); } static void __exit sample_cleanup_module(void) { tcf_unregister_action(&act_sample_ops, &sample_net_ops); } module_init(sample_init_module); module_exit(sample_cleanup_module); MODULE_AUTHOR("Yotam Gigi <*****@*****.**>"); MODULE_DESCRIPTION("Packet sampling action"); MODULE_LICENSE("GPL v2");
static int codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) { const struct codel_sched_data *q = qdisc_priv(sch); struct tc_codel_xstats st = { .maxpacket = q->stats.maxpacket, .count = q->vars.count, .lastcount = q->vars.lastcount, .drop_overlimit = q->drop_overlimit, .ldelay = codel_time_to_us(q->vars.ldelay), .dropping = q->vars.dropping, .ecn_mark = q->stats.ecn_mark, }; if (q->vars.dropping) { codel_tdiff_t delta = q->vars.drop_next - codel_get_time(); if (delta >= 0) st.drop_next = codel_time_to_us(delta); else st.drop_next = -codel_time_to_us(-delta); } return gnet_stats_copy_app(d, &st, sizeof(st)); } static void codel_reset(struct Qdisc *sch) { struct codel_sched_data *q = qdisc_priv(sch); qdisc_reset_queue(sch); codel_vars_init(&q->vars); } static struct Qdisc_ops codel_qdisc_ops __read_mostly = { .id = "codel", .priv_size = sizeof(struct codel_sched_data), .enqueue = codel_qdisc_enqueue, .dequeue = codel_qdisc_dequeue, .peek = qdisc_peek_dequeued, .init = codel_init, .reset = codel_reset, .change = codel_change, .dump = codel_dump, .dump_stats = codel_dump_stats, .owner = THIS_MODULE, }; static int __init codel_module_init(void) { return register_qdisc(&codel_qdisc_ops); } static void __exit codel_module_exit(void) { unregister_qdisc(&codel_qdisc_ops); } module_init(codel_module_init) module_exit(codel_module_exit) MODULE_DESCRIPTION("Controlled Delay queue discipline"); MODULE_AUTHOR("Dave Taht"); MODULE_AUTHOR("Eric Dumazet"); MODULE_LICENSE("Dual BSD/GPL");
static void imx_fpga_ack_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_ack_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = 1 << ((irq - IRQ_FPGA_START) % NB_IT); pr_debug("%s: irq %d ack:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_ISR); } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) static void imx_fpga_mask_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_mask_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = readw(mng->membase + FPGA_IMR); shadow &= ~( 1 << ((irq - IRQ_FPGA_START) % NB_IT)); pr_debug("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_IMR); } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) static void imx_fpga_unmask_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_unmask_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = readw(mng->membase + FPGA_IMR); shadow |= 1 << ((irq - IRQ_FPGA_START) % NB_IT); pr_debug("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_IMR); } static irqreturn_t ocore_irq_mng_interrupt(int irq, void *data) { struct irq_mng *mng = data; struct irq_desc *desc; unsigned int mask; mask = readw(mng->membase + FPGA_ISR); pr_debug("%s: mask:0x%04x\n", __FUNCTION__, mask); do { irq = IRQ_FPGA_START; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) desc = irq_to_desc(irq); #else desc = irq_desc + irq; #endif /* handle irqs */ while (mask) { if (mask & 1) { pr_debug("handling irq %d 0x%08x\n", irq, (unsigned int)desc); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) desc->handle_irq(irq, desc); #else desc_handle_irq(irq, desc); #endif } irq++; desc++; mask >>= 1; } mask = readw(mng->membase + FPGA_ISR); } while (mask != 0); return IRQ_HANDLED; } static struct irq_chip imx_fpga_chip = { .name = "FPGA", #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) .irq_ack = imx_fpga_ack_irq, .irq_mask = imx_fpga_mask_irq, .irq_unmask = imx_fpga_unmask_irq, #else .ack = imx_fpga_ack_irq, .mask = imx_fpga_mask_irq, .unmask = imx_fpga_unmask_irq, #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) .irq_set_type = imx_fpga_irq_type, #else .set_type = imx_fpga_irq_type, #endif }; #ifdef CONFIG_PM static int ocore_irq_mng_suspend(struct platform_device *pdev, pm_message_t state) { dev_dbg(&pdev->dev, "suspended\n"); return 0; } static int ocore_irq_mng_resume(struct platform_device *pdev) { dev_dbg(&pdev->dev, "resumed\n"); return 0; } #else # define ocore_irq_mng_suspend NULL # define ocore_irq_mng_resume NULL #endif /* CONFIG_PM */ #if LINUX_VERSION_CODE > KERNEL_VERSION(3,8,0) /* __dev* stuff is removed from Linux since 30/11/2012 */ #define __devinit #define __devexit #endif static int __devinit ocore_irq_mng_probe(struct platform_device *pdev) { struct ocore_irq_mng_pdata *pdata = pdev->dev.platform_data; unsigned int irq; u16 id; int ret = 0; struct resource *mem_res; struct resource *irq_res; struct irq_mng *mng; if (!pdata) { dev_err(&pdev->dev, "Platform data required !\n"); return -ENODEV; } /* get resources */ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { dev_err(&pdev->dev, "can't find mem resource\n"); return -EINVAL; } irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { dev_err(&pdev->dev, "can't find irq resource\n"); return -EINVAL; } mem_res = request_mem_region(mem_res->start, resource_size(mem_res), pdev->name); if (!mem_res) { dev_err(&pdev->dev, "iomem already in use\n"); return -EBUSY; } /* allocate memory for private structure */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) mng = kmalloc(sizeof(struct irq_mng), GFP_KERNEL); #else mng = &global_mng; #endif if (!mng) { ret = -ENOMEM; goto out_release_mem; } pdata->mng = mng; mng->membase = ioremap(mem_res->start, resource_size(mem_res)); if (!mng->membase) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto out_dev_free; } mng->mem_res = mem_res; mng->irq_res = irq_res; /* check if ID is correct */ id = readw(mng->membase + ID_OFFSET); if (id != pdata->idnum) { printk(KERN_WARNING "For irq_mngr id:%d doesn't match with id" "read %d,\n is device present ?\n", pdata->idnum, id); ret = -ENODEV; goto out_iounmap; } /* Mask all interrupts initially */ writew(0, mng->membase + FPGA_IMR); for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT); irq++) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) irq_set_chip_data(irq, mng); irq_set_chip_and_handler_name(irq, &imx_fpga_chip, handle_edge_irq, NULL); #else set_irq_chip_data(irq, mng); set_irq_chip_and_handler(irq, &imx_fpga_chip, handle_edge_irq); #endif set_irq_flags(irq, IRQF_VALID); } /* clear pending interrupts */ writew(0xffff, mng->membase + FPGA_ISR); ret = request_irq(mng->irq_res->start, ocore_irq_mng_interrupt, #if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) IRQF_SAMPLE_RANDOM, #else 0, #endif "ocore_irq_mng", mng); if (ret < 0) { printk(KERN_ERR "Can't register irq %d\n", mng->irq_res->start); goto request_irq_error; } pr_debug("FPGA IRQs initialized (Parent=%d)\n", mng->irq_res->start); return 0; request_irq_error: out_iounmap: iounmap(mng->membase); out_dev_free: #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) kfree(mng); #endif out_release_mem: release_mem_region(mem_res->start, resource_size(mem_res)); return ret; } static int __devexit ocore_irq_mng_remove(struct platform_device *pdev) { struct ocore_irq_mng_pdata *pdata = pdev->dev.platform_data; struct irq_mng *mng = pdata->mng; unsigned int irq; for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT); irq++) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) irq_set_chip(irq, NULL); irq_set_handler(irq, NULL); #else set_irq_chip(irq, NULL); set_irq_handler(irq, NULL); #endif set_irq_flags(irq, 0); } free_irq(mng->irq_res->start, mng); release_mem_region(mng->mem_res->start, resource_size(mng->mem_res)); iounmap(mng->membase); kfree(mng); return 0; } static struct platform_driver ocore_irq_mng_driver = { .probe = ocore_irq_mng_probe, .remove = ocore_irq_mng_remove, .suspend = ocore_irq_mng_suspend, .resume = ocore_irq_mng_resume, .driver = { .name = DRIVER_NAME, }, }; static int __init ocore_irq_mng_init(void) { return platform_driver_register(&ocore_irq_mng_driver); } static void __exit ocore_irq_mng_exit(void) { platform_driver_unregister(&ocore_irq_mng_driver); } module_init(ocore_irq_mng_init); module_exit(ocore_irq_mng_exit); MODULE_AUTHOR("Julien Boibessot, <*****@*****.**>"); MODULE_DESCRIPTION("Armadeus OpenCore IRQ manager"); MODULE_LICENSE("GPL");
static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { struct tcf_skbmod *d = to_skbmod(a); unsigned char *b = skb_tail_pointer(skb); struct tcf_skbmod_params *p = rtnl_dereference(d->skbmod_p); struct tc_skbmod opt = { .index = d->tcf_index, .refcnt = d->tcf_refcnt - ref, .bindcnt = d->tcf_bindcnt - bind, .action = d->tcf_action, }; struct tcf_t t; opt.flags = p->flags; if (nla_put(skb, TCA_SKBMOD_PARMS, sizeof(opt), &opt)) goto nla_put_failure; if ((p->flags & SKBMOD_F_DMAC) && nla_put(skb, TCA_SKBMOD_DMAC, ETH_ALEN, p->eth_dst)) goto nla_put_failure; if ((p->flags & SKBMOD_F_SMAC) && nla_put(skb, TCA_SKBMOD_SMAC, ETH_ALEN, p->eth_src)) goto nla_put_failure; if ((p->flags & SKBMOD_F_ETYPE) && nla_put_u16(skb, TCA_SKBMOD_ETYPE, ntohs(p->eth_type))) goto nla_put_failure; tcf_tm_dump(&t, &d->tcf_tm); if (nla_put_64bit(skb, TCA_SKBMOD_TM, sizeof(t), &t, TCA_SKBMOD_PAD)) goto nla_put_failure; return skb->len; nla_put_failure: rcu_read_unlock(); nlmsg_trim(skb, b); return -1; } static int tcf_skbmod_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, const struct tc_action_ops *ops) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); return tcf_generic_walker(tn, skb, cb, type, ops); } static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); return tcf_hash_search(tn, a, index); } static struct tc_action_ops act_skbmod_ops = { .kind = "skbmod", .type = TCA_ACT_SKBMOD, .owner = THIS_MODULE, .act = tcf_skbmod_run, .dump = tcf_skbmod_dump, .init = tcf_skbmod_init, .cleanup = tcf_skbmod_cleanup, .walk = tcf_skbmod_walker, .lookup = tcf_skbmod_search, .size = sizeof(struct tcf_skbmod), }; static __net_init int skbmod_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); return tc_action_net_init(tn, &act_skbmod_ops, SKBMOD_TAB_MASK); } static void __net_exit skbmod_exit_net(struct net *net) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); tc_action_net_exit(tn); } static struct pernet_operations skbmod_net_ops = { .init = skbmod_init_net, .exit = skbmod_exit_net, .id = &skbmod_net_id, .size = sizeof(struct tc_action_net), }; MODULE_AUTHOR("Jamal Hadi Salim, <*****@*****.**>"); MODULE_DESCRIPTION("SKB data mod-ing"); MODULE_LICENSE("GPL"); static int __init skbmod_init_module(void) { return tcf_register_action(&act_skbmod_ops, &skbmod_net_ops); } static void __exit skbmod_cleanup_module(void) { tcf_unregister_action(&act_skbmod_ops, &skbmod_net_ops); } module_init(skbmod_init_module); module_exit(skbmod_cleanup_module);
static long mtx1_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = (int __user *)argp; unsigned int value; static const struct watchdog_info ident = { .options = WDIOF_CARDRESET, .identity = "MTX-1 WDT", }; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: put_user(0, p); break; case WDIOC_SETOPTIONS: if (get_user(value, p)) return -EFAULT; if (value & WDIOS_ENABLECARD) mtx1_wdt_start(); else if (value & WDIOS_DISABLECARD) mtx1_wdt_stop(); else return -EINVAL; return 0; case WDIOC_KEEPALIVE: mtx1_wdt_reset(); break; default: return -ENOTTY; } return 0; } static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { if (!count) return -EIO; mtx1_wdt_reset(); return count; } static const struct file_operations mtx1_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .unlocked_ioctl = mtx1_wdt_ioctl, .open = mtx1_wdt_open, .write = mtx1_wdt_write, .release = mtx1_wdt_release, }; static struct miscdevice mtx1_wdt_misc = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &mtx1_wdt_fops, }; static int __devinit mtx1_wdt_probe(struct platform_device *pdev) { int ret; mtx1_wdt_device.gpio = pdev->resource[0].start; ret = gpio_request_one(mtx1_wdt_device.gpio, GPIOF_OUT_INIT_HIGH, "mtx1-wdt"); if (ret < 0) { dev_err(&pdev->dev, "failed to request gpio"); return ret; } spin_lock_init(&mtx1_wdt_device.lock); init_completion(&mtx1_wdt_device.stop); mtx1_wdt_device.queue = 0; clear_bit(0, &mtx1_wdt_device.inuse); setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); mtx1_wdt_device.default_ticks = ticks; ret = misc_register(&mtx1_wdt_misc); if (ret < 0) { dev_err(&pdev->dev, "failed to register\n"); return ret; } mtx1_wdt_start(); dev_info(&pdev->dev, "MTX-1 Watchdog driver\n"); return 0; } static int __devexit mtx1_wdt_remove(struct platform_device *pdev) { /* */ if (mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 0; wait_for_completion(&mtx1_wdt_device.stop); } gpio_free(mtx1_wdt_device.gpio); misc_deregister(&mtx1_wdt_misc); return 0; } static struct platform_driver mtx1_wdt_driver = { .probe = mtx1_wdt_probe, .remove = __devexit_p(mtx1_wdt_remove), .driver.name = "mtx1-wdt", .driver.owner = THIS_MODULE, }; module_platform_driver(mtx1_wdt_driver); MODULE_AUTHOR("Michael Stickel, Florian Fainelli"); MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS("platform:mtx1-wdt");
static int __init multipdp_init(void) { int ret; pdp_arg_t pdp_arg = { .id = 1, .ifname = "ttyCSD", }; pdp_arg_t efs_arg = { .id = 8, .ifname = "ttyEFS", }; pdp_arg_t gps_arg = { .id = 5, .ifname = "ttyGPS", }; pdp_arg_t xtra_arg = { .id = 6, .ifname = "ttyXTRA", }; pdp_arg_t smd_arg = { .id = 25, .ifname = "ttySMD", }; pdp_arg_t pcm_arg = { .id = 30, .ifname = "ttyPCM", } ; #ifdef LOOP_BACK_TEST pdp_arg_t loopback_arg = { .id = 31, .ifname = "ttyLOBK", }; #endif wake_lock_init(&pdp_wake_lock, WAKE_LOCK_SUSPEND, "MULTI_PDP"); /* run DPRAM I/O thread */ ret = kernel_thread(dpram_thread, NULL, CLONE_FS | CLONE_FILES); if (ret < 0) { EPRINTK("kernel_thread() failed\n"); return ret; } wait_for_completion(&dpram_complete); if (!dpram_task) { EPRINTK("DPRAM I/O thread error\n"); return -EIO; } /* create serial device for Circuit Switched Data */ ret = pdp_activate(&pdp_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for CSD\n"); goto err0; } ret = pdp_activate(&efs_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for EFS\n"); goto err1; } ret = pdp_activate(&gps_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for GPS\n"); goto err2; } ret = pdp_activate(&xtra_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for XTRA\n"); goto err3; } ret = pdp_activate(&smd_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for SMD\n"); goto err4; } ret = pdp_activate(&pcm_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for SMD\n"); goto err5; } #ifdef LOOP_BACK_TEST ret = pdp_activate(&loopback_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for LoopBack\n"); goto err6; } #endif /* create app. interface device */ ret = misc_register(&multipdp_dev); if (ret < 0) { EPRINTK("misc_register() failed\n"); goto err1; } #ifdef LOOP_BACK_TEST ret = device_create_file(multipdp_dev.this_device, &dev_attr_loopback); #endif #ifdef CONFIG_PROC_FS create_proc_read_entry(APP_DEVNAME, 0, 0, multipdp_proc_read, NULL); #endif #ifdef NO_TTY_DPRAM // printk("multipdp_init:multipdp_rx_noti_regi calling"); multipdp_rx_noti_regi(multipdp_rx_cback ); #endif // printk(KERN_INFO // "$Id: multipdp.c,v 1.10 2008/01/11 05:40:56 melonzz Exp $\n"); return 0; #ifdef LOOP_BACK_TEST err6: pdp_deactivate(&loopback_arg, 1); #endif err5: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&pcm_arg, 1); err4: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&smd_arg, 1); err3: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&xtra_arg, 1); err2: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&gps_arg, 1); err1: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&pdp_arg, 1); err0: /* kill DPRAM I/O thread */ if (dpram_task) { send_sig(SIGUSR1, dpram_task, 1); wait_for_completion(&dpram_complete); } return ret; } static void __exit multipdp_exit(void) { wake_lock_destroy(&pdp_wake_lock); #ifdef CONFIG_PROC_FS remove_proc_entry(APP_DEVNAME, 0); #endif /* remove app. interface device */ misc_deregister(&multipdp_dev); /* clean up PDP context table */ pdp_cleanup(); /* kill DPRAM I/O thread */ if (dpram_task) { send_sig(SIGUSR1, dpram_task, 1); wait_for_completion(&dpram_complete); } } //module_init(multipdp_init); late_initcall(multipdp_init); module_exit(multipdp_exit); MODULE_AUTHOR("SAMSUNG ELECTRONICS CO., LTD"); MODULE_DESCRIPTION("Multiple PDP Muxer / Demuxer"); MODULE_LICENSE("GPL");
static int __devinit sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA6, .port_ops = &sil680_port_ops }; static const struct ata_port_info info_slow = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA5, .port_ops = &sil680_port_ops }; const struct ata_port_info *ppi[] = { &info, NULL }; static int printed_version; struct ata_host *host; void __iomem *mmio_base; int rc, try_mmio; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); rc = pcim_enable_device(pdev); if (rc) return rc; switch (sil680_init_chip(pdev, &try_mmio)) { case 0: ppi[0] = &info_slow; break; case 0x30: return -ENODEV; } if (!try_mmio) goto use_ioports; /* Try to acquire MMIO resources and fallback to PIO if * that fails */ rc = pcim_iomap_regions(pdev, 1 << SIL680_MMIO_BAR, DRV_NAME); if (rc) goto use_ioports; /* Allocate host and set it up */ host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2); if (!host) return -ENOMEM; host->iomap = pcim_iomap_table(pdev); /* Setup DMA masks */ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) return rc; rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); if (rc) return rc; pci_set_master(pdev); /* Get MMIO base and initialize port addresses */ mmio_base = host->iomap[SIL680_MMIO_BAR]; host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x00; host->ports[0]->ioaddr.cmd_addr = mmio_base + 0x80; host->ports[0]->ioaddr.ctl_addr = mmio_base + 0x8a; host->ports[0]->ioaddr.altstatus_addr = mmio_base + 0x8a; ata_sff_std_ports(&host->ports[0]->ioaddr); host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x08; host->ports[1]->ioaddr.cmd_addr = mmio_base + 0xc0; host->ports[1]->ioaddr.ctl_addr = mmio_base + 0xca; host->ports[1]->ioaddr.altstatus_addr = mmio_base + 0xca; ata_sff_std_ports(&host->ports[1]->ioaddr); /* Register & activate */ return ata_host_activate(host, pdev->irq, ata_sff_interrupt, IRQF_SHARED, &sil680_sht); use_ioports: return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL); } #ifdef CONFIG_PM static int sil680_reinit_one(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); int try_mmio, rc; rc = ata_pci_device_do_resume(pdev); if (rc) return rc; sil680_init_chip(pdev, &try_mmio); ata_host_resume(host); return 0; } #endif static const struct pci_device_id sil680[] = { { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), }, { }, }; static struct pci_driver sil680_pci_driver = { .name = DRV_NAME, .id_table = sil680, .probe = sil680_init_one, .remove = ata_pci_remove_one, #ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = sil680_reinit_one, #endif }; static int __init sil680_init(void) { return pci_register_driver(&sil680_pci_driver); } static void __exit sil680_exit(void) { pci_unregister_driver(&sil680_pci_driver); } MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("low-level driver for SI680 PATA"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, sil680); MODULE_VERSION(DRV_VERSION); module_init(sil680_init); module_exit(sil680_exit);