int md_probe (struct md *md, int slot, struct mon *mon) { struct cdev *cdev; dev_t dev_id; int ret; struct class *bmi_class; md->removed = 0; cdev = &md->cdev; cdev_init (cdev, &md_fops); dev_id = MKDEV (md_major, slot); ret = cdev_add (cdev, dev_id, 1); //Create class device bmi_class = bmi_get_class (); md->class_dev = device_create (bmi_class, NULL, MKDEV(md_major, slot), md, "bmi_mdacc_mot_m%i", slot); if (IS_ERR(md->class_dev)) { printk(KERN_ERR "Unable to create " "class_device for bmi_mdacc_mot_m%i; errno = %ld\n", slot, PTR_ERR(md->class_dev)); md->class_dev = NULL; } md->open_flag = 0; md->enabled = 0; md->status = 0; init_waitqueue_head (&md->read_wait_queue); md->mon = mon; return ret; }
int acc_probe (struct acc *acc, int slot, struct mon *mon) { struct cdev *cdev; dev_t dev_id; int ret; struct class *bmi_class; // initialize cdev cdev = &acc->cdev; cdev_init (cdev, &acc_fops); dev_id = MKDEV (acc_major, slot); ret = cdev_add (cdev, dev_id, 1); //Create class device bmi_class = bmi_get_class (); acc->class_dev = device_create (bmi_class, NULL, MKDEV(acc_major, slot), acc, "bmi_mdacc_acc_m%i", slot); if (IS_ERR(acc->class_dev)) { printk(KERN_ERR "Unable to create " "class_device for bmi_mdacc_acc_m%i; errno = %ld\n", slot, PTR_ERR(acc->class_dev)); acc->class_dev = NULL; } acc->open_flag = 0; acc->mon = mon; // initialize mdacc_accel_config acc->cfg.read_queue_size = 1; acc->cfg.read_queue_threshold = 1; acc->cfg.delay_mode = 0; acc->cfg.delay = 4000; acc->cfg.delay_resolution = 1; acc->cfg.sensitivity = 0; acc->cfg.run = 0; // initialize cque acc->cque = cque_create (acc->cfg.read_queue_size, acc->cfg.read_queue_threshold); // initialize read_wait_queue init_waitqueue_head (&acc->read_wait_queue); return ret; }
void md_remove (struct md *md, int slot ) { struct class *bmi_class; md->removed = 1; md->ready = -1; wake_up_interruptible (&md->read_wait_queue); cdev_del (&md->cdev); bmi_class = bmi_get_class (); device_destroy (bmi_class, MKDEV(md_major, slot)); md->class_dev = 0; return; }
void acc_remove (struct acc *acc, int slot) { struct class *bmi_class; cque_destroy (acc->cque); bmi_class = bmi_get_class (); device_destroy (bmi_class, MKDEV(acc_major, slot)); acc->class_dev = 0; cdev_del (&acc->cdev); return; }
/* * Function is called when the video module hardwrae is physically removed */ void bmi_video_remove(struct bmi_device *bdev) { int irq; int i; int slot; struct bmi_video *video; struct class *bmi_class; static struct omap_dss_device *dssdev; printk(KERN_DEBUG "bmi_video: Module Removed...\n"); //Would turn LED red, but we can't trust the HW is connected still slot = bdev->slot->slotnum; video = &g_bmi_video; //removals have known unwind errors iff rmmod bmi_video_core while //device is plugged in device_remove_file(&bdev->dev, &dev_attr_vmode); device_remove_file(&bdev->dev, &dev_attr_vga_edid); device_remove_file(&bdev->dev, &dev_attr_dvi_edid); bmi_class = bmi_get_class (); device_destroy (bmi_class, MKDEV(major, slot)); // -- disable displays monitors_off_safe(video);//safe for missing HW // -- disable all displays for_each_dss_dev(dssdev) { omap_dss_get_device(dssdev); if (dssdev->state) dssdev->driver->disable(dssdev); } if(video->swap_eeprom){ //we are just 'borrowing' this pointer, //do not unregister! see bmi_video_probe. video->swap_eeprom = NULL; video->swap_eeprom_state = OFF; } if(video->eeprom_switch) { i2c_unregister_device(video->eeprom_switch); video->eeprom_switch = NULL; } if(video->gpio_controller) { //dbg_unexport_gpios_to_sysfs(); gpio_free_array(vid_gpios, ARRAY_SIZE(vid_gpios)); i2c_unregister_device(video->gpio_controller); video->gpio_controller= NULL; } if(video->dvi_controller) { i2c_unregister_device(video->dvi_controller); video->dvi_controller = NULL; } printk(KERN_INFO "bmi_video: 9\n"); if(video->vga_controller) { i2c_unregister_device(video->vga_controller); video->vga_controller = NULL; } irq = bdev->slot->status_irq; // -- legacy vodoo code. Left in for safety for (i = 0; i < 4; i++) bmi_slot_gpio_direction_in(slot, i); if (video->vga_monitor_edid) { kfree(video->vga_monitor_edid); //created by a library. we must free video->vga_monitor_edid = NULL; } if (video->dvi_monitor_edid) { kfree(video->dvi_monitor_edid); //created by a library. we must free video->dvi_monitor_edid = NULL; } //just in case, clear the global g_dvi_disp = NULL; g_vga_disp = NULL; video->class_dev = 0; // de-attach driver-specific struct from bmi_device structure bmi_device_set_drvdata (bdev, 0); video->bdev = 0; printk(KERN_INFO "bmi_video_remove done "); return; //Clean, squeaky clean }
// probe - insert PIM int bmi_video_probe(struct bmi_device *bdev) { int err = 0; int slot; int irq; struct bmi_video *video; struct class *bmi_class; struct i2c_adapter *adap; struct omap_dss_device *dssdev; printk (KERN_INFO "bmi_video.c: probe...\n"); slot = bdev->slot->slotnum; adap = bdev->slot->adap; video = &g_bmi_video; video->dvi_monitor_edid = NULL; video->vga_monitor_edid = NULL; video->bdev = 0; dssdev = NULL; g_dvi_disp = NULL; g_vga_disp = NULL; /* disable all video devices, store vga/dvi entries */ for_each_dss_dev(dssdev) { omap_dss_get_device(dssdev); if (dssdev->state) dssdev->driver->disable(dssdev); // our dss names are from buglabs board files if (strnicmp(dssdev->name, "dvi", 3) == 0) g_dvi_disp = dssdev; else if (strnicmp(dssdev->name, "vga", 3) == 0) g_vga_disp = dssdev; } // bind driver and bmi_device video->bdev = bdev; // create class device bmi_class = bmi_get_class(); // -- grab eeprom addr if(bdev->slot->eeprom) { video->swap_eeprom = bdev->slot->eeprom; video->swap_eeprom_state = OFF; //set to read bmi board eeprom //printk(KERN_ERR "swizzling slot eeprom, addr %x", // (unsigned int)video->swap_eeprom->addr); } else { printk(KERN_ERR "module eeprom is null. Module type is impossible"); video->swap_eeprom = 0x00; video->swap_eeprom_state = OFF; } // -- grap i2c expander switch video->eeprom_switch = i2c_new_device(adap, &i2cswitch_info); if(video->eeprom_switch == NULL) { printk(KERN_ERR "i2c addr %x fail", i2cswitch_info.addr); err = -ENOTTY; goto probe_fail1; } // -- grab i2c gpio chip and set it up if (gpio_is_valid(VIDEO_GPIO_BASE)) video->gpio_controller = i2c_new_device(adap,&gpio_controller_info); else { printk(KERN_ERR "i2c addr %x in use", VIDEO_GPIO_BASE); err = -ENOTTY; goto probe_fail2; } if(video->gpio_controller == NULL) { printk(KERN_ERR "i2c addr %x fail", gpio_controller_info.addr); err = -ENOTTY; goto probe_fail2; } err = gpio_request_array(vid_gpios, ARRAY_SIZE(vid_gpios)); if (err) { printk(KERN_ERR "GPIO's not requestable. Damm"); err = -ENOTTY; goto probe_fail3; } //dbg_export_gpios_to_sysfs(); //we have gpio's now, turn the LED to red since we are not initalized bmi_video_ledset(VIDEO_LED_RED); // -- grab i2c for the dvi controller video->dvi_controller = i2c_new_device(adap, &tfp_info); if (video->dvi_controller == NULL){ printk(KERN_ERR "DVI monitor controller not found\n"); err = -ENOTTY; goto probe_fail4; } video->vga_controller = i2c_new_device(adap, &ths_info); if (video->vga_controller == NULL) { printk(KERN_ERR "VGA monitor controller not found\n"); err = -ENOTTY; goto probe_fail5; } //FUTURE: enable pulg event interrupt for GPIO //ths_info.irq = gpio_to_irq(DVI_MONITOR_SENSE_GPIO); // -- to get ths8201 on the bus OK, we need to do a reset cycle ths8200_disable(video->vga_controller);//TRICKY: does some setup -> //didn't have time to debug why this works and 'init' doesn't ths8200_standby(VGA_RESET_GPIO); err = device_create_file(&bdev->dev, &dev_attr_vmode); if (err < 0) printk(KERN_ERR "Error creating SYSFS entries...\n"); //TRCIKY: don't exit on this error, tolerate it err = scan_for_monitors(AUTO, video); //based on monitor's found, choose the best' if(video->dvi_monitor_edid) { printk(KERN_INFO "dvi monitor detected"); enable_dvi(video); } else if(video->vga_monitor_edid) { printk(KERN_INFO "vga monitor detected"); enable_vga(video); } else { printk(KERN_ERR "no monitor detected"); monitors_off(video); } err = device_create_file(&bdev->dev, &dev_attr_vga_edid); if (err < 0) printk(KERN_ERR "Error creating SYSFS entries...\n"); //TRCIKY: don't exit on this error, tolerate it err = device_create_file(&bdev->dev, &dev_attr_dvi_edid); if (err < 0) printk(KERN_ERR "Error creating SYSFS entries...\n"); //TRCIKY: don't exit on this error, tolerate it //request PIM interrupt irq = bdev->slot->status_irq; sprintf (video->int_name, "bmi_video%d", slot); bmi_device_set_drvdata (bdev, video); // -- successfuly loaded, even if not everyting is perfect return 0; // -- failure/error cleanup probe_fail5: if(video->dvi_controller) { i2c_unregister_device(video->dvi_controller); video->dvi_controller = NULL; } probe_fail4: //dbg_unexport_gpios_to_sysfs(); probe_fail3: if(video->gpio_controller) { i2c_unregister_device(video->gpio_controller); video->gpio_controller = NULL; } probe_fail2: if(video->eeprom_switch) { i2c_unregister_device(video->eeprom_switch); video->eeprom_switch = NULL; } probe_fail1: video->swap_eeprom = 0x00; video->swap_eeprom_state = OFF; return err; }