📄 io_interface_mux.c
字号:
break; case if_shared_ram: SETS(gens, R_GEN_CONFIG, mio, select); break; case if_shared_ram_w: SETS(gens, R_GEN_CONFIG, mio_w, select); break; case if_par_0: SETS(gens, R_GEN_CONFIG, par0, select); break; case if_par_1: SETS(gens, R_GEN_CONFIG, par1, select); break; case if_par_w: SETS(gens, R_GEN_CONFIG, par0, select); SETS(gens, R_GEN_CONFIG, par_w, select); break; case if_scsi8_0: SETS(gens, R_GEN_CONFIG, scsi0, select); break; case if_scsi8_1: SETS(gens, R_GEN_CONFIG, scsi1, select); break; case if_scsi_w: SETS(gens, R_GEN_CONFIG, scsi0, select); SETS(gens, R_GEN_CONFIG, scsi0w, select); break; case if_ata: SETS(gens, R_GEN_CONFIG, ata, select); break; case if_csp: /* fall through */ case if_i2c: set_gen_config = 0; break; case if_usb_1: SETS(gens, R_GEN_CONFIG, usb1, select); break; case if_usb_2: SETS(gens, R_GEN_CONFIG, usb2, select); break; case if_gpio_grp_a: /* GPIO groups are only accounted, don't do configuration changes. */ /* fall through */ case if_gpio_grp_b: /* fall through */ case if_gpio_grp_c: /* fall through */ case if_gpio_grp_d: /* fall through */ case if_gpio_grp_e: /* fall through */ case if_gpio_grp_f: set_gen_config = 0; break; default: panic("cris_request_io_interface: Bad interface %u submitted for %s\n", ioif, device_id); } interfaces[ioif].used = 1; interfaces[ioif].owner = (char*)device_id; if (set_gen_config) { volatile int i; genconfig_shadow = gens; *R_GEN_CONFIG = genconfig_shadow; /* Wait 12 cycles before doing any DMA command */ for(i = 6; i > 0; i--) nop(); } if (set_gen_config_ii) { gen_config_ii_shadow = gens_ii; *R_GEN_CONFIG_II = gen_config_ii_shadow; } DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", gpio_in_pins, gpio_out_pins, gpio_pb_pins)); DBG(printk("grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", interfaces[ioif].gpio_g_in, interfaces[ioif].gpio_g_out, interfaces[ioif].gpio_b)); gpio_in_pins &= ~interfaces[ioif].gpio_g_in; gpio_out_pins &= ~interfaces[ioif].gpio_g_out; gpio_pb_pins &= ~interfaces[ioif].gpio_b; DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", gpio_in_pins, gpio_out_pins, gpio_pb_pins)); local_irq_restore(flags); notify_watchers(); return 0;}void cris_free_io_interface(enum cris_io_interface ioif){ struct if_group *grp; unsigned char group_set; unsigned long flags; (void)cris_io_interface_init(); if ((ioif >= if_max_interfaces) || (ioif < 0)) { printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n", ioif); return; } local_irq_save(flags); if (!interfaces[ioif].used) { printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n", ioif); local_irq_restore(flags); return; } group_set = interfaces[ioif].groups; while (NULL != (grp = get_group(group_set))) { if (grp->group == group_f) { switch (ioif) { case if_sync_serial_1: if ((grp->owner == if_sync_serial_1) && interfaces[if_sync_serial_3].used) { grp->owner = if_sync_serial_3; } else grp->used = 0; break; case if_sync_serial_3: if ((grp->owner == if_sync_serial_3) && interfaces[if_sync_serial_1].used) { grp->owner = if_sync_serial_1; } else grp->used = 0; break; case if_scsi8_0: if ((grp->owner == if_scsi8_0) && interfaces[if_scsi8_1].used) { grp->owner = if_scsi8_1; } else grp->used = 0; break; case if_scsi8_1: if ((grp->owner == if_scsi8_1) && interfaces[if_scsi8_0].used) { grp->owner = if_scsi8_0; } else grp->used = 0; break; default: grp->used = 0; } } else { grp->used = 0; } group_set = clear_group_from_set(group_set, grp); } interfaces[ioif].used = 0; interfaces[ioif].owner = NULL; DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", gpio_in_pins, gpio_out_pins, gpio_pb_pins)); DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", interfaces[ioif].gpio_g_in, interfaces[ioif].gpio_g_out, interfaces[ioif].gpio_b)); gpio_in_pins |= interfaces[ioif].gpio_g_in; gpio_out_pins |= interfaces[ioif].gpio_g_out; gpio_pb_pins |= interfaces[ioif].gpio_b; DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", gpio_in_pins, gpio_out_pins, gpio_pb_pins)); local_irq_restore(flags); notify_watchers();}/* Create a bitmask from bit 0 (inclusive) to bit stop_bit (non-inclusive). stop_bit == 0 returns 0x0 */static inline unsigned int create_mask(const unsigned stop_bit){ /* Avoid overflow */ if (stop_bit >= 32) { return 0xffffffff; } return (1<<stop_bit)-1;}/* port can be 'a', 'b' or 'g' */int cris_io_interface_allocate_pins(const enum cris_io_interface ioif, const char port, const unsigned start_bit, const unsigned stop_bit){ unsigned int i; unsigned int mask = 0; unsigned int tmp_mask; unsigned long int flags; enum cris_io_interface *owners; (void)cris_io_interface_init(); DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n", ioif, port, start_bit, stop_bit)); if (!((start_bit <= stop_bit) && ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) || ((port == 'g') && (stop_bit < 32))))) { return -EINVAL; } mask = create_mask(stop_bit + 1); tmp_mask = create_mask(start_bit); mask &= ~tmp_mask; DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n", port, start_bit, stop_bit, mask)); local_irq_save(flags); switch (port) { case 'a': if ((gpio_pa_pins & mask) != mask) { local_irq_restore(flags); return -EBUSY; } owners = gpio_pa_owners; gpio_pa_pins &= ~mask; break; case 'b': if ((gpio_pb_pins & mask) != mask) { local_irq_restore(flags); return -EBUSY; } owners = gpio_pb_owners; gpio_pb_pins &= ~mask; break; case 'g': if (((gpio_in_pins & mask) != mask) || ((gpio_out_pins & mask) != mask)) { local_irq_restore(flags); return -EBUSY; } owners = gpio_pg_owners; gpio_in_pins &= ~mask; gpio_out_pins &= ~mask; break; default: local_irq_restore(flags); return -EINVAL; } for (i = start_bit; i <= stop_bit; i++) { owners[i] = ioif; } local_irq_restore(flags); notify_watchers(); return 0;}/* port can be 'a', 'b' or 'g' */int cris_io_interface_free_pins(const enum cris_io_interface ioif, const char port, const unsigned start_bit, const unsigned stop_bit){ unsigned int i; unsigned int mask = 0; unsigned int tmp_mask; unsigned long int flags; enum cris_io_interface *owners; (void)cris_io_interface_init(); if (!((start_bit <= stop_bit) && ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) || ((port == 'g') && (stop_bit < 32))))) { return -EINVAL; } mask = create_mask(stop_bit + 1); tmp_mask = create_mask(start_bit); mask &= ~tmp_mask; DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n", port, start_bit, stop_bit, mask)); local_irq_save(flags); switch (port) { case 'a': if ((~gpio_pa_pins & mask) != mask) { local_irq_restore(flags); printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins"); } owners = gpio_pa_owners; break; case 'b': if ((~gpio_pb_pins & mask) != mask) { local_irq_restore(flags); printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins"); } owners = gpio_pb_owners; break; case 'g': if (((~gpio_in_pins & mask) != mask) || ((~gpio_out_pins & mask) != mask)) { local_irq_restore(flags); printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins"); } owners = gpio_pg_owners; break; default: owners = NULL; /* Cannot happen. Shut up, gcc! */ } for (i = start_bit; i <= stop_bit; i++) { if (owners[i] != ioif) { printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins"); } } /* All was ok, change data. */ switch (port) { case 'a': gpio_pa_pins |= mask; break; case 'b': gpio_pb_pins |= mask; break; case 'g': gpio_in_pins |= mask; gpio_out_pins |= mask; break; } for (i = start_bit; i <= stop_bit; i++) { owners[i] = if_unclaimed; } local_irq_restore(flags); notify_watchers(); return 0;}int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available, const unsigned int gpio_out_available, const unsigned char pa_available, const unsigned char pb_available)){ struct watcher *w; (void)cris_io_interface_init(); if (NULL == notify) { return -EINVAL; } w = kmalloc(sizeof(*w), GFP_KERNEL); if (!w) { return -ENOMEM; } w->notify = notify; w->next = watchers; watchers = w; w->notify((const unsigned int)gpio_in_pins, (const unsigned int)gpio_out_pins, (const unsigned char)gpio_pa_pins, (const unsigned char)gpio_pb_pins); return 0;}void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available, const unsigned int gpio_out_available, const unsigned char pa_available, const unsigned char pb_available)){ struct watcher *w = watchers, *prev = NULL; (void)cris_io_interface_init(); while ((NULL != w) && (w->notify != notify)){ prev = w; w = w->next; } if (NULL != w) { if (NULL != prev) { prev->next = w->next; } else { watchers = w->next; } kfree(w); return; } printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);}static int cris_io_interface_init(void){ static int first = 1; int i; if (!first) { return 0; } first = 0; for (i = 0; i<8; i++) { gpio_pa_owners[i] = if_unclaimed; gpio_pb_owners[i] = if_unclaimed; gpio_pg_owners[i] = if_unclaimed; } for (; i<32; i++) { gpio_pg_owners[i] = if_unclaimed; } return 0;}module_init(cris_io_interface_init);EXPORT_SYMBOL(cris_request_io_interface);EXPORT_SYMBOL(cris_free_io_interface);EXPORT_SYMBOL(cris_io_interface_allocate_pins);EXPORT_SYMBOL(cris_io_interface_free_pins);EXPORT_SYMBOL(cris_io_interface_register_watcher);EXPORT_SYMBOL(cris_io_interface_delete_watcher);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -