예제 #1
0
static int vprbrd_gpio_probe(struct platform_device *pdev)
{
	struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
	struct vprbrd_gpio *vb_gpio;
	int ret;

	vb_gpio = devm_kzalloc(&pdev->dev, sizeof(*vb_gpio), GFP_KERNEL);
	if (vb_gpio == NULL)
		return -ENOMEM;

	vb_gpio->vb = vb;
	/* registering gpio a */
	vb_gpio->gpioa.label = "viperboard gpio a";
	vb_gpio->gpioa.parent = &pdev->dev;
	vb_gpio->gpioa.owner = THIS_MODULE;
	vb_gpio->gpioa.base = -1;
	vb_gpio->gpioa.ngpio = 16;
	vb_gpio->gpioa.can_sleep = true;
	vb_gpio->gpioa.set = vprbrd_gpioa_set;
	vb_gpio->gpioa.get = vprbrd_gpioa_get;
	vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input;
	vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output;
	ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpioa, vb_gpio);
	if (ret < 0) {
		dev_err(vb_gpio->gpioa.parent, "could not add gpio a");
		return ret;
	}

	/* registering gpio b */
	vb_gpio->gpiob.label = "viperboard gpio b";
	vb_gpio->gpiob.parent = &pdev->dev;
	vb_gpio->gpiob.owner = THIS_MODULE;
	vb_gpio->gpiob.base = -1;
	vb_gpio->gpiob.ngpio = 16;
	vb_gpio->gpiob.can_sleep = true;
	vb_gpio->gpiob.set = vprbrd_gpiob_set;
	vb_gpio->gpiob.get = vprbrd_gpiob_get;
	vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input;
	vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output;
	ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpiob, vb_gpio);
	if (ret < 0) {
		dev_err(vb_gpio->gpiob.parent, "could not add gpio b");
		return ret;
	}

	platform_set_drvdata(pdev, vb_gpio);

	return ret;
}
예제 #2
0
파일: gpio-octeon.c 프로젝트: avagin/linux
static int octeon_gpio_probe(struct platform_device *pdev)
{
	struct octeon_gpio *gpio;
	struct gpio_chip *chip;
	void __iomem *reg_base;
	int err = 0;

	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
	if (!gpio)
		return -ENOMEM;
	chip = &gpio->chip;

	reg_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(reg_base))
		return PTR_ERR(reg_base);

	gpio->register_base = (u64)reg_base;
	pdev->dev.platform_data = chip;
	chip->label = "octeon-gpio";
	chip->parent = &pdev->dev;
	chip->owner = THIS_MODULE;
	chip->base = 0;
	chip->can_sleep = false;
	chip->ngpio = 20;
	chip->direction_input = octeon_gpio_dir_in;
	chip->get = octeon_gpio_get;
	chip->direction_output = octeon_gpio_dir_out;
	chip->set = octeon_gpio_set;
	err = devm_gpiochip_add_data(&pdev->dev, chip, gpio);
	if (err)
		return err;

	dev_info(&pdev->dev, "OCTEON GPIO driver probed.\n");
	return 0;
}
예제 #3
0
파일: gpio.c 프로젝트: Lyude/linux
static struct sh_pfc_chip *
sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *),
		    struct sh_pfc_window *mem)
{
	struct sh_pfc_chip *chip;
	int ret;

	chip = devm_kzalloc(pfc->dev, sizeof(*chip), GFP_KERNEL);
	if (unlikely(!chip))
		return ERR_PTR(-ENOMEM);

	chip->mem = mem;
	chip->pfc = pfc;

	ret = setup(chip);
	if (ret < 0)
		return ERR_PTR(ret);

	ret = devm_gpiochip_add_data(pfc->dev, &chip->gpio_chip, chip);
	if (unlikely(ret < 0))
		return ERR_PTR(ret);

	dev_info(pfc->dev, "%s handling gpio %u -> %u\n",
		 chip->gpio_chip.label, chip->gpio_chip.base,
		 chip->gpio_chip.base + chip->gpio_chip.ngpio - 1);

	return chip;
}
예제 #4
0
static int wm8994_gpio_probe(struct platform_device *pdev)
{
	struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
	struct wm8994_pdata *pdata = dev_get_platdata(wm8994->dev);
	struct wm8994_gpio *wm8994_gpio;
	int ret;

	wm8994_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm8994_gpio),
				   GFP_KERNEL);
	if (wm8994_gpio == NULL)
		return -ENOMEM;

	wm8994_gpio->wm8994 = wm8994;
	wm8994_gpio->gpio_chip = template_chip;
	wm8994_gpio->gpio_chip.ngpio = WM8994_GPIO_MAX;
	wm8994_gpio->gpio_chip.parent = &pdev->dev;
	if (pdata && pdata->gpio_base)
		wm8994_gpio->gpio_chip.base = pdata->gpio_base;
	else
		wm8994_gpio->gpio_chip.base = -1;

	ret = devm_gpiochip_add_data(&pdev->dev, &wm8994_gpio->gpio_chip,
				     wm8994_gpio);
	if (ret < 0) {
		dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
			ret);
		return ret;
	}

	platform_set_drvdata(pdev, wm8994_gpio);

	return ret;
}
예제 #5
0
static int wm831x_gpio_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_pdata *pdata = &wm831x->pdata;
	struct wm831x_gpio *wm831x_gpio;
	int ret;

	wm831x_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm831x_gpio),
				   GFP_KERNEL);
	if (wm831x_gpio == NULL)
		return -ENOMEM;

	wm831x_gpio->wm831x = wm831x;
	wm831x_gpio->gpio_chip = template_chip;
	wm831x_gpio->gpio_chip.ngpio = wm831x->num_gpio;
	wm831x_gpio->gpio_chip.parent = &pdev->dev;
	if (pdata && pdata->gpio_base)
		wm831x_gpio->gpio_chip.base = pdata->gpio_base;
	else
		wm831x_gpio->gpio_chip.base = -1;
#ifdef CONFIG_OF_GPIO
	wm831x_gpio->gpio_chip.of_node = wm831x->dev->of_node;
#endif

	ret = devm_gpiochip_add_data(&pdev->dev, &wm831x_gpio->gpio_chip,
				     wm831x_gpio);
	if (ret < 0) {
		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, wm831x_gpio);

	return ret;
}
예제 #6
0
static int clps711x_gpio_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	void __iomem *dat, *dir;
	struct gpio_chip *gc;
	struct resource *res;
	int err, id;

	if (!np)
		return -ENODEV;

	id = of_alias_get_id(np, "gpio");
	if ((id < 0) || (id > 4))
		return -ENODEV;

	gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
	if (!gc)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dat = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dat))
		return PTR_ERR(dat);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	dir = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dir))
		return PTR_ERR(dir);

	switch (id) {
	case 3:
		/* PORTD is inverted logic for direction register */
		err = bgpio_init(gc, &pdev->dev, 1, dat, NULL, NULL,
				 NULL, dir, 0);
		break;
	default:
		err = bgpio_init(gc, &pdev->dev, 1, dat, NULL, NULL,
				 dir, NULL, 0);
		break;
	}

	if (err)
		return err;

	switch (id) {
	case 4:
		/* PORTE is 3 lines only */
		gc->ngpio = 3;
		break;
	default:
		break;
	}

	gc->base = -1;
	gc->owner = THIS_MODULE;
	platform_set_drvdata(pdev, gc);

	return devm_gpiochip_add_data(&pdev->dev, gc, NULL);
}
예제 #7
0
static int arizona_gpio_probe(struct platform_device *pdev)
{
	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
	struct arizona_pdata *pdata = dev_get_platdata(arizona->dev);
	struct arizona_gpio *arizona_gpio;
	int ret;

	arizona_gpio = devm_kzalloc(&pdev->dev, sizeof(*arizona_gpio),
				    GFP_KERNEL);
	if (!arizona_gpio)
		return -ENOMEM;

	arizona_gpio->arizona = arizona;
	arizona_gpio->gpio_chip = template_chip;
	arizona_gpio->gpio_chip.parent = &pdev->dev;
#ifdef CONFIG_OF_GPIO
	arizona_gpio->gpio_chip.of_node = arizona->dev->of_node;
#endif

	switch (arizona->type) {
	case WM5102:
	case WM5110:
	case WM8280:
	case WM8997:
	case WM8998:
	case WM1814:
		arizona_gpio->gpio_chip.ngpio = 5;
		break;
	case WM1831:
	case CS47L24:
		arizona_gpio->gpio_chip.ngpio = 2;
		break;
	default:
		dev_err(&pdev->dev, "Unknown chip variant %d\n",
			arizona->type);
		return -EINVAL;
	}

	if (pdata && pdata->gpio_base)
		arizona_gpio->gpio_chip.base = pdata->gpio_base;
	else
		arizona_gpio->gpio_chip.base = -1;

	ret = devm_gpiochip_add_data(&pdev->dev, &arizona_gpio->gpio_chip,
				     arizona_gpio);
	if (ret < 0) {
		dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
			ret);
		goto err;
	}

	platform_set_drvdata(pdev, arizona_gpio);

	return ret;

err:
	return ret;
}
예제 #8
0
파일: gpio-f7188x.c 프로젝트: 020gzh/linux
static int f7188x_gpio_probe(struct platform_device *pdev)
{
	int err;
	int i;
	struct f7188x_sio *sio = dev_get_platdata(&pdev->dev);
	struct f7188x_gpio_data *data;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	switch (sio->type) {
	case f71869:
		data->nr_bank = ARRAY_SIZE(f71869_gpio_bank);
		data->bank = f71869_gpio_bank;
		break;
	case f71869a:
		data->nr_bank = ARRAY_SIZE(f71869a_gpio_bank);
		data->bank = f71869a_gpio_bank;
		break;
	case f71882fg:
		data->nr_bank = ARRAY_SIZE(f71882_gpio_bank);
		data->bank = f71882_gpio_bank;
		break;
	case f71889f:
		data->nr_bank = ARRAY_SIZE(f71889_gpio_bank);
		data->bank = f71889_gpio_bank;
		break;
	case f81866:
		data->nr_bank = ARRAY_SIZE(f81866_gpio_bank);
		data->bank = f81866_gpio_bank;
		break;
	default:
		return -ENODEV;
	}
	data->sio = sio;

	platform_set_drvdata(pdev, data);

	/* For each GPIO bank, register a GPIO chip. */
	for (i = 0; i < data->nr_bank; i++) {
		struct f7188x_gpio_bank *bank = &data->bank[i];

		bank->chip.parent = &pdev->dev;
		bank->data = data;

		err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank);
		if (err) {
			dev_err(&pdev->dev,
				"Failed to register gpiochip %d: %d\n",
				i, err);
			return err;
		}
	}

	return 0;
}
예제 #9
0
static int ttl_probe(struct platform_device *pdev)
{
	struct janz_platform_data *pdata;
	struct device *dev = &pdev->dev;
	struct ttl_module *mod;
	struct gpio_chip *gpio;
	struct resource *res;
	int ret;

	pdata = dev_get_platdata(&pdev->dev);
	if (!pdata) {
		dev_err(dev, "no platform data\n");
		return -ENXIO;
	}

	mod = devm_kzalloc(dev, sizeof(*mod), GFP_KERNEL);
	if (!mod)
		return -ENOMEM;

	platform_set_drvdata(pdev, mod);
	spin_lock_init(&mod->lock);

	/* get access to the MODULbus registers for this module */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	mod->regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(mod->regs))
		return PTR_ERR(mod->regs);

	ttl_setup_device(mod);

	/* Initialize the GPIO data structures */
	gpio = &mod->gpio;
	gpio->parent = &pdev->dev;
	gpio->label = pdev->name;
	gpio->get = ttl_get_value;
	gpio->set = ttl_set_value;
	gpio->owner = THIS_MODULE;

	/* request dynamic allocation */
	gpio->base = -1;
	gpio->ngpio = 20;

	ret = devm_gpiochip_add_data(dev, gpio, NULL);
	if (ret) {
		dev_err(dev, "unable to add GPIO chip\n");
		return ret;
	}

	return 0;
}
예제 #10
0
파일: gpio-ge.c 프로젝트: 020gzh/linux
static int __init gef_gpio_probe(struct platform_device *pdev)
{
	const struct of_device_id *of_id =
		of_match_device(gef_gpio_ids, &pdev->dev);
	struct gpio_chip *gc;
	void __iomem *regs;
	int ret;

	gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
	if (!gc)
		return -ENOMEM;

	regs = of_iomap(pdev->dev.of_node, 0);
	if (!regs)
		return -ENOMEM;

	ret = bgpio_init(gc, &pdev->dev, 4, regs + GEF_GPIO_IN,
			 regs + GEF_GPIO_OUT, NULL, NULL,
			 regs + GEF_GPIO_DIRECT, BGPIOF_BIG_ENDIAN_BYTE_ORDER);
	if (ret) {
		dev_err(&pdev->dev, "bgpio_init failed\n");
		goto err0;
	}

	/* Setup pointers to chip functions */
	gc->label = devm_kstrdup(&pdev->dev, pdev->dev.of_node->full_name,
				     GFP_KERNEL);
	if (!gc->label) {
		ret = -ENOMEM;
		goto err0;
	}

	gc->base = -1;
	gc->ngpio = (u16)(uintptr_t)of_id->data;
	gc->of_gpio_n_cells = 2;
	gc->of_node = pdev->dev.of_node;

	/* This function adds a memory mapped GPIO chip */
	ret = devm_gpiochip_add_data(&pdev->dev, gc, NULL);
	if (ret)
		goto err0;

	return 0;
err0:
	iounmap(regs);
	pr_err("%s: GPIO chip registration failed\n",
			pdev->dev.of_node->full_name);
	return ret;
};
예제 #11
0
static int crystalcove_gpio_probe(struct platform_device *pdev)
{
	int irq = platform_get_irq(pdev, 0);
	struct crystalcove_gpio *cg;
	int retval;
	struct device *dev = pdev->dev.parent;
	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);

	if (irq < 0)
		return irq;

	cg = devm_kzalloc(&pdev->dev, sizeof(*cg), GFP_KERNEL);
	if (!cg)
		return -ENOMEM;

	platform_set_drvdata(pdev, cg);

	mutex_init(&cg->buslock);
	cg->chip.label = KBUILD_MODNAME;
	cg->chip.direction_input = crystalcove_gpio_dir_in;
	cg->chip.direction_output = crystalcove_gpio_dir_out;
	cg->chip.get = crystalcove_gpio_get;
	cg->chip.set = crystalcove_gpio_set;
	cg->chip.base = -1;
	cg->chip.ngpio = CRYSTALCOVE_VGPIO_NUM;
	cg->chip.can_sleep = true;
	cg->chip.parent = dev;
	cg->chip.dbg_show = crystalcove_gpio_dbg_show;
	cg->regmap = pmic->regmap;

	retval = devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg);
	if (retval) {
		dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval);
		return retval;
	}

	gpiochip_irqchip_add(&cg->chip, &crystalcove_irqchip, 0,
			     handle_simple_irq, IRQ_TYPE_NONE);

	retval = request_threaded_irq(irq, NULL, crystalcove_gpio_irq_handler,
				      IRQF_ONESHOT, KBUILD_MODNAME, cg);

	if (retval) {
		dev_warn(&pdev->dev, "request irq failed: %d\n", retval);
		return retval;
	}

	return 0;
}
예제 #12
0
static int creg_gpio_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	struct device *dev = &pdev->dev;
	struct creg_gpio *hcg;
	struct resource *mem;
	u32 ngpios;
	int ret;

	hcg = devm_kzalloc(dev, sizeof(struct creg_gpio), GFP_KERNEL);
	if (!hcg)
		return -ENOMEM;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hcg->regs = devm_ioremap_resource(dev, mem);
	if (IS_ERR(hcg->regs))
		return PTR_ERR(hcg->regs);

	match = of_match_node(creg_gpio_ids, pdev->dev.of_node);
	hcg->layout = match->data;
	if (!hcg->layout)
		return -EINVAL;

	ret = of_property_read_u32(dev->of_node, "ngpios", &ngpios);
	if (ret)
		return ret;

	ret = creg_gpio_validate(dev, hcg, ngpios);
	if (ret)
		return ret;

	spin_lock_init(&hcg->lock);

	hcg->gc.label = dev_name(dev);
	hcg->gc.base = -1;
	hcg->gc.ngpio = ngpios;
	hcg->gc.set = creg_gpio_set;
	hcg->gc.direction_output = creg_gpio_dir_out;
	hcg->gc.of_node = dev->of_node;

	ret = devm_gpiochip_add_data(dev, &hcg->gc, hcg);
	if (ret)
		return ret;

	dev_info(dev, "GPIO controller with %d gpios probed\n", ngpios);

	return 0;
}
예제 #13
0
파일: gpio-xgene.c 프로젝트: AvalonSG/linux
static int xgene_gpio_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct xgene_gpio *gpio;
	int err = 0;

	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
	if (!gpio) {
		err = -ENOMEM;
		goto err;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	gpio->base = devm_ioremap_nocache(&pdev->dev, res->start,
							resource_size(res));
	if (!gpio->base) {
		err = -ENOMEM;
		goto err;
	}

	gpio->chip.ngpio = XGENE_MAX_GPIOS;

	spin_lock_init(&gpio->lock);
	gpio->chip.parent = &pdev->dev;
	gpio->chip.direction_input = xgene_gpio_dir_in;
	gpio->chip.direction_output = xgene_gpio_dir_out;
	gpio->chip.get = xgene_gpio_get;
	gpio->chip.set = xgene_gpio_set;
	gpio->chip.label = dev_name(&pdev->dev);
	gpio->chip.base = -1;

	platform_set_drvdata(pdev, gpio);

	err = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
	if (err) {
		dev_err(&pdev->dev,
			"failed to register gpiochip.\n");
		goto err;
	}

	dev_info(&pdev->dev, "X-Gene GPIO driver registered.\n");
	return 0;
err:
	dev_err(&pdev->dev, "X-Gene GPIO driver registration failed.\n");
	return err;
}
예제 #14
0
static int tps6586x_gpio_probe(struct platform_device *pdev)
{
	struct tps6586x_platform_data *pdata;
	struct tps6586x_gpio *tps6586x_gpio;
	int ret;

	pdata = dev_get_platdata(pdev->dev.parent);
	tps6586x_gpio = devm_kzalloc(&pdev->dev,
				sizeof(*tps6586x_gpio), GFP_KERNEL);
	if (!tps6586x_gpio)
		return -ENOMEM;

	tps6586x_gpio->parent = pdev->dev.parent;

	tps6586x_gpio->gpio_chip.owner = THIS_MODULE;
	tps6586x_gpio->gpio_chip.label = pdev->name;
	tps6586x_gpio->gpio_chip.parent = &pdev->dev;
	tps6586x_gpio->gpio_chip.ngpio = 4;
	tps6586x_gpio->gpio_chip.can_sleep = true;

	/* FIXME: add handling of GPIOs as dedicated inputs */
	tps6586x_gpio->gpio_chip.direction_output = tps6586x_gpio_output;
	tps6586x_gpio->gpio_chip.set	= tps6586x_gpio_set;
	tps6586x_gpio->gpio_chip.get	= tps6586x_gpio_get;
	tps6586x_gpio->gpio_chip.to_irq	= tps6586x_gpio_to_irq;

#ifdef CONFIG_OF_GPIO
	tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node;
#endif
	if (pdata && pdata->gpio_base)
		tps6586x_gpio->gpio_chip.base = pdata->gpio_base;
	else
		tps6586x_gpio->gpio_chip.base = -1;

	ret = devm_gpiochip_add_data(&pdev->dev, &tps6586x_gpio->gpio_chip,
				     tps6586x_gpio);
	if (ret < 0) {
		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, tps6586x_gpio);

	return ret;
}
예제 #15
0
파일: gpio-lp3943.c 프로젝트: 020gzh/linux
static int lp3943_gpio_probe(struct platform_device *pdev)
{
	struct lp3943 *lp3943 = dev_get_drvdata(pdev->dev.parent);
	struct lp3943_gpio *lp3943_gpio;

	lp3943_gpio = devm_kzalloc(&pdev->dev, sizeof(*lp3943_gpio),
				GFP_KERNEL);
	if (!lp3943_gpio)
		return -ENOMEM;

	lp3943_gpio->lp3943 = lp3943;
	lp3943_gpio->chip = lp3943_gpio_chip;
	lp3943_gpio->chip.parent = &pdev->dev;

	platform_set_drvdata(pdev, lp3943_gpio);

	return devm_gpiochip_add_data(&pdev->dev, &lp3943_gpio->chip,
				      lp3943_gpio);
}
예제 #16
0
static int gw_pld_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct device_node *np = dev->of_node;
	struct gw_pld *gw;
	int ret;

	gw = devm_kzalloc(dev, sizeof(*gw), GFP_KERNEL);
	if (!gw)
		return -ENOMEM;

	gw->chip.base = -1;
	gw->chip.can_sleep = true;
	gw->chip.parent = dev;
	gw->chip.of_node = np;
	gw->chip.owner = THIS_MODULE;
	gw->chip.label = dev_name(dev);
	gw->chip.ngpio = 8;
	gw->chip.direction_input = gw_pld_input8;
	gw->chip.get = gw_pld_get8;
	gw->chip.direction_output = gw_pld_output8;
	gw->chip.set = gw_pld_set8;
	gw->client = client;

	/*
	 * The Gateworks I2C PLD chip does not properly send the acknowledge
	 * bit at all times, but we can still use the standard i2c_smbus
	 * functions by simply ignoring this bit.
	 */
	client->flags |= I2C_M_IGNORE_NAK;
	gw->out = 0xFF;

	i2c_set_clientdata(client, gw);

	ret = devm_gpiochip_add_data(dev, &gw->chip, gw);
	if (ret)
		return ret;

	dev_info(dev, "registered Gateworks PLD GPIO device\n");

	return 0;
}
예제 #17
0
static int axp20x_gpio_probe(struct platform_device *pdev)
{
    struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
    struct axp20x_gpio *gpio;
    int ret;

    if (!of_device_is_available(pdev->dev.of_node))
        return -ENODEV;

    if (!axp20x) {
        dev_err(&pdev->dev, "Parent drvdata not set\n");
        return -EINVAL;
    }

    gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
    if (!gpio)
        return -ENOMEM;

    gpio->chip.base			= -1;
    gpio->chip.can_sleep		= true;
    gpio->chip.parent		= &pdev->dev;
    gpio->chip.label		= dev_name(&pdev->dev);
    gpio->chip.owner		= THIS_MODULE;
    gpio->chip.get			= axp20x_gpio_get;
    gpio->chip.set			= axp20x_gpio_set;
    gpio->chip.direction_input	= axp20x_gpio_input;
    gpio->chip.direction_output	= axp20x_gpio_output;
    gpio->chip.ngpio		= 3;

    gpio->regmap = axp20x->regmap;

    ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
    if (ret) {
        dev_err(&pdev->dev, "Failed to register GPIO chip\n");
        return ret;
    }

    dev_info(&pdev->dev, "AXP209 GPIO driver loaded\n");

    return 0;
}
예제 #18
0
파일: gpio-mlxbf.c 프로젝트: avagin/linux
static int mlxbf_gpio_probe(struct platform_device *pdev)
{
	struct mlxbf_gpio_state *gs;
	struct device *dev = &pdev->dev;
	struct gpio_chip *gc;
	int ret;

	gs = devm_kzalloc(&pdev->dev, sizeof(*gs), GFP_KERNEL);
	if (!gs)
		return -ENOMEM;

	gs->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(gs->base))
		return PTR_ERR(gs->base);

	gc = &gs->gc;
	ret = bgpio_init(gc, dev, 8,
			 gs->base + MLXBF_GPIO_PIN_STATE,
			 NULL,
			 NULL,
			 gs->base + MLXBF_GPIO_PIN_DIR_O,
			 gs->base + MLXBF_GPIO_PIN_DIR_I,
			 0);
	if (ret)
		return -ENODEV;

	gc->owner = THIS_MODULE;
	gc->ngpio = MLXBF_GPIO_NR;

	ret = devm_gpiochip_add_data(dev, &gs->gc, gs);
	if (ret) {
		dev_err(&pdev->dev, "Failed adding memory mapped gpiochip\n");
		return ret;
	}

	platform_set_drvdata(pdev, gs);
	dev_info(&pdev->dev, "registered Mellanox BlueField GPIO");
	return 0;
}
예제 #19
0
static int mc9s08dz60_probe(struct i2c_client *client,
			    const struct i2c_device_id *id)
{
	struct mc9s08dz60 *mc9s;

	mc9s = devm_kzalloc(&client->dev, sizeof(*mc9s), GFP_KERNEL);
	if (!mc9s)
		return -ENOMEM;

	mc9s->chip.label = client->name;
	mc9s->chip.base = -1;
	mc9s->chip.parent = &client->dev;
	mc9s->chip.owner = THIS_MODULE;
	mc9s->chip.ngpio = GPIO_NUM;
	mc9s->chip.can_sleep = true;
	mc9s->chip.get = mc9s08dz60_get_value;
	mc9s->chip.set = mc9s08dz60_set_value;
	mc9s->chip.direction_output = mc9s08dz60_direction_output;
	mc9s->client = client;
	i2c_set_clientdata(client, mc9s);

	return devm_gpiochip_add_data(&client->dev, &mc9s->chip, mc9s);
}
예제 #20
0
파일: gpio-rdc321x.c 프로젝트: 020gzh/linux
/*
 * Cache the initial value of both GPIO data registers
 */
static int rdc321x_gpio_probe(struct platform_device *pdev)
{
	int err;
	struct resource *r;
	struct rdc321x_gpio *rdc321x_gpio_dev;
	struct rdc321x_gpio_pdata *pdata;

	pdata = dev_get_platdata(&pdev->dev);
	if (!pdata) {
		dev_err(&pdev->dev, "no platform data supplied\n");
		return -ENODEV;
	}

	rdc321x_gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct rdc321x_gpio),
					GFP_KERNEL);
	if (!rdc321x_gpio_dev)
		return -ENOMEM;

	r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1");
	if (!r) {
		dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n");
		return -ENODEV;
	}

	spin_lock_init(&rdc321x_gpio_dev->lock);
	rdc321x_gpio_dev->sb_pdev = pdata->sb_pdev;
	rdc321x_gpio_dev->reg1_ctrl_base = r->start;
	rdc321x_gpio_dev->reg1_data_base = r->start + 0x4;

	r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg2");
	if (!r) {
		dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n");
		return -ENODEV;
	}

	rdc321x_gpio_dev->reg2_ctrl_base = r->start;
	rdc321x_gpio_dev->reg2_data_base = r->start + 0x4;

	rdc321x_gpio_dev->chip.label = "rdc321x-gpio";
	rdc321x_gpio_dev->chip.owner = THIS_MODULE;
	rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input;
	rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config;
	rdc321x_gpio_dev->chip.get = rdc_gpio_get_value;
	rdc321x_gpio_dev->chip.set = rdc_gpio_set_value;
	rdc321x_gpio_dev->chip.base = 0;
	rdc321x_gpio_dev->chip.ngpio = pdata->max_gpios;

	platform_set_drvdata(pdev, rdc321x_gpio_dev);

	/* This might not be, what others (BIOS, bootloader, etc.)
	   wrote to these registers before, but it's a good guess. Still
	   better than just using 0xffffffff. */
	err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
					rdc321x_gpio_dev->reg1_data_base,
					&rdc321x_gpio_dev->data_reg[0]);
	if (err)
		return err;

	err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
					rdc321x_gpio_dev->reg2_data_base,
					&rdc321x_gpio_dev->data_reg[1]);
	if (err)
		return err;

	dev_info(&pdev->dev, "registering %d GPIOs\n",
					rdc321x_gpio_dev->chip.ngpio);
	return devm_gpiochip_add_data(&pdev->dev, &rdc321x_gpio_dev->chip,
				      rdc321x_gpio_dev);
}
예제 #21
0
static int int0002_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	const struct x86_cpu_id *cpu_id;
	struct gpio_chip *chip;
	int irq, ret;

	/* Menlow has a different INT0002 device? <sigh> */
	cpu_id = x86_match_cpu(int0002_cpu_ids);
	if (!cpu_id)
		return -ENODEV;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "Error getting IRQ: %d\n", irq);
		return irq;
	}

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

	chip->label = DRV_NAME;
	chip->parent = dev;
	chip->owner = THIS_MODULE;
	chip->get = int0002_gpio_get;
	chip->set = int0002_gpio_set;
	chip->direction_input = int0002_gpio_get;
	chip->direction_output = int0002_gpio_direction_output;
	chip->base = -1;
	chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1;
	chip->irq.need_valid_mask = true;

	ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL);
	if (ret) {
		dev_err(dev, "Error adding gpio chip: %d\n", ret);
		return ret;
	}

	bitmap_clear(chip->irq.valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN);

	/*
	 * We manually request the irq here instead of passing a flow-handler
	 * to gpiochip_set_chained_irqchip, because the irq is shared.
	 */
	ret = devm_request_irq(dev, irq, int0002_irq,
			       IRQF_SHARED | IRQF_NO_THREAD, "INT0002", chip);
	if (ret) {
		dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret);
		return ret;
	}

	ret = gpiochip_irqchip_add(chip, &int0002_irqchip, 0, handle_edge_irq,
				   IRQ_TYPE_NONE);
	if (ret) {
		dev_err(dev, "Error adding irqchip: %d\n", ret);
		return ret;
	}

	gpiochip_set_chained_irqchip(chip, &int0002_irqchip, irq, NULL);

	return 0;
}
예제 #22
0
static int gpio_exar_probe(struct platform_device *pdev)
{
	struct pci_dev *pcidev = to_pci_dev(pdev->dev.parent);
	struct exar_gpio_chip *exar_gpio;
	u32 first_pin, ngpios;
	void __iomem *p;
	int index, ret;

	/*
	 * The UART driver must have mapped region 0 prior to registering this
	 * device - use it.
	 */
	p = pcim_iomap_table(pcidev)[0];
	if (!p)
		return -ENOMEM;

	ret = device_property_read_u32(&pdev->dev, "exar,first-pin",
				       &first_pin);
	if (ret)
		return ret;

	ret = device_property_read_u32(&pdev->dev, "ngpios", &ngpios);
	if (ret)
		return ret;

	exar_gpio = devm_kzalloc(&pdev->dev, sizeof(*exar_gpio), GFP_KERNEL);
	if (!exar_gpio)
		return -ENOMEM;

	mutex_init(&exar_gpio->lock);

	index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL);
	if (index < 0)
		goto err_destroy;

	sprintf(exar_gpio->name, "exar_gpio%d", index);
	exar_gpio->gpio_chip.label = exar_gpio->name;
	exar_gpio->gpio_chip.parent = &pdev->dev;
	exar_gpio->gpio_chip.direction_output = exar_direction_output;
	exar_gpio->gpio_chip.direction_input = exar_direction_input;
	exar_gpio->gpio_chip.get_direction = exar_get_direction;
	exar_gpio->gpio_chip.get = exar_get_value;
	exar_gpio->gpio_chip.set = exar_set_value;
	exar_gpio->gpio_chip.base = -1;
	exar_gpio->gpio_chip.ngpio = ngpios;
	exar_gpio->regs = p;
	exar_gpio->index = index;
	exar_gpio->first_pin = first_pin;

	ret = devm_gpiochip_add_data(&pdev->dev,
				     &exar_gpio->gpio_chip, exar_gpio);
	if (ret)
		goto err_destroy;

	platform_set_drvdata(pdev, exar_gpio);

	return 0;

err_destroy:
	ida_simple_remove(&ida_index, index);
	mutex_destroy(&exar_gpio->lock);
	return ret;
}
예제 #23
0
파일: gpio-adp5520.c 프로젝트: 020gzh/linux
static int adp5520_gpio_probe(struct platform_device *pdev)
{
	struct adp5520_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct adp5520_gpio *dev;
	struct gpio_chip *gc;
	int ret, i, gpios;
	unsigned char ctl_mask = 0;

	if (pdata == NULL) {
		dev_err(&pdev->dev, "missing platform data\n");
		return -ENODEV;
	}

	if (pdev->id != ID_ADP5520) {
		dev_err(&pdev->dev, "only ADP5520 supports GPIO\n");
		return -ENODEV;
	}

	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
	if (dev == NULL)
		return -ENOMEM;

	dev->master = pdev->dev.parent;

	for (gpios = 0, i = 0; i < ADP5520_MAXGPIOS; i++)
		if (pdata->gpio_en_mask & (1 << i))
			dev->lut[gpios++] = 1 << i;

	if (gpios < 1) {
		ret = -EINVAL;
		goto err;
	}

	gc = &dev->gpio_chip;
	gc->direction_input  = adp5520_gpio_direction_input;
	gc->direction_output = adp5520_gpio_direction_output;
	gc->get = adp5520_gpio_get_value;
	gc->set = adp5520_gpio_set_value;
	gc->can_sleep = true;

	gc->base = pdata->gpio_start;
	gc->ngpio = gpios;
	gc->label = pdev->name;
	gc->owner = THIS_MODULE;

	ret = adp5520_clr_bits(dev->master, ADP5520_GPIO_CFG_1,
		pdata->gpio_en_mask);

	if (pdata->gpio_en_mask & ADP5520_GPIO_C3)
		ctl_mask |= ADP5520_C3_MODE;

	if (pdata->gpio_en_mask & ADP5520_GPIO_R3)
		ctl_mask |= ADP5520_R3_MODE;

	if (ctl_mask)
		ret = adp5520_set_bits(dev->master, ADP5520_LED_CONTROL,
			ctl_mask);

	ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP,
		pdata->gpio_pullup_mask);

	if (ret) {
		dev_err(&pdev->dev, "failed to write\n");
		goto err;
	}

	ret = devm_gpiochip_add_data(&pdev->dev, &dev->gpio_chip, dev);
	if (ret)
		goto err;

	platform_set_drvdata(pdev, dev);
	return 0;

err:
	return ret;
}
예제 #24
0
static int xgene_gpio_sb_probe(struct platform_device *pdev)
{
	struct xgene_gpio_sb *priv;
	int ret;
	struct resource *res;
	void __iomem *regs;
	struct irq_domain *parent_domain = NULL;
	struct fwnode_handle *fwnode;
	u32 val32;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	priv->regs = regs;

	ret = platform_get_irq(pdev, 0);
	if (ret > 0) {
		priv->parent_irq_base = irq_get_irq_data(ret)->hwirq;
		parent_domain = irq_get_irq_data(ret)->domain;
	}
	if (!parent_domain) {
		dev_err(&pdev->dev, "unable to obtain parent domain\n");
		return -ENODEV;
	}

	ret = bgpio_init(&priv->gc, &pdev->dev, 4,
			regs + MPA_GPIO_IN_ADDR,
			regs + MPA_GPIO_OUT_ADDR, NULL,
			regs + MPA_GPIO_OE_ADDR, NULL, 0);
        if (ret)
                return ret;

	priv->gc.to_irq = xgene_gpio_sb_to_irq;

	/* Retrieve start irq pin, use default if property not found */
	priv->irq_start = XGENE_DFLT_IRQ_START_PIN;
	if (!device_property_read_u32(&pdev->dev,
					XGENE_IRQ_START_PROPERTY, &val32))
		priv->irq_start = val32;

	/* Retrieve number irqs, use default if property not found */
	priv->nirq = XGENE_DFLT_MAX_NIRQ;
	if (!device_property_read_u32(&pdev->dev, XGENE_NIRQ_PROPERTY, &val32))
		priv->nirq = val32;

	/* Retrieve number gpio, use default if property not found */
	priv->gc.ngpio = XGENE_DFLT_MAX_NGPIO;
	if (!device_property_read_u32(&pdev->dev, XGENE_NGPIO_PROPERTY, &val32))
		priv->gc.ngpio = val32;

	dev_info(&pdev->dev, "Support %d gpios, %d irqs start from pin %d\n",
			priv->gc.ngpio, priv->nirq, priv->irq_start);

	platform_set_drvdata(pdev, priv);

	if (pdev->dev.of_node)
		fwnode = of_node_to_fwnode(pdev->dev.of_node);
	else
		fwnode = pdev->dev.fwnode;

	priv->irq_domain = irq_domain_create_hierarchy(parent_domain,
					0, priv->nirq, fwnode,
					&xgene_gpio_sb_domain_ops, priv);
	if (!priv->irq_domain)
		return -ENODEV;

	priv->gc.irqdomain = priv->irq_domain;

	ret = devm_gpiochip_add_data(&pdev->dev, &priv->gc, priv);
	if (ret) {
		dev_err(&pdev->dev,
			"failed to register X-Gene GPIO Standby driver\n");
		irq_domain_remove(priv->irq_domain);
		return ret;
	}

	dev_info(&pdev->dev, "X-Gene GPIO Standby driver registered\n");

	if (priv->nirq > 0) {
		/* Register interrupt handlers for gpio signaled acpi events */
		acpi_gpiochip_request_interrupts(&priv->gc);
	}

	return ret;
}
예제 #25
0
static int tps65910_gpio_probe(struct platform_device *pdev)
{
	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
	struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
	struct tps65910_gpio *tps65910_gpio;
	int ret;
	int i;

	tps65910_gpio = devm_kzalloc(&pdev->dev,
				sizeof(*tps65910_gpio), GFP_KERNEL);
	if (!tps65910_gpio)
		return -ENOMEM;

	tps65910_gpio->tps65910 = tps65910;

	tps65910_gpio->gpio_chip.owner = THIS_MODULE;
	tps65910_gpio->gpio_chip.label = tps65910->i2c_client->name;

	switch (tps65910_chip_id(tps65910)) {
	case TPS65910:
		tps65910_gpio->gpio_chip.ngpio = TPS65910_NUM_GPIO;
		break;
	case TPS65911:
		tps65910_gpio->gpio_chip.ngpio = TPS65911_NUM_GPIO;
		break;
	default:
		return -EINVAL;
	}
	tps65910_gpio->gpio_chip.can_sleep = true;
	tps65910_gpio->gpio_chip.direction_input = tps65910_gpio_input;
	tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output;
	tps65910_gpio->gpio_chip.set	= tps65910_gpio_set;
	tps65910_gpio->gpio_chip.get	= tps65910_gpio_get;
	tps65910_gpio->gpio_chip.parent = &pdev->dev;
#ifdef CONFIG_OF_GPIO
	tps65910_gpio->gpio_chip.of_node = tps65910->dev->of_node;
#endif
	if (pdata && pdata->gpio_base)
		tps65910_gpio->gpio_chip.base = pdata->gpio_base;
	else
		tps65910_gpio->gpio_chip.base = -1;

	if (!pdata && tps65910->dev->of_node)
		pdata = tps65910_parse_dt_for_gpio(&pdev->dev, tps65910,
			tps65910_gpio->gpio_chip.ngpio);

	if (!pdata)
		goto skip_init;

	/* Configure sleep control for gpios if provided */
	for (i = 0; i < tps65910_gpio->gpio_chip.ngpio; ++i) {
		if (!pdata->en_gpio_sleep[i])
			continue;

		ret = tps65910_reg_set_bits(tps65910,
			TPS65910_GPIO0 + i, GPIO_SLEEP_MASK);
		if (ret < 0)
			dev_warn(tps65910->dev,
				"GPIO Sleep setting failed with err %d\n", ret);
	}

skip_init:
	ret = devm_gpiochip_add_data(&pdev->dev, &tps65910_gpio->gpio_chip,
				     tps65910_gpio);
	if (ret < 0) {
		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, tps65910_gpio);

	return ret;
}
예제 #26
0
파일: gpio-adp5588.c 프로젝트: 020gzh/linux
static int adp5588_gpio_probe(struct i2c_client *client,
					const struct i2c_device_id *id)
{
	struct adp5588_gpio_platform_data *pdata =
			dev_get_platdata(&client->dev);
	struct adp5588_gpio *dev;
	struct gpio_chip *gc;
	int ret, i, revid;

	if (!pdata) {
		dev_err(&client->dev, "missing platform data\n");
		return -ENODEV;
	}

	if (!i2c_check_functionality(client->adapter,
					I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
		return -EIO;
	}

	dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	dev->client = client;

	gc = &dev->gpio_chip;
	gc->direction_input = adp5588_gpio_direction_input;
	gc->direction_output = adp5588_gpio_direction_output;
	gc->get = adp5588_gpio_get_value;
	gc->set = adp5588_gpio_set_value;
	gc->can_sleep = true;

	gc->base = pdata->gpio_start;
	gc->ngpio = ADP5588_MAXGPIO;
	gc->label = client->name;
	gc->owner = THIS_MODULE;
	gc->names = pdata->names;

	mutex_init(&dev->lock);

	ret = adp5588_gpio_read(dev->client, DEV_ID);
	if (ret < 0)
		goto err;

	revid = ret & ADP5588_DEVICE_ID_MASK;

	for (i = 0, ret = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
		dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i);
		dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i);
		ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0);
		ret |= adp5588_gpio_write(client, GPIO_PULL1 + i,
				(pdata->pullup_dis_mask >> (8 * i)) & 0xFF);
		ret |= adp5588_gpio_write(client, GPIO_INT_EN1 + i, 0);
		if (ret)
			goto err;
	}

	if (pdata->irq_base) {
		if (WA_DELAYED_READOUT_REVID(revid)) {
			dev_warn(&client->dev, "GPIO int not supported\n");
		} else {
			ret = adp5588_irq_setup(dev);
			if (ret)
				goto err;
		}
	}

	ret = devm_gpiochip_add_data(&client->dev, &dev->gpio_chip, dev);
	if (ret)
		goto err_irq;

	dev_info(&client->dev, "IRQ Base: %d Rev.: %d\n",
			pdata->irq_base, revid);

	if (pdata->setup) {
		ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context);
		if (ret < 0)
			dev_warn(&client->dev, "setup failed, %d\n", ret);
	}

	i2c_set_clientdata(client, dev);

	return 0;

err_irq:
	adp5588_irq_teardown(dev);
err:
	return ret;
}
예제 #27
0
static int ftgpio_gpio_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct ftgpio_gpio *g;
	int irq;
	int ret;

	g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL);
	if (!g)
		return -ENOMEM;

	g->dev = dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	g->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(g->base))
		return PTR_ERR(g->base);

	irq = platform_get_irq(pdev, 0);
	if (irq <= 0)
		return irq ? irq : -EINVAL;

	ret = bgpio_init(&g->gc, dev, 4,
			 g->base + GPIO_DATA_IN,
			 g->base + GPIO_DATA_SET,
			 g->base + GPIO_DATA_CLR,
			 g->base + GPIO_DIR,
			 NULL,
			 0);
	if (ret) {
		dev_err(dev, "unable to init generic GPIO\n");
		return ret;
	}
	g->gc.label = "FTGPIO010";
	g->gc.base = -1;
	g->gc.parent = dev;
	g->gc.owner = THIS_MODULE;
	/* ngpio is set by bgpio_init() */

	ret = devm_gpiochip_add_data(dev, &g->gc, g);
	if (ret)
		return ret;

	/* Disable, unmask and clear all interrupts */
	writel(0x0, g->base + GPIO_INT_EN);
	writel(0x0, g->base + GPIO_INT_MASK);
	writel(~0x0, g->base + GPIO_INT_CLR);

	ret = gpiochip_irqchip_add(&g->gc, &ftgpio_gpio_irqchip,
				   0, handle_bad_irq,
				   IRQ_TYPE_NONE);
	if (ret) {
		dev_info(dev, "could not add irqchip\n");
		return ret;
	}
	gpiochip_set_chained_irqchip(&g->gc, &ftgpio_gpio_irqchip,
				     irq, ftgpio_gpio_irq_handler);

	dev_info(dev, "FTGPIO010 @%p registered\n", g->base);

	return 0;
}
예제 #28
0
static int dio48e_probe(struct device *dev, unsigned int id)
{
	struct dio48e_gpio *dio48egpio;
	const char *const name = dev_name(dev);
	int err;

	dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL);
	if (!dio48egpio)
		return -ENOMEM;

	if (!devm_request_region(dev, base[id], DIO48E_EXTENT, name)) {
		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
			base[id], base[id] + DIO48E_EXTENT);
		return -EBUSY;
	}

	dio48egpio->chip.label = name;
	dio48egpio->chip.parent = dev;
	dio48egpio->chip.owner = THIS_MODULE;
	dio48egpio->chip.base = -1;
	dio48egpio->chip.ngpio = DIO48E_NGPIO;
	dio48egpio->chip.names = dio48e_names;
	dio48egpio->chip.get_direction = dio48e_gpio_get_direction;
	dio48egpio->chip.direction_input = dio48e_gpio_direction_input;
	dio48egpio->chip.direction_output = dio48e_gpio_direction_output;
	dio48egpio->chip.get = dio48e_gpio_get;
	dio48egpio->chip.set = dio48e_gpio_set;
	dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
	dio48egpio->base = base[id];

	raw_spin_lock_init(&dio48egpio->lock);

	err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);
	if (err) {
		dev_err(dev, "GPIO registering failed (%d)\n", err);
		return err;
	}

	/* initialize all GPIO as output */
	outb(0x80, base[id] + 3);
	outb(0x00, base[id]);
	outb(0x00, base[id] + 1);
	outb(0x00, base[id] + 2);
	outb(0x00, base[id] + 3);
	outb(0x80, base[id] + 7);
	outb(0x00, base[id] + 4);
	outb(0x00, base[id] + 5);
	outb(0x00, base[id] + 6);
	outb(0x00, base[id] + 7);

	/* disable IRQ by default */
	inb(base[id] + 0xB);

	err = gpiochip_irqchip_add(&dio48egpio->chip, &dio48e_irqchip, 0,
		handle_edge_irq, IRQ_TYPE_NONE);
	if (err) {
		dev_err(dev, "Could not add irqchip (%d)\n", err);
		return err;
	}

	err = devm_request_irq(dev, irq[id], dio48e_irq_handler, 0, name,
		dio48egpio);
	if (err) {
		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
		return err;
	}

	return 0;
}
예제 #29
0
static int tb10x_gpio_probe(struct platform_device *pdev)
{
	struct tb10x_gpio *tb10x_gpio;
	struct resource *mem;
	struct device_node *dn = pdev->dev.of_node;
	int ret = -EBUSY;
	u32 ngpio;

	if (!dn)
		return -EINVAL;

	if (of_property_read_u32(dn, "abilis,ngpio", &ngpio))
		return -EINVAL;

	tb10x_gpio = devm_kzalloc(&pdev->dev, sizeof(*tb10x_gpio), GFP_KERNEL);
	if (tb10x_gpio == NULL)
		return -ENOMEM;

	spin_lock_init(&tb10x_gpio->spinlock);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	tb10x_gpio->base = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(tb10x_gpio->base))
		return PTR_ERR(tb10x_gpio->base);

	tb10x_gpio->gc.label		=
		devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOF", pdev->dev.of_node);
	if (!tb10x_gpio->gc.label)
		return -ENOMEM;

	tb10x_gpio->gc.parent		= &pdev->dev;
	tb10x_gpio->gc.owner		= THIS_MODULE;
	tb10x_gpio->gc.direction_input	= tb10x_gpio_direction_in;
	tb10x_gpio->gc.get		= tb10x_gpio_get;
	tb10x_gpio->gc.direction_output	= tb10x_gpio_direction_out;
	tb10x_gpio->gc.set		= tb10x_gpio_set;
	tb10x_gpio->gc.request		= gpiochip_generic_request;
	tb10x_gpio->gc.free		= gpiochip_generic_free;
	tb10x_gpio->gc.base		= -1;
	tb10x_gpio->gc.ngpio		= ngpio;
	tb10x_gpio->gc.can_sleep	= false;


	ret = devm_gpiochip_add_data(&pdev->dev, &tb10x_gpio->gc, tb10x_gpio);
	if (ret < 0) {
		dev_err(&pdev->dev, "Could not add gpiochip.\n");
		return ret;
	}

	platform_set_drvdata(pdev, tb10x_gpio);

	if (of_find_property(dn, "interrupt-controller", NULL)) {
		struct irq_chip_generic *gc;

		ret = platform_get_irq(pdev, 0);
		if (ret < 0) {
			dev_err(&pdev->dev, "No interrupt specified.\n");
			return ret;
		}

		tb10x_gpio->gc.to_irq	= tb10x_gpio_to_irq;
		tb10x_gpio->irq		= ret;

		ret = devm_request_irq(&pdev->dev, ret, tb10x_gpio_irq_cascade,
				IRQF_TRIGGER_NONE | IRQF_SHARED,
				dev_name(&pdev->dev), tb10x_gpio);
		if (ret != 0)
			return ret;

		tb10x_gpio->domain = irq_domain_add_linear(dn,
						tb10x_gpio->gc.ngpio,
						&irq_generic_chip_ops, NULL);
		if (!tb10x_gpio->domain) {
			return -ENOMEM;
		}

		ret = irq_alloc_domain_generic_chips(tb10x_gpio->domain,
				tb10x_gpio->gc.ngpio, 1, tb10x_gpio->gc.label,
				handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE,
				IRQ_GC_INIT_MASK_CACHE);
		if (ret)
			return ret;

		gc = tb10x_gpio->domain->gc->gc[0];
		gc->reg_base                         = tb10x_gpio->base;
		gc->chip_types[0].type               = IRQ_TYPE_EDGE_BOTH;
		gc->chip_types[0].chip.irq_ack       = irq_gc_ack_set_bit;
		gc->chip_types[0].chip.irq_mask      = irq_gc_mask_clr_bit;
		gc->chip_types[0].chip.irq_unmask    = irq_gc_mask_set_bit;
		gc->chip_types[0].chip.irq_set_type  = tb10x_gpio_irq_set_type;
		gc->chip_types[0].regs.ack           = OFFSET_TO_REG_CHANGE;
		gc->chip_types[0].regs.mask          = OFFSET_TO_REG_INT_EN;
	}

	return 0;
}
예제 #30
0
static int intel_gpio_probe(struct pci_dev *pdev,
			  const struct pci_device_id *id)
{
	void __iomem *base;
	struct intel_mid_gpio *priv;
	u32 gpio_base;
	u32 irq_base;
	int retval;
	struct intel_mid_gpio_ddata *ddata =
				(struct intel_mid_gpio_ddata *)id->driver_data;

	retval = pcim_enable_device(pdev);
	if (retval)
		return retval;

	retval = pcim_iomap_regions(pdev, 1 << 0 | 1 << 1, pci_name(pdev));
	if (retval) {
		dev_err(&pdev->dev, "I/O memory mapping error\n");
		return retval;
	}

	base = pcim_iomap_table(pdev)[1];

	irq_base = readl(base);
	gpio_base = readl(sizeof(u32) + base);

	/* release the IO mapping, since we already get the info from bar1 */
	pcim_iounmap_regions(pdev, 1 << 1);

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "can't allocate chip data\n");
		return -ENOMEM;
	}

	priv->reg_base = pcim_iomap_table(pdev)[0];
	priv->chip.label = dev_name(&pdev->dev);
	priv->chip.parent = &pdev->dev;
	priv->chip.request = intel_gpio_request;
	priv->chip.direction_input = intel_gpio_direction_input;
	priv->chip.direction_output = intel_gpio_direction_output;
	priv->chip.get = intel_gpio_get;
	priv->chip.set = intel_gpio_set;
	priv->chip.base = gpio_base;
	priv->chip.ngpio = ddata->ngpio;
	priv->chip.can_sleep = false;
	priv->pdev = pdev;

	spin_lock_init(&priv->lock);

	pci_set_drvdata(pdev, priv);
	retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv);
	if (retval) {
		dev_err(&pdev->dev, "gpiochip_add error %d\n", retval);
		return retval;
	}

	retval = gpiochip_irqchip_add(&priv->chip,
				      &intel_mid_irqchip,
				      irq_base,
				      handle_simple_irq,
				      IRQ_TYPE_NONE);
	if (retval) {
		dev_err(&pdev->dev,
			"could not connect irqchip to gpiochip\n");
		return retval;
	}

	intel_mid_irq_init_hw(priv);

	gpiochip_set_chained_irqchip(&priv->chip,
				     &intel_mid_irqchip,
				     pdev->irq,
				     intel_mid_irq_handler);

	pm_runtime_put_noidle(&pdev->dev);
	pm_runtime_allow(&pdev->dev);

	return 0;
}