예제 #1
0
static void __init omap_i2c_hwspinlock_init(int bus_id, int spinlock_id,
					struct omap_i2c_bus_board_data *pdata)
{
	/* spinlock_id should be -1 for a generic lock request */
	if (spinlock_id < 0)
		pdata->handle = hwspin_lock_request();
	else
		pdata->handle = hwspin_lock_request_specific(spinlock_id);

	if (pdata->handle != NULL) {
		pdata->hwspin_lock_timeout = hwspin_lock_timeout;
		pdata->hwspin_unlock = hwspin_unlock;
	} else {
		pr_err("I2C hwspinlock request failed for bus %d\n", bus_id);
	}
}
static int __init early_init_hwlocks(void)
{
	int i;
	struct hwspinlock **plock;
	arch_hwlocks_implemented();

	for (i = 0; i < HWSPINLOCK_ID_TOTAL_NUMS; ++i) {
		if (hwlocks_implemented[i]) {
			plock = &hwlocks[i];
			*plock = hwspin_lock_request_specific(i);
			if (WARN_ON(IS_ERR_OR_NULL(*plock)))
				*plock = NULL;
			else
				pr_info("early alloc hwspinlock id %d\n",
					hwspin_lock_get_id(*plock));
		}
	}
	return 0;
}
static struct hwspinlock *debugfs_hwspinlock_request_specific(int id,
						int *b_id, int *n_locks)
{
	struct hwspinlock_hisi *hwlockinfo;
	struct hwspinlock *_hwlock;

	_hwlock = hwspin_lock_request_specific(id);
	if (!_hwlock) {
		pr_err("hwspinlock %u is already in use\n", id);
		return NULL;
	}

	*b_id = _hwlock->bank->base_id;
	*n_locks = _hwlock->bank->num_locks;
	hwlockinfo = (struct hwspinlock_hisi *)(_hwlock->priv);
	pr_info("[Debug] Cat Sucess! RESOURCE_LOCK ID_IN_Group=%d  ADDR=%p\n",
				hwlockinfo->id_in_group, hwlockinfo->address);
	return _hwlock;
}
static int hi3630_srcup_normal_probe(struct platform_device *pdev)
{
	int ret = -1;
	struct device *dev = &pdev->dev;
	struct hi3630_srcup_data *pdata = NULL;

	if (!dev) {
		loge("platform_device has no device\n");
		return -ENOENT;
	}

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		dev_err(dev, "cannot allocate hi3630 srcup platform data\n");
		return -ENOMEM;
	}

	pdata->dev = dev;

#ifdef SRCUP_ENABLE
	pdata->hi3630_asp_irq = dev_get_drvdata(pdev->dev.parent);
	if (!pdata->hi3630_asp_irq) {
		dev_err(dev, "get parent device error\n");
		return -ENOENT;
	}

	pdata->irq = platform_get_irq_byname(pdev, "asp_srcup_normal");
	if (0 > pdata->irq) {
		dev_err(dev, "cannot get irq\n");
		return -ENOENT;
	}

	pdata->regu.supply = "asp-srcup-normal";
	ret = devm_regulator_bulk_get(dev, 1, &(pdata->regu));
	if (0 != ret) {
		dev_err(dev, "couldn't get regulators %d\n", ret);
		return -ENOENT;
	}

	pdata->hwlock = hwspin_lock_request_specific(HWLOCK_ID);
	if(NULL == pdata->hwlock) {
		dev_err(dev, "couldn't request hwlock:%d\n", HWLOCK_ID);
		return -ENOENT;
	}

#ifdef CONFIG_PM_RUNTIME
	pm_runtime_set_autosuspend_delay(dev, 100); /* 100ms*/
	pm_runtime_use_autosuspend(dev);

	pm_runtime_enable(dev);
#endif
#endif
	platform_set_drvdata(pdev, pdata);

	dev_set_name(dev, "hi3630-srcup-normal");

	ret = snd_soc_register_platform(dev, &hi3630_srcup_normal_platform);
	if (ret) {
		loge("snd_soc_register_platform return %d\n", ret);
		return -ENODEV;
	}

	return ret;
}
static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
{
	struct device *dev = &adev->dev;
	struct pl061_platform_data *pdata = dev->platform_data;
	struct pl061_gpio *chip;
	int ret, irq, i, irq_base;
	struct device_node *np = dev->of_node;

	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	if (pdata) {
		chip->gc.base = pdata->gpio_base;
		irq_base = pdata->irq_base;
		if (irq_base <= 0)
			return -ENODEV;
	} else {
		chip->gc.base = pl061_parse_gpio_base(dev);
		irq_base = 0;
	}

	if (!devm_request_mem_region(dev, adev->res.start,
				     resource_size(&adev->res), "pl061"))
		return -EBUSY;

	chip->base = devm_ioremap(dev, adev->res.start,
				  resource_size(&adev->res));
	if (!chip->base)
		return -ENOMEM;

	spin_lock_init(&chip->lock);

	if (of_get_property(np, "gpio,hwspinlock", NULL)) {
		gpio_hwlock = hwspin_lock_request_specific(GPIO_HWLOCK_ID);
		if (gpio_hwlock == NULL)
			return -EBUSY;
	}

	/* Hook the request()/free() for pinctrl operation */
	if (of_get_property(dev->of_node, "gpio-ranges", NULL)) {
		chip->gc.request = pl061_gpio_request;
		chip->gc.free = pl061_gpio_free;
	}
	chip->gc.direction_input = pl061_direction_input;
	chip->gc.direction_output = pl061_direction_output;
	chip->gc.get = pl061_get_value;
	chip->gc.set = pl061_set_value;
	chip->gc.to_irq = pl061_to_irq;
	chip->gc.ngpio = PL061_GPIO_NR;
	chip->gc.label = dev_name(dev);
	chip->gc.dev = dev;
	chip->gc.owner = THIS_MODULE;

	ret = gpiochip_add(&chip->gc);
	if (ret)
		return ret;

	/*
	 * irq_chip support
	 */
	writeb(0, chip->base + GPIOIE); /* disable irqs */
	irq = adev->irq[0];
	if (irq < 0)
		return -ENODEV;

	irq_set_chained_handler(irq, pl061_irq_handler);
	irq_set_handler_data(irq, chip);

	chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR,
					     irq_base, &pl061_domain_ops, chip);
	if (!chip->domain)
		return -ENODEV;

	for (i = 0; i < PL061_GPIO_NR; i++) {
		if (pdata) {
			if (pdata->directions & (1 << i))
				pl061_direction_output(&chip->gc, i,
						pdata->values & (1 << i));
			else
				pl061_direction_input(&chip->gc, i);
		}
	}

	amba_set_drvdata(adev, chip);

	return 0;
}
static ssize_t
debugfs_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
{
	struct hwspinlock *__hwlock;
	char buf[128];
	char *cmd = NULL;
	char *_cmd = NULL;
	int id;
	int timeout;
	int unlock;
	int ret ;

	if (NULL == ubuf || 0 == cnt){
		pr_err("buf is null !\n");
		return (-EINVAL);
	}
	if(cnt > sizeof(buf))
	{
		pr_err("input count larger! \n");
		return (-ENOMEM);
	}

	if (copy_from_user(buf, ubuf, cnt - 1)) {
		pr_err("[Hwspinlock Debugfs] can not copy from user\n");
		cnt = -EINVAL;
		goto out;
	}

	buf[cnt - 1] = '\0';
	cmd = buf;
	_cmd = buf;
	pr_debug("[Hwspinlock Debugfs] [cmd: %s[cnt: %d]]\n", cmd, (int)cnt);

	if (!strncmp("request ", _cmd, strlen("request "))) {
		cmd = cmd + strlen("request ");
		_cmd = cmd;
		while ((' ' != *_cmd) && ('\0' != *_cmd))
			_cmd++;
		*_cmd = '\0';

		if (kstrtos32(cmd, 10, &id)) {
			pr_err("Hwspinlock Debugfs cmd error\n");
			cnt = -EINVAL;
			goto out;
		}

		hwlock = hwspin_lock_request_specific(id);
		if (!hwlock)
			pr_err("hwspinlock %u is already in use\n", id);
		else
			pr_info("[debug] Request hwspinlock %d sucess!",id);
	} else if (!strncmp("free_lock ", _cmd, strlen("free_lock "))) {
		cmd = cmd + strlen("free_lock ");
		_cmd = cmd;
		while ((' ' != *_cmd) && ('\0' != *_cmd))
			_cmd++;
		*_cmd = '\0';
		if (kstrtos32(cmd, 10, &id)) {
			pr_err("Hwspinlock Debugfs cmd error\n");
			cnt = -EINVAL;
			goto out;
		}

		if (!hwlock){
			__hwlock = hwspin_lock_lookup(id);
			if (__hwlock){
				debugfs_hwspinlock_lock_free(__hwlock);
				__hwlock = NULL;
			}else{
				pr_err("Current haven't requested the hwspinlock %d\n",id);
				goto out;
			}
		}else if (hwlock_to_id(hwlock) == id){
			debugfs_hwspinlock_lock_free(hwlock);
			hwlock = NULL;
		}else
			pr_err("[debug] please freelock the correct lock!\n");
	} else if (!strncmp("trylock ", _cmd, strlen("trylock "))) {
		cmd = cmd + strlen("trylock ");
		_cmd = cmd;
		while ((' ' != *_cmd) && ('\0' != *_cmd))
			_cmd++;

		if ('\0' == *_cmd) {
			pr_err("[debug] cmd error\n");
			cnt = -EINVAL;
			goto out;
		}
		*_cmd = '\0';

		if (kstrtos32(cmd, 10, &id)) {
			pr_err("[debug] cmd error\n");
			cnt = -EINVAL;
			goto out;
		}

		cmd = _cmd + 1;
		_cmd = cmd;
		while ((' ' != *_cmd) && ('\0' != *_cmd))
			_cmd++;
		*_cmd = '\0';
		if (kstrtos32(cmd, 10, &timeout)) {
			pr_err("[debug] cmd error\n");
			cnt = -EINVAL;
			goto out;
		}

		cmd = _cmd + 1;
		_cmd = cmd;
		while ((' ' != *_cmd) && ('\0' != *_cmd))
			_cmd++;
		*_cmd = '\0';

		if (kstrtos32(cmd, 10, &unlock)) {
			pr_err("[debug] cmd error\n");
			cnt = -EINVAL;
			goto out;
		}

		if (!hwlock){
			pr_err("Current haven't requested the hwspinlock %d\n",id);
			goto out;
		}else if (hwlock_to_id(hwlock) == id && timeout >= 0){
			ret =debugfs_hwspinlock_trylock_timeout(id, timeout, unlock);
			if (!ret){
				if (0 == timeout)
					pr_info("[debug] hwspin_trylock %d sucess!\n",id);
				else
					pr_info("[debug] hwspin_trylock_timout %d sucess!\n",id);
			}
		}else if(timeout < 0)
			pr_err("[debug] cmd err! timeout must > 0\n");
		else
			pr_err("[debug] please trylock the correct lock!\n");
	}else if (!strncmp("unlock ", _cmd, strlen("unlock "))) {
		cmd = cmd + strlen("unlock ");
		_cmd = cmd;
		while ((' ' != *_cmd) && ('\0' != *_cmd))
			_cmd++;
		*_cmd = '\0';
		if (kstrtos32(cmd, 10, &id)) {
			pr_err("Hwspinlock Debugfs cmd error\n");
			cnt = -EINVAL;
			goto out;
		}

                if (!hwlock){
			pr_err("Current don't echo request the hwspinlock %d\n",id);
			goto out;
		}else if(hwlock_to_id(hwlock) == id && locked == 1){
			hwspin_unlock(hwlock);
			pr_info("[debug] hwspin_unlock id=%d sucess!\n",id);
		}else
			pr_err("[debug] please free the correct request lock!\n");
	} else {
		pr_err("Hwspinlock Debugfs cmd error\n");
		cnt = -EINVAL;
	}
out:
	return cnt;
}
예제 #7
0
static int sc27xx_adc_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct sc27xx_adc_data *sc27xx_data;
	struct iio_dev *indio_dev;
	int ret;

	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*sc27xx_data));
	if (!indio_dev)
		return -ENOMEM;

	sc27xx_data = iio_priv(indio_dev);

	sc27xx_data->regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!sc27xx_data->regmap) {
		dev_err(&pdev->dev, "failed to get ADC regmap\n");
		return -ENODEV;
	}

	ret = of_property_read_u32(np, "reg", &sc27xx_data->base);
	if (ret) {
		dev_err(&pdev->dev, "failed to get ADC base address\n");
		return ret;
	}

	sc27xx_data->irq = platform_get_irq(pdev, 0);
	if (sc27xx_data->irq < 0) {
		dev_err(&pdev->dev, "failed to get ADC irq number\n");
		return sc27xx_data->irq;
	}

	ret = of_hwspin_lock_get_id(np, 0);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to get hwspinlock id\n");
		return ret;
	}

	sc27xx_data->hwlock = hwspin_lock_request_specific(ret);
	if (!sc27xx_data->hwlock) {
		dev_err(&pdev->dev, "failed to request hwspinlock\n");
		return -ENXIO;
	}

	ret = devm_add_action(&pdev->dev, sc27xx_adc_free_hwlock,
			      sc27xx_data->hwlock);
	if (ret) {
		sc27xx_adc_free_hwlock(sc27xx_data->hwlock);
		dev_err(&pdev->dev, "failed to add hwspinlock action\n");
		return ret;
	}

	init_completion(&sc27xx_data->completion);
	sc27xx_data->dev = &pdev->dev;

	ret = sc27xx_adc_enable(sc27xx_data);
	if (ret) {
		dev_err(&pdev->dev, "failed to enable ADC module\n");
		return ret;
	}

	ret = devm_add_action(&pdev->dev, sc27xx_adc_disable, sc27xx_data);
	if (ret) {
		sc27xx_adc_disable(sc27xx_data);
		dev_err(&pdev->dev, "failed to add ADC disable action\n");
		return ret;
	}

	ret = devm_request_threaded_irq(&pdev->dev, sc27xx_data->irq, NULL,
					sc27xx_adc_isr, IRQF_ONESHOT,
					pdev->name, sc27xx_data);
	if (ret) {
		dev_err(&pdev->dev, "failed to request ADC irq\n");
		return ret;
	}

	indio_dev->dev.parent = &pdev->dev;
	indio_dev->name = dev_name(&pdev->dev);
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &sc27xx_info;
	indio_dev->channels = sc27xx_channels;
	indio_dev->num_channels = ARRAY_SIZE(sc27xx_channels);
	ret = devm_iio_device_register(&pdev->dev, indio_dev);
	if (ret)
		dev_err(&pdev->dev, "could not register iio (ADC)");

	return ret;
}