static int cm36686_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct cm36686_data *cm36686 = NULL; pr_info("%s is called.\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s: i2c functionality check failed!\n", __func__); return ret; } cm36686 = kzalloc(sizeof(struct cm36686_data), GFP_KERNEL); if (!cm36686) { pr_err("%s: failed to alloc memory for cm36686 module data\n", __func__); return -ENOMEM; } cm36686->pdata = client->dev.platform_data; cm36686->i2c_client = client; i2c_set_clientdata(client, cm36686); mutex_init(&cm36686->power_lock); mutex_init(&cm36686->read_lock); if(cm36686->pdata->cm36686_light_power != NULL) { cm36686->cm36686_light_vddpower = cm36686->pdata->cm36686_light_power; if (cm36686->cm36686_light_vddpower) cm36686->cm36686_light_vddpower(true); } if(cm36686->pdata->cm36686_proxi_power != NULL) { cm36686->cm36686_proxi_vddpower = cm36686->pdata->cm36686_proxi_power; if (cm36686->cm36686_proxi_vddpower) cm36686->cm36686_proxi_vddpower(true); } /* wake lock init for proximity sensor */ wake_lock_init(&cm36686->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); if (cm36686->pdata->cm36686_led_on) { cm36686->pdata->cm36686_led_on(true); msleep(20); } /* Check if the device is there or not. */ ret = cm36686_i2c_write_word(cm36686, REG_CS_CONF1, 0x0001); if (ret < 0) { pr_err("%s: cm36686 is not connected.(%d)\n", __func__, ret); goto err_setup_reg; } /* setup initial registers */ ret = cm36686_setup_reg(cm36686); if (ret < 0) { pr_err("%s: could not setup regs\n", __func__); goto err_setup_reg; } if (cm36686->pdata->cm36686_led_on) cm36686->pdata->cm36686_led_on(false); if (cm36686->cm36686_light_vddpower) cm36686->cm36686_light_vddpower(false); if (cm36686->cm36686_proxi_vddpower) cm36686->cm36686_proxi_vddpower(false); /* allocate proximity input_device */ cm36686->proximity_input_dev = input_allocate_device(); if (!cm36686->proximity_input_dev) { pr_err("%s: could not allocate proximity input device\n", __func__); goto err_input_allocate_device_proximity; } input_set_drvdata(cm36686->proximity_input_dev, cm36686); cm36686->proximity_input_dev->name = "proximity_sensor"; input_set_capability(cm36686->proximity_input_dev, EV_ABS, ABS_DISTANCE); input_set_abs_params(cm36686->proximity_input_dev, ABS_DISTANCE, 0, 1, 0, 0); ret = input_register_device(cm36686->proximity_input_dev); if (ret < 0) { input_free_device(cm36686->proximity_input_dev); pr_err("%s: could not register input device\n", __func__); goto err_input_register_device_proximity; } ret = sysfs_create_group(&cm36686->proximity_input_dev->dev.kobj, &proximity_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_proximity; } #if defined(CONFIG_SENSOR_USE_SYMLINK) ret = sensors_initialize_symlink(cm36686->proximity_input_dev); if (ret < 0) { pr_err("%s - proximity_sensors_initialize_symlink error(%d).\n", __func__, ret); goto err_setup_irq; } #endif /* setup irq */ ret = cm36686_setup_irq(cm36686); if (ret) { pr_err("%s: could not setup irq\n", __func__); goto err_setup_irq; } /* For factory test mode, we use timer to get average proximity data. */ /* prox_timer settings. we poll for light values using a timer. */ hrtimer_init(&cm36686->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cm36686->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);/*2 sec*/ cm36686->prox_timer.function = cm36686_prox_timer_func; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ cm36686->prox_wq = create_singlethread_workqueue("cm36686_prox_wq"); if (!cm36686->prox_wq) { ret = -ENOMEM; pr_err("%s: could not create prox workqueue\n", __func__); goto err_create_prox_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&cm36686->work_prox, cm36686_work_func_prox); /* allocate lightsensor input_device */ cm36686->light_input_dev = input_allocate_device(); if (!cm36686->light_input_dev) { pr_err("%s: could not allocate light input device\n", __func__); goto err_input_allocate_device_light; } input_set_drvdata(cm36686->light_input_dev, cm36686); cm36686->light_input_dev->name = "light_sensor"; input_set_capability(cm36686->light_input_dev, EV_REL, REL_MISC); input_set_capability(cm36686->light_input_dev, EV_REL, REL_DIAL); input_set_capability(cm36686->light_input_dev, EV_REL, REL_WHEEL); ret = input_register_device(cm36686->light_input_dev); if (ret < 0) { input_free_device(cm36686->light_input_dev); pr_err("%s: could not register input device\n", __func__); goto err_input_register_device_light; } ret = sysfs_create_group(&cm36686->light_input_dev->dev.kobj, &light_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_light; } #if defined(CONFIG_SENSOR_USE_SYMLINK) ret = sensors_initialize_symlink(cm36686->light_input_dev); if (ret < 0) { pr_err("%s - light_sensors_initialize_symlink error(%d).\n", __func__, ret); goto err_create_light_workqueue; } #endif /* light_timer settings. we poll for light values using a timer. */ hrtimer_init(&cm36686->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cm36686->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC); cm36686->light_timer.function = cm36686_light_timer_func; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ cm36686->light_wq = create_singlethread_workqueue("cm36686_light_wq"); if (!cm36686->light_wq) { ret = -ENOMEM; pr_err("%s: could not create light workqueue\n", __func__); goto err_create_light_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&cm36686->work_light, cm36686_work_func_light); /* set sysfs for proximity sensor */ cm36686->proximity_dev = sensors_classdev_register("proximity_sensor"); if (IS_ERR(cm36686->proximity_dev)) { pr_err("%s: could not create proximity_dev\n", __func__); goto err_proximity_device_create; } if (device_create_file(cm36686->proximity_dev, &dev_attr_state) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_state.attr.name); goto err_proximity_device_create_file1; } if (device_create_file(cm36686->proximity_dev, &attr_prox_raw) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, attr_prox_raw.attr.name); goto err_proximity_device_create_file2; } #ifdef CM36686_CANCELATION if (device_create_file(cm36686->proximity_dev, &dev_attr_prox_cal) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_cal.attr.name); goto err_proximity_device_create_file3; } if (device_create_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_offset_pass.attr.name); goto err_proximity_device_create_file4; } #endif if (device_create_file(cm36686->proximity_dev, &dev_attr_prox_avg) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_avg.attr.name); goto err_proximity_device_create_file5; } if (device_create_file(cm36686->proximity_dev, &dev_attr_thresh_high) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_thresh_high.attr.name); goto err_proximity_device_create_file6; } if (device_create_file(cm36686->proximity_dev, &dev_attr_vendor) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_proximity_device_create_file7; } if (device_create_file(cm36686->proximity_dev, &dev_attr_name) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_proximity_device_create_file8; } if (device_create_file(cm36686->proximity_dev, &dev_attr_thresh_low) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_thresh_low.attr.name); goto err_proximity_device_create_file9; } dev_set_drvdata(cm36686->proximity_dev, cm36686); /* set sysfs for light sensor */ cm36686->light_dev = sensors_classdev_register("light_sensor"); if (IS_ERR(cm36686->light_dev)) { pr_err("%s: could not create light_dev\n", __func__); goto err_light_device_create; } if (device_create_file(cm36686->light_dev, &dev_attr_lux) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_lux.attr.name); goto err_light_device_create_file1; } if (device_create_file(cm36686->light_dev, &dev_attr_raw_data) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_raw_data.attr.name); goto err_light_device_create_file2; } if (device_create_file(cm36686->light_dev, &dev_attr_vendor) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_light_device_create_file3; } if (device_create_file(cm36686->light_dev, &dev_attr_name) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_light_device_create_file4; } dev_set_drvdata(cm36686->light_dev, cm36686); pr_info("%s is success.\n", __func__); goto done; /* error, unwind it all */ err_light_device_create_file4: device_remove_file(cm36686->light_dev, &dev_attr_vendor); err_light_device_create_file3: device_remove_file(cm36686->light_dev, &dev_attr_raw_data); err_light_device_create_file2: device_remove_file(cm36686->light_dev, &dev_attr_lux); err_light_device_create_file1: sensors_classdev_unregister(cm36686->light_dev); err_light_device_create: device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low); err_proximity_device_create_file9: device_remove_file(cm36686->proximity_dev, &dev_attr_name); err_proximity_device_create_file8: device_remove_file(cm36686->proximity_dev, &dev_attr_vendor); err_proximity_device_create_file7: device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high); err_proximity_device_create_file6: device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg); err_proximity_device_create_file5: #ifdef CM36686_CANCELATION device_remove_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass); err_proximity_device_create_file4: device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal); err_proximity_device_create_file3: #endif device_remove_file(cm36686->proximity_dev, &attr_prox_raw); err_proximity_device_create_file2: device_remove_file(cm36686->proximity_dev, &dev_attr_state); err_proximity_device_create_file1: sensors_classdev_unregister(cm36686->proximity_dev); err_proximity_device_create: destroy_workqueue(cm36686->light_wq); err_create_light_workqueue: sysfs_remove_group(&cm36686->light_input_dev->dev.kobj, &light_attribute_group); err_sysfs_create_group_light: input_unregister_device(cm36686->light_input_dev); err_input_register_device_light: err_input_allocate_device_light: destroy_workqueue(cm36686->prox_wq); err_create_prox_workqueue: free_irq(cm36686->irq, cm36686); gpio_free(cm36686->pdata->irq); err_setup_irq: sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj, &proximity_attribute_group); err_sysfs_create_group_proximity: input_unregister_device(cm36686->proximity_input_dev); err_input_register_device_proximity: err_input_allocate_device_proximity: err_setup_reg: if (cm36686->pdata->cm36686_led_on) cm36686->pdata->cm36686_led_on(false); if (cm36686->cm36686_light_vddpower) cm36686->cm36686_light_vddpower(false); if (cm36686->cm36686_proxi_vddpower) cm36686->cm36686_proxi_vddpower(false); wake_lock_destroy(&cm36686->prx_wake_lock); mutex_destroy(&cm36686->read_lock); mutex_destroy(&cm36686->power_lock); kfree(cm36686); done: return ret; }
static int __init init_cifs(void) { int rc = 0; cifs_proc_init(); INIT_LIST_HEAD(&cifs_tcp_ses_list); #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */ INIT_LIST_HEAD(&GlobalDnotifyReqList); INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */ /* * Initialize Global counters */ atomic_set(&sesInfoAllocCount, 0); atomic_set(&tconInfoAllocCount, 0); atomic_set(&tcpSesAllocCount, 0); atomic_set(&tcpSesReconnectCount, 0); atomic_set(&tconInfoReconnectCount, 0); atomic_set(&bufAllocCount, 0); atomic_set(&smBufAllocCount, 0); #ifdef CONFIG_CIFS_STATS2 atomic_set(&totBufAllocCount, 0); atomic_set(&totSmBufAllocCount, 0); #endif /* CONFIG_CIFS_STATS2 */ atomic_set(&midCount, 0); GlobalCurrentXid = 0; GlobalTotalActiveXid = 0; GlobalMaxActiveXid = 0; spin_lock_init(&cifs_tcp_ses_lock); spin_lock_init(&cifs_file_list_lock); spin_lock_init(&GlobalMid_Lock); #ifdef CONFIG_CIFS_SMB2 get_random_bytes(cifs_client_guid, SMB2_CLIENT_GUID_SIZE); #endif if (cifs_max_pending < 2) { cifs_max_pending = 2; cFYI(1, "cifs_max_pending set to min of 2"); } else if (cifs_max_pending > CIFS_MAX_REQ) { cifs_max_pending = CIFS_MAX_REQ; cFYI(1, "cifs_max_pending set to max of %u", CIFS_MAX_REQ); } cifsiod_wq = alloc_workqueue("cifsiod", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); if (!cifsiod_wq) { rc = -ENOMEM; goto out_clean_proc; } rc = cifs_fscache_register(); if (rc) goto out_destroy_wq; rc = cifs_init_inodecache(); if (rc) goto out_unreg_fscache; rc = cifs_init_mids(); if (rc) goto out_destroy_inodecache; rc = cifs_init_request_bufs(); if (rc) goto out_destroy_mids; #ifdef CONFIG_CIFS_UPCALL rc = register_key_type(&cifs_spnego_key_type); if (rc) goto out_destroy_request_bufs; #endif /* CONFIG_CIFS_UPCALL */ #ifdef CONFIG_CIFS_ACL rc = init_cifs_idmap(); if (rc) goto out_register_key_type; #endif /* CONFIG_CIFS_ACL */ rc = register_filesystem(&cifs_fs_type); if (rc) goto out_init_cifs_idmap; return 0; out_init_cifs_idmap: #ifdef CONFIG_CIFS_ACL exit_cifs_idmap(); out_register_key_type: #endif #ifdef CONFIG_CIFS_UPCALL unregister_key_type(&cifs_spnego_key_type); out_destroy_request_bufs: #endif cifs_destroy_request_bufs(); out_destroy_mids: cifs_destroy_mids(); out_destroy_inodecache: cifs_destroy_inodecache(); out_unreg_fscache: cifs_fscache_unregister(); out_destroy_wq: destroy_workqueue(cifsiod_wq); out_clean_proc: cifs_proc_clean(); return rc; }
static int __devinit ezx_pcap_probe(struct spi_device *spi) { struct pcap_platform_data *pdata = spi->dev.platform_data; struct pcap_chip *pcap; int i, adc_irq; int ret = -ENODEV; /* platform data is required */ if (!pdata) goto ret; pcap = kzalloc(sizeof(*pcap), GFP_KERNEL); if (!pcap) { ret = -ENOMEM; goto ret; } mutex_init(&pcap->io_mutex); mutex_init(&pcap->adc_mutex); INIT_WORK(&pcap->isr_work, pcap_isr_work); INIT_WORK(&pcap->msr_work, pcap_msr_work); dev_set_drvdata(&spi->dev, pcap); /* setup spi */ spi->bits_per_word = 32; spi->mode = SPI_MODE_0 | (pdata->config & PCAP_CS_AH ? SPI_CS_HIGH : 0); ret = spi_setup(spi); if (ret) goto free_pcap; pcap->spi = spi; /* setup irq */ pcap->irq_base = pdata->irq_base; pcap->workqueue = create_singlethread_workqueue("pcapd"); if (!pcap->workqueue) { ret = -ENOMEM; dev_err(&spi->dev, "can't create pcap thread\n"); goto free_pcap; } /* redirect interrupts to AP, except adcdone2 */ if (!(pdata->config & PCAP_SECOND_PORT)) ezx_pcap_write(pcap, PCAP_REG_INT_SEL, (1 << PCAP_IRQ_ADCDONE2)); /* setup irq chip */ for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) { irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); irq_set_chip_data(i, pcap); #ifdef CONFIG_ARM set_irq_flags(i, IRQF_VALID); #else irq_set_noprobe(i); #endif } /* mask/ack all PCAP interrupts */ ezx_pcap_write(pcap, PCAP_REG_MSR, PCAP_MASK_ALL_INTERRUPT); ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER); pcap->msr = PCAP_MASK_ALL_INTERRUPT; irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); irq_set_handler_data(spi->irq, pcap); irq_set_chained_handler(spi->irq, pcap_irq_handler); irq_set_irq_wake(spi->irq, 1); /* ADC */ adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ? PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE); ret = request_irq(adc_irq, pcap_adc_irq, 0, "ADC", pcap); if (ret) goto free_irqchip; /* setup subdevs */ for (i = 0; i < pdata->num_subdevs; i++) { ret = pcap_add_subdev(pcap, &pdata->subdevs[i]); if (ret) goto remove_subdevs; } /* board specific quirks */ if (pdata->init) pdata->init(pcap); return 0; remove_subdevs: device_for_each_child(&spi->dev, NULL, pcap_remove_subdev); /* free_adc: */ free_irq(adc_irq, pcap); free_irqchip: for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) irq_set_chip_and_handler(i, NULL, NULL); /* destroy_workqueue: */ destroy_workqueue(pcap->workqueue); free_pcap: kfree(pcap); ret: return ret; }
/** * gserial_setup - initialize TTY driver for one or more ports * @g: gadget to associate with these ports * @count: how many ports to support * Context: may sleep * * The TTY stack needs to know in advance how many devices it should * plan to manage. Use this call to set up the ports you will be * exporting through USB. Later, connect them to functions based * on what configuration is activated by the USB host; and disconnect * them as appropriate. * * An example would be a two-configuration device in which both * configurations expose port 0, but through different functions. * One configuration could even expose port 1 while the other * one doesn't. * * Returns negative errno or zero. */ int gserial_setup(struct usb_gadget *g, unsigned count) { unsigned i; struct usb_cdc_line_coding coding; int status; if (count == 0 || count > N_PORTS) return -EINVAL; gs_tty_driver = alloc_tty_driver(count); if (!gs_tty_driver) return -ENOMEM; gs_tty_driver->owner = THIS_MODULE; gs_tty_driver->driver_name = "g_serial"; gs_tty_driver->name = PREFIX; /* uses dynamically assigned dev_t values */ gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS; gs_tty_driver->init_termios = tty_std_termios; /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on * MS-Windows. Otherwise, most of these flags shouldn't affect * anything unless we were to actually hook up to a serial line. */ gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; gs_tty_driver->init_termios.c_ispeed = 9600; gs_tty_driver->init_termios.c_ospeed = 9600; coding.dwDTERate = __constant_cpu_to_le32(480000000); coding.bCharFormat = USB_CDC_1_STOP_BITS; coding.bParityType = USB_CDC_NO_PARITY; coding.bDataBits = 8; tty_set_operations(gs_tty_driver, &gs_tty_ops); gserial_wq = create_singlethread_workqueue("k_gserial"); if (!gserial_wq) { status = -ENOMEM; goto fail; } /* make devices be openable */ for (i = 0; i < count; i++) { mutex_init(&ports[i].lock); status = gs_port_alloc(i, &coding); if (status) { count = i; goto fail; } } n_ports = count; /* export the driver ... */ status = tty_register_driver(gs_tty_driver); if (status) { put_tty_driver(gs_tty_driver); pr_err("%s: cannot register, err %d\n", __func__, status); goto fail; } /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */ for (i = 0; i < count; i++) { struct device *tty_dev; tty_dev = tty_register_device(gs_tty_driver, i, &g->dev); if (IS_ERR(tty_dev)) pr_warning("%s: no classdev for port %d, err %ld\n", __func__, i, PTR_ERR(tty_dev)); } pr_debug("%s: registered %d ttyGS* device%s\n", __func__, count, (count == 1) ? "" : "s"); return status; fail: while (count--) kfree(ports[count].port); destroy_workqueue(gserial_wq); put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; return status; }
void rds_threads_exit(void) { destroy_workqueue(rds_wq); }
static int hva_probe(struct platform_device *pdev) { struct hva_dev *hva; struct device *dev = &pdev->dev; int ret; hva = devm_kzalloc(dev, sizeof(*hva), GFP_KERNEL); if (!hva) { ret = -ENOMEM; goto err; } hva->dev = dev; hva->pdev = pdev; platform_set_drvdata(pdev, hva); mutex_init(&hva->lock); /* probe hardware */ ret = hva_hw_probe(pdev, hva); if (ret) goto err; /* register all available encoders */ register_encoders(hva); /* register all supported formats */ register_formats(hva); /* register on V4L2 */ ret = v4l2_device_register(dev, &hva->v4l2_dev); if (ret) { dev_err(dev, "%s %s failed to register V4L2 device\n", HVA_PREFIX, HVA_NAME); goto err_hw; } hva->work_queue = create_workqueue(HVA_NAME); if (!hva->work_queue) { dev_err(dev, "%s %s failed to allocate work queue\n", HVA_PREFIX, HVA_NAME); ret = -ENOMEM; goto err_v4l2; } /* register device */ ret = hva_register_device(hva); if (ret) goto err_work_queue; dev_info(dev, "%s %s registered as /dev/video%d\n", HVA_PREFIX, HVA_NAME, hva->vdev->num); return 0; err_work_queue: destroy_workqueue(hva->work_queue); err_v4l2: v4l2_device_unregister(&hva->v4l2_dev); err_hw: hva_hw_remove(hva); err: return ret; }
void diagfwd_bridge_init(void) { int ret; pr_debug("diag: in %s\n", __func__); driver->diag_bridge_wq = create_singlethread_workqueue( "diag_bridge_wq"); driver->read_len_mdm = 0; driver->write_len_mdm = 0; driver->num_hsic_buf_tbl_entries = 0; if (driver->usb_buf_mdm_out == NULL) driver->usb_buf_mdm_out = kzalloc(USB_MAX_OUT_BUF, GFP_KERNEL); if (driver->usb_buf_mdm_out == NULL) goto err; /* Only used by smux move to smux probe function */ if (driver->write_ptr_mdm == NULL) driver->write_ptr_mdm = kzalloc( sizeof(struct diag_request), GFP_KERNEL); if (driver->write_ptr_mdm == NULL) goto err; if (driver->usb_read_mdm_ptr == NULL) driver->usb_read_mdm_ptr = kzalloc( sizeof(struct diag_request), GFP_KERNEL); if (driver->usb_read_mdm_ptr == NULL) goto err; if (driver->hsic_buf_tbl == NULL) driver->hsic_buf_tbl = kzalloc(NUM_HSIC_BUF_TBL_ENTRIES * sizeof(struct diag_write_device), GFP_KERNEL); if (driver->hsic_buf_tbl == NULL) goto err; driver->count_hsic_pool = 0; driver->count_hsic_write_pool = 0; driver->itemsize_hsic = READ_HSIC_BUF_SIZE; driver->poolsize_hsic = N_MDM_WRITE; driver->itemsize_hsic_write = sizeof(struct diag_request); driver->poolsize_hsic_write = N_MDM_WRITE; #ifdef CONFIG_DIAG_OVER_USB INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn); #endif INIT_WORK(&(driver->diag_disconnect_work), diag_disconnect_work_fn); INIT_WORK(&(driver->diag_usb_read_complete_work), diag_usb_read_complete_fn); #ifdef CONFIG_DIAG_OVER_USB driver->mdm_ch = usb_diag_open(DIAG_MDM, driver, diagfwd_bridge_notifier); if (IS_ERR(driver->mdm_ch)) { pr_err("diag: Unable to open USB diag MDM channel\n"); goto err; } #endif /* register HSIC device */ ret = platform_driver_register(&msm_hsic_ch_driver); if (ret) pr_err("diag: could not register HSIC device, ret: %d\n", ret); /* register SMUX device */ ret = platform_driver_register(&msm_diagfwd_smux_driver); if (ret) pr_err("diag: could not register SMUX device, ret: %d\n", ret); return; err: pr_err("diag: Could not initialize for bridge forwarding\n"); kfree(driver->usb_buf_mdm_out); kfree(driver->hsic_buf_tbl); kfree(driver->write_ptr_mdm); kfree(driver->usb_read_mdm_ptr); if (driver->diag_bridge_wq) destroy_workqueue(driver->diag_bridge_wq); return; }
void __exit xen_pcibk_xenbus_unregister(void) { destroy_workqueue(xen_pcibk_wq); xenbus_unregister_driver(&xen_pcibk_driver); }
static void __exit aps_12d_exit(void) { i2c_del_driver(&aps_driver); if (aps_wq) destroy_workqueue(aps_wq); }
int ieee802154_register_hw(struct ieee802154_hw *hw) { struct ieee802154_local *local = hw_to_local(hw); struct net_device *dev; int rc = -ENOSYS; local->workqueue = create_singlethread_workqueue(wpan_phy_name(local->phy)); if (!local->workqueue) { rc = -ENOMEM; goto out; } hrtimer_init(&local->ifs_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); local->ifs_timer.function = ieee802154_xmit_ifs_timer; wpan_phy_set_dev(local->phy, local->hw.parent); ieee802154_setup_wpan_phy_pib(local->phy); if (!(hw->flags & IEEE802154_HW_CSMA_PARAMS)) { local->phy->supported.min_csma_backoffs = 4; local->phy->supported.max_csma_backoffs = 4; local->phy->supported.min_maxbe = 5; local->phy->supported.max_maxbe = 5; local->phy->supported.min_minbe = 3; local->phy->supported.max_minbe = 3; } if (!(hw->flags & IEEE802154_HW_FRAME_RETRIES)) { local->phy->supported.min_frame_retries = 3; local->phy->supported.max_frame_retries = 3; } if (hw->flags & IEEE802154_HW_PROMISCUOUS) local->phy->supported.iftypes |= BIT(NL802154_IFTYPE_MONITOR); rc = wpan_phy_register(local->phy); if (rc < 0) goto out_wq; rtnl_lock(); dev = ieee802154_if_add(local, "wpan%d", NET_NAME_ENUM, NL802154_IFTYPE_NODE, cpu_to_le64(0x0000000000000000ULL)); if (IS_ERR(dev)) { rtnl_unlock(); rc = PTR_ERR(dev); goto out_phy; } rtnl_unlock(); return 0; out_phy: wpan_phy_unregister(local->phy); out_wq: destroy_workqueue(local->workqueue); out: return rc; }
static struct isert_device *isert_device_create(struct ib_device *ib_dev) { struct isert_device *isert_dev; struct ib_device_attr *dev_attr; int cqe_num, err; struct ib_pd *pd; struct ib_mr *mr; struct ib_cq *cq; char wq_name[64]; int i, j; TRACE_ENTRY(); isert_dev = kzalloc(sizeof(*isert_dev), GFP_KERNEL); if (unlikely(isert_dev == NULL)) { pr_err("Failed to allocate iser dev\n"); err = -ENOMEM; goto out; } dev_attr = &isert_dev->device_attr; err = ib_query_device(ib_dev, dev_attr); if (unlikely(err)) { pr_err("Failed to query device, err: %d\n", err); goto fail_query; } isert_dev->num_cqs = min_t(int, num_online_cpus(), ib_dev->num_comp_vectors); isert_dev->cq_qps = kzalloc(sizeof(*isert_dev->cq_qps) * isert_dev->num_cqs, GFP_KERNEL); if (unlikely(isert_dev->cq_qps == NULL)) { pr_err("Failed to allocate iser cq_qps\n"); err = -ENOMEM; goto fail_cq_qps; } isert_dev->cq_desc = vmalloc(sizeof(*isert_dev->cq_desc) * isert_dev->num_cqs); if (unlikely(isert_dev->cq_desc == NULL)) { pr_err("Failed to allocate %ld bytes for iser cq_desc\n", sizeof(*isert_dev->cq_desc) * isert_dev->num_cqs); err = -ENOMEM; goto fail_alloc_cq_desc; } pd = ib_alloc_pd(ib_dev); if (unlikely(IS_ERR(pd))) { err = PTR_ERR(pd); pr_err("Failed to alloc iser dev pd, err:%d\n", err); goto fail_pd; } mr = ib_get_dma_mr(pd, IB_ACCESS_LOCAL_WRITE); if (unlikely(IS_ERR(mr))) { err = PTR_ERR(mr); pr_err("Failed to get dma mr, err: %d\n", err); goto fail_mr; } cqe_num = min(isert_dev->device_attr.max_cqe, ISER_CQ_ENTRIES); cqe_num = cqe_num / isert_dev->num_cqs; #ifdef CONFIG_SCST_EXTRACHECKS if (isert_dev->device_attr.max_cqe == 0) pr_err("Zero max_cqe encountered: you may have a compilation problem\n"); #endif for (i = 0; i < isert_dev->num_cqs; ++i) { struct isert_cq *cq_desc = &isert_dev->cq_desc[i]; cq_desc->dev = isert_dev; cq_desc->idx = i; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) INIT_WORK(&cq_desc->cq_comp_work, isert_cq_comp_work_cb, NULL); #else INIT_WORK(&cq_desc->cq_comp_work, isert_cq_comp_work_cb); #endif snprintf(wq_name, sizeof(wq_name), "isert_cq_%p", cq_desc); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) cq_desc->cq_workqueue = create_singlethread_workqueue(wq_name); #else #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 36) cq_desc->cq_workqueue = alloc_workqueue(wq_name, WQ_CPU_INTENSIVE| WQ_RESCUER, 1); #else cq_desc->cq_workqueue = alloc_workqueue(wq_name, WQ_CPU_INTENSIVE| WQ_MEM_RECLAIM, 1); #endif #endif if (unlikely(!cq_desc->cq_workqueue)) { pr_err("Failed to alloc iser cq work queue for dev:%s\n", ib_dev->name); err = -ENOMEM; goto fail_cq; } cq = ib_create_cq(ib_dev, isert_cq_comp_handler, isert_async_evt_handler, cq_desc, /* context */ cqe_num, i); /* completion vector */ if (unlikely(IS_ERR(cq))) { cq_desc->cq = NULL; err = PTR_ERR(cq); pr_err("Failed to create iser dev cq, err:%d\n", err); goto fail_cq; } cq_desc->cq = cq; err = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS); if (unlikely(err)) { pr_err("Failed to request notify cq, err: %d\n", err); goto fail_cq; } } isert_dev->ib_dev = ib_dev; isert_dev->pd = pd; isert_dev->mr = mr; INIT_LIST_HEAD(&isert_dev->conn_list); lockdep_assert_held(&dev_list_mutex); isert_dev_list_add(isert_dev); pr_info("iser created device:%p\n", isert_dev); return isert_dev; fail_cq: for (j = 0; j <= i; ++j) { if (isert_dev->cq_desc[j].cq) ib_destroy_cq(isert_dev->cq_desc[j].cq); if (isert_dev->cq_desc[j].cq_workqueue) destroy_workqueue(isert_dev->cq_desc[j].cq_workqueue); } ib_dereg_mr(mr); fail_mr: ib_dealloc_pd(pd); fail_pd: vfree(isert_dev->cq_desc); fail_alloc_cq_desc: kfree(isert_dev->cq_qps); fail_cq_qps: fail_query: kfree(isert_dev); out: TRACE_EXIT_RES(err); return ERR_PTR(err); }
static int max77693_haptic_probe(struct platform_device *pdev) { int error = 0; struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); struct max77693_platform_data *max77693_pdata = dev_get_platdata(max77693->dev); struct max77693_haptic_platform_data *pdata = max77693_pdata->haptic_data; struct max77693_haptic_data *hap_data; pr_debug("[VIB] ++ %s\n", __func__); if (pdata == NULL) { pr_err("%s: no pdata\n", __func__); return -ENODEV; } hap_data = kzalloc(sizeof(struct max77693_haptic_data), GFP_KERNEL); if (!hap_data) return -ENOMEM; platform_set_drvdata(pdev, hap_data); g_hap_data = hap_data; hap_data->max77693 = max77693; hap_data->i2c = max77693->haptic; hap_data->pmic_i2c = max77693->i2c; hap_data->pdata = pdata; hap_data->workqueue = create_singlethread_workqueue("hap_work"); if (IS_ERR(hap_data->workqueue)) { pr_err("[VIB] Failed to create workqueue for hap_work\n"); error = -EFAULT; goto err_create_workqueue; } INIT_WORK(&(hap_data->work), haptic_work); spin_lock_init(&(hap_data->lock)); hap_data->pwm = pwm_request(hap_data->pdata->pwm_id, "vibrator"); if (IS_ERR(hap_data->pwm)) { pr_err("[VIB] Failed to request pwm\n"); error = -EFAULT; goto err_pwm_request; } pwm_config(hap_data->pwm, pdata->period / 2, pdata->period); vibetonz_clk_on(&pdev->dev, true); if (pdata->init_hw) pdata->init_hw(); hap_data->regulator = regulator_get(NULL, pdata->regulator_name); if (IS_ERR(hap_data->regulator)) { pr_err("[VIB] Failed to get vmoter regulator.\n"); error = -EFAULT; goto err_regulator_get; } /* hrtimer init */ hrtimer_init(&hap_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hap_data->timer.function = haptic_timer_func; /* timed_output_dev init*/ hap_data->tout_dev.name = "vibrator"; hap_data->tout_dev.get_time = haptic_get_time; hap_data->tout_dev.enable = haptic_enable; create_vibrator_sysfs(); #ifdef CONFIG_ANDROID_TIMED_OUTPUT error = timed_output_dev_register(&hap_data->tout_dev); if (error < 0) { pr_err("[VIB] Failed to register timed_output : %d\n", error); error = -EFAULT; goto err_timed_output_register; } pr_err("[VIB] timed_output device is registrated\n"); /* User controllable pwm level */ error = device_create_file(hap_data->tout_dev.dev, &dev_attr_pwm_value); if (error < 0) { pr_err("[VIB] create sysfs fail: pwm_value\n"); } #endif pr_debug("[VIB] -- %s\n", __func__); return error; err_timed_output_register: regulator_put(hap_data->regulator); err_regulator_get: pwm_free(hap_data->pwm); err_pwm_request: destroy_workqueue(hap_data->workqueue); err_create_workqueue: kfree(hap_data); g_hap_data = NULL; return error; }
void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv) { destroy_workqueue(dev_priv->mm.userptr_wq); }
static int cm36686_i2c_remove(struct i2c_client *client) { struct cm36686_data *cm36686 = i2c_get_clientdata(client); /* free irq */ if (cm36686->power_state & PROXIMITY_ENABLED) { disable_irq_wake(cm36686->irq); disable_irq(cm36686->irq); } free_irq(cm36686->irq, cm36686); gpio_free(cm36686->pdata->irq); /* device off */ if (cm36686->power_state & LIGHT_ENABLED) cm36686_light_disable(cm36686); if (cm36686->power_state & PROXIMITY_ENABLED) { cm36686_i2c_write_word(cm36686, REG_PS_CONF1, 0x0001); if (cm36686->pdata->cm36686_led_on) cm36686->pdata->cm36686_led_on(false); if (cm36686->cm36686_light_vddpower) cm36686->cm36686_light_vddpower(false); if (cm36686->cm36686_proxi_vddpower) cm36686->cm36686_proxi_vddpower(false); } /* destroy workqueue */ destroy_workqueue(cm36686->light_wq); destroy_workqueue(cm36686->prox_wq); /* sysfs destroy */ device_remove_file(cm36686->light_dev, &dev_attr_name); device_remove_file(cm36686->light_dev, &dev_attr_vendor); device_remove_file(cm36686->light_dev, &dev_attr_raw_data); device_remove_file(cm36686->light_dev, &dev_attr_lux); sensors_classdev_unregister(cm36686->light_dev); device_remove_file(cm36686->proximity_dev, &dev_attr_name); device_remove_file(cm36686->proximity_dev, &dev_attr_vendor); device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high); device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low); device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg); #ifdef CM36686_CANCELATION device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal); device_remove_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass); #endif device_remove_file(cm36686->proximity_dev, &attr_prox_raw); device_remove_file(cm36686->proximity_dev, &dev_attr_state); sensors_classdev_unregister(cm36686->proximity_dev); /* input device destroy */ sysfs_remove_group(&cm36686->light_input_dev->dev.kobj, &light_attribute_group); input_unregister_device(cm36686->light_input_dev); sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj, &proximity_attribute_group); input_unregister_device(cm36686->proximity_input_dev); /* lock destroy */ mutex_destroy(&cm36686->read_lock); mutex_destroy(&cm36686->power_lock); wake_lock_destroy(&cm36686->prx_wake_lock); kfree(cm36686); return 0; }
void adf_exit_aer(void) { if (device_reset_wq) destroy_workqueue(device_reset_wq); device_reset_wq = NULL; }
static int lge_hsd_probe(struct platform_device *pdev) { int ret; struct gpio_switch_platform_data *pdata = pdev->dev.platform_data; HSD_DBG("%s\n", pdata->name); if (!pdata) { HSD_ERR("The platform data is null\n"); return -EBUSY; } hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL); if (!hi) { HSD_ERR("Failed to allloate headset per device info\n"); return -ENOMEM; } hi->gpio = pdata->gpio; mutex_init(&hi->mutex_lock); hi->sdev.name = pdata->name; hi->sdev.print_state = lge_hsd_print_state; hi->sdev.print_name = lge_hsd_print_name; ret = switch_dev_register(&hi->sdev); if (ret < 0) { HSD_ERR("Failed to register switch device\n"); goto err_switch_dev_register; } hs_detect_work_queue = create_workqueue("hs_detect"); if (hs_detect_work_queue == NULL) { HSD_ERR("Failed to create workqueue\n"); goto err_create_work_queue; } ret = gpio_request(hi->gpio, pdev->name); if (ret < 0) { HSD_ERR("Failed to request gpio%d\n", hi->gpio); goto err_request_detect_gpio; } ret = gpio_direction_input(hi->gpio); if (ret < 0) { HSD_ERR("Failed to set gpio%d as input\n", hi->gpio); goto err_set_detect_gpio; } if (hi->gpio == LGE_HEADSET_DETECT_GPIO) { ret = gpio_tlmm_config(GPIO_CFG(hi->gpio, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (ret < 0) { HSD_ERR("Failed to configure gpio%d tlmm\n", hi->gpio); goto err_set_detect_gpio; } } hi->irq = gpio_to_irq(pdata->gpio); if (hi->irq < 0) { HSD_ERR("Failed to get interrupt number\n"); ret = hi->irq; goto err_get_irq_num_failed; } ret = request_irq(hi->irq, gpio_irq_handler, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, NULL); if (ret < 0) { HSD_ERR("Failed to request interrupt handler\n"); goto err_request_detect_irq; } ret = irq_set_irq_wake(hi->irq, 1); if (ret < 0) { HSD_ERR("Failed to set interrupt wake\n"); goto err_request_input_dev; } hi->input = input_allocate_device(); if (!hi->input) { HSD_ERR("Failed to allocate input device\n"); ret = -ENOMEM; goto err_request_input_dev; } if (pdev->dev.platform_data) hi->input->name = "7k_headset"; else hi->input->name = "hsd_headset"; hi->input->id.vendor = 0x0001; hi->input->id.product = 1; hi->input->id.version = 1; input_set_capability(hi->input, EV_SW, SW_HEADPHONE_INSERT); ret = input_register_device(hi->input); if (ret) { HSD_ERR("Failed to register input device\n"); goto err_register_input_dev; } /* Perform initial detection */ return 0; err_register_input_dev: input_free_device(hi->input); err_request_input_dev: free_irq(hi->irq, 0); err_request_detect_irq: err_get_irq_num_failed: err_set_detect_gpio: gpio_free(hi->gpio); err_request_detect_gpio: destroy_workqueue(hs_detect_work_queue); err_create_work_queue: switch_dev_unregister(&hi->sdev); err_switch_dev_register: HSD_ERR("Failed to register driver\n"); return ret; }
static void __exit test_exit(void) { destroy_workqueue(queue); }
static void __exit appledisplay_exit(void) { flush_workqueue(wq); destroy_workqueue(wq); usb_deregister(&appledisplay_driver); }
static int mxhci_hsic_probe(struct platform_device *pdev) { struct hc_driver *driver; struct device_node *node = pdev->dev.of_node; struct mxhci_hsic_hcd *mxhci; struct xhci_hcd *xhci; struct resource *res; struct usb_hcd *hcd; unsigned int reg; int ret; int irq; u32 tmp[3]; if (usb_disabled()) return -ENODEV; driver = &mxhci_hsic_hc_driver; pdev->dev.dma_mask = &dma_mask; /* dbg log event settings */ dbg_hsic.log_events = enable_dbg_log; dbg_hsic.log_payload = enable_payload_log; dbg_hsic.inep_log_mask = ep_addr_rxdbg_mask; dbg_hsic.outep_log_mask = ep_addr_rxdbg_mask; /* usb2.0 root hub */ driver->hcd_priv_size = sizeof(struct mxhci_hsic_hcd); hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) return -ENOMEM; irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = -ENODEV; goto put_hcd; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { ret = -ENODEV; goto put_hcd; } hcd_to_bus(hcd)->skip_resume = true; hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = devm_request_and_ioremap(&pdev->dev, res); if (!hcd->regs) { dev_err(&pdev->dev, "error mapping memory\n"); ret = -EFAULT; goto put_hcd; } mxhci = hcd_to_hsic(hcd); mxhci->dev = &pdev->dev; mxhci->strobe = of_get_named_gpio(node, "hsic,strobe-gpio", 0); if (mxhci->strobe < 0) { ret = -EINVAL; goto put_hcd; } mxhci->data = of_get_named_gpio(node, "hsic,data-gpio", 0); if (mxhci->data < 0) { ret = -EINVAL; goto put_hcd; } ret = of_property_read_u32_array(node, "qcom,vdd-voltage-level", tmp, ARRAY_SIZE(tmp)); if (!ret) { mxhci->vdd_no_vol_level = tmp[0]; mxhci->vdd_low_vol_level = tmp[1]; mxhci->vdd_high_vol_level = tmp[2]; } else { dev_err(&pdev->dev, "failed to read qcom,vdd-voltage-level property\n"); ret = -EINVAL; goto put_hcd; } ret = mxhci_msm_config_gdsc(mxhci, 1); if (ret) { dev_err(&pdev->dev, "unable to configure hsic gdsc\n"); goto put_hcd; } ret = mxhci_hsic_init_clocks(mxhci, 1); if (ret) { dev_err(&pdev->dev, "unable to initialize clocks\n"); goto put_hcd; } ret = mxhci_hsic_init_vddcx(mxhci, 1); if (ret) { dev_err(&pdev->dev, "unable to initialize vddcx\n"); goto deinit_clocks; } mxhci_hsic_reset(mxhci); /* HSIC phy caliberation:set periodic caliberation interval ~2.048sec */ mxhci_hsic_ulpi_write(mxhci, 0xFF, MSM_HSIC_IO_CAL_PER); /* Enable periodic IO calibration in HSIC_CFG register */ mxhci_hsic_ulpi_write(mxhci, 0xA8, MSM_HSIC_CFG); /* Configure Strobe and Data GPIOs to enable HSIC */ ret = mxhci_hsic_config_gpios(mxhci); if (ret) { dev_err(mxhci->dev, " gpio configuarion failed\n"); goto deinit_vddcx; } /* enable STROBE_PAD_CTL */ reg = readl_relaxed(TLMM_GPIO_HSIC_STROBE_PAD_CTL); writel_relaxed(reg | 0x2000000, TLMM_GPIO_HSIC_STROBE_PAD_CTL); /* enable DATA_PAD_CTL */ reg = readl_relaxed(TLMM_GPIO_HSIC_DATA_PAD_CTL); writel_relaxed(reg | 0x2000000, TLMM_GPIO_HSIC_DATA_PAD_CTL); mb(); /* Enable LPM in Sleep mode and suspend mode */ reg = readl_relaxed(MSM_HSIC_CTRL_REG); reg |= CTRLREG_PLL_CTRL_SLEEP | CTRLREG_PLL_CTRL_SUSP; writel_relaxed(reg, MSM_HSIC_CTRL_REG); if (of_property_read_bool(node, "qti,disable-hw-clk-gating")) { reg = readl_relaxed(MSM_HSIC_GCTL); writel_relaxed((reg | GCTL_DSBLCLKGTNG), MSM_HSIC_GCTL); } /* enable pwr event irq for LPM_IN_L2_IRQ */ writel_relaxed(LPM_IN_L2_IRQ_MASK, MSM_HSIC_PWR_EVNT_IRQ_MASK); mxhci->wakeup_irq = platform_get_irq_byname(pdev, "wakeup_irq"); if (mxhci->wakeup_irq < 0) { mxhci->wakeup_irq = 0; dev_err(&pdev->dev, "failed to init wakeup_irq\n"); } else { /* enable wakeup irq only when entering lpm */ irq_set_status_flags(mxhci->wakeup_irq, IRQ_NOAUTOEN); ret = devm_request_irq(&pdev->dev, mxhci->wakeup_irq, mxhci_hsic_wakeup_irq, 0, "mxhci_hsic_wakeup", mxhci); if (ret) { dev_err(&pdev->dev, "request irq failed (wakeup irq)\n"); goto deinit_vddcx; } } ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto deinit_vddcx; hcd = dev_get_drvdata(&pdev->dev); xhci = hcd_to_xhci(hcd); /* USB 3.0 roothub */ /* no need for another instance of mxhci */ driver->hcd_priv_size = sizeof(struct xhci_hcd *); xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, dev_name(&pdev->dev), hcd); if (!xhci->shared_hcd) { ret = -ENOMEM; goto remove_usb2_hcd; } hcd_to_bus(xhci->shared_hcd)->skip_resume = true; /* * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset) * is called by usb_add_hcd(). */ *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); if (ret) goto put_usb3_hcd; spin_lock_init(&mxhci->wakeup_lock); mxhci->pwr_event_irq = platform_get_irq_byname(pdev, "pwr_event_irq"); if (mxhci->pwr_event_irq < 0) { dev_err(&pdev->dev, "platform_get_irq for pwr_event_irq failed\n"); goto remove_usb3_hcd; } ret = devm_request_irq(&pdev->dev, mxhci->pwr_event_irq, mxhci_hsic_pwr_event_irq, 0, "mxhci_hsic_pwr_evt", mxhci); if (ret) { dev_err(&pdev->dev, "request irq failed (pwr event irq)\n"); goto remove_usb3_hcd; } init_completion(&mxhci->phy_in_lpm); mxhci->wq = create_singlethread_workqueue("mxhci_wq"); if (!mxhci->wq) { dev_err(&pdev->dev, "unable to create workqueue\n"); ret = -ENOMEM; goto remove_usb3_hcd; } INIT_WORK(&mxhci->bus_vote_w, mxhci_hsic_bus_vote_w); mxhci->bus_scale_table = msm_bus_cl_get_pdata(pdev); if (!mxhci->bus_scale_table) { dev_dbg(&pdev->dev, "bus scaling is disabled\n"); } else { mxhci->bus_perf_client = msm_bus_scale_register_client(mxhci->bus_scale_table); /* Configure BUS performance parameters for MAX bandwidth */ if (mxhci->bus_perf_client) { mxhci->bus_vote = true; queue_work(mxhci->wq, &mxhci->bus_vote_w); } else { dev_err(&pdev->dev, "%s: bus scaling client reg err\n", __func__); ret = -ENODEV; goto delete_wq; } } ret = device_create_file(&pdev->dev, &dev_attr_config_imod); if (ret) dev_dbg(&pdev->dev, "%s: unable to create imod sysfs entry\n", __func__); /* Enable HSIC PHY */ mxhci_hsic_ulpi_write(mxhci, 0x01, MSM_HSIC_CFG_SET); device_init_wakeup(&pdev->dev, 1); wakeup_source_init(&mxhci->ws, dev_name(&pdev->dev)); pm_stay_awake(mxhci->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; delete_wq: destroy_workqueue(mxhci->wq); remove_usb3_hcd: usb_remove_hcd(xhci->shared_hcd); put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); remove_usb2_hcd: usb_remove_hcd(hcd); deinit_vddcx: mxhci_hsic_init_vddcx(mxhci, 0); deinit_clocks: mxhci_hsic_init_clocks(mxhci, 0); put_hcd: usb_put_hcd(hcd); return ret; }
static ssize_t debug_flag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long state = 0; HS_DBG(); if (strncmp(buf, "enable", count - 1) == 0) { if (hi->debug_flag & DEBUG_FLAG_ADC) { HS_LOG("Debug work is already running"); return count; } if (!debug_wq) { debug_wq = create_workqueue("debug"); if (!debug_wq) { HS_LOG("Failed to create debug workqueue"); return count; } } HS_LOG("Enable headset debug"); mutex_lock(&hi->mutex_lock); hi->debug_flag |= DEBUG_FLAG_ADC; mutex_unlock(&hi->mutex_lock); queue_work(debug_wq, &debug_work); } else if (strncmp(buf, "disable", count - 1) == 0) { if (!(hi->debug_flag & DEBUG_FLAG_ADC)) { HS_LOG("Debug work has been stopped"); return count; } HS_LOG("Disable headset debug"); mutex_lock(&hi->mutex_lock); hi->debug_flag &= ~DEBUG_FLAG_ADC; mutex_unlock(&hi->mutex_lock); if (debug_wq) { flush_workqueue(debug_wq); destroy_workqueue(debug_wq); debug_wq = NULL; } } else if (strncmp(buf, "debug_log_enable", count - 1) == 0) { HS_LOG("Enable headset debug log"); hi->debug_flag |= DEBUG_FLAG_LOG; } else if (strncmp(buf, "debug_log_disable", count - 1) == 0) { HS_LOG("Disable headset debug log"); hi->debug_flag &= ~DEBUG_FLAG_LOG; } else if (strncmp(buf, "no_headset", count - 1) == 0) { HS_LOG("Headset simulation: no_headset"); state = BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_35MM_HEADSET | BIT_USB_AUDIO_OUT; switch_send_event(state, 0); } else if (strncmp(buf, "35mm_mic", count - 1) == 0) { HS_LOG("Headset simulation: 35mm_mic"); state = BIT_HEADSET | BIT_35MM_HEADSET; switch_send_event(state, 1); } else if (strncmp(buf, "35mm_no_mic", count - 1) == 0) { HS_LOG("Headset simulation: 35mm_no_mic"); state = BIT_HEADSET_NO_MIC | BIT_35MM_HEADSET; switch_send_event(state, 1); } else if (strncmp(buf, "usb_audio", count - 1) == 0) { HS_LOG("Headset simulation: usb_audio"); state = BIT_USB_AUDIO_OUT; switch_send_event(state, 1); } else { HS_LOG("Invalid parameter"); return count; } return count; }
static int fimg2d_probe(struct platform_device *pdev) { struct resource *res; struct fimg2d_platdata *pdata; int ret; pdata = to_fimg2d_plat(&pdev->dev); if (!pdata) { printk(KERN_ERR "FIMG2D failed to get platform data\n"); ret = -ENOMEM; goto err_plat; } /* global structure */ info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { printk(KERN_ERR "FIMG2D failed to allocate memory for controller\n"); ret = -ENOMEM; goto err_plat; } /* setup global info */ ret = fimg2d_setup_controller(info); if (ret) { printk(KERN_ERR "FIMG2D failed to setup controller\n"); goto err_setup; } info->dev = &pdev->dev; /* memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { printk(KERN_ERR "FIMG2D failed to get resource\n"); ret = -ENOENT; goto err_res; } info->mem = request_mem_region(res->start, resource_size(res), pdev->name); if (!info->mem) { printk(KERN_ERR "FIMG2D failed to request memory region\n"); ret = -ENOMEM; goto err_region; } /* ioremap */ info->regs = ioremap(res->start, resource_size(res)); if (!info->regs) { printk(KERN_ERR "FIMG2D failed to ioremap for SFR\n"); ret = -ENOENT; goto err_map; } fimg2d_debug("device name: %s base address: 0x%lx\n", pdev->name, (unsigned long)res->start); /* irq */ info->irq = platform_get_irq(pdev, 0); if (!info->irq) { printk(KERN_ERR "FIMG2D failed to get irq resource\n"); ret = -ENOENT; goto err_map; } fimg2d_debug("irq: %d\n", info->irq); ret = request_irq(info->irq, fimg2d_irq, IRQF_DISABLED, pdev->name, info); if (ret) { printk(KERN_ERR "FIMG2D failed to request irq\n"); ret = -ENOENT; goto err_irq; } ret = fimg2d_clk_setup(info); if (ret) { printk(KERN_ERR "FIMG2D failed to setup clk\n"); ret = -ENOENT; goto err_clk; } #ifdef CONFIG_PM_RUNTIME pm_runtime_enable(info->dev); fimg2d_debug("enable runtime pm\n"); #endif #ifdef CONFIG_BUSFREQ_OPP #if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) /* To lock bus frequency in OPP mode */ info->bus_dev = dev_get("exynos-busfreq"); #endif #endif s5p_sysmmu_set_fault_handler(info->dev, fimg2d_sysmmu_fault_handler); fimg2d_debug("register sysmmu page fault handler\n"); /* misc register */ ret = misc_register(&fimg2d_dev); if (ret) { printk(KERN_ERR "FIMG2D failed to register misc driver\n"); goto err_reg; } printk(KERN_INFO "Samsung Graphics 2D driver, (c) 2011 Samsung Electronics\n"); return 0; err_reg: fimg2d_clk_release(info); err_clk: free_irq(info->irq, NULL); err_irq: iounmap(info->regs); err_map: kfree(info->mem); err_region: release_resource(info->mem); err_res: destroy_workqueue(info->work_q); err_setup: kfree(info); err_plat: return ret; }
static int htc_headset_mgr_probe(struct platform_device *pdev) { int ret; struct htc_headset_mgr_platform_data *pdata = pdev->dev.platform_data; HS_LOG("++++++++++++++++++++"); hi = kzalloc(sizeof(struct htc_headset_mgr_info), GFP_KERNEL); if (!hi) return -ENOMEM; hi->pdata.driver_flag = pdata->driver_flag; hi->pdata.headset_devices_num = pdata->headset_devices_num; hi->pdata.headset_devices = pdata->headset_devices; hi->driver_init_seq = 0; wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME); hi->hpin_jiffies = jiffies; hi->usb_headset.type = USB_NO_HEADSET; hi->usb_headset.status = STATUS_DISCONNECTED; hi->ext_35mm_status = HTC_35MM_UNPLUG; hi->h2w_35mm_status = HTC_35MM_UNPLUG; hi->is_ext_insert = 0; hi->mic_bias_state = 0; hi->mic_detect_counter = 0; hi->key_level_flag = -1; atomic_set(&hi->btn_state, 0); hi->tty_enable_flag = 0; hi->fm_flag = 0; hi->debug_flag = 0; mutex_init(&hi->mutex_lock); hi->sdev.name = "h2w"; hi->sdev.print_name = h2w_print_name; ret = switch_dev_register(&hi->sdev); if (ret < 0) goto err_switch_dev_register; detect_wq = create_workqueue("detect"); if (detect_wq == NULL) { ret = -ENOMEM; HS_ERR("Failed to create detect workqueue"); goto err_create_detect_work_queue; } button_wq = create_workqueue("button"); if (button_wq == NULL) { ret = -ENOMEM; HS_ERR("Failed to create button workqueue"); goto err_create_button_work_queue; } hi->input = input_allocate_device(); if (!hi->input) { ret = -ENOMEM; goto err_request_input_dev; } hi->input->name = "h2w headset"; set_bit(EV_SYN, hi->input->evbit); set_bit(EV_KEY, hi->input->evbit); set_bit(KEY_END, hi->input->keybit); set_bit(KEY_MUTE, hi->input->keybit); set_bit(KEY_VOLUMEDOWN, hi->input->keybit); set_bit(KEY_VOLUMEUP, hi->input->keybit); set_bit(KEY_NEXTSONG, hi->input->keybit); set_bit(KEY_PLAYPAUSE, hi->input->keybit); set_bit(KEY_PREVIOUSSONG, hi->input->keybit); set_bit(KEY_MEDIA, hi->input->keybit); set_bit(KEY_SEND, hi->input->keybit); ret = input_register_device(hi->input); if (ret < 0) goto err_register_input_dev; ret = register_attributes(); if (ret) goto err_register_attributes; if (hi->pdata.driver_flag & DRIVER_HS_MGR_RPC_SERVER) { /* Create RPC server */ ret = msm_rpc_create_server(&hs_rpc_server); if (ret < 0) { HS_ERR("Failed to create RPC server"); goto err_create_rpc_server; } HS_LOG("Create RPC server successfully"); } hs_notify_driver_ready(DRIVER_NAME); HS_LOG("--------------------"); return 0; err_create_rpc_server: err_register_attributes: input_unregister_device(hi->input); err_register_input_dev: input_free_device(hi->input); err_request_input_dev: destroy_workqueue(button_wq); err_create_button_work_queue: destroy_workqueue(detect_wq); err_create_detect_work_queue: switch_dev_unregister(&hi->sdev); err_switch_dev_register: mutex_destroy(&hi->mutex_lock); wake_lock_destroy(&hi->hs_wake_lock); kfree(hi); HS_ERR("Failed to register %s driver", DRIVER_NAME); return ret; }
void mlx5_health_cleanup(struct mlx5_core_dev *dev) { struct mlx5_core_health *health = &dev->priv.health; destroy_workqueue(health->wq); }
static void ksuspend_usb_cleanup(void) { destroy_workqueue(ksuspend_usb_wq); }
static void __exit bridge_exit(void) { data_bridge_debugfs_exit(); destroy_workqueue(bridge_wq); usb_deregister(&bridge_driver); }
static int __init bridge_init(void) { struct data_bridge *dev; int ret; int i = 0; ret = ctrl_bridge_init(); if (ret) return ret; bridge_wq = create_singlethread_workqueue("mdm_bridge"); if (!bridge_wq) { pr_err("%s: Unable to create workqueue:bridge\n", __func__); ret = -ENOMEM; goto free_ctrl; } for (i = 0; i < MAX_BRIDGE_DEVICES; i++) { dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { err("%s: unable to allocate dev\n", __func__); ret = -ENOMEM; goto error; } dev->wq = bridge_wq; init_usb_anchor(&dev->tx_active); init_usb_anchor(&dev->rx_active); INIT_LIST_HEAD(&dev->rx_idle); skb_queue_head_init(&dev->rx_done); INIT_WORK(&dev->kevent, defer_kevent); INIT_WORK(&dev->process_rx_w, data_bridge_process_rx); __dev[i] = dev; } ret = usb_register(&bridge_driver); if (ret) { err("%s: unable to register mdm_bridge driver", __func__); goto error; } data_bridge_debugfs_init(); return 0; error: while (--i >= 0) { kfree(__dev[i]); __dev[i] = NULL; } destroy_workqueue(bridge_wq); free_ctrl: ctrl_bridge_exit(); return ret; }
static int __devinit therm_est_probe(struct platform_device *pdev) { int i; struct therm_estimator *est; struct therm_est_data *data; est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL); if (IS_ERR_OR_NULL(est)) return -ENOMEM; platform_set_drvdata(pdev, est); data = therm_est_get_pdata(&pdev->dev); est->devs = data->devs; est->ndevs = data->ndevs; est->toffset = data->toffset; est->polling_period = data->polling_period; est->tc1 = data->tc1; est->tc2 = data->tc2; est->cur_temp = DEFAULT_TEMP; est->ntemp = HIST_UNINIT; /* initialize timer trips */ est->num_timer_trips = data->num_timer_trips; est->timer_trips = data->timer_trips; therm_est_init_timer_trips(est); mutex_init(&est->timer_trip_lock); INIT_DELAYED_WORK(&est->timer_trip_work, therm_est_timer_trip_work_func); est->workqueue = alloc_workqueue(dev_name(&pdev->dev), WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1); if (!est->workqueue) goto err; INIT_DELAYED_WORK(&est->therm_est_work, therm_est_work_func); queue_delayed_work(est->workqueue, &est->therm_est_work, msecs_to_jiffies(est->polling_period)); est->num_trips = data->num_trips; est->trips = data->trips; est->tzp = data->tzp; est->thz = thermal_zone_device_register(dev_name(&pdev->dev), est->num_trips, (1 << est->num_trips) - 1, est, &therm_est_ops, est->tzp, data->passive_delay, 0); if (IS_ERR_OR_NULL(est->thz)) goto err; for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++) device_create_file(&pdev->dev, &therm_est_nodes[i].dev_attr); #ifdef CONFIG_PM est->pm_nb.notifier_call = therm_est_pm_notify, register_pm_notifier(&est->pm_nb); #endif return 0; err: cancel_delayed_work_sync(&est->therm_est_work); if (est->workqueue) destroy_workqueue(est->workqueue); kfree(est); return -EINVAL; }
static __devinit int sec_battery_probe(struct platform_device *pdev) { struct sec_battery_platform_data *pdata = pdev->dev.platform_data; struct chg_data *chg; int ret = 0; pr_info("%s : Samsung Battery Driver Loading\n", __func__); chg = kzalloc(sizeof(*chg), GFP_KERNEL); if (!chg) return -ENOMEM; chg->pdata = pdata; if (!chg->pdata || !chg->pdata->adc_table) { pr_err("%s : No platform data & adc_table supplied\n", __func__); ret = -EINVAL; goto err_bat_table; } chg->psy_bat.name = "battery", chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY, chg->psy_bat.properties = sec_battery_props, chg->psy_bat.num_properties = ARRAY_SIZE(sec_battery_props), chg->psy_bat.get_property = sec_bat_get_property, chg->psy_usb.name = "usb", chg->psy_usb.type = POWER_SUPPLY_TYPE_USB, chg->psy_usb.supplied_to = supply_list, chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list), chg->psy_usb.properties = sec_power_properties, chg->psy_usb.num_properties = ARRAY_SIZE(sec_power_properties), chg->psy_usb.get_property = sec_usb_get_property, chg->psy_ac.name = "ac", chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS, chg->psy_ac.supplied_to = supply_list, chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list), chg->psy_ac.properties = sec_power_properties, chg->psy_ac.num_properties = ARRAY_SIZE(sec_power_properties), chg->psy_ac.get_property = sec_ac_get_property, chg->present = 1; chg->polling_interval = POLLING_INTERVAL; chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD; chg->bat_info.batt_is_full = false; chg->set_charge_timeout = false; chg->bat_info.batt_improper_ta = false; chg->is_recharging = false; #ifdef CONFIG_BATTERY_MAX17042 // Get battery type from fuelgauge driver. if(chg->pdata && chg->pdata->fuelgauge_cb) chg->battery_type = (battery_type_t)chg->pdata->fuelgauge_cb( REQ_TEST_MODE_INTERFACE, TEST_MODE_BATTERY_TYPE_CHECK, 0); // Check UV charging case. if(chg->pdata && chg->pdata->pmic_charger && chg->pdata->pmic_charger->get_connection_status) { if(chg->pdata->pmic_charger->get_connection_status() && check_UV_charging_case(chg)) chg->low_batt_boot_flag = true; } else chg->low_batt_boot_flag = false; // init delayed work INIT_DELAYED_WORK(&chg->full_chg_work, full_comp_work_handler); // Init low batt check threshold values. if(chg->battery_type == SDI_BATTERY_TYPE) chg->check_start_vol = 3550; // Under 3.55V else if(chg->battery_type == ATL_BATTERY_TYPE) chg->check_start_vol = 3450; // Under 3.45V #endif chg->cable_status = CABLE_TYPE_NONE; chg->charging_status = CHARGING_STATUS_NONE; mutex_init(&chg->mutex); platform_set_drvdata(pdev, chg); wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present"); wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND, "sec_battery_work"); INIT_WORK(&chg->bat_work, sec_bat_work); chg->monitor_wqueue = create_freezeable_workqueue(dev_name(&pdev->dev)); if (!chg->monitor_wqueue) { pr_err("Failed to create freezeable workqueue\n"); ret = -ENOMEM; goto err_wake_lock; } chg->last_poll = alarm_get_elapsed_realtime(); alarm_init(&chg->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, sec_battery_alarm); /* init power supplier framework */ ret = power_supply_register(&pdev->dev, &chg->psy_bat); if (ret) { pr_err("Failed to register power supply psy_bat\n"); goto err_wqueue; } ret = power_supply_register(&pdev->dev, &chg->psy_usb); if (ret) { pr_err("Failed to register power supply psy_usb\n"); goto err_supply_unreg_bat; } ret = power_supply_register(&pdev->dev, &chg->psy_ac); if (ret) { pr_err("Failed to register power supply psy_ac\n"); goto err_supply_unreg_usb; } sec_bat_create_attrs(chg->psy_bat.dev); chg->callbacks.set_cable = sec_bat_set_cable; chg->callbacks.set_status = sec_bat_set_status; chg->callbacks.force_update = sec_bat_force_update; if (chg->pdata->register_callbacks) chg->pdata->register_callbacks(&chg->callbacks); wake_lock(&chg->work_wake_lock); queue_work(chg->monitor_wqueue, &chg->bat_work); p1_lpm_mode_check(chg); return 0; err_supply_unreg_ac: power_supply_unregister(&chg->psy_ac); err_supply_unreg_usb: power_supply_unregister(&chg->psy_usb); err_supply_unreg_bat: power_supply_unregister(&chg->psy_bat); err_wqueue: destroy_workqueue(chg->monitor_wqueue); cancel_work_sync(&chg->bat_work); alarm_cancel(&chg->alarm); err_wake_lock: wake_lock_destroy(&chg->work_wake_lock); wake_lock_destroy(&chg->vbus_wake_lock); mutex_destroy(&chg->mutex); err_bat_table: kfree(chg); return ret; }
static void ks7010_sdio_remove(struct sdio_func *func) { int ret; struct ks_sdio_card *card; struct ks_wlan_private *priv; struct net_device *netdev; DPRINTK(1, "ks7010_sdio_remove()\n"); card = sdio_get_drvdata(func); if (card == NULL) return; DPRINTK(1, "priv = card->priv\n"); priv = card->priv; netdev = priv->net_dev; if (priv) { ks_wlan_net_stop(netdev); DPRINTK(1, "ks_wlan_net_stop\n"); /* interrupt disable */ sdio_claim_host(func); sdio_writeb(func, 0, INT_ENABLE, &ret); sdio_writeb(func, 0xff, INT_PENDING, &ret); sdio_release_host(func); DPRINTK(1, "interrupt disable\n"); /* send stop request to MAC */ { struct hostif_stop_request_t *pp; pp = (struct hostif_stop_request_t *) kzalloc(hif_align_size(sizeof(*pp)), GFP_KERNEL); if (pp == NULL) { DPRINTK(3, "allocate memory failed..\n"); return; /* to do goto ni suru */ } pp->header.size = cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size))); pp->header.event = cpu_to_le16((uint16_t) HIF_STOP_REQ); sdio_claim_host(func); write_to_device(priv, (unsigned char *)pp, hif_align_size(sizeof(*pp))); sdio_release_host(func); kfree(pp); } DPRINTK(1, "STOP Req\n"); if (priv->ks_wlan_hw.ks7010sdio_wq) { flush_workqueue(priv->ks_wlan_hw.ks7010sdio_wq); destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq); } DPRINTK(1, "destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);\n"); hostif_exit(priv); DPRINTK(1, "hostif_exit\n"); unregister_netdev(netdev); trx_device_exit(priv); if (priv->ks_wlan_hw.read_buf) { kfree(priv->ks_wlan_hw.read_buf); } free_netdev(priv->net_dev); card->priv = NULL; } sdio_claim_host(func); sdio_release_irq(func); DPRINTK(1, "sdio_release_irq()\n"); sdio_disable_func(func); DPRINTK(1, "sdio_disable_func()\n"); sdio_release_host(func); sdio_set_drvdata(func, NULL); kfree(card); DPRINTK(1, "kfree()\n"); DPRINTK(5, " Bye !!\n"); return; }
static int __init mt7697spi_init(void) { char str[32]; struct spi_master *master = NULL; struct device *dev; struct spi_device *spi; struct mt7697q_info *qinfo = NULL; int bus_num = MT7697_SPI_BUS_NUM; int ret = 0; pr_info(DRVNAME" %s(): '%s' initialize\n", __func__, DRVNAME); while (!master && (bus_num >= 0)) { master = spi_busnum_to_master(bus_num); if (!master) bus_num--; } if (!master) { pr_err(DRVNAME" spi_busnum_to_master() failed\n"); ret = -EINVAL; goto cleanup; } ret = cp2130_update_ch_config(master, MT7697_SPI_CONFIG); if (ret < 0) { dev_err(&master->dev, "%s(): cp2130_update_ch_config() failed(%d)\n", __func__, ret); goto cleanup; } snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), MT7697_SPI_CS); dev_info(&master->dev, "%s(): find SPI device('%s')\n", __func__, str); dev = bus_find_device_by_name(&spi_bus_type, NULL, str); if (!dev) { dev_err(&master->dev, "%s(): bus_find_device_by_name('%s') failed\n", __func__, str); ret = -EINVAL; goto cleanup; } spi = to_spi_device(dev); if (!spi) { dev_err(&master->dev, "%s(): get SPI device failed\n", __func__); ret = -EINVAL; goto cleanup; } dev_info(&master->dev, "%s(): dev('%s') mode(%d) max speed(%d) " "CS(%d) bits/word(%d)\n", __func__, spi->modalias, spi->mode, spi->max_speed_hz, spi->chip_select, spi->bits_per_word); qinfo = kzalloc(sizeof(struct mt7697q_info), GFP_KERNEL); if (!qinfo) { dev_err(&master->dev, "%s(): create queue info failed\n", __func__); ret = -ENOMEM; goto cleanup; } qinfo->dev = &spi->dev; qinfo->hw_priv = spi; qinfo->hw_ops = &hw_ops; mutex_init(&qinfo->mutex); INIT_DELAYED_WORK(&qinfo->irq_delayed_work, mt7697q_irq_delayed_work); INIT_WORK(&qinfo->irq_work, mt7697q_irq_work); qinfo->irq_workq = alloc_workqueue(DRVNAME"wq", WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); if (!qinfo->irq_workq) { dev_err(qinfo->dev, "%s(): alloc_workqueue() failed\n", __func__); ret = -ENOMEM; goto cleanup; } qinfo->gpio_pin = MT7697_SPI_INTR_GPIO_PIN; ret = gpio_request(qinfo->gpio_pin, MT7697_SPI_GPIO_IRQ_NAME); if (ret < 0) { if (ret != -EBUSY) { dev_err(qinfo->dev, "%s(): gpio_request() failed(%d)", __func__, ret); goto failed_workqueue; } qinfo->irq = gpio_to_irq(qinfo->gpio_pin); qinfo->gpio_pin = MT7697_SPI_INTR_GPIO_PIN_INVALID; } else { gpio_direction_input(qinfo->gpio_pin); qinfo->irq = gpio_to_irq(qinfo->gpio_pin); } dev_info(qinfo->dev, "%s(): request irq(%d)\n", __func__, qinfo->irq); ret = request_irq(qinfo->irq, mt7697q_isr, 0, DRVNAME, qinfo); if (ret < 0) { dev_err(qinfo->dev, "%s(): request_irq() failed(%d)", __func__, ret); goto failed_gpio_req; } irq_set_irq_type(qinfo->irq, IRQ_TYPE_EDGE_BOTH); spi_set_drvdata(spi, qinfo); dev_info(qinfo->dev, "%s(): '%s' initialized\n", __func__, DRVNAME); return 0; failed_gpio_req: if (qinfo->gpio_pin > 0) gpio_free(qinfo->gpio_pin); failed_workqueue: destroy_workqueue(qinfo->irq_workq); cleanup: if (qinfo) kfree(qinfo); return ret; }