/**************************************************************************** * * Called to perform module cleanup when the module is unloaded. * ***************************************************************************/ static void __exit bcm_gpio_kp_remove(struct platform_device *pdev) { struct CBLK *bcm_kp = platform_get_drvdata(pdev); BCMKP_DBG(KERN_NOTICE "bcm_gpio_kp_remove\n"); /*disable keypad interrupt handling*/ free_all_irqs( bcm_kp ); /* unregister everything */ input_unregister_device(bcm_kp->input_dev); input_free_device(bcm_kp->input_dev); return; }
void cleanup_module (void) { int i; if (MOD_IN_USE) { return; } if (chrdev_registered) module_unregister_chrdev (sound_major, "sound"); #ifdef CONFIG_SEQUENCER sound_stop_timer (); #endif #ifdef CONFIG_LOWLEVEL_SOUND { extern void sound_unload_lowlevel_drivers (void); sound_unload_lowlevel_drivers (); } #endif sound_unload_drivers (); for (i = 0; i < sound_nblocks; i++) vfree (sound_mem_blocks[i]); free_all_irqs (); /* If something was left allocated by accident */ for (i = 0; i < 8; i++) if (dma_alloc_map[i] != DMA_MAP_UNAVAIL) { printk ("Sound: Hmm, DMA%d was left allocated - fixed\n", i); sound_free_dma (i); } }
/**************************************************************************** * * Called to perform module initialization when the module is loaded * ***************************************************************************/ static int __devinit bcm_gpio_kp_probe(struct platform_device *pdev) { int ret; struct CBLK *bcm_kp; struct BCM_KEYPAD_PLATFORM_DATA *pdata = pdev->dev.platform_data; struct BCM_GPIO_KEYMAP *keymap_p = pdata->keymap; BCMKP_DBG(KERN_NOTICE "bcm_gpio_kp_probe\n"); if(( bcm_kp = kmalloc(sizeof(*bcm_kp), GFP_KERNEL)) == NULL ) { printk(KERN_ERR "%s(%s:%u)::Failed to allocate keypad structure...\n", __FUNCTION__, __FILE__, __LINE__); return -ENOMEM; } memset( bcm_kp, 0, sizeof(*bcm_kp)); if(( bcm_kp->input_dev = input_allocate_device()) == NULL ) { printk(KERN_ERR "%s(%s:%u)::Failed to allocate input device...\n", __FUNCTION__, __FILE__, __LINE__); return -ENOMEM; } platform_set_drvdata(pdev, bcm_kp); /* Setup input device */ set_bit(EV_KEY , bcm_kp->input_dev->evbit); set_bit(EV_REP, bcm_kp->input_dev->evbit); bcm_kp->input_dev->name = "keypad"; bcm_kp->input_dev->phys = "keypad/input0"; bcm_kp->input_dev->id.bustype = BUS_HOST; bcm_kp->input_dev->id.vendor = 0x0001; bcm_kp->input_dev->id.product = 0x0001; bcm_kp->input_dev->id.version = 0x0100; bcm_kp->input_dev->keycode = bcm_kp->keycode; bcm_kp->input_dev->keycodesize = sizeof( bcm_kp->keycode[0] ); bcm_kp->input_dev->keycodemax = ARRAYSIZE( bcm_kp->keycode ) ; memset( bcm_kp->prevDown, 0, sizeof( bcm_kp->prevDown )); #ifdef SET_GPIO_KEYPAD /* If any special hardware specific initilization is needed before gpios can be used, please put them under this macro. e.g in BCM2153 chip, by default the keypad gpios goes through keypad controller and this macro switchs them back to be used as regular gpios. */ SET_GPIO_KEYPAD; #endif /* Setup GPIO and Interrupt handler */ bcm_kp->direct_key_col_index = -1; bcm_kp->key_count = pdata->array_size; bcm_kp->row_count = CreateRowArray( bcm_kp, keymap_p ); bcm_kp->col_count = CreateColArray( bcm_kp, keymap_p ); CreateKeyMap( bcm_kp, keymap_p ); SetColOutput( bcm_kp->keyColArray, bcm_kp->col_count ); ret = SetRowInput( bcm_kp->keyRowArray, bcm_kp->row_count, bcm_kp ); if (ret < 0) { printk(KERN_ERR "%s(%s:%u)::Unable to register GPIO-keypad IRQ\n", __FUNCTION__, __FILE__, __LINE__); goto free_irq; } ret = input_register_device(bcm_kp->input_dev); if (ret < 0) { printk(KERN_ERR "%s(%s:%u)::Unable to register GPIO-keypad input device\n", __FUNCTION__, __FILE__, __LINE__); goto free_dev; } /* Initialization Finished */ BCMKP_DBG(KERN_DEBUG "BCM keypad initialization completed...\n"); return (ret); free_dev: input_unregister_device(bcm_kp->input_dev); input_free_device(bcm_kp->input_dev); free_irq: free_all_irqs( bcm_kp ); return -EINVAL; }