static int em28xx_dvb_init(struct em28xx *dev) { int result = 0, mfe_shared = 0; struct em28xx_dvb *dvb; if (!dev->board.has_dvb) { /* This device does not support the extension */ printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n"); return 0; } dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { em28xx_info("em28xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; dvb->fe[0] = dvb->fe[1] = NULL; mutex_lock(&dev->lock); em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); /* init frontend */ switch (dev->model) { case EM2874_BOARD_LEADERSHIP_ISDBT: dvb->fe[0] = dvb_attach(s921_attach, &sharp_isdbt, &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; } break; case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->fe[0] = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_KWORLD_DVB_310U: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_with_xc3028, &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2882_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_EMPIRE_DUAL_TV: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: case EM2881_BOARD_PINNACLE_HYBRID_PRO: case EM2882_BOARD_DIKOM_DK300: case EM2882_BOARD_KWORLD_VS_DVBT: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] == NULL) { /* This board could have either a zl10353 or a mt352. If the chip id isn't for zl10353, try mt352 */ dvb->fe[0] = dvb_attach(mt352_attach, &terratec_xs_mt352_cfg, &dev->i2c_adap[dev->def_i2c_bus]); } if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2870_BOARD_KWORLD_355U: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_no_i2c_gate_dev, &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] != NULL) dvb_attach(qt1010_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], &em28xx_qt1010_config); break; case EM2883_BOARD_KWORLD_HYBRID_330U: case EM2882_BOARD_EVGA_INDTUBE: dvb->fe[0] = dvb_attach(s5h1409_attach, &em28xx_s5h1409_with_xc3028, &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2882_BOARD_KWORLD_ATSC_315U: dvb->fe[0] = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] != NULL) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x61, TUNER_THOMSON_DTT761X)) { result = -EINVAL; goto out_free; } } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E: dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL, &dev->i2c_adap[dev->def_i2c_bus], &dev->udev->dev); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2870_BOARD_REDDO_DVB_C_USB_BOX: /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ dvb->fe[0] = dvb_attach(tda10023_attach, &em28xx_tda10023_config, &dev->i2c_adap[dev->def_i2c_bus], 0x48); if (dvb->fe[0]) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x60, TUNER_PHILIPS_CU1216L)) { result = -EINVAL; goto out_free; } } break; case EM2870_BOARD_KWORLD_A340: dvb->fe[0] = dvb_attach(lgdt3305_attach, &em2870_lgdt3304_dev, &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] != NULL) dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap[dev->def_i2c_bus], &kworld_a340_config); break; case EM28174_BOARD_PCTV_290E: /* set default GPIO0 for LNA, used if GPIOLIB is undefined */ dvb->lna_gpio = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L; dvb->fe[0] = dvb_attach(cxd2820r_attach, &em28xx_cxd2820r_config, &dev->i2c_adap[dev->def_i2c_bus], &dvb->lna_gpio); if (dvb->fe[0]) { /* FE 0 attach tuner */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { dvb_frontend_detach(dvb->fe[0]); result = -EINVAL; goto out_free; } #ifdef CONFIG_GPIOLIB /* enable LNA for DVB-T, DVB-T2 and DVB-C */ result = gpio_request_one(dvb->lna_gpio, GPIOF_OUT_INIT_LOW, NULL); if (result) em28xx_errdev("gpio request failed %d\n", result); else gpio_free(dvb->lna_gpio); result = 0; /* continue even set LNA fails */ #endif dvb->fe[0]->ops.set_lna = em28xx_pctv_290e_set_lna; } break; case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: { struct xc5000_config cfg; hauppauge_hvr930c_init(dev); dvb->fe[0] = dvb_attach(drxk_attach, &hauppauge_930c_drxk, &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; } /* FIXME: do we need a pll semaphore? */ dvb->fe[0]->sec_priv = dvb; sema_init(&dvb->pll_mutex, 1); dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; /* Attach xc5000 */ memset(&cfg, 0, sizeof(cfg)); cfg.i2c_address = 0x61; cfg.if_khz = 4000; if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], &cfg)) { result = -EINVAL; goto out_free; } if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); break; } case EM2884_BOARD_TERRATEC_H5: terratec_h5_init(dev); dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; } /* FIXME: do we need a pll semaphore? */ dvb->fe[0]->sec_priv = dvb; sema_init(&dvb->pll_mutex, 1); dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; /* Attach tda18271 to DVB-C frontend */ if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { result = -EINVAL; goto out_free; } if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); break; case EM2884_BOARD_C3TECH_DIGITAL_DUO: dvb->fe[0] = dvb_attach(mb86a20s_attach, &c3tech_duo_mb86a20s_config, &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] != NULL) dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap[dev->def_i2c_bus], &c3tech_duo_tda18271_config); break; case EM28174_BOARD_PCTV_460E: /* attach demod */ dvb->fe[0] = dvb_attach(tda10071_attach, &em28xx_tda10071_config, &dev->i2c_adap[dev->def_i2c_bus]); /* attach SEC */ if (dvb->fe[0]) dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], &em28xx_a8293_config); break; case EM2874_BOARD_DELOCK_61959: case EM2874_BOARD_MAXMEDIA_UB425_TC: /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk, &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) { /* disable I2C-gate */ dvb->fe[0]->ops.i2c_gate_ctrl = NULL; /* attach tuner */ if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { dvb_frontend_detach(dvb->fe[0]); result = -EINVAL; goto out_free; } } /* TODO: we need drx-3913k firmware in order to support DVB-T */ em28xx_info("MaxMedia UB425-TC/Delock 61959: only DVB-C " \ "supported by that driver version\n"); break; case EM2884_BOARD_PCTV_510E: case EM2884_BOARD_PCTV_520E: pctv_520e_init(dev); /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk, &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) { /* attach tuner */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { dvb_frontend_detach(dvb->fe[0]); result = -EINVAL; goto out_free; } } break; case EM2884_BOARD_CINERGY_HTC_STICK: terratec_htc_stick_init(dev); /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk, &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; } /* Attach the demodulator. */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { result = -EINVAL; goto out_free; } break; case EM2884_BOARD_TERRATEC_HTC_USB_XS: terratec_htc_usb_xs_init(dev); /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk, &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; } /* Attach the demodulator. */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { result = -EINVAL; goto out_free; } break; default: em28xx_errdev("/2: The frontend of your DVB/ATSC card" " isn't supported yet\n"); break; } if (NULL == dvb->fe[0]) { em28xx_errdev("/2: frontend initialization failed\n"); result = -EINVAL; goto out_free; } /* define general-purpose callback pointer */ dvb->fe[0]->callback = em28xx_tuner_callback; if (dvb->fe[1]) dvb->fe[1]->callback = em28xx_tuner_callback; /* register everything */ result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); if (result < 0) goto out_free; /* MFE lock */ dvb->adapter.mfe_shared = mfe_shared; em28xx_info("Successfully loaded em28xx-dvb\n"); ret: em28xx_set_mode(dev, EM28XX_SUSPEND); mutex_unlock(&dev->lock); return result; out_free: kfree(dvb); dev->dvb = NULL; goto ret; }
/* * returns 1 if valid, 0 otherwise. */ int unionfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) { int valid = 1; /* default is valid (1); invalid is 0. */ struct dentry *hidden_dentry; int bindex, bstart, bend; int sbgen, dgen; int positive = 0; int locked = 0; int restart = 0; int interpose_flag; struct nameidata lowernd; /* TODO: be gentler to the stack */ if (nd) memcpy(&lowernd, nd, sizeof(struct nameidata)); else memset(&lowernd, 0, sizeof(struct nameidata)); restart: verify_locked(dentry); /* if the dentry is unhashed, do NOT revalidate */ if (d_deleted(dentry)) { printk(KERN_DEBUG "unhashed dentry being revalidated: %*s\n", dentry->d_name.len, dentry->d_name.name); goto out; } BUG_ON(dbstart(dentry) == -1); if (dentry->d_inode) positive = 1; dgen = atomic_read(&UNIONFS_D(dentry)->generation); sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation); /* If we are working on an unconnected dentry, then there is no * revalidation to be done, because this file does not exist within the * namespace, and Unionfs operates on the namespace, not data. */ if (sbgen != dgen) { struct dentry *result; int pdgen; unionfs_read_lock(dentry->d_sb); locked = 1; /* The root entry should always be valid */ BUG_ON(IS_ROOT(dentry)); /* We can't work correctly if our parent isn't valid. */ pdgen = atomic_read(&UNIONFS_D(dentry->d_parent)->generation); if (!restart && (pdgen != sbgen)) { unionfs_read_unlock(dentry->d_sb); locked = 0; /* We must be locked before our parent. */ if (! (dentry->d_parent->d_op-> d_revalidate(dentry->d_parent, nd))) { valid = 0; goto out; } restart = 1; goto restart; } BUG_ON(pdgen != sbgen); /* Free the pointers for our inodes and this dentry. */ bstart = dbstart(dentry); bend = dbend(dentry); if (bstart >= 0) { struct dentry *hidden_dentry; for (bindex = bstart; bindex <= bend; bindex++) { hidden_dentry = unionfs_lower_dentry_idx(dentry, bindex); dput(hidden_dentry); } } set_dbstart(dentry, -1); set_dbend(dentry, -1); interpose_flag = INTERPOSE_REVAL_NEG; if (positive) { interpose_flag = INTERPOSE_REVAL; mutex_lock(&dentry->d_inode->i_mutex); bstart = ibstart(dentry->d_inode); bend = ibend(dentry->d_inode); if (bstart >= 0) { struct inode *hidden_inode; for (bindex = bstart; bindex <= bend; bindex++) { hidden_inode = unionfs_lower_inode_idx(dentry->d_inode, bindex); iput(hidden_inode); } } kfree(UNIONFS_I(dentry->d_inode)->lower_inodes); UNIONFS_I(dentry->d_inode)->lower_inodes = NULL; ibstart(dentry->d_inode) = -1; ibend(dentry->d_inode) = -1; mutex_unlock(&dentry->d_inode->i_mutex); } result = unionfs_lookup_backend(dentry, &lowernd, interpose_flag); if (result) { if (IS_ERR(result)) { valid = 0; goto out; } /* current unionfs_lookup_backend() doesn't return * a valid dentry */ dput(dentry); dentry = result; } if (positive && UNIONFS_I(dentry->d_inode)->stale) { make_bad_inode(dentry->d_inode); d_drop(dentry); valid = 0; goto out; } goto out; } /* The revalidation must occur across all branches */ bstart = dbstart(dentry); bend = dbend(dentry); BUG_ON(bstart == -1); for (bindex = bstart; bindex <= bend; bindex++) { hidden_dentry = unionfs_lower_dentry_idx(dentry, bindex); if (!hidden_dentry || !hidden_dentry->d_op || !hidden_dentry->d_op->d_revalidate) continue; if (!hidden_dentry->d_op->d_revalidate(hidden_dentry, nd)) valid = 0; } if (!dentry->d_inode) valid = 0; if (valid) { fsstack_copy_attr_all(dentry->d_inode, unionfs_lower_inode(dentry->d_inode), unionfs_get_nlinks); fsstack_copy_inode_size(dentry->d_inode, unionfs_lower_inode(dentry->d_inode)); } out: if (locked) unionfs_read_unlock(dentry->d_sb); return valid; }
/* * Pipe output worker. This sets up our pipe format with the page cache * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). */ static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) { int ret, do_wakeup, page_nr; ret = 0; do_wakeup = 0; page_nr = 0; if (pipe->inode) mutex_lock(&pipe->inode->i_mutex); for (;;) { if (!pipe->readers) { send_sig(SIGPIPE, current, 0); if (!ret) ret = -EPIPE; break; } if (pipe->nrbufs < PIPE_BUFFERS) { int newbuf = (pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1); struct pipe_buffer *buf = pipe->bufs + newbuf; buf->page = spd->pages[page_nr]; buf->offset = spd->partial[page_nr].offset; buf->len = spd->partial[page_nr].len; buf->ops = spd->ops; if (spd->flags & SPLICE_F_GIFT) buf->flags |= PIPE_BUF_FLAG_GIFT; pipe->nrbufs++; page_nr++; ret += buf->len; if (pipe->inode) do_wakeup = 1; if (!--spd->nr_pages) break; if (pipe->nrbufs < PIPE_BUFFERS) continue; break; } if (spd->flags & SPLICE_F_NONBLOCK) { if (!ret) ret = -EAGAIN; break; } if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; break; } if (do_wakeup) { smp_mb(); if (waitqueue_active(&pipe->wait)) wake_up_interruptible_sync(&pipe->wait); kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); do_wakeup = 0; } pipe->waiting_writers++; pipe_wait(pipe); pipe->waiting_writers--; } if (pipe->inode) mutex_unlock(&pipe->inode->i_mutex); if (do_wakeup) { smp_mb(); if (waitqueue_active(&pipe->wait)) wake_up_interruptible(&pipe->wait); kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); } while (page_nr < spd->nr_pages) page_cache_release(spd->pages[page_nr++]); return ret; }
void nfnl_unlock(void) { mutex_unlock(&nfnl_mutex); }
static long ugidctl_setgroups(struct ugidctl_context *ctx, void __user *arg) { struct ugidctl_setgroups_rq req; enum pid_type ptype; gid_t __user *list; struct cred *cred; unsigned i, count; gid_t *bulk; pid_t pid; long rc; if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; arg += sizeof(req); list = arg; count = (unsigned) req.count; if (count > NGROUPS_MAX) return -EINVAL; if (!count) return ugidctl_sys_setgroups(0, arg); if (capable(CAP_SETGID)) return ugidctl_sys_setgroups((int) count, list); if (memcmp(ctx->key, req.key, sizeof(ctx->key))) return -EPERM; mutex_lock(&ctx->lock); ptype = ctx->ptype; pid = ctx->pid; mutex_unlock(&ctx->lock); if (pid != pid_nr(get_task_pid(current, ptype))) return -EPERM; bulk = kmalloc(count > UGIDCTL_BULKSIZE ? sizeof(gid_t) * UGIDCTL_BULKSIZE : sizeof(gid_t) * count, GFP_KERNEL); if (!bulk) return -ENOMEM; while (count) { unsigned size = count > UGIDCTL_BULKSIZE ? UGIDCTL_BULKSIZE : count; if (copy_from_user(bulk, arg, sizeof(gid_t) * size)) return -EFAULT; mutex_lock(&ctx->lock); for (i = 0; i < size; i++) { if (ugidctl_find_gid(ctx, bulk[i])) { mutex_unlock(&ctx->lock); kfree(bulk); return -EPERM; } } mutex_unlock(&ctx->lock); arg += sizeof(gid_t) * size; count -= size; } kfree(bulk); cred = prepare_creds(); if (!cred) return -ENOMEM; cap_raise(cred->cap_effective, CAP_SETGID); commit_creds(cred); rc = ugidctl_sys_setgroups((int) req.count, list); cred = prepare_creds(); if (!cred) { /* unable to restore process capabilities - kill process */ do_exit(SIGKILL); return -ENOMEM; } cap_lower(cred->cap_effective, CAP_SETGID); commit_creds(cred); return rc; }
/** * input_ff_upload() - upload effect into force-feedback device * @dev: input device * @effect: effect to be uploaded * @file: owner of the effect */ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file) { struct ff_device *ff = dev->ff; struct ff_effect *old; int ret = 0; int id; if (!test_bit(EV_FF, dev->evbit)) return -ENOSYS; if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX || !test_bit(effect->type, dev->ffbit)) { dev_dbg(&dev->dev, "invalid or not supported effect type in upload\n"); return -EINVAL; } if (effect->type == FF_PERIODIC && (effect->u.periodic.waveform < FF_WAVEFORM_MIN || effect->u.periodic.waveform > FF_WAVEFORM_MAX || !test_bit(effect->u.periodic.waveform, dev->ffbit))) { dev_dbg(&dev->dev, "invalid or not supported wave form in upload\n"); return -EINVAL; } if (!test_bit(effect->type, ff->ffbit)) { ret = compat_effect(ff, effect); if (ret) return ret; } mutex_lock(&ff->mutex); if (effect->id == -1) { for (id = 0; id < ff->max_effects; id++) if (!ff->effect_owners[id]) break; if (id >= ff->max_effects) { ret = -ENOSPC; goto out; } effect->id = id; old = NULL; } else { id = effect->id; ret = check_effect_access(ff, id, file); if (ret) goto out; old = &ff->effects[id]; if (!check_effects_compatible(effect, old)) { ret = -EINVAL; goto out; } } ret = ff->upload(dev, effect, old); if (ret) goto out; spin_lock_irq(&dev->event_lock); ff->effects[id] = *effect; ff->effect_owners[id] = file; spin_unlock_irq(&dev->event_lock); out: mutex_unlock(&ff->mutex); return ret; }
/** * iavf_asq_send_command - send command to Admin Queue * @hw: pointer to the hw struct * @desc: prefilled descriptor describing the command (non DMA mem) * @buff: buffer to use for indirect commands * @buff_size: size of buffer for indirect commands * @cmd_details: pointer to command details structure * * This is the main send command driver routine for the Admin Queue send * queue. It runs the queue, cleans the queue, etc **/ iavf_status iavf_asq_send_command(struct iavf_hw *hw, struct i40e_aq_desc *desc, void *buff, /* can be NULL */ u16 buff_size, struct i40e_asq_cmd_details *cmd_details) { struct iavf_dma_mem *dma_buff = NULL; struct i40e_asq_cmd_details *details; struct i40e_aq_desc *desc_on_ring; bool cmd_completed = false; iavf_status status = 0; u16 retval = 0; u32 val = 0; mutex_lock(&hw->aq.asq_mutex); if (hw->aq.asq.count == 0) { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: Admin queue not initialized.\n"); status = I40E_ERR_QUEUE_EMPTY; goto asq_send_command_error; } hw->aq.asq_last_status = I40E_AQ_RC_OK; val = rd32(hw, hw->aq.asq.head); if (val >= hw->aq.num_asq_entries) { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: head overrun at %d\n", val); status = I40E_ERR_QUEUE_EMPTY; goto asq_send_command_error; } details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use); if (cmd_details) { *details = *cmd_details; /* If the cmd_details are defined copy the cookie. The * cpu_to_le32 is not needed here because the data is ignored * by the FW, only used by the driver */ if (details->cookie) { desc->cookie_high = cpu_to_le32(upper_32_bits(details->cookie)); desc->cookie_low = cpu_to_le32(lower_32_bits(details->cookie)); } } else { memset(details, 0, sizeof(struct i40e_asq_cmd_details)); } /* clear requested flags and then set additional flags if defined */ desc->flags &= ~cpu_to_le16(details->flags_dis); desc->flags |= cpu_to_le16(details->flags_ena); if (buff_size > hw->aq.asq_buf_size) { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: Invalid buffer size: %d.\n", buff_size); status = I40E_ERR_INVALID_SIZE; goto asq_send_command_error; } if (details->postpone && !details->async) { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: Async flag not set along with postpone flag"); status = I40E_ERR_PARAM; goto asq_send_command_error; } /* call clean and check queue available function to reclaim the * descriptors that were processed by FW, the function returns the * number of desc available */ /* the clean function called here could be called in a separate thread * in case of asynchronous completions */ if (i40e_clean_asq(hw) == 0) { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: Error queue is full.\n"); status = I40E_ERR_ADMIN_QUEUE_FULL; goto asq_send_command_error; } /* initialize the temp desc pointer with the right desc */ desc_on_ring = IAVF_ADMINQ_DESC(hw->aq.asq, hw->aq.asq.next_to_use); /* if the desc is available copy the temp desc to the right place */ *desc_on_ring = *desc; /* if buff is not NULL assume indirect command */ if (buff) { dma_buff = &hw->aq.asq.r.asq_bi[hw->aq.asq.next_to_use]; /* copy the user buff into the respective DMA buff */ memcpy(dma_buff->va, buff, buff_size); desc_on_ring->datalen = cpu_to_le16(buff_size); /* Update the address values in the desc with the pa value * for respective buffer */ desc_on_ring->params.external.addr_high = cpu_to_le32(upper_32_bits(dma_buff->pa)); desc_on_ring->params.external.addr_low = cpu_to_le32(lower_32_bits(dma_buff->pa)); } /* bump the tail */ iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n"); iavf_debug_aq(hw, IAVF_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff, buff_size); (hw->aq.asq.next_to_use)++; if (hw->aq.asq.next_to_use == hw->aq.asq.count) hw->aq.asq.next_to_use = 0; if (!details->postpone) wr32(hw, hw->aq.asq.tail, hw->aq.asq.next_to_use); /* if cmd_details are not defined or async flag is not set, * we need to wait for desc write back */ if (!details->async && !details->postpone) { u32 total_delay = 0; do { /* AQ designers suggest use of head for better * timing reliability than DD bit */ if (iavf_asq_done(hw)) break; udelay(50); total_delay += 50; } while (total_delay < hw->aq.asq_cmd_timeout); } /* if ready, copy the desc back to temp */ if (iavf_asq_done(hw)) { *desc = *desc_on_ring; if (buff) memcpy(buff, dma_buff->va, buff_size); retval = le16_to_cpu(desc->retval); if (retval != 0) { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: Command completed with error 0x%X.\n", retval); /* strip off FW internal code */ retval &= 0xff; } cmd_completed = true; if ((enum i40e_admin_queue_err)retval == I40E_AQ_RC_OK) status = 0; else if ((enum i40e_admin_queue_err)retval == I40E_AQ_RC_EBUSY) status = I40E_ERR_NOT_READY; else status = I40E_ERR_ADMIN_QUEUE_ERROR; hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval; } iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer writeback:\n"); iavf_debug_aq(hw, IAVF_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size); /* save writeback aq if requested */ if (details->wb_desc) *details->wb_desc = *desc_on_ring; /* update the error if time out occurred */ if ((!cmd_completed) && (!details->async && !details->postpone)) { if (rd32(hw, hw->aq.asq.len) & IAVF_VF_ATQLEN1_ATQCRIT_MASK) { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: AQ Critical error.\n"); status = I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR; } else { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQTX: Writeback timeout.\n"); status = I40E_ERR_ADMIN_QUEUE_TIMEOUT; } } asq_send_command_error: mutex_unlock(&hw->aq.asq_mutex); return status; }
static void mei_nfc_init(struct work_struct *work) { struct mei_device *dev; struct mei_cl_device *cldev; struct mei_nfc_dev *ndev; struct mei_cl *cl_info; ndev = container_of(work, struct mei_nfc_dev, init_work); cl_info = ndev->cl_info; dev = cl_info->dev; mutex_lock(&dev->device_lock); if (mei_cl_connect(cl_info, NULL) < 0) { mutex_unlock(&dev->device_lock); dev_err(&dev->pdev->dev, "Could not connect to the NFC INFO ME client"); goto err; } mutex_unlock(&dev->device_lock); if (mei_nfc_if_version(ndev) < 0) { dev_err(&dev->pdev->dev, "Could not get the NFC interfave version"); goto err; } dev_info(&dev->pdev->dev, "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n", ndev->fw_ivn, ndev->vendor_id, ndev->radio_type); mutex_lock(&dev->device_lock); if (mei_cl_disconnect(cl_info) < 0) { mutex_unlock(&dev->device_lock); dev_err(&dev->pdev->dev, "Could not disconnect the NFC INFO ME client"); goto err; } mutex_unlock(&dev->device_lock); if (mei_nfc_build_bus_name(ndev) < 0) { dev_err(&dev->pdev->dev, "Could not build the bus ID name\n"); return; } cldev = mei_cl_add_device(dev, mei_nfc_guid, ndev->bus_name, &nfc_ops); if (!cldev) { dev_err(&dev->pdev->dev, "Could not add the NFC device to the MEI bus\n"); goto err; } cldev->priv_data = ndev; return; err: mei_nfc_free(ndev); return; }
static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; struct msm_dai_auxpcm_pdata *auxpcm_pdata = (struct msm_dai_auxpcm_pdata *) dai->dev->platform_data; mutex_lock(&aux_pcm_mutex); if (aux_pcm_count == 2) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 2. Just" " return.\n", __func__, dai->id); mutex_unlock(&aux_pcm_mutex); return 0; } else if (aux_pcm_count > 2) { dev_err(dai->dev, "%s(): ERROR: dai->id %d" " aux_pcm_count = %d > 2\n", __func__, dai->id, aux_pcm_count); mutex_unlock(&aux_pcm_mutex); return 0; } aux_pcm_count++; if (aux_pcm_count == 2) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d after " " increment\n", __func__, dai->id, aux_pcm_count); mutex_unlock(&aux_pcm_mutex); return 0; } pr_debug("%s:dai->id:%d aux_pcm_count = %d. opening afe\n", __func__, dai->id, aux_pcm_count); rc = afe_q6_interface_prepare(); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to open AFE APR\n"); /* * For AUX PCM Interface the below sequence of clk * settings and afe_open is a strict requirement. * * Also using afe_open instead of afe_port_start_nowait * to make sure the port is open before deasserting the * clock line. This is required because pcm register is * not written before clock deassert. Hence the hw does * not get updated with new setting if the below clock * assert/deasset and afe_open sequence is not followed. */ clk_reset(pcm_clk, CLK_RESET_ASSERT); afe_open(PCM_RX, &dai_data->port_config, dai_data->rate); afe_open(PCM_TX, &dai_data->port_config, dai_data->rate); rc = clk_set_rate(pcm_clk, auxpcm_pdata->pcm_clk_rate); if (rc < 0) { pr_err("%s: clk_set_rate failed\n", __func__); return rc; } clk_enable(pcm_clk); //HTC_AUD++ //There is downlink no sound when receiving a MT-call. //Adding a delay to solve this issue. usleep(15000); //HTC_AUD-- clk_reset(pcm_clk, CLK_RESET_DEASSERT); mutex_unlock(&aux_pcm_mutex); return rc; }
static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) { struct mm_struct *mm = current->mm; struct desc_struct ldt; int error; struct user_desc ldt_info; int oldsize, newsize; struct ldt_struct *new_ldt, *old_ldt; error = -EINVAL; if (bytecount != sizeof(ldt_info)) goto out; error = -EFAULT; if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) goto out; error = -EINVAL; if (ldt_info.entry_number >= LDT_ENTRIES) goto out; if (ldt_info.contents == 3) { if (oldmode) goto out; if (ldt_info.seg_not_present == 0) goto out; } if ((oldmode && !ldt_info.base_addr && !ldt_info.limit) || LDT_empty(&ldt_info)) { /* The user wants to clear the entry. */ memset(&ldt, 0, sizeof(ldt)); } else { if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) { error = -EINVAL; goto out; } fill_ldt(&ldt, &ldt_info); if (oldmode) ldt.avl = 0; } mutex_lock(&mm->context.lock); old_ldt = mm->context.ldt; oldsize = old_ldt ? old_ldt->size : 0; newsize = max((int)(ldt_info.entry_number + 1), oldsize); error = -ENOMEM; new_ldt = alloc_ldt_struct(newsize); if (!new_ldt) goto out_unlock; if (old_ldt) memcpy(new_ldt->entries, old_ldt->entries, oldsize * LDT_ENTRY_SIZE); new_ldt->entries[ldt_info.entry_number] = ldt; finalize_ldt_struct(new_ldt); install_ldt(mm, new_ldt); free_ldt_struct(old_ldt); error = 0; out_unlock: mutex_unlock(&mm->context.lock); out: return error; }
void amdgpu_bo_list_put(struct amdgpu_bo_list *list) { mutex_unlock(&list->lock); }
static int bq27xxx_battery_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bq27xxx_device_info *di; int ret; char *name; int num; /* Get new ID for the new battery device */ mutex_lock(&battery_mutex); num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL); mutex_unlock(&battery_mutex); if (num < 0) return num; name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num); if (!name) goto err_mem; di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); if (!di) goto err_mem; di->id = num; di->dev = &client->dev; di->chip = id->driver_data; di->name = name; di->bus.read = bq27xxx_battery_i2c_read; ret = bq27xxx_battery_setup(di); if (ret) goto err_failed; /* Schedule a polling after about 1 min */ schedule_delayed_work(&di->work, 60 * HZ); i2c_set_clientdata(client, di); if (client->irq) { ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, bq27xxx_battery_irq_handler_thread, IRQF_ONESHOT, di->name, di); if (ret) { dev_err(&client->dev, "Unable to register IRQ %d error %d\n", client->irq, ret); return ret; } } return 0; err_mem: ret = -ENOMEM; err_failed: mutex_lock(&battery_mutex); idr_remove(&battery_id, num); mutex_unlock(&battery_mutex); return ret; }
static void android_bat_monitor_work(struct work_struct *work) { struct android_bat_data *battery = container_of(work, struct android_bat_data, monitor_work); struct timespec cur_time; wake_lock(&battery->monitor_wake_lock); android_bat_update_data(battery); mutex_lock(&android_bat_state_lock); switch (battery->charging_status) { case POWER_SUPPLY_STATUS_FULL: if (battery->batt_vcell < battery->pdata->recharging_voltage && !battery->recharging) { battery->recharging = true; android_bat_enable_charging(battery, true); pr_info("battery: start recharging, v=%d\n", battery->batt_vcell/1000); } break; case POWER_SUPPLY_STATUS_DISCHARGING: break; case POWER_SUPPLY_STATUS_CHARGING: switch (battery->batt_health) { case POWER_SUPPLY_HEALTH_OVERHEAT: case POWER_SUPPLY_HEALTH_COLD: case POWER_SUPPLY_HEALTH_OVERVOLTAGE: case POWER_SUPPLY_HEALTH_DEAD: case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE: battery->charging_status = POWER_SUPPLY_STATUS_NOT_CHARGING; android_bat_enable_charging(battery, false); pr_info("battery: Not charging, health=%d\n", battery->batt_health); break; default: break; } break; case POWER_SUPPLY_STATUS_NOT_CHARGING: if (battery->batt_health == POWER_SUPPLY_HEALTH_GOOD) { pr_info("battery: battery health recovered\n"); if (battery->charge_source != CHARGE_SOURCE_NONE) { android_bat_enable_charging(battery, true); battery->charging_status = POWER_SUPPLY_STATUS_CHARGING; } else { battery->charging_status = POWER_SUPPLY_STATUS_DISCHARGING; } } break; default: pr_err("%s: Undefined battery status: %d\n", __func__, battery->charging_status); break; } android_bat_charging_timer(battery); get_monotonic_boottime(&cur_time); pr_info("battery: l=%d v=%d c=%d temp=%s%ld.%ld h=%d st=%d%s ct=%lu type=%s\n", battery->batt_soc, battery->batt_vcell/1000, battery->batt_current, battery->batt_temp < 0 ? "-" : "", abs(battery->batt_temp / 10), abs(battery->batt_temp % 10), battery->batt_health, battery->charging_status, battery->recharging ? "r" : "", battery->charging_start_time ? cur_time.tv_sec - battery->charging_start_time : 0, charge_source_str(battery->charge_source)); mutex_unlock(&android_bat_state_lock); power_supply_changed(&battery->psy_bat); battery->last_poll = ktime_get_boottime(); android_bat_monitor_set_alarm(battery, FAST_POLL); wake_unlock(&battery->monitor_wake_lock); return; }
int i2c_release(i2c_t dev) { assert(dev < I2C_NUMOF); mutex_unlock(&locks[dev]); return 0; }
static void sdio_mux_read_data(struct work_struct *work) { struct sk_buff *skb_mux; void *ptr = 0; int sz, rc, len = 0; struct sdio_mux_hdr *hdr; static int workqueue_pinned; if (!workqueue_pinned) { struct cpumask cpus; cpumask_clear(&cpus); cpumask_set_cpu(0, &cpus); if (sched_setaffinity(current->pid, &cpus)) pr_err("%s: sdio_dmux set CPU affinity failed\n", __func__); workqueue_pinned = 1; } DBG("%s: reading\n", __func__); /* should probably have a separate read lock */ mutex_lock(&sdio_mux_lock); sz = sdio_read_avail(sdio_mux_ch); DBG("%s: read avail %d\n", __func__, sz); if (sz <= 0) { if (sz) pr_err("%s: read avail failed %d\n", __func__, sz); mutex_unlock(&sdio_mux_lock); return; } /* net_ip_aling is probably not required */ if (sdio_partial_pkt.valid) len = sdio_partial_pkt.skb->len; /* If allocation fails attempt to get a smaller chunk of mem */ do { skb_mux = __dev_alloc_skb(sz + NET_IP_ALIGN + len, GFP_KERNEL); if (skb_mux) break; pr_err("%s: cannot allocate skb of size:%d + " "%d (NET_SKB_PAD)\n", __func__, sz + NET_IP_ALIGN + len, NET_SKB_PAD); /* the skb structure adds NET_SKB_PAD bytes to the memory * request, which may push the actual request above PAGE_SIZE * in that case, we need to iterate one more time to make sure * we get the memory request under PAGE_SIZE */ if (sz + NET_IP_ALIGN + len + NET_SKB_PAD <= PAGE_SIZE) { pr_err("%s: allocation failed\n", __func__); mutex_unlock(&sdio_mux_lock); return; } sz /= 2; } while (1); skb_reserve(skb_mux, NET_IP_ALIGN + len); ptr = skb_put(skb_mux, sz); /* half second wakelock is fine? */ wake_lock_timeout(&sdio_mux_ch_wakelock, HZ / 2); rc = sdio_read(sdio_mux_ch, ptr, sz); DBG("%s: read %d\n", __func__, rc); if (rc) { pr_err("%s: sdio read failed %d\n", __func__, rc); dev_kfree_skb_any(skb_mux); mutex_unlock(&sdio_mux_lock); queue_work(sdio_mux_workqueue, &work_sdio_mux_read); return; } mutex_unlock(&sdio_mux_lock); DBG_INC_READ_CNT(sz); DBG("%s: head %p data %p tail %p end %p len %d\n", __func__, skb_mux->head, skb_mux->data, skb_mux->tail, skb_mux->end, skb_mux->len); /* move to a separate function */ /* probably do skb_pull instead of pointer adjustment */ hdr = handle_sdio_partial_pkt(skb_mux); while ((void *)hdr < (void *)skb_mux->tail) { if (((void *)hdr + sizeof(*hdr)) > (void *)skb_mux->tail) { /* handle partial header */ sdio_mux_save_partial_pkt(hdr, skb_mux); break; } if (hdr->magic_num != SDIO_MUX_HDR_MAGIC_NO) { pr_err("%s: packet error\n", __func__); break; } hdr = handle_sdio_mux_command(hdr, skb_mux); } dev_kfree_skb_any(skb_mux); DBG("%s: read done\n", __func__); queue_work(sdio_mux_workqueue, &work_sdio_mux_read); }
static int nilfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { struct nilfs_super_data sd; struct super_block *s; struct the_nilfs *nilfs; int err, need_to_close = 1; sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type); if (IS_ERR(sd.bdev)) return PTR_ERR(sd.bdev); /* * To get mount instance using sget() vfs-routine, NILFS needs * much more information than normal filesystems to identify mount * instance. For snapshot mounts, not only a mount type (ro-mount * or rw-mount) but also a checkpoint number is required. */ sd.cno = 0; sd.flags = flags; if (nilfs_identify((char *)data, &sd)) { err = -EINVAL; goto failed; } nilfs = find_or_create_nilfs(sd.bdev); if (!nilfs) { err = -ENOMEM; goto failed; } mutex_lock(&nilfs->ns_mount_mutex); if (!sd.cno) { /* * Check if an exclusive mount exists or not. * Snapshot mounts coexist with a current mount * (i.e. rw-mount or ro-mount), whereas rw-mount and * ro-mount are mutually exclusive. */ down_read(&nilfs->ns_super_sem); if (nilfs->ns_current && ((nilfs->ns_current->s_super->s_flags ^ flags) & MS_RDONLY)) { up_read(&nilfs->ns_super_sem); err = -EBUSY; goto failed_unlock; } up_read(&nilfs->ns_super_sem); } /* * Find existing nilfs_sb_info struct */ sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno); /* * Get super block instance holding the nilfs_sb_info struct. * A new instance is allocated if no existing mount is present or * existing instance has been unmounted. */ s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd); if (sd.sbi) nilfs_put_sbinfo(sd.sbi); if (IS_ERR(s)) { err = PTR_ERR(s); goto failed_unlock; } if (!s->s_root) { char b[BDEVNAME_SIZE]; /* New superblock instance created */ s->s_flags = flags; strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id)); sb_set_blocksize(s, block_size(sd.bdev)); err = nilfs_fill_super(s, data, flags & MS_VERBOSE, nilfs); if (err) goto cancel_new; s->s_flags |= MS_ACTIVE; need_to_close = 0; } mutex_unlock(&nilfs->ns_mount_mutex); put_nilfs(nilfs); if (need_to_close) close_bdev_exclusive(sd.bdev, flags); simple_set_mnt(mnt, s); return 0; failed_unlock: mutex_unlock(&nilfs->ns_mount_mutex); put_nilfs(nilfs); failed: close_bdev_exclusive(sd.bdev, flags); return err; cancel_new: /* Abandoning the newly allocated superblock */ mutex_unlock(&nilfs->ns_mount_mutex); put_nilfs(nilfs); up_write(&s->s_umount); deactivate_super(s); /* * deactivate_super() invokes close_bdev_exclusive(). * We must finish all post-cleaning before this call; * put_nilfs() needs the block device. */ return err; }
static long acdb_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { int32_t result = 0; int32_t size; int32_t map_fd; uint32_t topology; uint32_t data[MAX_IOCTL_DATA]; struct msm_spk_prot_status prot_status; struct msm_spk_prot_status acdb_spk_status; pr_debug("%s\n", __func__); mutex_lock(&acdb_data.acdb_mutex); switch (cmd) { case AUDIO_REGISTER_PMEM: pr_debug("AUDIO_REGISTER_PMEM\n"); result = deregister_memory(); if (result < 0) pr_err("%s: deregister_memory failed returned %d!\n", __func__, result); if (copy_from_user(&map_fd, (void *)arg, sizeof(map_fd))) { pr_err("%s: fail to copy memory handle!\n", __func__); result = -EFAULT; } else { acdb_data.map_handle = map_fd; result = register_memory(); } goto done; case AUDIO_DEREGISTER_PMEM: pr_debug("AUDIO_DEREGISTER_PMEM\n"); result = deregister_memory(); goto done; case AUDIO_SET_VOICE_RX_TOPOLOGY: if (copy_from_user(&topology, (void *)arg, sizeof(topology))) { pr_err("%s: fail to copy topology!\n", __func__); result = -EFAULT; } store_voice_rx_topology(topology); goto done; case AUDIO_SET_VOICE_TX_TOPOLOGY: if (copy_from_user(&topology, (void *)arg, sizeof(topology))) { pr_err("%s: fail to copy topology!\n", __func__); result = -EFAULT; } store_voice_tx_topology(topology); goto done; case AUDIO_SET_ADM_RX_TOPOLOGY: if (copy_from_user(&topology, (void *)arg, sizeof(topology))) { pr_err("%s: fail to copy topology!\n", __func__); result = -EFAULT; } store_adm_rx_topology(topology); goto done; case AUDIO_SET_ADM_TX_TOPOLOGY: if (copy_from_user(&topology, (void *)arg, sizeof(topology))) { pr_err("%s: fail to copy topology!\n", __func__); result = -EFAULT; } store_adm_tx_topology(topology); goto done; case AUDIO_SET_ASM_TOPOLOGY: if (copy_from_user(&topology, (void *)arg, sizeof(topology))) { pr_err("%s: fail to copy topology!\n", __func__); result = -EFAULT; } store_asm_topology(topology); goto done; case AUDIO_SET_SPEAKER_PROT: if (copy_from_user(&acdb_data.spk_prot_cfg, (void *)arg, sizeof(acdb_data.spk_prot_cfg))) { pr_err("%s fail to copy spk_prot_cfg\n", __func__); result = -EFAULT; } goto done; case AUDIO_GET_SPEAKER_PROT: /*Indicates calibration was succesfull*/ if (acdb_data.spk_prot_cfg.mode == MSM_SPKR_PROT_CALIBRATED) { prot_status.r0 = acdb_data.spk_prot_cfg.r0; prot_status.status = 0; } else if (acdb_data.spk_prot_cfg.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) { /*Call AFE to query the status*/ acdb_spk_status.status = -EINVAL; acdb_spk_status.r0 = -1; get_spk_protection_status(&acdb_spk_status); prot_status.r0 = acdb_spk_status.r0; prot_status.status = acdb_spk_status.status; if (!acdb_spk_status.status) { acdb_data.spk_prot_cfg.mode = MSM_SPKR_PROT_CALIBRATED; acdb_data.spk_prot_cfg.r0 = prot_status.r0; } } else { /*Indicates calibration data is invalid*/ prot_status.status = -EINVAL; prot_status.r0 = -1; } if (copy_to_user((void *)arg, &prot_status, sizeof(prot_status))) { pr_err("%s: Failed to update prot_status\n", __func__); } goto done; case AUDIO_REGISTER_VOCPROC_VOL_TABLE: result = register_vocvol_table(); goto done; case AUDIO_DEREGISTER_VOCPROC_VOL_TABLE: result = deregister_vocvol_table(); goto done; case AUDIO_SET_HW_DELAY_RX: result = store_hw_delay(RX_CAL, (void *)arg); goto done; case AUDIO_SET_HW_DELAY_TX: result = store_hw_delay(TX_CAL, (void *)arg); goto done; } if (copy_from_user(&size, (void *) arg, sizeof(size))) { result = -EFAULT; goto done; } if ((size <= 0) || (size > sizeof(data))) { pr_err("%s: Invalid size sent to driver: %d\n", __func__, size); result = -EFAULT; goto done; } switch (cmd) { case AUDIO_SET_VOCPROC_COL_CAL: result = store_voice_col_data(VOCPROC_CAL, size, (uint32_t *)arg); goto done; case AUDIO_SET_VOCSTRM_COL_CAL: result = store_voice_col_data(VOCSTRM_CAL, size, (uint32_t *)arg); goto done; case AUDIO_SET_VOCVOL_COL_CAL: result = store_voice_col_data(VOCVOL_CAL, size, (uint32_t *)arg); goto done; } if (copy_from_user(data, (void *)(arg + sizeof(size)), size)) { pr_err("%s: fail to copy table size %d\n", __func__, size); result = -EFAULT; goto done; } if (data == NULL) { pr_err("%s: NULL pointer sent to driver!\n", __func__); result = -EFAULT; goto done; } if (size > sizeof(struct cal_block)) pr_err("%s: More cal data for ioctl 0x%x then expected, size received: %d\n", __func__, cmd, size); switch (cmd) { case AUDIO_SET_AUDPROC_TX_CAL: result = store_audproc_cal(TX_CAL, (struct cal_block *)data); goto done; case AUDIO_SET_AUDPROC_RX_CAL: result = store_audproc_cal(RX_CAL, (struct cal_block *)data); goto done; case AUDIO_SET_AUDPROC_TX_STREAM_CAL: result = store_audstrm_cal(TX_CAL, (struct cal_block *)data); goto done; case AUDIO_SET_AUDPROC_RX_STREAM_CAL: result = store_audstrm_cal(RX_CAL, (struct cal_block *)data); goto done; case AUDIO_SET_AUDPROC_TX_VOL_CAL: result = store_audvol_cal(TX_CAL, (struct cal_block *)data); goto done; case AUDIO_SET_AUDPROC_RX_VOL_CAL: result = store_audvol_cal(RX_CAL, (struct cal_block *)data); goto done; case AUDIO_SET_AFE_TX_CAL: result = store_afe_cal(TX_CAL, (struct cal_block *)data); goto done; case AUDIO_SET_AFE_RX_CAL: result = store_afe_cal(RX_CAL, (struct cal_block *)data); goto done; case AUDIO_SET_VOCPROC_CAL: result = store_vocproc_cal((struct cal_block *)data); goto done; case AUDIO_SET_VOCPROC_STREAM_CAL: result = store_vocstrm_cal((struct cal_block *)data); goto done; case AUDIO_SET_VOCPROC_VOL_CAL: result = store_vocvol_cal((struct cal_block *)data); goto done; case AUDIO_SET_VOCPROC_DEV_CFG_CAL: result = store_vocproc_dev_cfg_cal((struct cal_block *)data); goto done; case AUDIO_SET_SIDETONE_CAL: store_sidetone_cal((struct sidetone_cal *)data); goto done; case AUDIO_SET_ANC_CAL: result = store_anc_cal((struct cal_block *)data); goto done; case AUDIO_SET_LSM_CAL: result = store_lsm_cal((struct cal_block *)data); goto done; case AUDIO_SET_ADM_CUSTOM_TOPOLOGY: result = store_adm_custom_topology((struct cal_block *)data); goto done; case AUDIO_SET_ASM_CUSTOM_TOPOLOGY: result = store_asm_custom_topology((struct cal_block *)data); goto done; case AUDIO_SET_AANC_CAL: result = store_aanc_cal((struct cal_block *)data); goto done; default: pr_err("ACDB=> ACDB ioctl not found!\n"); result = -EFAULT; goto done; } done: mutex_unlock(&acdb_data.acdb_mutex); return result; }
int lte_him_enqueue_ip_packet(unsigned char *data, int size, int pdn) { int error = 0; unsigned int packet_length, curr_pdn = 0; unsigned long flags; unsigned char *tmp_packet; tx_packet_list *curr_item; /* BEGIN: 0018522 [email protected] 2011-03-24 */ /* MOD 0018522: [LTE] Kernel crash happen, When the SDIO TX & RX fail in 5sec */ if(gLte_sdio_info->flag_gpio_l2k_host_status == FALSE){ /* BEGIN: 0018684 [email protected] 2011-03-30 */ /* MOD 0018684: [LTE] Remove a debug code for tracking the unwoken host */ // LTE_INFO(" *********** MSM SDCC doesn't resume *********** \n"); /* END: 0018684 [email protected] 2011-03-30 */ return -EIO; } /* END: 0018522 [email protected] 2011-03-24 */ if (gLte_sdio_info == NULL) { return -ENXIO; } if(size==0 || data == NULL) { return -EINVAL; } /*BEGIN: 0017497 [email protected] 2011-03-05 */ /*MOD 0017497: [LTE] LTE SW Assert stability is update: blocking of tx operation */ if (gLte_sdio_info->flag_tx_blocking == TRUE) { LTE_ERROR("[LTE_ASSERT] SDIO Tx(IP data) blocking, return -EIO \n"); return -EIO; } /*END: 0017497 [email protected] 2011-03-05 */ mutex_lock(&gLte_sdio_info->tx_lock_mutex); /* packet_length = 4 byte aligned HIM packet size */ packet_length = lte_him_calc_dummy(HIM_PACKET_HEADER_SIZE + size); /* memory allocation for tx packet list */ curr_item = (tx_packet_list *)kzalloc(sizeof(tx_packet_list), GFP_KERNEL); if(!curr_item) { /* BEGIN: 0011698 [email protected] 2010-12-01 */ /* ADD 0011698: [LTE] ADD : Debug message for him packet */ LTE_ERROR("Failed to allocate memory\n"); /* END : 0011698 [email protected] 2010-12-01 */ mutex_unlock(&gLte_sdio_info->tx_lock_mutex); return -ENOMEM; } /* memory allocation for tx packet */ tmp_packet = (unsigned char *)kzalloc(packet_length, GFP_KERNEL); if(!tmp_packet) { /* BEGIN: 0011698 [email protected] 2010-12-01 */ /* ADD 0011698: [LTE] ADD : Debug message for him packet */ LTE_ERROR("Failed to allocate memory\n"); /* END : 0011698 [email protected] 2010-12-01 */ kfree(curr_item); mutex_unlock(&gLte_sdio_info->tx_lock_mutex); return -ENOMEM; } curr_item->tx_packet = tmp_packet; curr_item->size = packet_length; switch(pdn) { case 0: curr_pdn = HIM_NIC_1; break; case 1: curr_pdn = HIM_NIC_2; break; case 2: curr_pdn = HIM_NIC_3; break; case 3: curr_pdn = HIM_IP_PACKET_1; break; case 4: curr_pdn = HIM_IP_PACKET_2; break; case 5: curr_pdn = HIM_IP_PACKET_3; break; case 6: curr_pdn = HIM_IP_PACKET_4; break; case 7: curr_pdn = HIM_IP_PACKET_5; break; case 8: curr_pdn = HIM_IP_PACKET_6; break; case 9: curr_pdn = HIM_IP_PACKET_7; break; case 10: curr_pdn = HIM_IP_PACKET_8; break; default: /* defect */ /* When default case, free the memory */ mutex_unlock(&gLte_sdio_info->tx_lock_mutex); kfree(curr_item); /* defect */ /* BEGIN: 0011698 [email protected] 2010-12-01 */ /* ADD 0011698: [LTE] ADD : Debug message for him packet */ LTE_ERROR("Unsupported PDN\n"); /* END : 0011698 [email protected] 2010-12-01 */ return -EIO; } ((him_packet_header *)(tmp_packet))->payload_size = (unsigned short)size; ((him_packet_header *)(tmp_packet))->packet_type = curr_pdn; memcpy(tmp_packet + HIM_PACKET_HEADER_SIZE, data, size); list_add_tail(&curr_item->list, &gLte_sdio_info->tx_packet_head->list); gLte_sdio_info->tx_list_size += packet_length; mutex_unlock(&gLte_sdio_info->tx_lock_mutex); #ifndef SDIO_TX_TIMER queue_work(gLte_sdio_info->tx_workqueue, &gLte_sdio_info->tx_worker); #endif return error; }
/** * ecryptfs_open * @inode: inode speciying file to open * @file: Structure to return filled in * * Opens the file specified by inode. * * Returns zero on success; non-zero otherwise */ static int ecryptfs_open(struct inode *inode, struct file *file) { int rc = 0; struct ecryptfs_crypt_stat *crypt_stat = NULL; struct ecryptfs_mount_crypt_stat *mount_crypt_stat; struct dentry *ecryptfs_dentry = file->f_path.dentry; /* Private value of ecryptfs_dentry allocated in * ecryptfs_lookup() */ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); struct ecryptfs_file_info *file_info; mount_crypt_stat = &ecryptfs_superblock_to_private( ecryptfs_dentry->d_sb)->mount_crypt_stat; if ((mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) && ((file->f_flags & O_WRONLY) || (file->f_flags & O_RDWR) || (file->f_flags & O_CREAT) || (file->f_flags & O_TRUNC) || (file->f_flags & O_APPEND))) { printk(KERN_WARNING "Mount has encrypted view enabled; " "files may only be read\n"); rc = -EPERM; goto out; } /* Released in ecryptfs_release or end of function if failure */ file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL); ecryptfs_set_file_private(file, file_info); if (!file_info) { ecryptfs_printk(KERN_ERR, "Error attempting to allocate memory\n"); rc = -ENOMEM; goto out; } lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; mutex_lock(&crypt_stat->cs_mutex); if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) { ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); /* Policy code enabled in future release */ crypt_stat->flags |= (ECRYPTFS_POLICY_APPLIED | ECRYPTFS_ENCRYPTED); } mutex_unlock(&crypt_stat->cs_mutex); if (!ecryptfs_inode_to_private(inode)->lower_file) { rc = ecryptfs_init_persistent_file(ecryptfs_dentry); if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " "the persistent file for the dentry with name " "[%s]; rc = [%d]\n", __func__, ecryptfs_dentry->d_name.name, rc); goto out; } } if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY) && !(file->f_flags & O_RDONLY)) { rc = -EPERM; printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " "file must hence be opened RO\n", __func__); goto out; } ecryptfs_set_file_lower( file, ecryptfs_inode_to_private(inode)->lower_file); if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); mutex_lock(&crypt_stat->cs_mutex); crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); mutex_unlock(&crypt_stat->cs_mutex); rc = 0; goto out; } mutex_lock(&crypt_stat->cs_mutex); if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { rc = ecryptfs_read_metadata(ecryptfs_dentry); if (rc) { ecryptfs_printk(KERN_DEBUG, "Valid headers not found\n"); if (!(mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { rc = -EIO; printk(KERN_WARNING "Either the lower file " "is not in a valid eCryptfs format, " "or the key could not be retrieved. " "Plaintext passthrough mode is not " "enabled; returning -EIO\n"); mutex_unlock(&crypt_stat->cs_mutex); goto out_free; } rc = 0; crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); mutex_unlock(&crypt_stat->cs_mutex); goto out; } } mutex_unlock(&crypt_stat->cs_mutex); ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] " "size: [0x%.16x]\n", inode, inode->i_ino, i_size_read(inode)); goto out; out_free: kmem_cache_free(ecryptfs_file_info_cache, ecryptfs_file_to_private(file)); out: return rc; }
int lte_him_write_control_packet_tty_lldm(const unsigned char *data, int size) { //FUNC_ENTER(); unsigned char *tmp_lldm_him_blk; int error, blk_count = 0; unsigned int him_blk_length, packet_length, write_length = 0; unsigned long flags; if (gLte_sdio_info == NULL) { return -ENXIO; } #ifdef LTE_WAKE_UP /* SET LTE_WU = HIGH */ gpio_set_value(GPIO_L2K_LTE_WAKEUP,TRUE); #endif /* LTE_WAKE_UP */ packet_length = lte_him_calc_dummy(HIM_PACKET_HEADER_SIZE + size); him_blk_length = HIM_BLOCK_HEADER_SIZE + packet_length; /* Memery allocation for the HIM packet */ tmp_lldm_him_blk = (unsigned char *)kzalloc(him_blk_length, GFP_KERNEL); if(!tmp_lldm_him_blk) { LTE_ERROR("Failed to allocate memory\n"); #ifdef LTE_WAKE_UP /* SET LTE_WU = LOW */ gpio_set_value(GPIO_L2K_LTE_WAKEUP,FALSE); #endif /* LTE_WAKE_UP */ wake_unlock(&gLte_sdio_info->tx_control_wake_lock); mutex_unlock(&gLte_sdio_info->tx_lock_mutex); return -ENOMEM; } /* Packing a HIM packet */ ((him_block_header *)(tmp_lldm_him_blk))->total_block_size = him_blk_length; ((him_block_header *)(tmp_lldm_him_blk))->seq_num = gLte_sdio_info->him_tx_cnt; ((him_block_header *)(tmp_lldm_him_blk))->packet_num = 1; ((him_block_header *)(tmp_lldm_him_blk))->him_block_type = HIM_BLOCK_MISC; ((him_packet_header *)(tmp_lldm_him_blk + HIM_BLOCK_HEADER_SIZE))->payload_size = (unsigned short)size; ((him_packet_header *)(tmp_lldm_him_blk + HIM_BLOCK_HEADER_SIZE))->packet_type = HIM_LLDM_PACKET; memcpy(tmp_lldm_him_blk + HIM_BLOCK_HEADER_SIZE + HIM_PACKET_HEADER_SIZE, data, size); if((him_blk_length % LTE_SDIO_BLK_SIZE) != 0) { blk_count = (him_blk_length / LTE_SDIO_BLK_SIZE); write_length = (LTE_SDIO_BLK_SIZE * blk_count) + LTE_SDIO_BLK_SIZE; } else { write_length = him_blk_length; } /* Write a packet to SDIO channel */ #ifndef LGE_NO_HARDWARE #ifdef LTE_WAKE_UP error = lte_sdio_wake_up_tx((void *)tmp_lldm_him_blk, write_length); #else /* LTE_WAKE_UP */ sdio_claim_host(gLte_sdio_info->func); error = sdio_memcpy_toio(gLte_sdio_info->func, DATA_PORT, (void*)tmp_lldm_him_blk, write_length); sdio_release_host(gLte_sdio_info->func); #endif /* LTE_WAKE_UP */ #else /* LGE_NO_HARDWARE */ error = 0; #endif /* LGE_NO_HARDWARE */ if(error != 0) { LTE_ERROR("Failed to wrtie data to LTE. Error = 0x%x\n", error); } else { if(gLte_sdio_info->him_tx_cnt == 0xFFFFFFFF) gLte_sdio_info->him_tx_cnt = 1; else gLte_sdio_info->him_tx_cnt++; } kfree(tmp_lldm_him_blk); #ifdef LTE_WAKE_UP /* SET LTE_WU = LOW */ gpio_set_value(GPIO_L2K_LTE_WAKEUP,FALSE); #endif /* LTE_WAKE_UP */ //FUNC_EXIT(); return error; }
/** * iavf_clean_arq_element * @hw: pointer to the hw struct * @e: event info from the receive descriptor, includes any buffers * @pending: number of events that could be left to process * * This function cleans one Admin Receive Queue element and returns * the contents through e. It can also return how many events are * left to process through 'pending' **/ iavf_status iavf_clean_arq_element(struct iavf_hw *hw, struct i40e_arq_event_info *e, u16 *pending) { u16 ntc = hw->aq.arq.next_to_clean; struct i40e_aq_desc *desc; iavf_status ret_code = 0; struct iavf_dma_mem *bi; u16 desc_idx; u16 datalen; u16 flags; u16 ntu; /* pre-clean the event info */ memset(&e->desc, 0, sizeof(e->desc)); /* take the lock before we start messing with the ring */ mutex_lock(&hw->aq.arq_mutex); if (hw->aq.arq.count == 0) { iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQRX: Admin queue not initialized.\n"); ret_code = I40E_ERR_QUEUE_EMPTY; goto clean_arq_element_err; } /* set next_to_use to head */ ntu = rd32(hw, hw->aq.arq.head) & IAVF_VF_ARQH1_ARQH_MASK; if (ntu == ntc) { /* nothing to do - shouldn't need to update ring's values */ ret_code = I40E_ERR_ADMIN_QUEUE_NO_WORK; goto clean_arq_element_out; } /* now clean the next descriptor */ desc = IAVF_ADMINQ_DESC(hw->aq.arq, ntc); desc_idx = ntc; hw->aq.arq_last_status = (enum i40e_admin_queue_err)le16_to_cpu(desc->retval); flags = le16_to_cpu(desc->flags); if (flags & I40E_AQ_FLAG_ERR) { ret_code = I40E_ERR_ADMIN_QUEUE_ERROR; iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQRX: Event received with error 0x%X.\n", hw->aq.arq_last_status); } e->desc = *desc; datalen = le16_to_cpu(desc->datalen); e->msg_len = min(datalen, e->buf_len); if (e->msg_buf && (e->msg_len != 0)) memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va, e->msg_len); iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n"); iavf_debug_aq(hw, IAVF_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf, hw->aq.arq_buf_size); /* Restore the original datalen and buffer address in the desc, * FW updates datalen to indicate the event message * size */ bi = &hw->aq.arq.r.arq_bi[ntc]; memset((void *)desc, 0, sizeof(struct i40e_aq_desc)); desc->flags = cpu_to_le16(I40E_AQ_FLAG_BUF); if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF) desc->flags |= cpu_to_le16(I40E_AQ_FLAG_LB); desc->datalen = cpu_to_le16((u16)bi->size); desc->params.external.addr_high = cpu_to_le32(upper_32_bits(bi->pa)); desc->params.external.addr_low = cpu_to_le32(lower_32_bits(bi->pa)); /* set tail = the last cleaned desc index. */ wr32(hw, hw->aq.arq.tail, ntc); /* ntc is updated to tail + 1 */ ntc++; if (ntc == hw->aq.num_arq_entries) ntc = 0; hw->aq.arq.next_to_clean = ntc; hw->aq.arq.next_to_use = ntu; clean_arq_element_out: /* Set pending if needed, unlock and return */ if (pending) *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc); clean_arq_element_err: mutex_unlock(&hw->aq.arq_mutex); return ret_code; }
int sst_alloc_stream_mfld(char *params, struct sst_block *block) { struct ipc_post *msg = NULL; struct snd_sst_alloc_params_mfld alloc_param; struct snd_sst_params *str_params; struct stream_info *str_info; unsigned int stream_ops, device; struct snd_sst_stream_params_mfld *sparams; unsigned int pcm_slot = 0, num_ch, pcm_wd_sz, sfreq; int str_id; u8 codec; u32 rb_size, rb_addr, period_count; unsigned long irq_flags; pr_debug("In %s\n", __func__); BUG_ON(!params); str_params = (struct snd_sst_params *)params; stream_ops = str_params->ops; codec = str_params->codec; device = str_params->device_type; num_ch = sst_get_num_channel(str_params); sfreq = sst_get_sfreq(str_params); pcm_wd_sz = sst_get_wdsize(str_params); rb_size = str_params->aparams.ring_buf_info[0].size; rb_addr = str_params->aparams.ring_buf_info[0].addr; period_count = str_params->aparams.frag_size / 4; pr_debug("period_size = %d\n", period_count); pr_debug("ring_buf_addr = 0x%x\n", rb_addr); pr_debug("ring_buf_size = %d\n", rb_size); pr_debug("device_type=%d\n", device); pr_debug("sfreq =%d\n", sfreq); pr_debug("stream_ops%d codec%d device%d\n", stream_ops, codec, device); sparams = kzalloc(sizeof(*sparams), GFP_KERNEL); if (!sparams) { pr_err("Unable to allocate snd_sst_stream_params\n"); return -ENOMEM; } sparams->uc.pcm_params.codec = codec; sparams->uc.pcm_params.num_chan = num_ch; sparams->uc.pcm_params.pcm_wd_sz = pcm_wd_sz; sparams->uc.pcm_params.reserved = 0; sparams->uc.pcm_params.sfreq = sfreq; sparams->uc.pcm_params.ring_buffer_size = rb_size; sparams->uc.pcm_params.period_count = period_count; sparams->uc.pcm_params.ring_buffer_addr = rb_addr; mutex_lock(&sst_drv_ctx->stream_lock); str_id = device; mutex_unlock(&sst_drv_ctx->stream_lock); pr_debug("slot %x\n", pcm_slot); /*allocate device type context*/ sst_init_stream(&sst_drv_ctx->streams[str_id], codec, str_id, stream_ops, pcm_slot); /* send msg to FW to allocate a stream */ if (sst_create_ipc_msg(&msg, true)) { kfree(sparams); return -ENOMEM; } alloc_param.str_type.codec_type = codec; alloc_param.str_type.str_type = SST_STREAM_TYPE_MUSIC; alloc_param.str_type.operation = stream_ops; alloc_param.str_type.protected_str = 0; /* non drm */ alloc_param.str_type.time_slots = pcm_slot; alloc_param.str_type.reserved = 0; alloc_param.str_type.result = 0; block->drv_id = str_id; block->msg_id = IPC_IA_ALLOC_STREAM; sst_fill_header(&msg->header, IPC_IA_ALLOC_STREAM, 1, str_id); msg->header.part.data = sizeof(alloc_param) + sizeof(u32); memcpy(&alloc_param.stream_params, sparams, sizeof(*sparams)); kfree(sparams); memcpy(msg->mailbox_data, &msg->header, sizeof(u32)); memcpy(msg->mailbox_data + sizeof(u32), &alloc_param, sizeof(alloc_param)); str_info = &sst_drv_ctx->streams[str_id]; spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags); list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list); spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); sst_drv_ctx->ops->post_message(&sst_drv_ctx->ipc_post_msg_wq); pr_debug("SST DBG:alloc stream done\n"); return str_id; }
void osd_ext_clone_set_angle(int angle) { mutex_lock(&osd_ext_clone_mutex); s_osd_ext_clone.angle = angle; mutex_unlock(&osd_ext_clone_mutex); }
/** * sst_resume_stream - Send msg for resuming stream * @str_id: stream ID * * This function is called by any function which wants to resume * an already paused stream. */ int sst_resume_stream(int str_id) { int retval = 0; struct ipc_post *msg = NULL; struct stream_info *str_info; struct intel_sst_ops *ops; unsigned long irq_flags; struct sst_block *block = NULL; int pvt_id, len; struct ipc_dsp_hdr dsp_hdr; pr_debug("SST DBG:sst_resume_stream for %d\n", str_id); str_info = get_stream_info(str_id); if (!str_info) return -EINVAL; ops = sst_drv_ctx->ops; if (str_info->status == STREAM_RUNNING) return 0; if (str_info->status == STREAM_PAUSED) { if (!sst_drv_ctx->use_32bit_ops) { pvt_id = sst_assign_pvt_id(sst_drv_ctx); retval = sst_create_block_and_ipc_msg(&msg, true, sst_drv_ctx, &block, IPC_CMD, pvt_id); if (retval) return retval; sst_fill_header_mrfld(&msg->mrfld_header, IPC_CMD, str_info->task_id, 1, pvt_id); msg->mrfld_header.p.header_high.part.res_rqd = 1; len = sizeof(dsp_hdr); msg->mrfld_header.p.header_low_payload = len; sst_fill_header_dsp(&dsp_hdr, IPC_IA_RESUME_STREAM_MRFLD, str_info->pipe_id, 0); memcpy(msg->mailbox_data, &dsp_hdr, sizeof(dsp_hdr)); } else { retval = sst_create_block_and_ipc_msg(&msg, false, sst_drv_ctx, &block, IPC_IA_RESUME_STREAM, str_id); if (retval) return retval; sst_fill_header(&msg->header, IPC_IA_RESUME_STREAM, 0, str_id); } spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags); list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list); spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); ops->post_message(&sst_drv_ctx->ipc_post_msg_wq); retval = sst_wait_timeout(sst_drv_ctx, block); sst_free_block(sst_drv_ctx, block); if (!retval) { if (str_info->prev == STREAM_RUNNING) str_info->status = STREAM_RUNNING; else str_info->status = STREAM_INIT; str_info->prev = STREAM_PAUSED; } else if (retval == -SST_ERR_INVALID_STREAM_ID) { retval = -EINVAL; mutex_lock(&sst_drv_ctx->stream_lock); sst_clean_stream(str_info); mutex_unlock(&sst_drv_ctx->stream_lock); } } else { retval = -EBADRQC; pr_err("SST ERR: BADQRC for stream\n"); } return retval; }
int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo) { struct soc_pcmcia_socket *skt; int ret, i; mutex_lock(&soc_pcmcia_sockets_lock); for (i = 0; i < sinfo->nskt; i++) { skt = &sinfo->skt[i]; skt->socket.ops = &soc_common_pcmcia_operations; skt->socket.owner = ops->owner; skt->socket.dev.parent = dev; init_timer(&skt->poll_timer); skt->poll_timer.function = soc_common_pcmcia_poll_event; skt->poll_timer.data = (unsigned long)skt; skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD; skt->dev = dev; skt->ops = ops; ret = request_resource(&iomem_resource, &skt->res_skt); if (ret) goto out_err_1; ret = request_resource(&skt->res_skt, &skt->res_io); if (ret) goto out_err_2; ret = request_resource(&skt->res_skt, &skt->res_mem); if (ret) goto out_err_3; ret = request_resource(&skt->res_skt, &skt->res_attr); if (ret) goto out_err_4; skt->virt_io = ioremap(skt->res_io.start, 0x10000); if (skt->virt_io == NULL) { ret = -ENOMEM; goto out_err_5; } if (list_empty(&soc_pcmcia_sockets)) soc_pcmcia_cpufreq_register(); list_add(&skt->node, &soc_pcmcia_sockets); ops->set_timing(skt); ret = ops->hw_init(skt); if (ret) goto out_err_6; skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD; skt->socket.resource_ops = &pccard_static_ops; skt->socket.irq_mask = 0; skt->socket.map_size = PAGE_SIZE; skt->socket.pci_irq = skt->irq; skt->socket.io_offset = (unsigned long)skt->virt_io; skt->status = soc_common_pcmcia_skt_state(skt); ret = pcmcia_register_socket(&skt->socket); if (ret) goto out_err_7; WARN_ON(skt->socket.sock != i); add_timer(&skt->poll_timer); ret = device_create_file(&skt->socket.dev, &dev_attr_status); if (ret) goto out_err_8; } dev_set_drvdata(dev, sinfo); ret = 0; goto out; do { skt = &sinfo->skt[i]; device_remove_file(&skt->socket.dev, &dev_attr_status); out_err_8: del_timer_sync(&skt->poll_timer); pcmcia_unregister_socket(&skt->socket); out_err_7: flush_scheduled_work(); ops->hw_shutdown(skt); out_err_6: list_del(&skt->node); iounmap(skt->virt_io); out_err_5: release_resource(&skt->res_attr); out_err_4: release_resource(&skt->res_mem); out_err_3: release_resource(&skt->res_io); out_err_2: release_resource(&skt->res_skt); out_err_1: i--; } while (i > 0); kfree(sinfo); out: mutex_unlock(&soc_pcmcia_sockets_lock); return ret; }
/** * sst_free_stream - Frees a stream * @str_id: stream ID * * This function is called by any function which wants to free * a stream. */ int sst_free_stream(int str_id) { int retval = 0; unsigned int pvt_id; struct ipc_post *msg = NULL; struct stream_info *str_info; struct intel_sst_ops *ops; unsigned long irq_flags; struct ipc_dsp_hdr dsp_hdr; struct sst_block *block; pr_debug("SST DBG:sst_free_stream for %d\n", str_id); mutex_lock(&sst_drv_ctx->sst_lock); if (sst_drv_ctx->sst_state == SST_UN_INIT) { mutex_unlock(&sst_drv_ctx->sst_lock); return -ENODEV; } mutex_unlock(&sst_drv_ctx->sst_lock); str_info = get_stream_info(str_id); if (!str_info) return -EINVAL; ops = sst_drv_ctx->ops; mutex_lock(&str_info->lock); if (str_info->status != STREAM_UN_INIT) { str_info->prev = str_info->status; str_info->status = STREAM_UN_INIT; mutex_unlock(&str_info->lock); if (!sst_drv_ctx->use_32bit_ops) { pvt_id = sst_assign_pvt_id(sst_drv_ctx); retval = sst_create_block_and_ipc_msg(&msg, true, sst_drv_ctx, &block, IPC_CMD, pvt_id); if (retval) return retval; sst_fill_header_mrfld(&msg->mrfld_header, IPC_CMD, str_info->task_id, 1, pvt_id); msg->mrfld_header.p.header_low_payload = sizeof(dsp_hdr); sst_fill_header_dsp(&dsp_hdr, IPC_IA_FREE_STREAM_MRFLD, str_info->pipe_id, 0); memcpy(msg->mailbox_data, &dsp_hdr, sizeof(dsp_hdr)); } else { retval = sst_create_block_and_ipc_msg(&msg, false, sst_drv_ctx, &block, IPC_IA_FREE_STREAM, str_id); if (retval) return retval; sst_fill_header(&msg->header, IPC_IA_FREE_STREAM, 0, str_id); } spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags); list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list); spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); if (!sst_drv_ctx->use_32bit_ops) { /*FIXME: do we need to wake up drain stream here, * how to get the pvt_id and msg_id */ } else { sst_wake_up_block(sst_drv_ctx, 0, str_id, IPC_IA_DRAIN_STREAM, NULL, 0); } ops->post_message(&sst_drv_ctx->ipc_post_msg_wq); retval = sst_wait_timeout(sst_drv_ctx, block); pr_debug("sst: wait for free returned %d\n", retval); mutex_lock(&sst_drv_ctx->stream_lock); sst_clean_stream(str_info); mutex_unlock(&sst_drv_ctx->stream_lock); pr_debug("SST DBG:Stream freed\n"); sst_free_block(sst_drv_ctx, block); } else { mutex_unlock(&str_info->lock); retval = -EBADRQC; pr_debug("SST DBG:BADQRC for stream\n"); } return retval; }
/* * Link contents of ipipe to opipe. */ static int link_pipe(struct pipe_inode_info *ipipe, struct pipe_inode_info *opipe, size_t len, unsigned int flags) { struct pipe_buffer *ibuf, *obuf; int ret = 0, i = 0, nbuf; /* * Potential ABBA deadlock, work around it by ordering lock * grabbing by inode address. Otherwise two different processes * could deadlock (one doing tee from A -> B, the other from B -> A). */ if (ipipe->inode < opipe->inode) { mutex_lock(&ipipe->inode->i_mutex); mutex_lock(&opipe->inode->i_mutex); } else { mutex_lock(&opipe->inode->i_mutex); mutex_lock(&ipipe->inode->i_mutex); } do { if (!opipe->readers) { send_sig(SIGPIPE, current, 0); if (!ret) ret = -EPIPE; break; } /* * If we have iterated all input buffers or ran out of * output room, break. */ if (i >= ipipe->nrbufs || opipe->nrbufs >= PIPE_BUFFERS) break; ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1)); nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1); /* * Get a reference to this pipe buffer, * so we can copy the contents over. */ ibuf->ops->get(ipipe, ibuf); obuf = opipe->bufs + nbuf; *obuf = *ibuf; /* * Don't inherit the gift flag, we need to * prevent multiple steals of this page. */ obuf->flags &= ~PIPE_BUF_FLAG_GIFT; if (obuf->len > len) obuf->len = len; opipe->nrbufs++; ret += obuf->len; len -= obuf->len; i++; } while (len); mutex_unlock(&ipipe->inode->i_mutex); mutex_unlock(&opipe->inode->i_mutex); /* * If we put data in the output pipe, wakeup any potential readers. */ if (ret > 0) { smp_mb(); if (waitqueue_active(&opipe->wait)) wake_up_interruptible(&opipe->wait); kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN); } return ret; }
static int cyttsp5_hw_power(struct cyttsp5_core_platform_data *pdata, struct device *dev, int on) { struct regulator *regulator_vdd; struct regulator *regulator_avdd; mutex_lock(&pdata->poweronoff_lock); if (enabled == on) { tsp_debug_err(true, dev, "%s: same command. not excute(%d)\n", __func__, enabled); mutex_unlock(&pdata->poweronoff_lock); return 0; } regulator_vdd = regulator_get(NULL, "vdd_tsp_1v8"); if (IS_ERR(regulator_vdd)) { tsp_debug_err(true, dev, "%s: tsp_vdd regulator_get failed\n", __func__); mutex_unlock(&pdata->poweronoff_lock); return PTR_ERR(regulator_vdd); } regulator_avdd = regulator_get(NULL, "vtsp_a3v3"); if (IS_ERR(regulator_avdd)) { tsp_debug_err(true, dev, "%s: tsp_avdd regulator_get failed\n", __func__); regulator_put(regulator_vdd); mutex_unlock(&pdata->poweronoff_lock); return PTR_ERR(regulator_avdd); } tsp_debug_err(true, dev, "%s %s\n", __func__, on ? "on" : "off"); if (on) { regulator_enable(regulator_avdd); regulator_enable(regulator_vdd); s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf)); #ifdef CONFIG_MACH_KMINI if (system_rev >= 1) s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_UP); else s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE); #else s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE); #endif } else { s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT); s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN); /* * TODO: If there is a case the regulator must be disabled * (e,g firmware update?), consider regulator_force_disable. */ regulator_disable(regulator_vdd); regulator_disable(regulator_avdd); /* TODO: Delay time should be adjusted */ //msleep(10); } enabled = on; regulator_put(regulator_vdd); regulator_put(regulator_avdd); mutex_unlock(&pdata->poweronoff_lock); return 0; }
/* * Pipe input worker. Most of this logic works like a regular pipe, the * key here is the 'actor' worker passed in that actually moves the data * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. */ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags, splice_actor *actor) { int ret, do_wakeup, err; struct splice_desc sd; ret = 0; do_wakeup = 0; sd.total_len = len; sd.flags = flags; sd.file = out; sd.pos = *ppos; if (pipe->inode) mutex_lock(&pipe->inode->i_mutex); for (;;) { if (pipe->nrbufs) { struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; struct pipe_buf_operations *ops = buf->ops; sd.len = buf->len; if (sd.len > sd.total_len) sd.len = sd.total_len; err = actor(pipe, buf, &sd); if (err <= 0) { if (!ret && err != -ENODATA) ret = err; break; } ret += err; buf->offset += err; buf->len -= err; sd.len -= err; sd.pos += err; sd.total_len -= err; if (sd.len) continue; if (!buf->len) { buf->ops = NULL; ops->release(pipe, buf); pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1); pipe->nrbufs--; if (pipe->inode) do_wakeup = 1; } if (!sd.total_len) break; } if (pipe->nrbufs) continue; if (!pipe->writers) break; if (!pipe->waiting_writers) { if (ret) break; } if (flags & SPLICE_F_NONBLOCK) { if (!ret) ret = -EAGAIN; break; } if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; break; } if (do_wakeup) { smp_mb(); if (waitqueue_active(&pipe->wait)) wake_up_interruptible_sync(&pipe->wait); kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); do_wakeup = 0; } pipe_wait(pipe); } if (pipe->inode) mutex_unlock(&pipe->inode->i_mutex); if (do_wakeup) { smp_mb(); if (waitqueue_active(&pipe->wait)) wake_up_interruptible(&pipe->wait); kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); } return ret; }
int ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { return( mutex_unlock( mutex ) ); }