/** * irq_sim_init - Initialize the interrupt simulator: allocate a range of * dummy interrupts. * * @sim: The interrupt simulator object to initialize. * @num_irqs: Number of interrupts to allocate * * Returns 0 on success and a negative error number on failure. */ int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs) { int i; sim->irqs = kmalloc_array(num_irqs, sizeof(*sim->irqs), GFP_KERNEL); if (!sim->irqs) return -ENOMEM; sim->irq_base = irq_alloc_descs(-1, 0, num_irqs, 0); if (sim->irq_base < 0) { kfree(sim->irqs); return sim->irq_base; } for (i = 0; i < num_irqs; i++) { sim->irqs[i].irqnum = sim->irq_base + i; sim->irqs[i].enabled = false; irq_set_chip(sim->irq_base + i, &irq_sim_irqchip); irq_set_chip_data(sim->irq_base + i, &sim->irqs[i]); irq_set_handler(sim->irq_base + i, &handle_simple_irq); irq_modify_status(sim->irq_base + i, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); } init_irq_work(&sim->work_ctx.work, irq_sim_handle_irq); sim->irq_count = num_irqs; return 0; }
static int iio_sysfs_trigger_probe(int id) { struct iio_sysfs_trig *t; int ret; bool foundit = false; mutex_lock(&iio_sysfs_trig_list_mut); list_for_each_entry(t, &iio_sysfs_trig_list, l) if (id == t->id) { foundit = true; break; } if (foundit) { ret = -EINVAL; goto out1; } t = kmalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) { ret = -ENOMEM; goto out1; } t->id = id; t->trig = iio_trigger_alloc("sysfstrig%d", id); if (!t->trig) { ret = -ENOMEM; goto free_t; } t->trig->dev.groups = iio_sysfs_trigger_attr_groups; t->trig->ops = &iio_sysfs_trigger_ops; t->trig->dev.parent = &iio_sysfs_trig_dev; iio_trigger_set_drvdata(t->trig, t); init_irq_work(&t->work, iio_sysfs_trigger_work); ret = iio_trigger_register(t->trig); if (ret) goto out2; list_add(&t->l, &iio_sysfs_trig_list); __module_get(THIS_MODULE); mutex_unlock(&iio_sysfs_trig_list_mut); return 0; out2: iio_trigger_put(t->trig); free_t: kfree(t); out1: mutex_unlock(&iio_sysfs_trig_list_mut); return ret; }
/** * iio_simple_dummy_events_register() - setup interrupt handling for events * @indio_dev: device instance data * * Normally the irq is a hardware interrupt and the number comes * from board configuration files. Here we get it from a companion * module that fakes the interrupt for us. Note that module in * no way forms part of this example. Just assume that events magically * appear via the provided interrupt. */ int iio_simple_dummy_events_register(struct iio_dev *indio_dev) { struct iio_dummy_state *st = iio_priv(indio_dev); /* attach registers from evgen driver */ st->regs = iio_dummy_evgen_get_regs(); st->regs->src_dev = indio_dev; if (!st->regs) return -EPERM; init_irq_work(&st->work, iio_simple_dummy_event_handler); return 0; }
static int init_rootdomain(struct root_domain *rd) { if (!zalloc_cpumask_var(&rd->span, GFP_KERNEL)) goto out; if (!zalloc_cpumask_var(&rd->online, GFP_KERNEL)) goto free_span; if (!zalloc_cpumask_var(&rd->dlo_mask, GFP_KERNEL)) goto free_online; if (!zalloc_cpumask_var(&rd->rto_mask, GFP_KERNEL)) goto free_dlo_mask; #ifdef HAVE_RT_PUSH_IPI rd->rto_cpu = -1; raw_spin_lock_init(&rd->rto_lock); init_irq_work(&rd->rto_push_work, rto_push_irq_work_func); #endif init_dl_bw(&rd->dl_bw); if (cpudl_init(&rd->cpudl) != 0) goto free_rto_mask; if (cpupri_init(&rd->cpupri) != 0) goto free_cpudl; return 0; free_cpudl: cpudl_cleanup(&rd->cpudl); free_rto_mask: free_cpumask_var(rd->rto_mask); free_dlo_mask: free_cpumask_var(rd->dlo_mask); free_online: free_cpumask_var(rd->online); free_span: free_cpumask_var(rd->span); out: return -ENOMEM; }
static int yas_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct yas_state *st; struct iio_dev *indio_dev; int ret, i; s8 *bias; struct yas_acc_platform_data *pdata; I("%s\n", __func__); this_client = i2c; indio_dev = iio_device_alloc(sizeof(*st)); if (!indio_dev) { ret = -ENOMEM; goto error_ret; } i2c_set_clientdata(i2c, indio_dev); indio_dev->name = id->name; indio_dev->dev.parent = &i2c->dev; indio_dev->info = &yas_info; indio_dev->channels = yas_channels; indio_dev->num_channels = ARRAY_SIZE(yas_channels); indio_dev->modes = INDIO_DIRECT_MODE; st = iio_priv(indio_dev); st->client = i2c; st->sampling_frequency = 20; st->acc.callback.device_open = yas_device_open; st->acc.callback.device_close = yas_device_close; st->acc.callback.device_read = yas_device_read; st->acc.callback.device_write = yas_device_write; st->acc.callback.usleep = yas_usleep; st->acc.callback.current_time = yas_current_time; st->indio_dev = indio_dev; INIT_DELAYED_WORK(&st->work, yas_work_func); INIT_WORK(&st->resume_work, yas_resume_work_func); mutex_init(&st->lock); #ifdef CONFIG_HAS_EARLYSUSPEND st->sus.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; st->sus.suspend = yas_early_suspend; st->sus.resume = yas_late_resume; register_early_suspend(&st->sus); #endif ret = yas_probe_buffer(indio_dev); if (ret) goto error_free_dev; ret = yas_probe_trigger(indio_dev); if (ret) goto error_remove_buffer; ret = iio_device_register(indio_dev); if (ret) goto error_remove_trigger; ret = yas_acc_driver_init(&st->acc); if (ret < 0) { ret = -EFAULT; goto error_unregister_iio; } ret = st->acc.init(); if (ret < 0) { ret = -EFAULT; goto error_unregister_iio; } ret = st->acc.set_enable(1); if (ret < 0) { ret = -EFAULT; goto error_driver_term; } pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (pdata == NULL) E("%s: memory allocation for pdata failed.", __func__); else yas_parse_dt(&i2c->dev, pdata); for (i = 0; i < 3; i++) { st->accel_data[i] = 0; bias = (s8 *)&pdata->gs_kvalue; st->calib_bias[i] = -(bias[2-i] * YAS_GRAVITY_EARTH / 256); I("%s: calib_bias[%d] = %d\n", __func__, i, st->calib_bias[i]); } mutex_lock(&st->lock); if ((pdata->placement < 8) && (pdata->placement >= 0)) { ret = st->acc.set_position(pdata->placement); I("%s: set position = %d\n", __func__, pdata->placement); } else { ret = st->acc.set_position(5); D("%s: set default position = 5\n", __func__); } mutex_unlock(&st->lock); #ifdef CONFIG_CIR_ALWAYS_READY module.IRQ = pdata->intr; I("%s: IRQ = %d\n", __func__, module.IRQ); ret = request_irq(module.IRQ, kxtj2_irq_handler, IRQF_TRIGGER_RISING, "kxtj2", &module); enable_irq_wake(module.IRQ); if (ret) E("%s: Could not request irq = %d\n", __func__, module.IRQ); module.kxtj2_wq = create_singlethread_workqueue("kxtj2_wq"); if (!module.kxtj2_wq) { E("%s: Can't create workqueue\n", __func__); ret = -ENOMEM; goto error_create_singlethread_workqueue; } #endif init_irq_work(&st->iio_irq_work, iio_trigger_work); g_st = st; ret = create_sysfs_interfaces(st); if (ret) { E("%s: create_sysfs_interfaces fail, ret = %d\n", __func__, ret); goto err_create_fixed_sysfs; } I("%s: Successfully probe\n", __func__); return 0; err_create_fixed_sysfs: #ifdef CONFIG_CIR_ALWAYS_READY if (module.kxtj2_wq) destroy_workqueue(module.kxtj2_wq); error_create_singlethread_workqueue: #endif kfree(pdata); error_driver_term: st->acc.term(); error_unregister_iio: iio_device_unregister(indio_dev); error_remove_trigger: yas_remove_trigger(indio_dev); error_remove_buffer: yas_remove_buffer(indio_dev); error_free_dev: #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&st->sus); #endif iio_device_free(indio_dev); error_ret: i2c_set_clientdata(i2c, NULL); this_client = NULL; return ret; }
static int yas_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct yas_state *st; struct iio_dev *indio_dev; int ret, i; struct yas_acc_platform_data *pdata; this_client = i2c; printk("%s: yas_kionix_accel_probe start ---\n", __FUNCTION__); indio_dev = iio_device_alloc(sizeof(*st)); if (!indio_dev) { ret = -ENOMEM; goto error_ret; } i2c_set_clientdata(i2c, indio_dev); indio_dev->name = id->name; indio_dev->dev.parent = &i2c->dev; indio_dev->info = &yas_info; indio_dev->channels = yas_channels; indio_dev->num_channels = ARRAY_SIZE(yas_channels); indio_dev->modes = INDIO_DIRECT_MODE; st = iio_priv(indio_dev); st->client = i2c; st->sampling_frequency = 20; st->acc.callback.device_open = yas_device_open; st->acc.callback.device_close = yas_device_close; st->acc.callback.device_read = yas_device_read; st->acc.callback.device_write = yas_device_write; st->acc.callback.usleep = yas_usleep; st->acc.callback.current_time = yas_current_time; st->indio_dev = indio_dev; INIT_DELAYED_WORK(&st->work, yas_work_func); mutex_init(&st->lock); #ifdef CONFIG_HAS_EARLYSUSPEND st->sus.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; st->sus.suspend = yas_early_suspend; st->sus.resume = yas_late_resume; register_early_suspend(&st->sus); #endif for (i = 0; i < 3; i++) { st->compass_data[i] = 0; st->calib_bias[i] = 0; } ret = yas_probe_buffer(indio_dev); if (ret) goto error_free_dev; ret = yas_probe_trigger(indio_dev); if (ret) goto error_remove_buffer; ret = iio_device_register(indio_dev); if (ret) goto error_remove_trigger; ret = yas_acc_driver_init(&st->acc); if (ret < 0) { ret = -EFAULT; goto error_unregister_iio; } ret = st->acc.init(); if (ret < 0) { ret = -EFAULT; goto error_unregister_iio; } ret = st->acc.set_enable(1); if (ret < 0) { ret = -EFAULT; goto error_driver_term; } init_irq_work(&st->iio_irq_work, iio_trigger_work); g_st = st; ret = create_sysfs_interfaces(st); if (ret) { printk(KERN_ERR"%s: create_sysfs_interfaces fail, ret = %d\n", __func__, ret); goto err_create_fixed_sysfs; } return 0; err_create_fixed_sysfs: kfree(pdata); error_driver_term: st->acc.term(); error_unregister_iio: iio_device_unregister(indio_dev); error_remove_trigger: yas_remove_trigger(indio_dev); error_remove_buffer: yas_remove_buffer(indio_dev); error_free_dev: #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&st->sus); #endif iio_device_free(indio_dev); error_ret: i2c_set_clientdata(i2c, NULL); this_client = NULL; return ret; }