コード例 #1
0
ファイル: amba-pl011.c プロジェクト: smx-smx/dsl-n55u
static int pl011_probe(struct amba_device *dev, void *id)
{
	struct uart_amba_port *uap;
	void __iomem *base;
	int i, ret;

	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
		if (amba_ports[i] == NULL)
			break;

	if (i == ARRAY_SIZE(amba_ports)) {
		ret = -EBUSY;
		goto out;
	}

	uap = kmalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
	if (uap == NULL) {
		ret = -ENOMEM;
		goto out;
	}

	base = ioremap(dev->res.start, PAGE_SIZE);
	if (!base) {
		ret = -ENOMEM;
		goto free;
	}

	memset(uap, 0, sizeof(struct uart_amba_port));
	uap->clk = clk_get(&dev->dev, "UARTCLK");
	if (IS_ERR(uap->clk)) {
		ret = PTR_ERR(uap->clk);
		goto unmap;
	}

	uap->port.dev = &dev->dev;
	uap->port.mapbase = dev->res.start;
	uap->port.membase = base;
	uap->port.iotype = UPIO_MEM;
	uap->port.irq = dev->irq[0];
	uap->port.fifosize = 16;
	uap->port.ops = &amba_pl011_pops;
	uap->port.flags = UPF_BOOT_AUTOCONF;
	uap->port.line = i;

	amba_ports[i] = uap;

	amba_set_drvdata(dev, uap);
	ret = uart_add_one_port(&amba_reg, &uap->port);
	if (ret) {
		amba_set_drvdata(dev, NULL);
		amba_ports[i] = NULL;
		clk_put(uap->clk);
 unmap:
		iounmap(base);
 free:
		kfree(uap);
	}
 out:
	return ret;
}
コード例 #2
0
static int pl010_probe(struct amba_device *dev, void *id)
{
	struct uart_amba_port *port;
	void __iomem *base;
	int i, ret;

	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
		if (amba_ports[i] == NULL)
			break;

	if (i == ARRAY_SIZE(amba_ports)) {
		ret = -EBUSY;
		goto out;
	}

	port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
	if (!port) {
		ret = -ENOMEM;
		goto out;
	}

	base = ioremap(dev->res.start, PAGE_SIZE);
	if (!base) {
		ret = -ENOMEM;
		goto free;
	}

	port->port.dev = &dev->dev;
	port->port.mapbase = dev->res.start;
	port->port.membase = base;
	port->port.iotype = UPIO_MEM;
	port->port.irq = dev->irq[0];
	port->port.uartclk = 14745600;
	port->port.fifosize = 16;
	port->port.ops = &amba_pl010_pops;
	port->port.flags = UPF_BOOT_AUTOCONF;
	port->port.line = i;
	port->dev = dev;
	port->data = dev->dev.platform_data;

	amba_ports[i] = port;

	amba_set_drvdata(dev, port);
	ret = uart_add_one_port(&amba_reg, &port->port);
	if (ret) {
		amba_set_drvdata(dev, NULL);
		amba_ports[i] = NULL;
		iounmap(base);
 free:
		kfree(port);
	}

 out:
	return ret;
}
コード例 #3
0
ファイル: etm.c プロジェクト: 08opt/linux
static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id)
{
	struct tracectx *t = &tracer;
	int ret = 0;

	ret = amba_request_regions(dev, NULL);
	if (ret)
		goto out;

	t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
	if (!t->etb_regs) {
		ret = -ENOMEM;
		goto out_release;
	}

	amba_set_drvdata(dev, t);

	etb_miscdev.parent = &dev->dev;

	ret = misc_register(&etb_miscdev);
	if (ret)
		goto out_unmap;

	t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
	if (IS_ERR(t->emu_clk)) {
		dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
		return -EFAULT;
	}

	clk_enable(t->emu_clk);

	etb_unlock(t);
	t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
	dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);

	/* make sure trace capture is disabled */
	etb_writel(t, 0, ETBR_CTRL);
	etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
	etb_lock(t);

	dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");

out:
	return ret;

out_unmap:
	amba_set_drvdata(dev, NULL);
	iounmap(t->etb_regs);

out_release:
	amba_release_regions(dev);

	return ret;
}
コード例 #4
0
static int pl031_probe(struct amba_device *adev, struct amba_id *id)
{
	int ret;
	struct pl031_local *ldata;

	ret = amba_request_regions(adev, NULL);
	if (ret)
		goto err_req;

	ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL);
	if (!ldata) {
		ret = -ENOMEM;
		goto out;
	}

	ldata->base = ioremap(adev->res.start,
			      adev->res.end - adev->res.start + 1);
	if (!ldata->base) {
		ret = -ENOMEM;
		goto out_no_remap;
	}

	amba_set_drvdata(adev, ldata);

	if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED,
			"rtc-pl031", ldata->rtc)) {
		ret = -EIO;
		goto out_no_irq;
	}

	ldata->rtc = rtc_device_register("pl031", &adev->dev, &pl031_ops,
					 THIS_MODULE);
	if (IS_ERR(ldata->rtc)) {
		ret = PTR_ERR(ldata->rtc);
		goto out_no_rtc;
	}

	return 0;

out_no_rtc:
	free_irq(adev->irq[0], ldata->rtc);
out_no_irq:
	iounmap(ldata->base);
	amba_set_drvdata(adev, NULL);
out_no_remap:
	kfree(ldata);
out:
	amba_release_regions(adev);
err_req:
	return ret;
}
コード例 #5
0
ファイル: mmci.c プロジェクト: liuyang201666/linux-akae
static int mmci_remove(struct amba_device *dev)
{
    struct mmc_host *mmc = amba_get_drvdata(dev);

    amba_set_drvdata(dev, NULL);

    if (mmc) {
        struct mmci_host *host = mmc_priv(mmc);

        del_timer_sync(&host->timer);

        mmc_remove_host(mmc);

        writel(0, host->base + MMCIMASK0);
        writel(0, host->base + MMCIMASK1);

        writel(0, host->base + MMCICOMMAND);
        writel(0, host->base + MMCIDATACTRL);

        free_irq(dev->irq[0], host);
        free_irq(dev->irq[1], host);

        iounmap(host->base);
        clk_disable(host->clk);
        clk_put(host->clk);

        mmc_free_host(mmc);

        amba_release_regions(dev);
    }

    return 0;
}
コード例 #6
0
ファイル: ambakmi.c プロジェクト: 3sOx/asuswrt-merlin
static int amba_kmi_probe(struct amba_device *dev, void *id)
{
	struct amba_kmi_port *kmi;
	struct serio *io;
	int ret;

	ret = amba_request_regions(dev, NULL);
	if (ret)
		return ret;

	kmi = kmalloc(sizeof(struct amba_kmi_port), GFP_KERNEL);
	io = kmalloc(sizeof(struct serio), GFP_KERNEL);
	if (!kmi || !io) {
		ret = -ENOMEM;
		goto out;
	}

	memset(kmi, 0, sizeof(struct amba_kmi_port));
	memset(io, 0, sizeof(struct serio));

	io->id.type	= SERIO_8042;
	io->write	= amba_kmi_write;
	io->open	= amba_kmi_open;
	io->close	= amba_kmi_close;
	strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
	strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
	io->port_data	= kmi;
	io->dev.parent	= &dev->dev;

	kmi->io 	= io;
	kmi->base	= ioremap(dev->res.start, KMI_SIZE);
	if (!kmi->base) {
		ret = -ENOMEM;
		goto out;
	}

	kmi->clk = clk_get(&dev->dev, "KMIREFCLK");
	if (IS_ERR(kmi->clk)) {
		ret = PTR_ERR(kmi->clk);
		goto unmap;
	}

	kmi->irq = dev->irq[0];
	amba_set_drvdata(dev, kmi);

	serio_register_port(kmi->io);
	return 0;

 unmap:
	iounmap(kmi->base);
 out:
	kfree(kmi);
	kfree(io);
	amba_release_regions(dev);
	return ret;
}
コード例 #7
0
static int pl010_remove(struct amba_device *dev)
{
	struct uart_amba_port *uap = amba_get_drvdata(dev);

	if (uap)
		uart_remove_one_port(&amba_reg, &uap->port);

	amba_set_drvdata(dev, NULL);

	return 0;
}
コード例 #8
0
ファイル: ambakmi.c プロジェクト: hellove1985/ZT-180
static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id)
{
	struct amba_kmi_port *kmi;
	struct serio *io;
	int ret;

	ret = amba_request_regions(dev, NULL);
	if (ret)
		return ret;

	kmi = kzalloc(sizeof(struct amba_kmi_port), GFP_KERNEL);
	io = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!kmi || !io) {
		ret = -ENOMEM;
		goto out;
	}


	io->id.type	= SERIO_8042;
	io->write	= amba_kmi_write;
	io->open	= amba_kmi_open;
	io->close	= amba_kmi_close;
	strlcpy(io->name, dev_name(&dev->dev), sizeof(io->name));
	strlcpy(io->phys, dev_name(&dev->dev), sizeof(io->phys));
	io->port_data	= kmi;
	io->dev.parent	= &dev->dev;

	kmi->io 	= io;
	kmi->base	= ioremap(dev->res.start, resource_size(&dev->res));
	if (!kmi->base) {
		ret = -ENOMEM;
		goto out;
	}

//	if (IS_ERR(kmi->clk)) {
//		ret = PTR_ERR(kmi->clk);
//		goto unmap;
//	}

	kmi->irq = dev->irq[0];
	amba_set_drvdata(dev, kmi);

	serio_register_port(kmi->io);
	return 0;

//unmap:
//	iounmap(kmi->base);
 out:
	kfree(kmi);
	kfree(io);
	amba_release_regions(dev);
	return ret;
}
コード例 #9
0
ファイル: rtc-pl030.c プロジェクト: AlexShiLucky/linux
static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
{
	struct pl030_rtc *rtc;
	int ret;

	ret = amba_request_regions(dev, NULL);
	if (ret)
		goto err_req;

	rtc = devm_kzalloc(&dev->dev, sizeof(*rtc), GFP_KERNEL);
	if (!rtc) {
		ret = -ENOMEM;
		goto err_rtc;
	}

	rtc->rtc = devm_rtc_allocate_device(&dev->dev);
	if (IS_ERR(rtc->rtc)) {
		ret = PTR_ERR(rtc->rtc);
		goto err_rtc;
	}

	rtc->rtc->ops = &pl030_ops;
	rtc->base = ioremap(dev->res.start, resource_size(&dev->res));
	if (!rtc->base) {
		ret = -ENOMEM;
		goto err_rtc;
	}

	__raw_writel(0, rtc->base + RTC_CR);
	__raw_writel(0, rtc->base + RTC_EOI);

	amba_set_drvdata(dev, rtc);

	ret = request_irq(dev->irq[0], pl030_interrupt, 0,
			  "rtc-pl030", rtc);
	if (ret)
		goto err_irq;

	ret = rtc_register_device(rtc->rtc);
	if (ret)
		goto err_reg;

	return 0;

 err_reg:
	free_irq(dev->irq[0], rtc);
 err_irq:
	iounmap(rtc->base);
 err_rtc:
	amba_release_regions(dev);
 err_req:
	return ret;
}
コード例 #10
0
static int pl031_remove(struct amba_device *adev)
{
	struct pl031_local *ldata = dev_get_drvdata(&adev->dev);

	amba_set_drvdata(adev, NULL);
	free_irq(adev->irq[0], ldata->rtc);
	rtc_device_unregister(ldata->rtc);
	iounmap(ldata->base);
	kfree(ldata);
	amba_release_regions(adev);

	return 0;
}
コード例 #11
0
ファイル: ambakmi.c プロジェクト: hellove1985/ZT-180
static int amba_kmi_remove(struct amba_device *dev)
{
	struct amba_kmi_port *kmi = amba_get_drvdata(dev);

	amba_set_drvdata(dev, NULL);

	serio_unregister_port(kmi->io);
	clk_put(kmi->clk);
	iounmap(kmi->base);
	kfree(kmi);
	amba_release_regions(dev);
	return 0;
}
コード例 #12
0
static int pl030_probe(struct amba_device *dev, struct amba_id *id)
{
	struct pl030_rtc *rtc;
	int ret;

	ret = amba_request_regions(dev, NULL);
	if (ret)
		goto err_req;

	rtc = kmalloc(sizeof(*rtc), GFP_KERNEL);
	if (!rtc) {
		ret = -ENOMEM;
		goto err_rtc;
	}

	rtc->base = ioremap(dev->res.start, resource_size(&dev->res));
	if (!rtc->base) {
		ret = -ENOMEM;
		goto err_map;
	}

	__raw_writel(0, rtc->base + RTC_CR);
	__raw_writel(0, rtc->base + RTC_EOI);

	amba_set_drvdata(dev, rtc);

	ret = request_irq(dev->irq[0], pl030_interrupt, IRQF_DISABLED,
			  "rtc-pl030", rtc);
	if (ret)
		goto err_irq;

	rtc->rtc = rtc_device_register("pl030", &dev->dev, &pl030_ops,
				       THIS_MODULE);
	if (IS_ERR(rtc->rtc)) {
		ret = PTR_ERR(rtc->rtc);
		goto err_reg;
	}

	return 0;

 err_reg:
	free_irq(dev->irq[0], rtc);
 err_irq:
	iounmap(rtc->base);
 err_map:
	kfree(rtc);
 err_rtc:
	amba_release_regions(dev);
 err_req:
	return ret;
}
コード例 #13
0
ファイル: gpio.c プロジェクト: 12019/linux-2.6.34-ts471x
static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id)
{
	struct nmk_gpio_platform_data *pdata;
	struct nmk_gpio_chip *nmk_chip;
	struct gpio_chip *chip;
	int ret;

	pdata = dev->dev.platform_data;
	ret = amba_request_regions(dev, pdata->name);
	if (ret)
		return ret;

	nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
	if (!nmk_chip) {
		ret = -ENOMEM;
		goto out_amba;
	}
	/*
	 * The virt address in nmk_chip->addr is in the nomadik register space,
	 * so we can simply convert the resource address, without remapping
	 */
	nmk_chip->addr = io_p2v(dev->res.start);
	nmk_chip->chip = nmk_gpio_template;
	nmk_chip->parent_irq = pdata->parent_irq;

	chip = &nmk_chip->chip;
	chip->base = pdata->first_gpio;
	chip->label = pdata->name;
	chip->dev = &dev->dev;
	chip->owner = THIS_MODULE;

	ret = gpiochip_add(&nmk_chip->chip);
	if (ret)
		goto out_free;

	amba_set_drvdata(dev, nmk_chip);

	nmk_gpio_init_irq(nmk_chip);

	dev_info(&dev->dev, "Bits %i-%i at address %p\n",
		 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
	return 0;

 out_free:
	kfree(nmk_chip);
 out_amba:
	amba_release_regions(dev);
	dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
		  pdata->first_gpio, pdata->first_gpio+31);
	return ret;
}
コード例 #14
0
ファイル: pl111_drv.c プロジェクト: mkrufky/linux
static int pl111_amba_probe(struct amba_device *amba_dev,
			    const struct amba_id *id)
{
	struct device *dev = &amba_dev->dev;
	struct pl111_drm_dev_private *priv;
	struct drm_device *drm;
	int ret;

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

	drm = drm_dev_alloc(&pl111_drm_driver, dev);
	if (IS_ERR(drm))
		return PTR_ERR(drm);
	amba_set_drvdata(amba_dev, drm);
	priv->drm = drm;
	drm->dev_private = priv;

	priv->regs = devm_ioremap_resource(dev, &amba_dev->res);
	if (IS_ERR(priv->regs)) {
		dev_err(dev, "%s failed mmio\n", __func__);
		return PTR_ERR(priv->regs);
	}

	/* turn off interrupts before requesting the irq */
	writel(0, priv->regs + CLCD_PL111_IENB);

	ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0,
			       "pl111", priv);
	if (ret != 0) {
		dev_err(dev, "%s failed irq %d\n", __func__, ret);
		return ret;
	}

	ret = pl111_modeset_init(drm);
	if (ret != 0)
		goto dev_unref;

	ret = drm_dev_register(drm, 0);
	if (ret < 0)
		goto dev_unref;

	return 0;

dev_unref:
	drm_dev_unref(drm);
	return ret;
}
コード例 #15
0
ファイル: etm.c プロジェクト: 08opt/linux
static int etb_remove(struct amba_device *dev)
{
	struct tracectx *t = amba_get_drvdata(dev);

	amba_set_drvdata(dev, NULL);

	iounmap(t->etb_regs);
	t->etb_regs = NULL;

	clk_disable(t->emu_clk);
	clk_put(t->emu_clk);

	amba_release_regions(dev);

	return 0;
}
コード例 #16
0
static int pl010_probe(struct amba_device *dev, void *id)
{
	int i;

	for (i = 0; i < UART_NR; i++) {
		if (amba_ports[i].port.mapbase != dev->res.start)
			continue;

		amba_ports[i].port.dev = &dev->dev;
		uart_add_one_port(&amba_reg, &amba_ports[i].port);
		amba_set_drvdata(dev, &amba_ports[i]);
		break;
	}

	return 0;
}
コード例 #17
0
ファイル: rtc-pl030.c プロジェクト: 33d/linux-2.6.21-hh20
static int pl030_remove(struct amba_device *dev)
{
	struct pl030_rtc *rtc = amba_get_drvdata(dev);

	amba_set_drvdata(dev, NULL);

	writel(0, rtc->base + RTC_CR);

	free_irq(dev->irq[0], rtc);
	rtc_device_unregister(rtc->rtc);
	iounmap(rtc->base);
	kfree(rtc);
	amba_release_regions(dev);

	return 0;
}
コード例 #18
0
ファイル: etm.c プロジェクト: 08opt/linux
static int etm_remove(struct amba_device *dev)
{
	struct tracectx *t = amba_get_drvdata(dev);

	amba_set_drvdata(dev, NULL);

	iounmap(t->etm_regs);
	t->etm_regs = NULL;

	amba_release_regions(dev);

	sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
	sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
	sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);

	return 0;
}
コード例 #19
0
static int pl010_remove(struct amba_device *dev)
{
	struct uart_amba_port *port = amba_get_drvdata(dev);
	int i;

	amba_set_drvdata(dev, NULL);

	uart_remove_one_port(&amba_reg, &port->port);

	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
		if (amba_ports[i] == port)
			amba_ports[i] = NULL;

	iounmap(port->port.membase);
	kfree(port);

	return 0;
}
コード例 #20
0
ファイル: amba-pl011.c プロジェクト: smx-smx/dsl-n55u
static int pl011_remove(struct amba_device *dev)
{
	struct uart_amba_port *uap = amba_get_drvdata(dev);
	int i;

	amba_set_drvdata(dev, NULL);

	uart_remove_one_port(&amba_reg, &uap->port);

	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
		if (amba_ports[i] == uap)
			amba_ports[i] = NULL;

	iounmap(uap->port.membase);
	clk_put(uap->clk);
	kfree(uap);
	return 0;
}
コード例 #21
0
static int __devexit mmci_remove(struct amba_device *dev)
{
	struct mmc_host *mmc = amba_get_drvdata(dev);

	amba_set_drvdata(dev, NULL);

	if (mmc) {
		struct mmci_host *host = mmc_priv(mmc);

		del_timer_sync(&host->timer);

		mmc_remove_host(mmc);

		writel(0, host->base + MMCIMASK0);
		writel(0, host->base + MMCIMASK1);

		writel(0, host->base + MMCICOMMAND);
		writel(0, host->base + MMCIDATACTRL);

		free_irq(dev->irq[0], host);
		free_irq(dev->irq[1], host);

		if (host->gpio_wp != -ENOSYS)
			gpio_free(host->gpio_wp);
		if (host->gpio_cd != -ENOSYS)
			gpio_free(host->gpio_cd);

		iounmap(host->base);
		clk_disable(host->clk);
		clk_put(host->clk);

		if (regulator_is_enabled(host->vcc))
			regulator_disable(host->vcc);
		regulator_put(host->vcc);

		mmc_free_host(mmc);

		amba_release_regions(dev);
	}

	return 0;
}
コード例 #22
0
ファイル: etm.c プロジェクト: 08opt/linux
static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
{
	struct tracectx *t = &tracer;
	int ret = 0;

	if (t->etm_regs) {
		dev_dbg(&dev->dev, "ETM already initialized\n");
		ret = -EBUSY;
		goto out;
	}

	ret = amba_request_regions(dev, NULL);
	if (ret)
		goto out;

	t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
	if (!t->etm_regs) {
		ret = -ENOMEM;
		goto out_release;
	}

	amba_set_drvdata(dev, t);

	mutex_init(&t->mutex);
	t->dev = &dev->dev;
	t->flags = TRACER_CYCLE_ACC;
	t->etm_portsz = 1;

	etm_unlock(t);
	(void)etm_readl(t, ETMMR_PDSR);
	/* dummy first read */
	(void)etm_readl(&tracer, ETMMR_OSSRR);

	t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
	etm_writel(t, 0x440, ETMR_CTRL);
	etm_lock(t);

	ret = sysfs_create_file(&dev->dev.kobj,
			&trace_running_attr.attr);
	if (ret)
		goto out_unmap;

	/* failing to create any of these two is not fatal */
	ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
	if (ret)
		dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");

	ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
	if (ret)
		dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");

	dev_dbg(t->dev, "ETM AMBA driver initialized.\n");

out:
	return ret;

out_unmap:
	amba_set_drvdata(dev, NULL);
	iounmap(t->etm_regs);

out_release:
	amba_release_regions(dev);

	return ret;
}
コード例 #23
0
ファイル: mmci.c プロジェクト: liuyang201666/linux-akae
static int mmci_probe(struct amba_device *dev, void *id)
{
    struct mmc_platform_data *plat = dev->dev.platform_data;
    struct mmci_host *host;
    struct mmc_host *mmc;
    int ret;

    /* must have platform data */
    if (!plat) {
        ret = -EINVAL;
        goto out;
    }

    ret = amba_request_regions(dev, DRIVER_NAME);
    if (ret)
        goto out;

    mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
    if (!mmc) {
        ret = -ENOMEM;
        goto rel_regions;
    }

    host = mmc_priv(mmc);
    host->clk = clk_get(&dev->dev, "MCLK");
    if (IS_ERR(host->clk)) {
        ret = PTR_ERR(host->clk);
        host->clk = NULL;
        goto host_free;
    }

    ret = clk_enable(host->clk);
    if (ret)
        goto clk_free;

    host->plat = plat;
    host->mclk = clk_get_rate(host->clk);
    /*
     * According to the spec, mclk is max 100 MHz,
     * so we try to adjust the clock down to this,
     * (if possible).
     */
    if (host->mclk > 100000000) {
        ret = clk_set_rate(host->clk, 100000000);
        if (ret < 0)
            goto clk_disable;
        host->mclk = clk_get_rate(host->clk);
        DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
    }
    host->mmc = mmc;
    host->base = ioremap(dev->res.start, SZ_4K);
    if (!host->base) {
        ret = -ENOMEM;
        goto clk_disable;
    }

    mmc->ops = &mmci_ops;
    mmc->f_min = (host->mclk + 511) / 512;
    mmc->f_max = min(host->mclk, fmax);
    mmc->ocr_avail = plat->ocr_mask;

    /*
     * We can do SGIO
     */
    mmc->max_hw_segs = 16;
    mmc->max_phys_segs = NR_SG;

    /*
     * Since we only have a 16-bit data length register, we must
     * ensure that we don't exceed 2^16-1 bytes in a single request.
     */
    mmc->max_req_size = 65535;

    /*
     * Set the maximum segment size.  Since we aren't doing DMA
     * (yet) we are only limited by the data length register.
     */
    mmc->max_seg_size = mmc->max_req_size;

    /*
     * Block size can be up to 2048 bytes, but must be a power of two.
     */
    mmc->max_blk_size = 2048;

    /*
     * No limit on the number of blocks transferred.
     */
    mmc->max_blk_count = mmc->max_req_size;

    spin_lock_init(&host->lock);

    writel(0, host->base + MMCIMASK0);
    writel(0, host->base + MMCIMASK1);
    writel(0xfff, host->base + MMCICLEAR);

    ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
    if (ret)
        goto unmap;

    ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, DRIVER_NAME " (pio)", host);
    if (ret)
        goto irq0_free;

    writel(MCI_IRQENABLE, host->base + MMCIMASK0);

    amba_set_drvdata(dev, mmc);

    mmc_add_host(mmc);

    printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n",
           mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
           (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);

    init_timer(&host->timer);
    host->timer.data = (unsigned long)host;
    host->timer.function = mmci_check_status;
    host->timer.expires = jiffies + HZ;
    add_timer(&host->timer);

    return 0;

irq0_free:
    free_irq(dev->irq[0], host);
unmap:
    iounmap(host->base);
clk_disable:
    clk_disable(host->clk);
clk_free:
    clk_put(host->clk);
host_free:
    mmc_free_host(mmc);
rel_regions:
    amba_release_regions(dev);
out:
    return ret;
}
コード例 #24
0
static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
{
	struct mmci_platform_data *plat = dev->dev.platform_data;
	struct mmci_host *host;
	struct mmc_host *mmc;
	int ret;

	/* must have platform data */
	if (!plat) {
		ret = -EINVAL;
		goto out;
	}

	ret = amba_request_regions(dev, DRIVER_NAME);
	if (ret)
		goto out;

	mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto rel_regions;
	}

	host = mmc_priv(mmc);
	host->mmc = mmc;

	host->gpio_wp = -ENOSYS;
	host->gpio_cd = -ENOSYS;

	host->hw_designer = amba_manf(dev);
	host->hw_revision = amba_rev(dev);
	DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
	DBG(host, "revision = 0x%01x\n", host->hw_revision);

	host->clk = clk_get(&dev->dev, NULL);
	if (IS_ERR(host->clk)) {
		ret = PTR_ERR(host->clk);
		host->clk = NULL;
		goto host_free;
	}

	ret = clk_enable(host->clk);
	if (ret)
		goto clk_free;

	host->plat = plat;
	host->mclk = clk_get_rate(host->clk);
	/*
	 * According to the spec, mclk is max 100 MHz,
	 * so we try to adjust the clock down to this,
	 * (if possible).
	 */
	if (host->mclk > 100000000) {
		ret = clk_set_rate(host->clk, 100000000);
		if (ret < 0)
			goto clk_disable;
		host->mclk = clk_get_rate(host->clk);
		DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
	}
	host->base = ioremap(dev->res.start, resource_size(&dev->res));
	if (!host->base) {
		ret = -ENOMEM;
		goto clk_disable;
	}

	mmc->ops = &mmci_ops;
	mmc->f_min = (host->mclk + 511) / 512;
	mmc->f_max = min(host->mclk, fmax);
#ifdef CONFIG_REGULATOR
	/* If we're using the regulator framework, try to fetch a regulator */
	host->vcc = regulator_get(&dev->dev, "vmmc");
	if (IS_ERR(host->vcc))
		host->vcc = NULL;
	else {
		int mask = mmc_regulator_get_ocrmask(host->vcc);

		if (mask < 0)
			dev_err(&dev->dev, "error getting OCR mask (%d)\n",
				mask);
		else {
			host->mmc->ocr_avail = (u32) mask;
			if (plat->ocr_mask)
				dev_warn(&dev->dev,
				 "Provided ocr_mask/setpower will not be used "
				 "(using regulator instead)\n");
		}
	}
#endif
	/* Fall back to platform data if no regulator is found */
	if (host->vcc == NULL)
		mmc->ocr_avail = plat->ocr_mask;
	mmc->caps = plat->capabilities;

	/*
	 * We can do SGIO
	 */
	mmc->max_hw_segs = 16;
	mmc->max_phys_segs = NR_SG;

	/*
	 * Since we only have a 16-bit data length register, we must
	 * ensure that we don't exceed 2^16-1 bytes in a single request.
	 */
	mmc->max_req_size = 65535;

	/*
	 * Set the maximum segment size.  Since we aren't doing DMA
	 * (yet) we are only limited by the data length register.
	 */
	mmc->max_seg_size = mmc->max_req_size;

	/*
	 * Block size can be up to 2048 bytes, but must be a power of two.
	 */
	mmc->max_blk_size = 2048;

	/*
	 * No limit on the number of blocks transferred.
	 */
	mmc->max_blk_count = mmc->max_req_size;

	spin_lock_init(&host->lock);

	writel(0, host->base + MMCIMASK0);
	writel(0, host->base + MMCIMASK1);
	writel(0xfff, host->base + MMCICLEAR);

	if (gpio_is_valid(plat->gpio_cd)) {
		ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
		if (ret == 0)
			ret = gpio_direction_input(plat->gpio_cd);
		if (ret == 0)
			host->gpio_cd = plat->gpio_cd;
		else if (ret != -ENOSYS)
			goto err_gpio_cd;
	}
	if (gpio_is_valid(plat->gpio_wp)) {
		ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
		if (ret == 0)
			ret = gpio_direction_input(plat->gpio_wp);
		if (ret == 0)
			host->gpio_wp = plat->gpio_wp;
		else if (ret != -ENOSYS)
			goto err_gpio_wp;
	}

	ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
	if (ret)
		goto unmap;

	ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, DRIVER_NAME " (pio)", host);
	if (ret)
		goto irq0_free;

	writel(MCI_IRQENABLE, host->base + MMCIMASK0);

	amba_set_drvdata(dev, mmc);
	host->oldstat = mmci_get_cd(host->mmc);

	mmc_add_host(mmc);

	printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n",
		mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
		(unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);

	init_timer(&host->timer);
	host->timer.data = (unsigned long)host;
	host->timer.function = mmci_check_status;
	host->timer.expires = jiffies + HZ;
	add_timer(&host->timer);

	return 0;

 irq0_free:
	free_irq(dev->irq[0], host);
 unmap:
	if (host->gpio_wp != -ENOSYS)
		gpio_free(host->gpio_wp);
 err_gpio_wp:
	if (host->gpio_cd != -ENOSYS)
		gpio_free(host->gpio_cd);
 err_gpio_cd:
	iounmap(host->base);
 clk_disable:
	clk_disable(host->clk);
 clk_free:
	clk_put(host->clk);
 host_free:
	mmc_free_host(mmc);
 rel_regions:
	amba_release_regions(dev);
 out:
	return ret;
}
コード例 #25
0
ファイル: pl111_drv.c プロジェクト: ReneNyffenegger/linux
static int pl111_amba_probe(struct amba_device *amba_dev,
			    const struct amba_id *id)
{
	struct device *dev = &amba_dev->dev;
	struct pl111_drm_dev_private *priv;
	struct pl111_variant_data *variant = id->data;
	struct drm_device *drm;
	int ret;

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

	drm = drm_dev_alloc(&pl111_drm_driver, dev);
	if (IS_ERR(drm))
		return PTR_ERR(drm);
	amba_set_drvdata(amba_dev, drm);
	priv->drm = drm;
	drm->dev_private = priv;
	priv->variant = variant;

	/*
	 * The PL110 and PL111 variants have two registers
	 * swapped: interrupt enable and control. For this reason
	 * we use offsets that we can change per variant.
	 */
	if (variant->is_pl110) {
		/*
		 * The ARM Versatile boards are even more special:
		 * their PrimeCell ID say they are PL110 but the
		 * control and interrupt enable registers are anyway
		 * swapped to the PL111 order so they are not following
		 * the PL110 datasheet.
		 */
		if (of_machine_is_compatible("arm,versatile-ab") ||
		    of_machine_is_compatible("arm,versatile-pb")) {
			priv->ienb = CLCD_PL111_IENB;
			priv->ctrl = CLCD_PL111_CNTL;
		} else {
			priv->ienb = CLCD_PL110_IENB;
			priv->ctrl = CLCD_PL110_CNTL;
		}
	} else {
		priv->ienb = CLCD_PL111_IENB;
		priv->ctrl = CLCD_PL111_CNTL;
	}

	priv->regs = devm_ioremap_resource(dev, &amba_dev->res);
	if (IS_ERR(priv->regs)) {
		dev_err(dev, "%s failed mmio\n", __func__);
		return PTR_ERR(priv->regs);
	}

	/* turn off interrupts before requesting the irq */
	writel(0, priv->regs + priv->ienb);

	ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0,
			       variant->name, priv);
	if (ret != 0) {
		dev_err(dev, "%s failed irq %d\n", __func__, ret);
		return ret;
	}

	ret = pl111_versatile_init(dev, priv);
	if (ret)
		goto dev_unref;

	ret = pl111_modeset_init(drm);
	if (ret != 0)
		goto dev_unref;

	ret = drm_dev_register(drm, 0);
	if (ret < 0)
		goto dev_unref;

	return 0;

dev_unref:
	drm_dev_unref(drm);
	return ret;
}
コード例 #26
0
ファイル: gpio-pl061.c プロジェクト: mdr78/Linux-x1000
static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
{
	struct device *dev = &adev->dev;
	struct pl061_platform_data *pdata = dev_get_platdata(dev);
	struct pl061_gpio *chip;
	int ret, irq, i, irq_base;

	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) {
			dev_err(&adev->dev, "invalid IRQ base in pdata\n");
			return -ENODEV;
		}
	} else {
		chip->gc.base = -1;
		irq_base = 0;
	}

	chip->base = devm_ioremap_resource(dev, &adev->res);
	if (IS_ERR(chip->base))
		return PTR_ERR(chip->base);

	spin_lock_init(&chip->lock);

	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) {
		dev_err(&adev->dev, "invalid IRQ\n");
		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) {
		dev_err(&adev->dev, "no irq domain\n");
		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);
	dev_info(&adev->dev, "PL061 GPIO chip @%pa registered\n",
		 &adev->res.start);

	return 0;
}
コード例 #27
0
static int mmci_probe(struct amba_device *dev, void *id)
{
	struct mmc_platform_data *plat = dev->dev.platform_data;
	struct mmci_host *host;
	struct mmc_host *mmc;
	int ret;

	/* must have platform data */
	if (!plat) {
		ret = -EINVAL;
		goto out;
	}

	ret = amba_request_regions(dev, DRIVER_NAME);
	if (ret)
		goto out;

	mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto rel_regions;
	}

	host = mmc_priv(mmc);
	host->clk = clk_get(&dev->dev, "MCLK");
	if (IS_ERR(host->clk)) {
		ret = PTR_ERR(host->clk);
		host->clk = NULL;
		goto host_free;
	}

	ret = clk_use(host->clk);
	if (ret)
		goto clk_free;

	ret = clk_enable(host->clk);
	if (ret)
		goto clk_unuse;

	host->plat = plat;
	host->mclk = clk_get_rate(host->clk);
	host->mmc = mmc;
	host->base = ioremap(dev->res.start, SZ_4K);
	if (!host->base) {
		ret = -ENOMEM;
		goto clk_disable;
	}

	mmc->ops = &mmci_ops;
	mmc->f_min = (host->mclk + 511) / 512;
	mmc->f_max = min(host->mclk, fmax);
	mmc->ocr_avail = plat->ocr_mask;

	/*
	 * We can do SGIO
	 */
	mmc->max_hw_segs = 16;
	mmc->max_phys_segs = NR_SG;

	/*
	 * Since we only have a 16-bit data length register, we must
	 * ensure that we don't exceed 2^16-1 bytes in a single request.
	 * Choose 64 (512-byte) sectors as the limit.
	 */
	mmc->max_sectors = 64;

	/*
	 * Set the maximum segment size.  Since we aren't doing DMA
	 * (yet) we are only limited by the data length register.
	 */
	mmc->max_seg_size = mmc->max_sectors << 9;

	spin_lock_init(&host->lock);

	writel(0, host->base + MMCIMASK0);
	writel(0, host->base + MMCIMASK1);
	writel(0xfff, host->base + MMCICLEAR);

	ret = request_irq(dev->irq[0], mmci_irq, SA_SHIRQ, DRIVER_NAME " (cmd)", host);
	if (ret)
		goto unmap;

	ret = request_irq(dev->irq[1], mmci_pio_irq, SA_SHIRQ, DRIVER_NAME " (pio)", host);
	if (ret)
		goto irq0_free;

	writel(MCI_IRQENABLE, host->base + MMCIMASK0);

	amba_set_drvdata(dev, mmc);

	mmc_add_host(mmc);

	printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n",
		mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
		dev->res.start, dev->irq[0], dev->irq[1]);

	init_timer(&host->timer);
	host->timer.data = (unsigned long)host;
	host->timer.function = mmci_check_status;
	host->timer.expires = jiffies + HZ;
	add_timer(&host->timer);

	return 0;

 irq0_free:
	free_irq(dev->irq[0], host);
 unmap:
	iounmap(host->base);
 clk_disable:
	clk_disable(host->clk);
 clk_unuse:
	clk_unuse(host->clk);
 clk_free:
	clk_put(host->clk);
 host_free:
	mmc_free_host(mmc);
 rel_regions:
	amba_release_regions(dev);
 out:
	return ret;
}
コード例 #28
0
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;
}