예제 #1
0
struct device *mcuio_add_soft_hc(struct mcuio_device_id *id,
				 const struct mcuio_soft_hc_ops *ops,
				 void *priv)
{
	struct mcuio_hc_platform_data *plat;
	struct mcuio_soft_hc *shc = __setup_shc(ops, priv);
	struct device *out;
	int stat;
	if (IS_ERR(shc))
		return ERR_PTR(PTR_ERR(shc));
	plat = kzalloc(sizeof(*plat), GFP_KERNEL);
	if (!plat) {
		kfree(shc);
		return ERR_PTR(-ENOMEM);
	}
	plat->setup_regmap = mcuio_soft_hc_setup_regmap;
	plat->data = shc;

	stat = bus_register_notifier(&mcuio_bus_type, &device_nb);
	if (stat < 0) {
		kfree(shc);
		return ERR_PTR(stat);
	}

	out = mcuio_add_hc_device(id ? id : &default_soft_hc_id, plat,
				  mcuio_soft_hc_release);
	if (IS_ERR(out)) {
		kfree(shc);
		bus_unregister_notifier(&mcuio_bus_type, &device_nb);
		return out;
	}
	shc->hc = to_mcuio_dev(out);
	return out;
}
예제 #2
0
static void __device_added(struct device *dev)
{
	struct mcuio_device *mdev = to_mcuio_dev(dev);
	struct mcuio_device *hc;
	struct mcuio_soft_hc *shc;
	struct mcuio_device *ic;
	struct mcuio_hc_platform_data *plat;
	int base_irq;

	/* Ignore the hc */
	if (!mdev->device)
		return;
	hc = to_mcuio_dev(dev->parent);
	plat = dev_get_platdata(&hc->dev);
	if (!plat) {
		WARN_ON(1);
		return;
	}
	shc = plat->data;
	if (!shc) {
		WARN_ON(1);
		return;
	}
	/* FIXME: ADD LOCKING */
	ic = shc->irq_controllers[mdev->device];
	if (ic)
		return;
	base_irq = irq_alloc_descs(-1, 0, MCUIO_FUNCS_PER_DEV, 0);
	/* New device, add soft local irq controller */
	ic = mcuio_add_soft_local_irq_ctrl(hc, mdev->device, base_irq);
	if (!ic) {
		pr_err("mcuio soft hc: error adding irq ctrl for dev %d\n",
		       mdev->device);
		return;
	}
	shc->irq_controllers[mdev->device] = ic;
	/*
	  This is the first function of the new device. When the corresponding
	  mcuio_device was instantiated, the hc had no irqs, fix the field
	  up now
	*/
	mdev->irq = base_irq + mdev->fn;
}
예제 #3
0
static struct regmap_mcuio_context *
regmap_mcuio_setup_context(struct mcuio_device *mdev,
			   const struct regmap_config *config)
{
	struct mcuio_device *hc = to_mcuio_dev(mdev->dev.parent);
	struct regmap_mcuio_context *ctx;
	int min_stride;

	if (config->reg_bits != 32)
		return ERR_PTR(-EINVAL);

	switch (config->val_bits) {
	case 8:
		/* The core treats 0 as 1 */
		min_stride = 0;
		break;
	case 16:
		min_stride = 2;
		break;
	case 32:
		min_stride = 4;
		break;
#ifdef CONFIG_64BIT
	case 64:
		min_stride = 8;
		break;
#endif
		break;
	default:
		return ERR_PTR(-EINVAL);
	}

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return ERR_PTR(-ENOMEM);

	ctx->hc = hc;
	ctx->dev = mdev->device;
	ctx->func = mdev->fn;
	ctx->val_bytes = config->val_bits / 8;
	return ctx;
}
예제 #4
0
파일: sysfs.c 프로젝트: LastRitter/mcuio
static ssize_t show_func(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct mcuio_device *mdev = to_mcuio_dev(dev);
	return sprintf(buf, "%u", mdev->fn);
}
예제 #5
0
파일: sysfs.c 프로젝트: LastRitter/mcuio
static ssize_t show_class(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	struct mcuio_device *mdev = to_mcuio_dev(dev);
	return sprintf(buf, "0x%08x", mdev->id.class);
}
예제 #6
0
파일: sysfs.c 프로젝트: LastRitter/mcuio
static ssize_t show_vendor(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct mcuio_device *mdev = to_mcuio_dev(dev);
	return sprintf(buf, "0x%04x", mdev->id.vendor);
}