m32r_pcc.c
来自「linux 内核源代码」· C语言 代码 · 共 772 行 · 第 1/2 页
C
772 行
if (j == 20) printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n"); debug(4, "m32r-pcc: interrupt done\n"); return IRQ_RETVAL(handled);} /* pcc_interrupt */static void pcc_interrupt_wrapper(u_long data){ pcc_interrupt(0, NULL); init_timer(&poll_timer); poll_timer.expires = jiffies + poll_interval; add_timer(&poll_timer);}/*====================================================================*/static int _pcc_get_status(u_short sock, u_int *value){ u_int status; status = pcc_get(sock,PCIRC); *value = ((status & PCIRC_CDIN1) && (status & PCIRC_CDIN2)) ? SS_DETECT : 0; status = pcc_get(sock,PCCR);#if 0 *value |= (status & PCCR_PCEN) ? SS_READY : 0;#else *value |= SS_READY; /* XXX: always */#endif status = pcc_get(sock,PCCSIGCR); *value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0; debug(3, "m32r-pcc: GetStatus(%d) = %#4.4x\n", sock, *value); return 0;} /* _get_status *//*====================================================================*/static int _pcc_set_socket(u_short sock, socket_state_t *state){ u_long reg = 0; debug(3, "m32r-pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); if (state->Vcc) { /* * 5V only */ if (state->Vcc == 50) { reg |= PCCSIGCR_VEN; } else { return -EINVAL; } } if (state->flags & SS_RESET) { debug(3, ":RESET\n"); reg |= PCCSIGCR_CRST; } if (state->flags & SS_OUTPUT_ENA){ debug(3, ":OUTPUT_ENA\n"); /* bit clear */ } else { reg |= PCCSIGCR_SEN; } pcc_set(sock,PCCSIGCR,reg);#ifdef DEBUG if(state->flags & SS_IOCARD){ debug(3, ":IOCARD"); } if (state->flags & SS_PWR_AUTO) { debug(3, ":PWR_AUTO"); } if (state->csc_mask & SS_DETECT) debug(3, ":csc-SS_DETECT"); if (state->flags & SS_IOCARD) { if (state->csc_mask & SS_STSCHG) debug(3, ":STSCHG"); } else { if (state->csc_mask & SS_BATDEAD) debug(3, ":BATDEAD"); if (state->csc_mask & SS_BATWARN) debug(3, ":BATWARN"); if (state->csc_mask & SS_READY) debug(3, ":READY"); } debug(3, "\n");#endif return 0;} /* _set_socket *//*====================================================================*/static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io){ u_char map; debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, " "%#lx-%#lx)\n", sock, io->map, io->flags, io->speed, io->start, io->stop); map = io->map; return 0;} /* _set_io_map *//*====================================================================*/static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem){ u_char map = mem->map; u_long mode; u_long addr; pcc_socket_t *t = &socket[sock];#ifdef CHAOS_PCC_DEBUG#if 0 pcc_as_t last = t->current_space;#endif#endif debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, " "%#lx, %#x)\n", sock, map, mem->flags, mem->speed, mem->static_start, mem->card_start); /* * sanity check */ if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){ return -EINVAL; } /* * de-activate */ if ((mem->flags & MAP_ACTIVE) == 0) { t->current_space = as_none; return 0; } /* * Disable first */ pcc_set(sock, PCCR, 0); /* * Set mode */ if (mem->flags & MAP_ATTRIB) { mode = PCMOD_AS_ATTRIB | PCMOD_CBSZ; t->current_space = as_attr; } else { mode = 0; /* common memory */ t->current_space = as_comm; } pcc_set(sock, PCMOD, mode); /* * Set address */ addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK); pcc_set(sock, PCADR, addr); mem->static_start = addr + mem->card_start; /* * Enable again */ pcc_set(sock, PCCR, 1);#ifdef CHAOS_PCC_DEBUG#if 0 if (last != as_attr) {#else if (1) {#endif dummy_readbuf = *(u_char *)(addr + KSEG1); }#endif return 0;} /* _set_mem_map */#if 0 /* driver model ordering issue *//*====================================================================== Routines for accessing socket information and register dumps via /proc/bus/pccard/...======================================================================*/static ssize_t show_info(struct class_device *class_dev, char *buf){ pcc_socket_t *s = container_of(class_dev, struct pcc_socket, socket.dev); return sprintf(buf, "type: %s\nbase addr: 0x%08lx\n", pcc[s->type].name, s->base);}static ssize_t show_exca(struct class_device *class_dev, char *buf){ /* FIXME */ return 0;}static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);#endif/*====================================================================*//* this is horribly ugly... proper locking needs to be done here at * some time... */#define LOCKED(x) do { \ int retval; \ unsigned long flags; \ spin_lock_irqsave(&pcc_lock, flags); \ retval = x; \ spin_unlock_irqrestore(&pcc_lock, flags); \ return retval; \} while (0)static int pcc_get_status(struct pcmcia_socket *s, u_int *value){ unsigned int sock = container_of(s, struct pcc_socket, socket)->number; if (socket[sock].flags & IS_ALIVE) { *value = 0; return -EINVAL; } LOCKED(_pcc_get_status(sock, value));}static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state){ unsigned int sock = container_of(s, struct pcc_socket, socket)->number; if (socket[sock].flags & IS_ALIVE) return -EINVAL; LOCKED(_pcc_set_socket(sock, state));}static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io){ unsigned int sock = container_of(s, struct pcc_socket, socket)->number; if (socket[sock].flags & IS_ALIVE) return -EINVAL; LOCKED(_pcc_set_io_map(sock, io));}static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem){ unsigned int sock = container_of(s, struct pcc_socket, socket)->number; if (socket[sock].flags & IS_ALIVE) return -EINVAL; LOCKED(_pcc_set_mem_map(sock, mem));}static int pcc_init(struct pcmcia_socket *s){ debug(4, "m32r-pcc: init call\n"); return 0;}static struct pccard_operations pcc_operations = { .init = pcc_init, .get_status = pcc_get_status, .set_socket = pcc_set_socket, .set_io_map = pcc_set_io_map, .set_mem_map = pcc_set_mem_map,};/*====================================================================*/static struct device_driver pcc_driver = { .name = "pcc", .bus = &platform_bus_type, .suspend = pcmcia_socket_dev_suspend, .resume = pcmcia_socket_dev_resume,};static struct platform_device pcc_device = { .name = "pcc", .id = 0,};/*====================================================================*/static int __init init_m32r_pcc(void){ int i, ret; ret = driver_register(&pcc_driver); if (ret) return ret; ret = platform_device_register(&pcc_device); if (ret){ driver_unregister(&pcc_driver); return ret; } printk(KERN_INFO "m32r PCC probe:\n"); pcc_sockets = 0; add_pcc_socket(M32R_PCC0_BASE, PCC0_IRQ, M32R_PCC0_MAPBASE, 0x1000);#ifdef CONFIG_M32RPCC_SLOT2 add_pcc_socket(M32R_PCC1_BASE, PCC1_IRQ, M32R_PCC1_MAPBASE, 0x2000);#endif if (pcc_sockets == 0) { printk("socket is not found.\n"); platform_device_unregister(&pcc_device); driver_unregister(&pcc_driver); return -ENODEV; } /* Set up interrupt handler(s) */ for (i = 0 ; i < pcc_sockets ; i++) { socket[i].socket.dev.parent = &pcc_device.dev; socket[i].socket.ops = &pcc_operations; socket[i].socket.resource_ops = &pccard_static_ops; socket[i].socket.owner = THIS_MODULE; socket[i].number = i; ret = pcmcia_register_socket(&socket[i].socket); if (!ret) socket[i].flags |= IS_REGISTERED;#if 0 /* driver model ordering issue */ class_device_create_file(&socket[i].socket.dev, &class_device_attr_info); class_device_create_file(&socket[i].socket.dev, &class_device_attr_exca);#endif } /* Finally, schedule a polling interrupt */ if (poll_interval != 0) { poll_timer.function = pcc_interrupt_wrapper; poll_timer.data = 0; init_timer(&poll_timer); poll_timer.expires = jiffies + poll_interval; add_timer(&poll_timer); } return 0;} /* init_m32r_pcc */static void __exit exit_m32r_pcc(void){ int i; for (i = 0; i < pcc_sockets; i++) if (socket[i].flags & IS_REGISTERED) pcmcia_unregister_socket(&socket[i].socket); platform_device_unregister(&pcc_device); if (poll_interval != 0) del_timer_sync(&poll_timer); driver_unregister(&pcc_driver);} /* exit_m32r_pcc */module_init(init_m32r_pcc);module_exit(exit_m32r_pcc);MODULE_LICENSE("Dual MPL/GPL");/*====================================================================*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?