コード例 #1
0
ファイル: spi-ath79.c プロジェクト: 7799/linux
static int ath79_spi_probe(struct platform_device *pdev)
{
	struct spi_master *master;
	struct ath79_spi *sp;
	struct ath79_spi_platform_data *pdata;
	struct resource	*r;
	unsigned long rate;
	int ret;

	master = spi_alloc_master(&pdev->dev, sizeof(*sp));
	if (master == NULL) {
		dev_err(&pdev->dev, "failed to allocate spi master\n");
		return -ENOMEM;
	}

	sp = spi_master_get_devdata(master);
	platform_set_drvdata(pdev, sp);

	pdata = dev_get_platdata(&pdev->dev);

	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
	master->setup = ath79_spi_setup;
	master->cleanup = ath79_spi_cleanup;
	if (pdata) {
		master->bus_num = pdata->bus_num;
		master->num_chipselect = pdata->num_chipselect;
	}

	sp->bitbang.master = master;
	sp->bitbang.chipselect = ath79_spi_chipselect;
	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
	sp->bitbang.flags = SPI_CS_HIGH;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (r == NULL) {
		ret = -ENOENT;
		goto err_put_master;
	}

	sp->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
	if (!sp->base) {
		ret = -ENXIO;
		goto err_put_master;
	}

	sp->clk = devm_clk_get(&pdev->dev, "ahb");
	if (IS_ERR(sp->clk)) {
		ret = PTR_ERR(sp->clk);
		goto err_put_master;
	}

	ret = clk_enable(sp->clk);
	if (ret)
		goto err_put_master;

	rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);
	if (!rate) {
		ret = -EINVAL;
		goto err_clk_disable;
	}

	sp->rrw_delay = ATH79_SPI_RRW_DELAY_FACTOR / rate;
	dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n",
		sp->rrw_delay);

	ath79_spi_enable(sp);
	ret = spi_bitbang_start(&sp->bitbang);
	if (ret)
		goto err_disable;

	return 0;

err_disable:
	ath79_spi_disable(sp);
err_clk_disable:
	clk_disable(sp->clk);
err_put_master:
	spi_master_put(sp->bitbang.master);

	return ret;
}
コード例 #2
0
static int serial_omap_probe(struct platform_device *pdev)
{
	struct uart_omap_port	*up;
	struct resource		*mem, *irq;
	struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data;
	int ret;

	if (pdev->dev.of_node)
		omap_up_info = of_get_uart_port_info(&pdev->dev);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "no mem resource?\n");
		return -ENODEV;
	}

	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!irq) {
		dev_err(&pdev->dev, "no irq resource?\n");
		return -ENODEV;
	}

	if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
				pdev->dev.driver->name)) {
		dev_err(&pdev->dev, "memory region already claimed\n");
		return -EBUSY;
	}

	if (gpio_is_valid(omap_up_info->DTR_gpio) &&
	    omap_up_info->DTR_present) {
		ret = gpio_request(omap_up_info->DTR_gpio, "omap-serial");
		if (ret < 0)
			return ret;
		ret = gpio_direction_output(omap_up_info->DTR_gpio,
					    omap_up_info->DTR_inverted);
		if (ret < 0)
			return ret;
	}

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

	if (gpio_is_valid(omap_up_info->DTR_gpio) &&
	    omap_up_info->DTR_present) {
		up->DTR_gpio = omap_up_info->DTR_gpio;
		up->DTR_inverted = omap_up_info->DTR_inverted;
	} else
		up->DTR_gpio = -EINVAL;
	up->DTR_active = 0;

	up->dev = &pdev->dev;
	up->port.dev = &pdev->dev;
	up->port.type = PORT_OMAP;
	up->port.iotype = UPIO_MEM;
	up->port.irq = irq->start;

	up->port.regshift = 2;
	up->port.fifosize = 64;
	up->port.ops = &serial_omap_pops;

	if (pdev->dev.of_node)
		up->port.line = of_alias_get_id(pdev->dev.of_node, "serial");
	else
		up->port.line = pdev->id;

	if (up->port.line < 0) {
		dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n",
								up->port.line);
		ret = -ENODEV;
		goto err_port_line;
	}

	up->pins = devm_pinctrl_get_select_default(&pdev->dev);
	if (IS_ERR(up->pins)) {
		dev_warn(&pdev->dev, "did not get pins for uart%i error: %li\n",
			 up->port.line, PTR_ERR(up->pins));
		up->pins = NULL;
	}

	sprintf(up->name, "OMAP UART%d", up->port.line);
	up->port.mapbase = mem->start;
	up->port.membase = devm_ioremap(&pdev->dev, mem->start,
						resource_size(mem));
	if (!up->port.membase) {
		dev_err(&pdev->dev, "can't ioremap UART\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	up->port.flags = omap_up_info->flags;
	up->port.uartclk = omap_up_info->uartclk;
	if (!up->port.uartclk) {
		up->port.uartclk = DEFAULT_CLK_SPEED;
		dev_warn(&pdev->dev, "No clock speed specified: using default:"
						"%d\n", DEFAULT_CLK_SPEED);
	}

	up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
	up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
	pm_qos_add_request(&up->pm_qos_request,
		PM_QOS_CPU_DMA_LATENCY, up->latency);
	serial_omap_uart_wq = create_singlethread_workqueue(up->name);
	INIT_WORK(&up->qos_work, serial_omap_uart_qos_work);

	platform_set_drvdata(pdev, up);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_use_autosuspend(&pdev->dev);
	pm_runtime_set_autosuspend_delay(&pdev->dev,
			omap_up_info->autosuspend_timeout);

	pm_runtime_irq_safe(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	omap_serial_fill_features_erratas(up);

	ui[up->port.line] = up;
	serial_omap_add_console_port(up);

	ret = uart_add_one_port(&serial_omap_reg, &up->port);
	if (ret != 0)
		goto err_add_port;

	pm_runtime_mark_last_busy(up->dev);
	pm_runtime_put_autosuspend(up->dev);
	return 0;

err_add_port:
	pm_runtime_put(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
err_ioremap:
err_port_line:
	dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
				pdev->id, __func__, ret);
	return ret;
}
コード例 #3
0
static int msm_iommu_probe(struct platform_device *pdev)
{
	struct iommu_pmon *pmon_info;
	struct msm_iommu_drvdata *drvdata;
	struct resource *r;
	int ret, needs_alt_core_clk, needs_alt_iface_clk;
	int global_cfg_irq, global_client_irq;
	u32 temp;

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

	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iommu_base");
	if (!r)
		return -EINVAL;

	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
	if (!drvdata->base)
		return -ENOMEM;

	drvdata->phys_base = r->start;

	r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
					"smmu_local_base");
	if (r) {
		drvdata->smmu_local_base =
			devm_ioremap(&pdev->dev, r->start, resource_size(r));
		if (!drvdata->smmu_local_base)
			return -ENOMEM;
	}

	drvdata->glb_base = drvdata->base;

	if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-mmu-500"))
		drvdata->model = MMU_500;

	if (of_get_property(pdev->dev.of_node, "vdd-supply", NULL)) {

		drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
		if (IS_ERR(drvdata->gdsc))
			return PTR_ERR(drvdata->gdsc);

		drvdata->alt_gdsc = devm_regulator_get(&pdev->dev,
							"qcom,alt-vdd");
		if (IS_ERR(drvdata->alt_gdsc))
			drvdata->alt_gdsc = NULL;
	} else {
		pr_debug("Warning: No regulator specified for IOMMU\n");
	}

	drvdata->pclk = devm_clk_get(&pdev->dev, "iface_clk");
	if (IS_ERR(drvdata->pclk))
		return PTR_ERR(drvdata->pclk);

	drvdata->clk = devm_clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(drvdata->clk))
		return PTR_ERR(drvdata->clk);

	needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
						   "qcom,needs-alt-core-clk");
	if (needs_alt_core_clk) {
		drvdata->aclk = devm_clk_get(&pdev->dev, "alt_core_clk");
		if (IS_ERR(drvdata->aclk))
			return PTR_ERR(drvdata->aclk);
	}

	needs_alt_iface_clk = of_property_read_bool(pdev->dev.of_node,
						   "qcom,needs-alt-iface-clk");
	if (needs_alt_iface_clk) {
		drvdata->aiclk = devm_clk_get(&pdev->dev, "alt_iface_clk");
		if (IS_ERR(drvdata->aiclk))
			return PTR_ERR(drvdata->aiclk);
	}

	if (!of_property_read_u32(pdev->dev.of_node,
				"qcom,cb-base-offset",
				&temp))
		drvdata->cb_base = drvdata->base + temp;
	else
		drvdata->cb_base = drvdata->base + 0x8000;

	if (clk_get_rate(drvdata->clk) == 0) {
		ret = clk_round_rate(drvdata->clk, 1000);
		clk_set_rate(drvdata->clk, ret);
	}

	if (drvdata->aclk && clk_get_rate(drvdata->aclk) == 0) {
		ret = clk_round_rate(drvdata->aclk, 1000);
		clk_set_rate(drvdata->aclk, ret);
	}

	if (drvdata->aiclk && clk_get_rate(drvdata->aiclk) == 0) {
		ret = clk_round_rate(drvdata->aiclk, 1000);
		clk_set_rate(drvdata->aiclk, ret);
	}

	ret = msm_iommu_parse_dt(pdev, drvdata);
	if (ret)
		return ret;

	dev_info(&pdev->dev,
		"device %s (model: %d) mapped at %p, with %d ctx banks\n",
		drvdata->name, drvdata->model, drvdata->base, drvdata->ncb);

	platform_set_drvdata(pdev, drvdata);

	pmon_info = msm_iommu_pm_alloc(&pdev->dev);
	if (pmon_info != NULL) {
		ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
		if (ret) {
			msm_iommu_pm_free(&pdev->dev);
			pr_info("%s: pmon not available.\n", drvdata->name);
		} else {
			pmon_info->iommu.base = drvdata->base;
			pmon_info->iommu.ops = msm_get_iommu_access_ops();
			pmon_info->iommu.hw_ops = iommu_pm_get_hw_ops_v1();
			pmon_info->iommu.iommu_name = drvdata->name;
			ret = msm_iommu_pm_iommu_register(pmon_info);
			if (ret) {
				pr_err("%s iommu register fail\n",
								drvdata->name);
				msm_iommu_pm_free(&pdev->dev);
			} else {
				pr_debug("%s iommu registered for pmon\n",
						pmon_info->iommu.iommu_name);
			}
		}
	}

	global_cfg_irq =
		platform_get_irq_byname(pdev, "global_cfg_NS_irq");
	if (global_cfg_irq > 0) {
		ret = devm_request_threaded_irq(&pdev->dev, global_cfg_irq,
				NULL,
				msm_iommu_global_fault_handler,
				IRQF_ONESHOT | IRQF_SHARED |
				IRQF_TRIGGER_RISING,
				"msm_iommu_global_cfg_irq", pdev);
		if (ret < 0)
			pr_err("Request Global CFG IRQ %d failed with ret=%d\n",
					global_cfg_irq, ret);
	}

	global_client_irq =
		platform_get_irq_byname(pdev, "global_client_NS_irq");
	if (global_client_irq > 0) {
		ret = devm_request_threaded_irq(&pdev->dev, global_client_irq,
				NULL,
				msm_iommu_global_fault_handler,
				IRQF_ONESHOT | IRQF_SHARED |
				IRQF_TRIGGER_RISING,
				"msm_iommu_global_client_irq", pdev);
		if (ret < 0)
			pr_err("Request Global Client IRQ %d failed with ret=%d\n",
					global_client_irq, ret);
	}

	return 0;
}
コード例 #4
0
static int sti_compositor_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *vtg_np;
	struct sti_compositor *compo;
	struct resource *res;
	unsigned int i;

	compo = devm_kzalloc(dev, sizeof(*compo), GFP_KERNEL);
	if (!compo) {
		DRM_ERROR("Failed to allocate compositor context\n");
		return -ENOMEM;
	}
	compo->dev = dev;
	for (i = 0; i < STI_MAX_MIXER; i++)
		compo->vtg_vblank_nb[i].notifier_call = sti_crtc_vblank_cb;

	/* populate data structure depending on compatibility */
	BUG_ON(!of_match_node(compositor_of_match, np)->data);

	memcpy(&compo->data, of_match_node(compositor_of_match, np)->data,
	       sizeof(struct sti_compositor_data));

	/* Get Memory ressources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		DRM_ERROR("Get memory resource failed\n");
		return -ENXIO;
	}
	compo->regs = devm_ioremap(dev, res->start, resource_size(res));
	if (compo->regs == NULL) {
		DRM_ERROR("Register mapping failed\n");
		return -ENXIO;
	}

	/* Get clock resources */
	compo->clk_compo_main = devm_clk_get(dev, "compo_main");
	if (IS_ERR(compo->clk_compo_main)) {
		DRM_ERROR("Cannot get compo_main clock\n");
		return PTR_ERR(compo->clk_compo_main);
	}

	compo->clk_compo_aux = devm_clk_get(dev, "compo_aux");
	if (IS_ERR(compo->clk_compo_aux)) {
		DRM_ERROR("Cannot get compo_aux clock\n");
		return PTR_ERR(compo->clk_compo_aux);
	}

	compo->clk_pix_main = devm_clk_get(dev, "pix_main");
	if (IS_ERR(compo->clk_pix_main)) {
		DRM_ERROR("Cannot get pix_main clock\n");
		return PTR_ERR(compo->clk_pix_main);
	}

	compo->clk_pix_aux = devm_clk_get(dev, "pix_aux");
	if (IS_ERR(compo->clk_pix_aux)) {
		DRM_ERROR("Cannot get pix_aux clock\n");
		return PTR_ERR(compo->clk_pix_aux);
	}

	/* Get reset resources */
	compo->rst_main = devm_reset_control_get_shared(dev, "compo-main");
	/* Take compo main out of reset */
	if (!IS_ERR(compo->rst_main))
		reset_control_deassert(compo->rst_main);

	compo->rst_aux = devm_reset_control_get_shared(dev, "compo-aux");
	/* Take compo aux out of reset */
	if (!IS_ERR(compo->rst_aux))
		reset_control_deassert(compo->rst_aux);

	vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 0);
	if (vtg_np)
		compo->vtg[STI_MIXER_MAIN] = of_vtg_find(vtg_np);
	of_node_put(vtg_np);

	vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 1);
	if (vtg_np)
		compo->vtg[STI_MIXER_AUX] = of_vtg_find(vtg_np);
	of_node_put(vtg_np);

	platform_set_drvdata(pdev, compo);

	return component_add(&pdev->dev, &sti_compositor_ops);
}
コード例 #5
0
static int stm_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct device *dev = &pdev->dev;
	struct coresight_platform_data *pdata = NULL;
	struct stm_drvdata *drvdata = NULL;
	struct resource *res = NULL;
	size_t res_size, bitmap_size;
	struct coresight_desc *desc = NULL;

	if (pdev->dev.of_node) {
		pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
		if (IS_ERR(pdata)) {
			dev_err(drvdata->dev, "of_get_coresight_platform_data error!\n");
			return PTR_ERR(pdata);
		}
		pdev->dev.platform_data = pdata;
	}

	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata) {
		dev_err(drvdata->dev, "coresight kzalloc error!\n");
		return -ENOMEM;
	}
	/* Store the driver data pointer for use in exported functions */
	stmdrvdata = drvdata;
	drvdata->dev = &pdev->dev;
	platform_set_drvdata(pdev, drvdata);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(drvdata->dev, "coresight get resource error!\n");
		return -ENODEV;
	}

	drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
	if (!drvdata->base) {
		dev_err(drvdata->dev, "coresight ioremap error!\n");
		return -ENOMEM;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res) {
		dev_err(drvdata->dev, "coresight get resource error!\n");
		return -ENODEV;
	}

	if (boot_nr_channel) {
		res_size = min((resource_size_t)(boot_nr_channel *
				  BYTES_PER_CHANNEL), resource_size(res));
		bitmap_size = boot_nr_channel * sizeof(long);
	} else {
		res_size = min((resource_size_t)(NR_STM_CHANNEL *
				 BYTES_PER_CHANNEL), resource_size(res));
		bitmap_size = NR_STM_CHANNEL * sizeof(long);
	}
	drvdata->chs.base = devm_ioremap(dev, res->start, res_size);
	if (!drvdata->chs.base) {
		dev_err(drvdata->dev, "coresight chds ioremap error!\n");
		return -ENOMEM;
	}
	drvdata->chs.bitmap = devm_kzalloc(dev, bitmap_size, GFP_KERNEL);
	if (!drvdata->chs.bitmap) {
		dev_err(drvdata->dev, "coresight chs bitmap kzalloc error!\n");
		return -ENOMEM;
	}

	spin_lock_init(&drvdata->spinlock);

	drvdata->clk_at= devm_clk_get(dev, pdata->clock_at);
	if (IS_ERR(drvdata->clk_at)) {
		dev_err(drvdata->dev, "coresight get clock error!\n");
		ret = PTR_ERR(drvdata->clk_at);
		goto err;
	}

	ret = clk_set_rate(drvdata->clk_at, 240000000);
	if (ret) {
		dev_err(drvdata->dev, "coresight set clock rate error!\n");
		goto err;
	}

	drvdata->clk_dbg= devm_clk_get(dev, pdata->clock_dbg);
	if (IS_ERR(drvdata->clk_dbg)) {
		dev_err(drvdata->dev, "coresight get clock error!\n");
		ret = PTR_ERR(drvdata->clk_dbg);
		goto err;
	}

	ret = clk_set_rate(drvdata->clk_dbg, 120000000);
	if (ret) {
		dev_err(drvdata->dev, "coresight set clock rate error!\n");
		goto err;
	}

	drvdata->entity = OST_ENTITY_ALL;
	drvdata->status = false;

	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
	if (!desc) {
		dev_err(drvdata->dev, "coresight desc kzalloc error!\n");
		return -ENOMEM;
	}
	desc->type = CORESIGHT_DEV_TYPE_SOURCE;
	desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
	desc->ops = &stm_cs_ops;
	desc->pdata = pdev->dev.platform_data;
	desc->dev = &pdev->dev;
	desc->groups = stm_attr_grps;
	desc->owner = THIS_MODULE;
	drvdata->csdev = coresight_register(desc);
	if (IS_ERR(drvdata->csdev)) {
		dev_err(drvdata->dev, "coresight_register error!\n");
		return PTR_ERR(drvdata->csdev);
	}

	drvdata->miscdev.name = ((struct coresight_platform_data *)
				 (pdev->dev.platform_data))->name;
	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
	drvdata->miscdev.fops = &stm_fops;
	ret = misc_register(&drvdata->miscdev);
	if (ret) {
		dev_err(drvdata->dev, "coresight misc_register error!\n");
		goto err;
	}

	dev_info(drvdata->dev, "STM initialized\n");

	/*
	 * Enable and disable STM to undo the temporary default STM enable
	 * done by RPM.
	 */
	coresight_enable(drvdata->csdev);
	coresight_disable(drvdata->csdev);

	if (boot_enable)
		coresight_enable(drvdata->csdev);

	return 0;
err:
	coresight_unregister(drvdata->csdev);
	return ret;
}
コード例 #6
0
ファイル: pata_mpc52xx.c プロジェクト: PennPanda/linux-repo
static int __devinit
mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
{
	unsigned int ipb_freq;
	struct resource res_mem;
	int ata_irq = NO_IRQ;
	struct mpc52xx_ata __iomem *ata_regs;
	struct mpc52xx_ata_priv *priv;
	int rv;

	/* Get ipb frequency */
	ipb_freq = mpc52xx_find_ipb_freq(op->node);
	if (!ipb_freq) {
		printk(KERN_ERR DRV_NAME ": "
			"Unable to find IPB Bus frequency\n" );
		return -ENODEV;
	}

	/* Get IRQ and register */
	rv = of_address_to_resource(op->node, 0, &res_mem);
	if (rv) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while parsing device node resource\n" );
		return rv;
	}

	ata_irq = irq_of_parse_and_map(op->node, 0);
	if (ata_irq == NO_IRQ) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while mapping the irq\n");
		return -EINVAL;
	}

	/* Request mem region */
	if (!devm_request_mem_region(&op->dev, res_mem.start,
				     sizeof(struct mpc52xx_ata), DRV_NAME)) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while requesting mem region\n");
		rv = -EBUSY;
		goto err;
	}

	/* Remap registers */
	ata_regs = devm_ioremap(&op->dev, res_mem.start,
				sizeof(struct mpc52xx_ata));
	if (!ata_regs) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while mapping register set\n");
		rv = -ENOMEM;
		goto err;
	}

	/* Prepare our private structure */
	priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv),
			    GFP_ATOMIC);
	if (!priv) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while allocating private structure\n");
		rv = -ENOMEM;
		goto err;
	}

	priv->ipb_period = 1000000000 / (ipb_freq / 1000);
	priv->ata_regs = ata_regs;
	priv->ata_irq = ata_irq;
	priv->csel = -1;

	/* Init the hw */
	rv = mpc52xx_ata_hw_init(priv);
	if (rv) {
		printk(KERN_ERR DRV_NAME ": Error during HW init\n");
		goto err;
	}

	/* Register ourselves to libata */
	rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start);
	if (rv) {
		printk(KERN_ERR DRV_NAME ": "
			"Error while registering to ATA layer\n");
		return rv;
	}

	/* Done */
	return 0;

	/* Error path */
err:
	irq_dispose_mapping(ata_irq);
	return rv;
}
コード例 #7
0
static int __init at32_wdt_probe(struct platform_device *pdev)
{
    struct resource	*regs;
    int ret;

    if (wdt) {
        dev_dbg(&pdev->dev, "only 1 wdt instance supported.\n");
        return -EBUSY;
    }

    regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!regs) {
        dev_dbg(&pdev->dev, "missing mmio resource\n");
        return -ENXIO;
    }

    wdt = devm_kzalloc(&pdev->dev, sizeof(struct wdt_at32ap700x),
                       GFP_KERNEL);
    if (!wdt) {
        dev_dbg(&pdev->dev, "no memory for wdt structure\n");
        return -ENOMEM;
    }

    wdt->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
    if (!wdt->regs) {
        ret = -ENOMEM;
        dev_dbg(&pdev->dev, "could not map I/O memory\n");
        goto err_free;
    }

    spin_lock_init(&wdt->io_lock);
    wdt->boot_status = at32_wdt_get_status();

    /* Work-around for watchdog silicon errata. */
    if (wdt->boot_status & WDIOF_CARDRESET) {
        dev_info(&pdev->dev, "CPU must be reset with external "
                 "reset or POR due to silicon errata.\n");
        ret = -EIO;
        goto err_free;
    } else {
        wdt->users = 0;
    }

    wdt->miscdev.minor	= WATCHDOG_MINOR;
    wdt->miscdev.name	= "watchdog";
    wdt->miscdev.fops	= &at32_wdt_fops;
    wdt->miscdev.parent	= &pdev->dev;

    platform_set_drvdata(pdev, wdt);

    if (at32_wdt_settimeout(timeout)) {
        at32_wdt_settimeout(TIMEOUT_DEFAULT);
        dev_dbg(&pdev->dev,
                "default timeout invalid, set to %d sec.\n",
                TIMEOUT_DEFAULT);
    }

    ret = misc_register(&wdt->miscdev);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register wdt miscdev\n");
        goto err_free;
    }

    dev_info(&pdev->dev,
             "AT32AP700X WDT at 0x%p, timeout %d sec (nowayout=%d)\n",
             wdt->regs, wdt->timeout, nowayout);

    return 0;

err_free:
    wdt = NULL;
    return ret;
}
コード例 #8
0
ファイル: ahci_msm.c プロジェクト: kamarush/caf_kernel_mm
static int msm_sata_phy_init(struct device *dev)
{
	int ret = 0;
	u32 reg = 0;
	struct platform_device *pdev = to_platform_device(dev);
	struct msm_sata_hba *hba = dev_get_drvdata(dev);
	struct resource *mem;

	mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem");
	if (!mem) {
		dev_err(dev, "no mmio space\n");
		return -EINVAL;
	}

	hba->phy_base = devm_ioremap(dev, mem->start, resource_size(mem));
	if (!hba->phy_base) {
		dev_err(dev, "failed to allocate memory for SATA PHY\n");
		return -ENOMEM;
	}

	/* SATA phy initialization */

	writel_relaxed(0x01, hba->phy_base + SATA_PHY_SER_CTRL);

	writel_relaxed(0xB1, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);
	mb();
	msm_sata_delay_us(10);

	writel_relaxed(0x01, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);
	writel_relaxed(0x3E, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_RX_IMCAL0);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_TX_IMCAL0);
	writel_relaxed(0x02, hba->phy_base + SATA_PHY_TX_IMCAL2);

	/* Write UNIPHYPLL registers to configure PLL */
	writel_relaxed(0x04, hba->phy_base + UNIPHY_PLL_REFCLK_CFG);
	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_PWRGEN_CFG);

	writel_relaxed(0x0A, hba->phy_base + UNIPHY_PLL_CAL_CFG0);
	writel_relaxed(0xF3, hba->phy_base + UNIPHY_PLL_CAL_CFG8);
	writel_relaxed(0x01, hba->phy_base + UNIPHY_PLL_CAL_CFG9);
	writel_relaxed(0xED, hba->phy_base + UNIPHY_PLL_CAL_CFG10);
	writel_relaxed(0x02, hba->phy_base + UNIPHY_PLL_CAL_CFG11);

	writel_relaxed(0x36, hba->phy_base + UNIPHY_PLL_SDM_CFG0);
	writel_relaxed(0x0D, hba->phy_base + UNIPHY_PLL_SDM_CFG1);
	writel_relaxed(0xA3, hba->phy_base + UNIPHY_PLL_SDM_CFG2);
	writel_relaxed(0xF0, hba->phy_base + UNIPHY_PLL_SDM_CFG3);
	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_SDM_CFG4);

	writel_relaxed(0x19, hba->phy_base + UNIPHY_PLL_SSC_CFG0);
	writel_relaxed(0xE1, hba->phy_base + UNIPHY_PLL_SSC_CFG1);
	writel_relaxed(0x00, hba->phy_base + UNIPHY_PLL_SSC_CFG2);
	writel_relaxed(0x11, hba->phy_base + UNIPHY_PLL_SSC_CFG3);

	writel_relaxed(0x04, hba->phy_base + UNIPHY_PLL_LKDET_CFG0);
	writel_relaxed(0xFF, hba->phy_base + UNIPHY_PLL_LKDET_CFG1);

	writel_relaxed(0x02, hba->phy_base + UNIPHY_PLL_GLB_CFG);
	mb();
	msm_sata_delay_us(40);

	writel_relaxed(0x03, hba->phy_base + UNIPHY_PLL_GLB_CFG);
	mb();
	msm_sata_delay_us(400);

	writel_relaxed(0x05, hba->phy_base + UNIPHY_PLL_LKDET_CFG2);
	mb();

	/* poll for ready status, timeout after 1 sec */
	ret = readl_poll_timeout(hba->phy_base + UNIPHY_PLL_STATUS, reg,
			(reg & 1 << 0), 100, 1000000);
	if (ret) {
		dev_err(dev, "poll timeout UNIPHY_PLL_STATUS\n");
		goto out;
	}

	ret = readl_poll_timeout(hba->phy_base + SATA_PHY_TX_IMCAL_STAT, reg,
			(reg & 1 << 0), 100, 1000000);
	if (ret) {
		dev_err(dev, "poll timeout SATA_PHY_TX_IMCAL_STAT\n");
		goto out;
	}

	ret = readl_poll_timeout(hba->phy_base + SATA_PHY_RX_IMCAL_STAT, reg,
			(reg & 1 << 0), 100, 1000000);
	if (ret) {
		dev_err(dev, "poll timeout SATA_PHY_RX_IMCAL_STAT\n");
		goto out;
	}

	/* SATA phy calibrated succesfully, power up to functional mode */
	writel_relaxed(0x3E, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_RX_IMCAL0);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_TX_IMCAL0);

	writel_relaxed(0x00, hba->phy_base + SATA_PHY_POW_DWN_CTRL1);
	writel_relaxed(0x59, hba->phy_base + SATA_PHY_CDR_CTRL0);
	writel_relaxed(0x04, hba->phy_base + SATA_PHY_CDR_CTRL1);
	writel_relaxed(0x00, hba->phy_base + SATA_PHY_CDR_CTRL2);
	writel_relaxed(0x00, hba->phy_base + SATA_PHY_PI_CTRL0);
	writel_relaxed(0x00, hba->phy_base + SATA_PHY_CDR_CTRL3);
	writel_relaxed(0x01, hba->phy_base + SATA_PHY_POW_DWN_CTRL0);

	writel_relaxed(0x11, hba->phy_base + SATA_PHY_TX_DATA_CTRL);
	writel_relaxed(0x43, hba->phy_base + SATA_PHY_ALIGNP);
	writel_relaxed(0x04, hba->phy_base + SATA_PHY_OOB_TERM);

	writel_relaxed(0x01, hba->phy_base + SATA_PHY_EQUAL);
	writel_relaxed(0x09, hba->phy_base + SATA_PHY_TX_DRIV_CTRL0);
	writel_relaxed(0x09, hba->phy_base + SATA_PHY_TX_DRIV_CTRL1);
	mb();

	dev_dbg(dev, "SATA PHY powered up in functional mode\n");

out:
	/* power down PHY in case of failure */
	if (ret)
		msm_sata_phy_deinit(dev);

	return ret;
}
コード例 #9
0
static int __devinit pil_riva_probe(struct platform_device *pdev)
{
    struct riva_data *drv;
    struct resource *res;
    struct pil_desc *desc;
    int ret;

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!res)
        return -EINVAL;

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

    drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
    if (!drv->base)
        return -ENOMEM;

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

    drv->pll_supply = regulator_get(&pdev->dev, "pll_vdd");
    if (IS_ERR(drv->pll_supply)) {
        dev_err(&pdev->dev, "failed to get pll supply\n");
        return PTR_ERR(drv->pll_supply);
    }
    ret = regulator_set_voltage(drv->pll_supply, 1800000, 1800000);
    if (ret) {
        dev_err(&pdev->dev, "failed to set pll supply voltage\n");
        goto err;
    }

    ret = regulator_set_optimum_mode(drv->pll_supply, 100000);
    if (ret < 0) {
        dev_err(&pdev->dev, "failed to set pll supply optimum mode\n");
        goto err;
    }

    desc->name = "wcnss";
    desc->dev = &pdev->dev;

    if (pas_supported(PAS_RIVA) > 0) {
        desc->ops = &pil_riva_ops_trusted;
        dev_info(&pdev->dev, "using secure boot\n");
    } else {
        desc->ops = &pil_riva_ops;
        dev_info(&pdev->dev, "using non-secure boot\n");
    }

    drv->xo = clk_get(&pdev->dev, "cxo");
    if (IS_ERR(drv->xo)) {
        ret = PTR_ERR(drv->xo);
        goto err;
    }
    wake_lock_init(&drv->wlock, WAKE_LOCK_SUSPEND, "riva-wlock");
    INIT_DELAYED_WORK(&drv->work, pil_riva_remove_proxy_votes);

    ret = msm_pil_register(desc);
    if (ret)
        goto err_register;
    return 0;
err_register:
    flush_delayed_work_sync(&drv->work);
    wake_lock_destroy(&drv->wlock);
    clk_put(drv->xo);
err:
    regulator_put(drv->pll_supply);
    return ret;
}
コード例 #10
0
static int tegra20_i2s_platform_probe(struct platform_device *pdev)
{
	struct tegra20_i2s *i2s;
	struct resource *mem, *memregion, *dmareq;
	u32 of_dma[2];
	u32 dma_ch;
	void __iomem *regs;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate tegra20_i2s\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, i2s);

	i2s->dai = tegra20_i2s_dai_template;
	i2s->dai.name = dev_name(&pdev->dev);

	i2s->clk_i2s = clk_get(&pdev->dev, NULL);
	if (IS_ERR(i2s->clk_i2s)) {
		dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
		ret = PTR_ERR(i2s->clk_i2s);
		goto err;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!dmareq) {
		if (of_property_read_u32_array(pdev->dev.of_node,
					"nvidia,dma-request-selector",
					of_dma, 2) < 0) {
			dev_err(&pdev->dev, "No DMA resource\n");
			ret = -ENODEV;
			goto err_clk_put;
		}
		dma_ch = of_dma[1];
	} else {
		dma_ch = dmareq->start;
	}

	memregion = devm_request_mem_region(&pdev->dev, mem->start,
					    resource_size(mem), DRV_NAME);
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_clk_put;
	}

	regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_clk_put;
	}

	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
					    &tegra20_i2s_regmap_config);
	if (IS_ERR(i2s->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		ret = PTR_ERR(i2s->regmap);
		goto err_clk_put;
	}

	i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
	i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	i2s->capture_dma_data.maxburst = 4;
	i2s->capture_dma_data.slave_id = dma_ch;

	i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
	i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	i2s->playback_dma_data.maxburst = 4;
	i2s->playback_dma_data.slave_id = dma_ch;

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = tegra20_i2s_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	ret = snd_soc_register_component(&pdev->dev, &tegra20_i2s_component,
					 &i2s->dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_suspend;
	}

	ret = tegra_pcm_platform_register(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_unregister_component;
	}

	return 0;

err_unregister_component:
	snd_soc_unregister_component(&pdev->dev);
err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		tegra20_i2s_runtime_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);
err_clk_put:
	clk_put(i2s->clk_i2s);
err:
	return ret;
}
コード例 #11
0
static int __devinit pil_q6v4_driver_probe(struct platform_device *pdev)
{
	const struct pil_q6v4_pdata *pdata = pdev->dev.platform_data;
	struct q6v4_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -EINVAL;

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

	drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!drv->base)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res) {
		drv->modem_base = devm_ioremap(&pdev->dev, res->start,
				resource_size(res));
		if (!drv->modem_base)
			return -ENOMEM;
	}

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

	drv->pll_supply = devm_regulator_get(&pdev->dev, "pll_vdd");
	if (IS_ERR(drv->pll_supply)) {
		drv->pll_supply = NULL;
	} else {
		ret = regulator_set_voltage(drv->pll_supply, 1800000, 1800000);
		if (ret) {
			dev_err(&pdev->dev, "failed to set pll voltage\n");
			return ret;
		}

		ret = regulator_set_optimum_mode(drv->pll_supply, 100000);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to set pll optimum mode\n");
			return ret;
		}
	}

	desc->name = pdata->name;
	desc->depends_on = pdata->depends;
	desc->dev = &pdev->dev;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = 10000;

	if (pas_supported(pdata->pas_id) > 0) {
		desc->ops = &pil_q6v4_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_q6v4_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}

	drv->vreg = devm_regulator_get(&pdev->dev, "core_vdd");
	if (IS_ERR(drv->vreg))
		return PTR_ERR(drv->vreg);

	ret = regulator_set_optimum_mode(drv->vreg, 100000);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to set regulator's mode.\n");
		return ret;
	}

	drv->xo = devm_clk_get(&pdev->dev, "xo");
	if (IS_ERR(drv->xo))
		return PTR_ERR(drv->xo);

	if (pdata->xo1_id) {
		drv->xo1 = msm_xo_get(pdata->xo1_id, pdata->name);
		if (IS_ERR(drv->xo1))
			return PTR_ERR(drv->xo1);
	}

	if (pdata->xo2_id) {
		drv->xo2 = msm_xo_get(pdata->xo2_id, pdata->name);
		if (IS_ERR(drv->xo2)) {
			msm_xo_put(drv->xo1);
			return PTR_ERR(drv->xo2);
		}
	}

	drv->pil = msm_pil_register(desc);
	if (IS_ERR(drv->pil)) {
		msm_xo_put(drv->xo2);
		msm_xo_put(drv->xo1);
		return PTR_ERR(drv->pil);
	}
	return 0;
}
コード例 #12
0
static int octeon_i2c_probe(struct platform_device *pdev)
{
	int irq, result = 0;
	struct octeon_i2c *i2c;
	struct resource *res_mem;

	/* All adaptors have an irq.  */
	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
	if (!i2c) {
		dev_err(&pdev->dev, "kzalloc failed\n");
		result = -ENOMEM;
		goto out;
	}
	i2c->dev = &pdev->dev;

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (res_mem == NULL) {
		dev_err(i2c->dev, "found no memory resource\n");
		result = -ENXIO;
		goto out;
	}
	i2c->twsi_phys = res_mem->start;
	i2c->regsize = resource_size(res_mem);

	/*
	 * "clock-rate" is a legacy binding, the official binding is
	 * "clock-frequency".  Try the official one first and then
	 * fall back if it doesn't exist.
	 */
	if (of_property_read_u32(pdev->dev.of_node,
				 "clock-frequency", &i2c->twsi_freq) &&
	    of_property_read_u32(pdev->dev.of_node,
				 "clock-rate", &i2c->twsi_freq)) {
		dev_err(i2c->dev,
			"no I2C 'clock-rate' or 'clock-frequency' property\n");
		result = -ENXIO;
		goto out;
	}

	i2c->sys_freq = octeon_get_io_clock_rate();

	if (!devm_request_mem_region(&pdev->dev, i2c->twsi_phys, i2c->regsize,
				      res_mem->name)) {
		dev_err(i2c->dev, "request_mem_region failed\n");
		goto out;
	}
	i2c->twsi_base = devm_ioremap(&pdev->dev, i2c->twsi_phys, i2c->regsize);

	init_waitqueue_head(&i2c->queue);

	i2c->irq = irq;

	result = devm_request_irq(&pdev->dev, i2c->irq,
				  octeon_i2c_isr, 0, DRV_NAME, i2c);
	if (result < 0) {
		dev_err(i2c->dev, "failed to attach interrupt\n");
		goto out;
	}

	result = octeon_i2c_initlowlevel(i2c);
	if (result) {
		dev_err(i2c->dev, "init low level failed\n");
		goto  out;
	}

	result = octeon_i2c_setclock(i2c);
	if (result) {
		dev_err(i2c->dev, "clock init failed\n");
		goto  out;
	}

	i2c->adap = octeon_i2c_ops;
	i2c->adap.dev.parent = &pdev->dev;
	i2c->adap.dev.of_node = pdev->dev.of_node;
	i2c_set_adapdata(&i2c->adap, i2c);
	platform_set_drvdata(pdev, i2c);

	result = i2c_add_adapter(&i2c->adap);
	if (result < 0) {
		dev_err(i2c->dev, "failed to add adapter\n");
		goto out;
	}
	dev_info(i2c->dev, "version %s\n", DRV_VERSION);

	return 0;

out:
	return result;
};
コード例 #13
0
ファイル: tegra30_i2s.c プロジェクト: Cool-Joe/imx23-audio
static int tegra30_i2s_platform_probe(struct platform_device *pdev)
{
    struct tegra30_i2s *i2s;
    u32 cif_ids[2];
    struct resource *mem, *memregion;
    void __iomem *regs;
    int ret;

    i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL);
    if (!i2s) {
        dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n");
        ret = -ENOMEM;
        goto err;
    }
    dev_set_drvdata(&pdev->dev, i2s);

    i2s->dai = tegra30_i2s_dai_template;
    i2s->dai.name = dev_name(&pdev->dev);

    ret = of_property_read_u32_array(pdev->dev.of_node,
                                     "nvidia,ahub-cif-ids", cif_ids,
                                     ARRAY_SIZE(cif_ids));
    if (ret < 0)
        goto err;

    i2s->playback_i2s_cif = cif_ids[0];
    i2s->capture_i2s_cif = cif_ids[1];

    i2s->clk_i2s = clk_get(&pdev->dev, NULL);
    if (IS_ERR(i2s->clk_i2s)) {
        dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
        ret = PTR_ERR(i2s->clk_i2s);
        goto err;
    }

    mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!mem) {
        dev_err(&pdev->dev, "No memory resource\n");
        ret = -ENODEV;
        goto err_clk_put;
    }

    memregion = devm_request_mem_region(&pdev->dev, mem->start,
                                        resource_size(mem), DRV_NAME);
    if (!memregion) {
        dev_err(&pdev->dev, "Memory region already claimed\n");
        ret = -EBUSY;
        goto err_clk_put;
    }

    regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
    if (!regs) {
        dev_err(&pdev->dev, "ioremap failed\n");
        ret = -ENOMEM;
        goto err_clk_put;
    }

    i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
                                        &tegra30_i2s_regmap_config);
    if (IS_ERR(i2s->regmap)) {
        dev_err(&pdev->dev, "regmap init failed\n");
        ret = PTR_ERR(i2s->regmap);
        goto err_clk_put;
    }
    regcache_cache_only(i2s->regmap, true);

    pm_runtime_enable(&pdev->dev);
    if (!pm_runtime_enabled(&pdev->dev)) {
        ret = tegra30_i2s_runtime_resume(&pdev->dev);
        if (ret)
            goto err_pm_disable;
    }

    ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
                                     &i2s->dai, 1);
    if (ret) {
        dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
        ret = -ENOMEM;
        goto err_suspend;
    }

    ret = tegra_pcm_platform_register(&pdev->dev);
    if (ret) {
        dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
        goto err_unregister_component;
    }

    return 0;

err_unregister_component:
    snd_soc_unregister_component(&pdev->dev);
err_suspend:
    if (!pm_runtime_status_suspended(&pdev->dev))
        tegra30_i2s_runtime_suspend(&pdev->dev);
err_pm_disable:
    pm_runtime_disable(&pdev->dev);
err_clk_put:
    clk_put(i2s->clk_i2s);
err:
    return ret;
}
コード例 #14
0
static int __devinit pil_q6v4_modem_driver_probe(struct platform_device *pdev)
{
	struct q6v4_data *drv_fw, *drv_sw;
	struct q6v4_modem *drv;
	struct resource *res;
	struct regulator *pll_supply;
	int ret;
	const struct pil_q6v4_pdata *pdata = pdev->dev.platform_data;

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

	drv_fw = &drv->q6_fw;
	drv_sw = &drv->q6_sw;

	drv_fw->wdog_irq = platform_get_irq(pdev, 0);
	if (drv_fw->wdog_irq < 0)
		return drv_fw->wdog_irq;

	drv_sw->wdog_irq = platform_get_irq(pdev, 1);
	if (drv_sw->wdog_irq < 0)
		return drv_sw->wdog_irq;

	drv->loadable = !!pdata; /* No pdata = don't use PIL */
	if (drv->loadable) {
		ret = pil_q6v4_proc_init(drv_fw, pdev, 0);
		if (ret)
			return ret;

		ret = pil_q6v4_proc_init(drv_sw, pdev, 1);
		if (ret)
			return ret;

		pll_supply = devm_regulator_get(&pdev->dev, "pll_vdd");
		drv_fw->pll_supply = drv_sw->pll_supply = pll_supply;
		if (IS_ERR(pll_supply))
			return PTR_ERR(pll_supply);

		ret = regulator_set_voltage(pll_supply, 1800000, 1800000);
		if (ret) {
			dev_err(&pdev->dev, "failed to set pll voltage\n");
			return ret;
		}

		ret = regulator_set_optimum_mode(pll_supply, 100000);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to set pll optimum mode\n");
			return ret;
		}

		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		drv->modem_base = devm_request_and_ioremap(&pdev->dev, res);
		if (!drv->modem_base)
			return -ENOMEM;

		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
		if (!res)
			return -EINVAL;
		drv->cbase = devm_ioremap(&pdev->dev, res->start,
					  resource_size(res));
		if (!drv->cbase)
			return -ENOMEM;

		ret = pil_desc_init(&drv_fw->desc);
		if (ret)
			return ret;

		ret = pil_desc_init(&drv_sw->desc);
		if (ret)
			goto err_pil_sw;
	}

	drv->subsys_desc.name = "modem";
	drv->subsys_desc.depends_on = "adsp";
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.shutdown = modem_shutdown;
	drv->subsys_desc.powerup = modem_powerup;
	drv->subsys_desc.ramdump = modem_ramdump;
	drv->subsys_desc.crash_shutdown = modem_crash_shutdown;

	drv->fw_ramdump_dev = create_ramdump_device("modem_fw", &pdev->dev);
	if (!drv->fw_ramdump_dev) {
		ret = -ENOMEM;
		goto err_fw_ramdump;
	}

	drv->sw_ramdump_dev = create_ramdump_device("modem_sw", &pdev->dev);
	if (!drv->sw_ramdump_dev) {
		ret = -ENOMEM;
		goto err_sw_ramdump;
	}

	drv->smem_ramdump_dev = create_ramdump_device("smem-modem", &pdev->dev);
	if (!drv->smem_ramdump_dev) {
		ret = -ENOMEM;
		goto err_smem_ramdump;
	}

	drv->subsys = subsys_register(&drv->subsys_desc);
	if (IS_ERR(drv->subsys)) {
		ret = PTR_ERR(drv->subsys);
		goto err_subsys;
	}
	if (!drv->loadable)
		subsys_default_online(drv->subsys);

	ret = devm_request_irq(&pdev->dev, drv_fw->wdog_irq,
			modem_wdog_bite_irq, IRQF_TRIGGER_RISING,
			dev_name(&pdev->dev), drv);
	if (ret)
		goto err_irq;
	disable_irq(drv_fw->wdog_irq);

	ret = devm_request_irq(&pdev->dev, drv_sw->wdog_irq,
			modem_wdog_bite_irq, IRQF_TRIGGER_RISING,
			dev_name(&pdev->dev), drv);
	if (ret)
		goto err_irq;
	disable_irq(drv_sw->wdog_irq);

	scm_pas_init(MSM_BUS_MASTER_SPS);

	ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
			smsm_state_cb, drv);
	if (ret)
		goto err_irq;
	return 0;

err_irq:
	subsys_unregister(drv->subsys);
err_subsys:
	destroy_ramdump_device(drv->smem_ramdump_dev);
err_smem_ramdump:
	destroy_ramdump_device(drv->sw_ramdump_dev);
err_sw_ramdump:
	destroy_ramdump_device(drv->fw_ramdump_dev);
err_fw_ramdump:
	if (drv->loadable)
		pil_desc_release(&drv_sw->desc);
err_pil_sw:
	pil_desc_release(&drv_fw->desc);
	return ret;
}
コード例 #15
0
ファイル: pil-riva.c プロジェクト: 1n/xperia-m-source
static int __devinit pil_riva_probe(struct platform_device *pdev)
{
	struct riva_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -EINVAL;

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

	drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!drv->base)
		return -ENOMEM;

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

	drv->pll_supply = devm_regulator_get(&pdev->dev, "pll_vdd");
	if (IS_ERR(drv->pll_supply)) {
		dev_err(&pdev->dev, "failed to get pll supply\n");
		return PTR_ERR(drv->pll_supply);
	}
	if (regulator_count_voltages(drv->pll_supply) > 0) {
		ret = regulator_set_voltage(drv->pll_supply, 1800000, 1800000);
		if (ret) {
			dev_err(&pdev->dev,
				"failed to set pll supply voltage\n");
			return ret;
		}

		ret = regulator_set_optimum_mode(drv->pll_supply, 100000);
		if (ret < 0) {
			dev_err(&pdev->dev,
				"failed to set pll supply optimum mode\n");
			return ret;
		}
	}

	desc->name = "wcnss";
	desc->dev = &pdev->dev;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = 10000;

	if (pas_supported(PAS_WCNSS) > 0) {
		desc->ops = &pil_riva_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_riva_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}

	drv->xo = devm_clk_get(&pdev->dev, "cxo");
	if (IS_ERR(drv->xo))
		return PTR_ERR(drv->xo);

	drv->pil = msm_pil_register(desc);
	if (IS_ERR(drv->pil))
		return PTR_ERR(drv->pil);
	return 0;
}
コード例 #16
0
ファイル: pata_pxa.c プロジェクト: 0-T-0/ps4-linux
static int pxa_ata_probe(struct platform_device *pdev)
{
	struct ata_host *host;
	struct ata_port *ap;
	struct pata_pxa_data *data;
	struct resource *cmd_res;
	struct resource *ctl_res;
	struct resource *dma_res;
	struct resource *irq_res;
	struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev);
	struct dma_slave_config	config;
	dma_cap_mask_t mask;
	struct pxad_param param;
	int ret = 0;

	/*
	 * Resource validation, three resources are needed:
	 *  - CMD port base address
	 *  - CTL port base address
	 *  - DMA port base address
	 *  - IRQ pin
	 */
	if (pdev->num_resources != 4) {
		dev_err(&pdev->dev, "invalid number of resources\n");
		return -EINVAL;
	}

	/*
	 * CMD port base address
	 */
	cmd_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(cmd_res == NULL))
		return -EINVAL;

	/*
	 * CTL port base address
	 */
	ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (unlikely(ctl_res == NULL))
		return -EINVAL;

	/*
	 * DMA port base address
	 */
	dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (unlikely(dma_res == NULL))
		return -EINVAL;

	/*
	 * IRQ pin
	 */
	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (unlikely(irq_res == NULL))
		return -EINVAL;

	/*
	 * Allocate the host
	 */
	host = ata_host_alloc(&pdev->dev, 1);
	if (!host)
		return -ENOMEM;

	ap		= host->ports[0];
	ap->ops		= &pxa_ata_port_ops;
	ap->pio_mask	= ATA_PIO4;
	ap->mwdma_mask	= ATA_MWDMA2;

	ap->ioaddr.cmd_addr	= devm_ioremap(&pdev->dev, cmd_res->start,
						resource_size(cmd_res));
	ap->ioaddr.ctl_addr	= devm_ioremap(&pdev->dev, ctl_res->start,
						resource_size(ctl_res));
	ap->ioaddr.bmdma_addr	= devm_ioremap(&pdev->dev, dma_res->start,
						resource_size(dma_res));

	/*
	 * Adjust register offsets
	 */
	ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
	ap->ioaddr.data_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_DATA << pdata->reg_shift);
	ap->ioaddr.error_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_ERR << pdata->reg_shift);
	ap->ioaddr.feature_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_FEATURE << pdata->reg_shift);
	ap->ioaddr.nsect_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_NSECT << pdata->reg_shift);
	ap->ioaddr.lbal_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_LBAL << pdata->reg_shift);
	ap->ioaddr.lbam_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_LBAM << pdata->reg_shift);
	ap->ioaddr.lbah_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_LBAH << pdata->reg_shift);
	ap->ioaddr.device_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_DEVICE << pdata->reg_shift);
	ap->ioaddr.status_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_STATUS << pdata->reg_shift);
	ap->ioaddr.command_addr	= ap->ioaddr.cmd_addr +
					(ATA_REG_CMD << pdata->reg_shift);

	/*
	 * Allocate and load driver's internal data structure
	 */
	data = devm_kzalloc(&pdev->dev, sizeof(struct pata_pxa_data),
								GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	ap->private_data = data;

	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);
	param.prio = PXAD_PRIO_LOWEST;
	param.drcmr = pdata->dma_dreq;
	memset(&config, 0, sizeof(config));
	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
	config.src_addr = dma_res->start;
	config.dst_addr = dma_res->start;
	config.src_maxburst = 32;
	config.dst_maxburst = 32;

	/*
	 * Request the DMA channel
	 */
	data->dma_chan =
		dma_request_slave_channel_compat(mask, pxad_filter_fn,
						 &param, &pdev->dev, "data");
	if (!data->dma_chan)
		return -EBUSY;
	ret = dmaengine_slave_config(data->dma_chan, &config);
	if (ret < 0) {
		dev_err(&pdev->dev, "dma configuration failed: %d\n", ret);
		return ret;
	}

	/*
	 * Activate the ATA host
	 */
	ret = ata_host_activate(host, irq_res->start, ata_sff_interrupt,
				pdata->irq_flags, &pxa_ata_sht);
	if (ret)
		dma_release_channel(data->dma_chan);

	return ret;
}
コード例 #17
0
struct q6v5_data *pil_q6v5_init(struct platform_device *pdev)
{
	struct q6v5_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;

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

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6_base");
	drv->reg_base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->reg_base)
		return ERR_PTR(-ENOMEM);

	desc = &drv->desc;
	ret = of_property_read_string(pdev->dev.of_node, "qcom,firmware-name",
				      &desc->name);
	if (ret)
		return ERR_PTR(ret);

	desc->dev = &pdev->dev;

	drv->qdsp6v5_2_0 = of_device_is_compatible(pdev->dev.of_node,
						   "qcom,pil-femto-modem");

	if (drv->qdsp6v5_2_0)
		return drv;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "halt_base");
	drv->axi_halt_base = devm_ioremap(&pdev->dev, res->start,
					  resource_size(res));
	if (!drv->axi_halt_base)
		return ERR_PTR(-ENOMEM);

	drv->qdsp6v55 = of_device_is_compatible(pdev->dev.of_node,
						"qcom,pil-q6v55-mss");
	drv->qdsp6v55 |= of_device_is_compatible(pdev->dev.of_node,
						"qcom,pil-q6v55-lpass");
	drv->qdsp6v56 = of_device_is_compatible(pdev->dev.of_node,
						"qcom,pil-q6v56-mss");

	drv->non_elf_image = of_property_read_bool(pdev->dev.of_node,
						"qcom,mba-image-is-not-elf");

	drv->xo = devm_clk_get(&pdev->dev, "xo");
	if (IS_ERR(drv->xo))
		return ERR_CAST(drv->xo);

	drv->vreg_cx = devm_regulator_get(&pdev->dev, "vdd_cx");
	if (IS_ERR(drv->vreg_cx))
		return ERR_CAST(drv->vreg_cx);

	drv->vreg_pll = devm_regulator_get(&pdev->dev, "vdd_pll");
	if (!IS_ERR_OR_NULL(drv->vreg_pll)) {
		int voltage;
		ret = of_property_read_u32(pdev->dev.of_node, "qcom,vdd_pll",
					   &voltage);
		if (ret) {
			dev_err(&pdev->dev, "Failed to find vdd_pll voltage.\n");
			return ERR_PTR(ret);
		}

		ret = regulator_set_voltage(drv->vreg_pll, voltage, voltage);
		if (ret) {
			dev_err(&pdev->dev, "Failed to request vdd_pll voltage.\n");
			return ERR_PTR(ret);
		}

		ret = regulator_set_optimum_mode(drv->vreg_pll, 10000);
		if (ret < 0) {
			dev_err(&pdev->dev, "Failed to set vdd_pll mode.\n");
			return ERR_PTR(ret);
		}
	} else {
		 drv->vreg_pll = NULL;
	}

	return drv;
}
コード例 #18
0
static int __devinit pil_modem_driver_probe(struct platform_device *pdev)
{
	struct modem_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;

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

	drv->irq = platform_get_irq(pdev, 0);
	if (drv->irq < 0)
		return drv->irq;

	drv->xo = devm_clk_get(&pdev->dev, "xo");
	if (IS_ERR(drv->xo))
		return PTR_ERR(drv->xo);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	drv->base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->base)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	drv->wdog = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->wdog)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	if (!res)
		return -EINVAL;

	drv->cbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!drv->cbase)
		return -ENOMEM;

	desc = &drv->pil_desc;
	desc->name = "modem";
	desc->dev = &pdev->dev;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = 10000;

	if (pas_supported(PAS_MODEM) > 0) {
		desc->ops = &pil_modem_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_modem_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}
	ret = pil_desc_init(desc);
	if (ret)
		return ret;

	drv->notifier.notifier_call = modem_notif_handler,
	ret = modem_register_notifier(&drv->notifier);
	if (ret)
		goto err_notify;

	drv->subsys_desc.name = "modem";
	drv->subsys_desc.depends_on = "adsp";
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.start = modem_start;
	drv->subsys_desc.stop = modem_stop;
	drv->subsys_desc.shutdown = modem_shutdown;
	drv->subsys_desc.powerup = modem_powerup;
	drv->subsys_desc.ramdump = modem_ramdump;
	drv->subsys_desc.crash_shutdown = modem_crash_shutdown;

	INIT_WORK(&drv->fatal_work, modem_fatal_fn);
	INIT_DELAYED_WORK(&drv->unlock_work, modem_unlock_timeout);

	drv->subsys = subsys_register(&drv->subsys_desc);
	if (IS_ERR(drv->subsys)) {
		ret = PTR_ERR(drv->subsys);
		goto err_subsys;
	}

	drv->ramdump_dev = create_ramdump_device("modem", &pdev->dev);
	if (!drv->ramdump_dev) {
		ret = -ENOMEM;
		goto err_ramdump;
	}

	scm_pas_init(MSM_BUS_MASTER_SPS);

	ret = devm_request_irq(&pdev->dev, drv->irq, modem_wdog_bite_irq,
			IRQF_TRIGGER_RISING, "modem_watchdog", drv);
	if (ret)
		goto err_irq;
	return 0;

err_irq:
	destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
	subsys_unregister(drv->subsys);
err_subsys:
	modem_unregister_notifier(&drv->notifier);
err_notify:
	pil_desc_release(desc);
	return ret;
}
コード例 #19
0
static int zynqmp_r5_remoteproc_probe(struct platform_device *pdev)
{
	const unsigned char *prop;
	struct resource *res;
	int ret = 0;
	int method = 0;
	char *rproc_firmware = 0;
	struct zynqmp_r5_rproc_pdata *local;

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

	platform_set_drvdata(pdev, local);

	/* FIXME: it may need to extend to 64/48 bit */
	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret);
		goto dma_mask_fault;
	}

	prop = of_get_property(pdev->dev.of_node, "core_conf", NULL);
	if (!prop) {
		dev_warn(&pdev->dev, "default core_conf used: lock-step\n");
		prop = "lock-step";
	}

	dev_info(&pdev->dev, "RPU core_conf: %s\n", prop);
	if (!strcmp(prop, "split0")) {
		local->rpu_mode = SPLIT;
		local->rpu_id = 0;
	} else if (!strcmp(prop, "split1")) {
		local->rpu_mode = SPLIT;
		local->rpu_id = 1;
	} else if (!strcmp(prop, "lock-step")) {
		local->rpu_mode = LOCK_STEP;
		local->rpu_id = 0;
	} else {
		dev_err(&pdev->dev, "Invalid core_conf mode provided - %s , %d\n",
			prop, local->rpu_mode);
		ret = -EINVAL;
		goto dma_mask_fault;
	}

	prop = of_get_property(pdev->dev.of_node, "method", NULL);
	if (!prop) {
		dev_warn(&pdev->dev, "default method used: smc\n");
		prop = "direct";
	}

	dev_info(&pdev->dev, "IPI/RPU control method: %s\n", prop);
	if (!strcmp(prop, "direct")) {
		method = HW;
		local->ipi_ops = &ipi_hw_ops;
		local->rpu_ops = &rpu_hw_ops;
	} else if (!strcmp(prop, "hvc")) {
		method = HVC;
		local->ipi_ops = &ipi_hvc_ops;
		local->rpu_ops = &rpu_hvc_ops;
	} else if (!strcmp(prop, "smc")) {
		method = SMC;
		local->ipi_ops = &ipi_smc_ops;
		local->rpu_ops = &rpu_smc_ops;
	} else {
		dev_err(&pdev->dev, "Invalid method provided - %s\n",
			prop);
		ret = -EINVAL;
		goto dma_mask_fault;
	}

	/* Handle direct hardware access */
	/* (TODO: remove once RPU and IPI drivers are ready ) */
	if (method == HW) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
			"rpu_base");
		local->rpu_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
		if (IS_ERR(local->rpu_base)) {
			dev_err(&pdev->dev, "Unable to map RPU I/O memory\n");
			ret = PTR_ERR(local->rpu_base);
			goto dma_mask_fault;
		}

		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
			"apb_base");
		local->crl_apb_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
		if (IS_ERR(local->crl_apb_base)) {
			dev_err(&pdev->dev, "Unable to map CRL_APB I/O memory\n");
			ret = PTR_ERR(local->crl_apb_base);
			goto dma_mask_fault;
		}

		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipi");
		local->ipi_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
		if (IS_ERR(local->ipi_base)) {
			pr_err("%s: Unable to map IPI\n", __func__);
			ret = PTR_ERR(local->ipi_base);
			goto dma_mask_fault;
		}
	}

	/* IPI IRQ */
	local->vring0 = platform_get_irq(pdev, 0);
	if (local->vring0 < 0) {
		ret = local->vring0;
		dev_err(&pdev->dev, "unable to find IPI IRQ\n");
		goto dma_mask_fault;
	}
	ret = devm_request_irq(&pdev->dev, local->vring0,
		r5_remoteproc_interrupt, IRQF_SHARED, dev_name(&pdev->dev),
		&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "IRQ %d already allocated\n",
			local->vring0);
		goto dma_mask_fault;
	}
	dev_dbg(&pdev->dev, "vring0 irq: %d\n", local->vring0);

	if (local->rpu_id == 0) {
		local->ipi_dest_mask = RPU_0_IPI_MASK;
		rproc_firmware = firmware;
	} else {
		local->ipi_dest_mask = RPU_1_IPI_MASK;
		rproc_firmware = firmware1;
	}

	dev_dbg(&pdev->dev, "Using firmware: %s\n", rproc_firmware);
	local->rproc = rproc_alloc(&pdev->dev, dev_name(&pdev->dev),
		&zynqmp_r5_rproc_ops, rproc_firmware, sizeof(struct rproc));
	if (!local->rproc) {
		dev_err(&pdev->dev, "rproc allocation failed\n");
		goto rproc_fault;
	}

	zynqmp_r5_rproc_init(local->rproc);
	ret = rproc_add(local->rproc);
	if (ret) {
		dev_err(&pdev->dev, "rproc registration failed\n");
		goto rproc_fault;
	}

	return ret;

rproc_fault:
	rproc_put(local->rproc);

dma_mask_fault:
	dma_release_declared_memory(&pdev->dev);

	return ret;
}
コード例 #20
0
static int simplefb_probe(struct platform_device *pdev)
{
	int ret;
	struct simplefb_params params;
	struct fb_info *info;
	struct resource *mem;

	if (fb_get_options("simplefb", NULL))
		return -ENODEV;

	ret = simplefb_parse_dt(pdev, &params);
	if (ret)
		return ret;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		return -EINVAL;
	}

	info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
	if (!info)
		return -ENOMEM;
	platform_set_drvdata(pdev, info);

	info->fix = simplefb_fix;
	info->fix.smem_start = mem->start;
	info->fix.smem_len = resource_size(mem);
	info->fix.line_length = params.stride;

	info->var = simplefb_var;
	info->var.xres = params.width;
	info->var.yres = params.height;
	info->var.xres_virtual = params.width;
	info->var.yres_virtual = params.height;
	info->var.bits_per_pixel = params.format->bits_per_pixel;
	info->var.red = params.format->red;
	info->var.green = params.format->green;
	info->var.blue = params.format->blue;
	info->var.transp = params.format->transp;

	info->fbops = &simplefb_ops;
	info->flags = FBINFO_DEFAULT;
	info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start,
					 info->fix.smem_len);
	if (!info->screen_base) {
		framebuffer_release(info);
		return -ENODEV;
	}
	info->pseudo_palette = (void *)(info + 1);

	ret = register_framebuffer(info);
	if (ret < 0) {
		dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
		framebuffer_release(info);
		return ret;
	}

	dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);

	return 0;
}
コード例 #21
0
static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
{
	struct tegra_i2s * i2s;
	struct resource *mem, *memregion, *dmareq;
	u32 of_dma[2];
	u32 dma_ch;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, i2s);

	i2s->dai = tegra_i2s_dai_template;
	i2s->dai.name = dev_name(&pdev->dev);

	i2s->clk_i2s = clk_get(&pdev->dev, NULL);
	if (IS_ERR(i2s->clk_i2s)) {
		dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
		ret = PTR_ERR(i2s->clk_i2s);
		goto err;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!dmareq) {
		if (of_property_read_u32_array(pdev->dev.of_node,
					"nvidia,dma-request-selector",
					of_dma, 2) < 0) {
			dev_err(&pdev->dev, "No DMA resource\n");
			ret = -ENODEV;
			goto err_clk_put;
		}
		dma_ch = of_dma[1];
	} else {
		dma_ch = dmareq->start;
	}

	memregion = devm_request_mem_region(&pdev->dev, mem->start,
					    resource_size(mem), DRV_NAME);
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_clk_put;
	}

	i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!i2s->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_clk_put;
	}

	i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
	i2s->capture_dma_data.wrap = 4;
	i2s->capture_dma_data.width = 32;
	i2s->capture_dma_data.req_sel = dma_ch;

	i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
	i2s->playback_dma_data.wrap = 4;
	i2s->playback_dma_data.width = 32;
	i2s->playback_dma_data.req_sel = dma_ch;

	i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;

	ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_clk_put;
	}

	tegra_i2s_debug_add(i2s);

	return 0;

err_clk_put:
	clk_put(i2s->clk_i2s);
err:
	return ret;
}
コード例 #22
0
static int exynos_ehci_probe(struct platform_device *pdev)
{
	struct exynos_ehci_hcd *exynos_ehci;
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct resource *res;
	struct usb_phy *phy;
	int irq;
	int err;

	/*
	 * Right now device-tree probed devices don't get dma_mask set.
	 * Since shared usb code relies on it, set it here for now.
	 * Once we move to full device tree support this will vanish off.
	 */
	if (!pdev->dev.dma_mask)
		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
	if (!pdev->dev.coherent_dma_mask)
		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);

	exynos_setup_vbus_gpio(pdev);

	hcd = usb_create_hcd(&exynos_ehci_hc_driver,
			     &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		dev_err(&pdev->dev, "Unable to create HCD\n");
		return -ENOMEM;
	}
	exynos_ehci = to_exynos_ehci(hcd);

	if (of_device_is_compatible(pdev->dev.of_node,
					"samsung,exynos5440-ehci"))
		goto skip_phy;

	phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
	if (IS_ERR(phy)) {
		usb_put_hcd(hcd);
		dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
		return -EPROBE_DEFER;
	} else {
		exynos_ehci->phy = phy;
		exynos_ehci->otg = phy->otg;
	}

skip_phy:

	exynos_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");

	if (IS_ERR(exynos_ehci->clk)) {
		dev_err(&pdev->dev, "Failed to get usbhost clock\n");
		err = PTR_ERR(exynos_ehci->clk);
		goto fail_clk;
	}

	err = clk_prepare_enable(exynos_ehci->clk);
	if (err)
		goto fail_clk;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get I/O memory\n");
		err = -ENXIO;
		goto fail_io;
	}

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	hcd->regs = devm_ioremap(&pdev->dev, res->start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "Failed to remap I/O memory\n");
		err = -ENOMEM;
		goto fail_io;
	}

	irq = platform_get_irq(pdev, 0);
	if (!irq) {
		dev_err(&pdev->dev, "Failed to get IRQ\n");
		err = -ENODEV;
		goto fail_io;
	}

	if (exynos_ehci->otg)
		exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);

	if (exynos_ehci->phy)
		usb_phy_init(exynos_ehci->phy);

	ehci = hcd_to_ehci(hcd);
	ehci->caps = hcd->regs;

	/* DMA burst Enable */
	writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));

	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (err) {
		dev_err(&pdev->dev, "Failed to add USB HCD\n");
		goto fail_add_hcd;
	}

	platform_set_drvdata(pdev, hcd);

	return 0;

fail_add_hcd:
	if (exynos_ehci->phy)
		usb_phy_shutdown(exynos_ehci->phy);
fail_io:
	clk_disable_unprepare(exynos_ehci->clk);
fail_clk:
	usb_put_hcd(hcd);
	return err;
}
コード例 #23
0
ファイル: lpc32xx_adc.c プロジェクト: 19Dan01/linux
static int lpc32xx_adc_probe(struct platform_device *pdev)
{
	struct lpc32xx_adc_info *info = NULL;
	struct resource *res;
	int retval = -ENODEV;
	struct iio_dev *iodev = NULL;
	int irq;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to get platform I/O memory\n");
		return -EBUSY;
	}

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

	info = iio_priv(iodev);

	info->adc_base = devm_ioremap(&pdev->dev, res->start,
						resource_size(res));
	if (!info->adc_base) {
		dev_err(&pdev->dev, "failed mapping memory\n");
		return -EBUSY;
	}

	info->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(info->clk)) {
		dev_err(&pdev->dev, "failed getting clock\n");
		return PTR_ERR(info->clk);
	}

	irq = platform_get_irq(pdev, 0);
	if (irq <= 0) {
		dev_err(&pdev->dev, "failed getting interrupt resource\n");
		return -EINVAL;
	}

	retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
								MOD_NAME, info);
	if (retval < 0) {
		dev_err(&pdev->dev, "failed requesting interrupt\n");
		return retval;
	}

	platform_set_drvdata(pdev, iodev);

	init_completion(&info->completion);

	iodev->name = MOD_NAME;
	iodev->dev.parent = &pdev->dev;
	iodev->info = &lpc32xx_adc_iio_info;
	iodev->modes = INDIO_DIRECT_MODE;
	iodev->channels = lpc32xx_adc_iio_channels;
	iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels);

	retval = devm_iio_device_register(&pdev->dev, iodev);
	if (retval)
		return retval;

	dev_info(&pdev->dev, "LPC32XX ADC driver loaded, IRQ %d\n", irq);

	return 0;
}
コード例 #24
0
ファイル: 8250_ingenic.c プロジェクト: AlexShiLucky/linux
static int ingenic_uart_probe(struct platform_device *pdev)
{
	struct uart_8250_port uart = {};
	struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	struct ingenic_uart_data *data;
	const struct ingenic_uart_config *cdata;
	const struct of_device_id *match;
	int err, line;

	match = of_match_device(of_match, &pdev->dev);
	if (!match) {
		dev_err(&pdev->dev, "Error: No device match found\n");
		return -ENODEV;
	}
	cdata = match->data;

	if (!regs || !irq) {
		dev_err(&pdev->dev, "no registers/irq defined\n");
		return -EINVAL;
	}

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

	spin_lock_init(&uart.port.lock);
	uart.port.type = PORT_16550A;
	uart.port.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE;
	uart.port.iotype = UPIO_MEM;
	uart.port.mapbase = regs->start;
	uart.port.regshift = 2;
	uart.port.serial_out = ingenic_uart_serial_out;
	uart.port.serial_in = ingenic_uart_serial_in;
	uart.port.irq = irq->start;
	uart.port.dev = &pdev->dev;
	uart.port.fifosize = cdata->fifosize;
	uart.tx_loadsz = cdata->tx_loadsz;
	uart.capabilities = UART_CAP_FIFO | UART_CAP_RTOIE;

	/* Check for a fixed line number */
	line = of_alias_get_id(pdev->dev.of_node, "serial");
	if (line >= 0)
		uart.port.line = line;

	uart.port.membase = devm_ioremap(&pdev->dev, regs->start,
					 resource_size(regs));
	if (!uart.port.membase)
		return -ENOMEM;

	data->clk_module = devm_clk_get(&pdev->dev, "module");
	if (IS_ERR(data->clk_module)) {
		err = PTR_ERR(data->clk_module);
		if (err != -EPROBE_DEFER)
			dev_err(&pdev->dev,
				"unable to get module clock: %d\n", err);
		return err;
	}

	data->clk_baud = devm_clk_get(&pdev->dev, "baud");
	if (IS_ERR(data->clk_baud)) {
		err = PTR_ERR(data->clk_baud);
		if (err != -EPROBE_DEFER)
			dev_err(&pdev->dev,
				"unable to get baud clock: %d\n", err);
		return err;
	}

	err = clk_prepare_enable(data->clk_module);
	if (err) {
		dev_err(&pdev->dev, "could not enable module clock: %d\n", err);
		goto out;
	}

	err = clk_prepare_enable(data->clk_baud);
	if (err) {
		dev_err(&pdev->dev, "could not enable baud clock: %d\n", err);
		goto out_disable_moduleclk;
	}
	uart.port.uartclk = clk_get_rate(data->clk_baud);

	data->line = serial8250_register_8250_port(&uart);
	if (data->line < 0) {
		err = data->line;
		goto out_disable_baudclk;
	}

	platform_set_drvdata(pdev, data);
	return 0;

out_disable_baudclk:
	clk_disable_unprepare(data->clk_baud);
out_disable_moduleclk:
	clk_disable_unprepare(data->clk_module);
out:
	return err;
}
コード例 #25
0
static int __init ahci_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ahci_platform_data *pdata = dev->platform_data;
	struct ata_port_info pi = {
		.flags		= AHCI_FLAG_COMMON,
		.pio_mask	= ATA_PIO4,
		.udma_mask	= ATA_UDMA6,
		.port_ops	= &ahci_ops,
	};
	const struct ata_port_info *ppi[] = { &pi, NULL };
	struct ahci_host_priv *hpriv;
	struct ata_host *host;
	struct resource *mem;
	int irq;
	int n_ports;
	int i;
	int rc;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(dev, "no mmio space\n");
		return -EINVAL;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq <= 0) {
		dev_err(dev, "no irq\n");
		return -EINVAL;
	}

	if (pdata && pdata->init) {
		rc = pdata->init(dev);
		if (rc)
			return rc;
	}

	if (pdata && pdata->ata_port_info)
		pi = *pdata->ata_port_info;

	hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
	if (!hpriv) {
		rc = -ENOMEM;
		goto err0;
	}

	hpriv->flags |= (unsigned long)pi.private_data;

	hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
	if (!hpriv->mmio) {
		dev_err(dev, "can't map %pR\n", mem);
		rc = -ENOMEM;
		goto err0;
	}

	ahci_save_initial_config(dev, hpriv,
		pdata ? pdata->force_port_map : 0,
		pdata ? pdata->mask_port_map  : 0);

	/* prepare host */
	if (hpriv->cap & HOST_CAP_NCQ)
		pi.flags |= ATA_FLAG_NCQ;

	if (hpriv->cap & HOST_CAP_PMP)
		pi.flags |= ATA_FLAG_PMP;

	ahci_set_em_messages(hpriv, &pi);

	/* CAP.NP sometimes indicate the index of the last enabled
	 * port, at other times, that of the last possible port, so
	 * determining the maximum port number requires looking at
	 * both CAP.NP and port_map.
	 */
	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));

	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
	if (!host) {
		rc = -ENOMEM;
		goto err0;
	}

	host->private_data = hpriv;

	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
		host->flags |= ATA_HOST_PARALLEL_SCAN;
	else
		printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n");

	if (pi.flags & ATA_FLAG_EM)
		ahci_reset_em(host);

	for (i = 0; i < host->n_ports; i++) {
		struct ata_port *ap = host->ports[i];

		ata_port_desc(ap, "mmio %pR", mem);
		ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);

		/* set initial link pm policy */
		ap->pm_policy = NOT_AVAILABLE;

		/* set enclosure management message type */
		if (ap->flags & ATA_FLAG_EM)
			ap->em_message_type = hpriv->em_msg_type;

		/* disabled/not-implemented port */
		if (!(hpriv->port_map & (1 << i)))
			ap->ops = &ata_dummy_port_ops;
	}

	rc = ahci_reset_controller(host);
	if (rc)
		goto err0;

	ahci_init_controller(host);
	ahci_print_info(host, "platform");

	rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
			       &ahci_sht);
	if (rc)
		goto err0;

	return 0;
err0:
	if (pdata && pdata->exit)
		pdata->exit(dev);
	return rc;
}
コード例 #26
0
ファイル: rtc-stmp3xxx.c プロジェクト: AshishNamdev/linux
static int stmp3xxx_rtc_probe(struct platform_device *pdev)
{
	struct stmp3xxx_rtc_data *rtc_data;
	struct resource *r;
	u32 rtc_stat;
	u32 pers0_set, pers0_clr;
	u32 crystalfreq = 0;
	int err;

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

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource\n");
		return -ENXIO;
	}

	rtc_data->io = devm_ioremap(&pdev->dev, r->start, resource_size(r));
	if (!rtc_data->io) {
		dev_err(&pdev->dev, "ioremap failed\n");
		return -EIO;
	}

	rtc_data->irq_alarm = platform_get_irq(pdev, 0);

	rtc_stat = readl(rtc_data->io + STMP3XXX_RTC_STAT);
	if (!(rtc_stat & STMP3XXX_RTC_STAT_RTC_PRESENT)) {
		dev_err(&pdev->dev, "no device onboard\n");
		return -ENODEV;
	}

	platform_set_drvdata(pdev, rtc_data);

	err = stmp_reset_block(rtc_data->io);
	if (err) {
		dev_err(&pdev->dev, "stmp_reset_block failed: %d\n", err);
		return err;
	}

	/*
	 * Obviously the rtc needs a clock input to be able to run.
	 * This clock can be provided by an external 32k crystal. If that one is
	 * missing XTAL must not be disabled in suspend which consumes a
	 * lot of power. Normally the presence and exact frequency (supported
	 * are 32000 Hz and 32768 Hz) is detectable from fuses, but as reality
	 * proves these fuses are not blown correctly on all machines, so the
	 * frequency can be overridden in the device tree.
	 */
	if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32000_PRESENT)
		crystalfreq = 32000;
	else if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32768_PRESENT)
		crystalfreq = 32768;

	of_property_read_u32(pdev->dev.of_node, "stmp,crystal-freq",
			     &crystalfreq);

	switch (crystalfreq) {
	case 32000:
		/* keep 32kHz crystal running in low-power mode */
		pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ |
			STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
			STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
		pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP;
		break;
	case 32768:
		/* keep 32.768kHz crystal running in low-power mode */
		pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
			STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
		pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP |
			STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ;
		break;
	default:
		dev_warn(&pdev->dev,
			 "invalid crystal-freq specified in device-tree. Assuming no crystal\n");
		/* fall-through */
	case 0:
		/* keep XTAL on in low-power mode */
		pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP;
		pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
			STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
	}

	writel(pers0_set, rtc_data->io + STMP3XXX_RTC_PERSISTENT0 +
			STMP_OFFSET_REG_SET);

	writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
			STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
			STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE | pers0_clr,
		rtc_data->io + STMP3XXX_RTC_PERSISTENT0 + STMP_OFFSET_REG_CLR);

	writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN |
			STMP3XXX_RTC_CTRL_ALARM_IRQ_EN,
		rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_CLR);

	rtc_data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
				&stmp3xxx_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc_data->rtc))
		return PTR_ERR(rtc_data->rtc);

	err = devm_request_irq(&pdev->dev, rtc_data->irq_alarm,
			stmp3xxx_rtc_interrupt, 0, "RTC alarm", &pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "Cannot claim IRQ%d\n",
			rtc_data->irq_alarm);
		return err;
	}

	stmp3xxx_wdt_register(pdev);
	return 0;
}
コード例 #27
0
ファイル: spear_thermal.c プロジェクト: 404992361/mi1_kernel
static int spear_thermal_probe(struct platform_device *pdev)
{
	struct thermal_zone_device *spear_thermal = NULL;
	struct spear_thermal_dev *stdev;
	struct spear_thermal_pdata *pdata;
	int ret = 0;
	struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!stres) {
		dev_err(&pdev->dev, "memory resource missing\n");
		return -ENODEV;
	}

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

	stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL);
	if (!stdev) {
		dev_err(&pdev->dev, "kzalloc fail\n");
		return -ENOMEM;
	}

	/* Enable thermal sensor */
	stdev->thermal_base = devm_ioremap(&pdev->dev, stres->start,
			resource_size(stres));
	if (!stdev->thermal_base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		return -ENOMEM;
	}

	stdev->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(stdev->clk)) {
		dev_err(&pdev->dev, "Can't get clock\n");
		return PTR_ERR(stdev->clk);
	}

	ret = clk_enable(stdev->clk);
	if (ret) {
		dev_err(&pdev->dev, "Can't enable clock\n");
		goto put_clk;
	}

	stdev->flags = pdata->thermal_flags;
	writel_relaxed(stdev->flags, stdev->thermal_base);

	spear_thermal = thermal_zone_device_register("spear_thermal", 0,
				stdev, &ops, 0, 0, 0, 0);
	if (IS_ERR(spear_thermal)) {
		dev_err(&pdev->dev, "thermal zone device is NULL\n");
		ret = PTR_ERR(spear_thermal);
		goto disable_clk;
	}

	platform_set_drvdata(pdev, spear_thermal);

	dev_info(&spear_thermal->device, "Thermal Sensor Loaded at: 0x%p.\n",
			stdev->thermal_base);

	return 0;

disable_clk:
	clk_disable(stdev->clk);
put_clk:
	clk_put(stdev->clk);

	return ret;
}
コード例 #28
0
ファイル: gdsc.c プロジェクト: HB72K1/LG-G2-D802-Kernel
static int __devinit gdsc_probe(struct platform_device *pdev)
{
	static atomic_t gdsc_count = ATOMIC_INIT(-1);
	struct regulator_init_data *init_data;
	struct resource *res;
	struct gdsc *sc;
	uint32_t regval;
	bool retain_mem, retain_periph;
	int i, ret;
#ifdef CONFIG_MACH_LGE
	int use_lge_workaround = 0; /* default: all not applied */
#endif

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

	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
	if (init_data == NULL)
		return -ENOMEM;

	if (of_get_property(pdev->dev.of_node, "parent-supply", NULL))
		init_data->supply_regulator = "parent";

	ret = of_property_read_string(pdev->dev.of_node, "regulator-name",
				      &sc->rdesc.name);
	if (ret)
		return ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL)
		return -EINVAL;
	sc->gdscr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (sc->gdscr == NULL)
		return -ENOMEM;

	sc->clock_count = of_property_count_strings(pdev->dev.of_node,
					    "qcom,clock-names");
	if (sc->clock_count == -EINVAL) {
		sc->clock_count = 0;
	} else if (IS_ERR_VALUE(sc->clock_count)) {
		dev_err(&pdev->dev, "Failed to get clock names\n");
		return -EINVAL;
	}

	sc->clocks = devm_kzalloc(&pdev->dev,
			sizeof(struct clk *) * sc->clock_count, GFP_KERNEL);
	if (!sc->clocks)
		return -ENOMEM;
	for (i = 0; i < sc->clock_count; i++) {
		const char *clock_name;
		of_property_read_string_index(pdev->dev.of_node,
					      "qcom,clock-names", i,
					      &clock_name);
		sc->clocks[i] = devm_clk_get(&pdev->dev, clock_name);
		if (IS_ERR(sc->clocks[i])) {
			int rc = PTR_ERR(sc->clocks[i]);
			if (rc != -EPROBE_DEFER)
				dev_err(&pdev->dev, "Failed to get %s\n",
					clock_name);
			return rc;
		}
	}
#ifdef CONFIG_MACH_LGE
	of_property_read_u32(pdev->dev.of_node, "lge,use_workaround",
			&use_lge_workaround);
	sc->use_lge_workaround = !(!use_lge_workaround);
#endif
	sc->rdesc.id = atomic_inc_return(&gdsc_count);
	sc->rdesc.ops = &gdsc_ops;
	sc->rdesc.type = REGULATOR_VOLTAGE;
	sc->rdesc.owner = THIS_MODULE;
	platform_set_drvdata(pdev, sc);

	/*
	 * Disable HW trigger: collapse/restore occur based on registers writes.
	 * Disable SW override: Use hardware state-machine for sequencing.
	 */
	regval = readl_relaxed(sc->gdscr);
	regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);

	/* Configure wait time between states. */
	regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
	regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
	writel_relaxed(regval, sc->gdscr);

	retain_mem = of_property_read_bool(pdev->dev.of_node,
					    "qcom,retain-mem");
	sc->toggle_mem = !retain_mem;
	retain_periph = of_property_read_bool(pdev->dev.of_node,
					    "qcom,retain-periph");
	sc->toggle_periph = !retain_periph;
	sc->toggle_logic = !of_property_read_bool(pdev->dev.of_node,
						"qcom,skip-logic-collapse");
	if (!sc->toggle_logic) {
#ifdef CONFIG_MACH_LGE
		/* LGE workaround is not used if a device is good pdn revision */
		if (lge_get_board_revno() >= use_lge_workaround) {
			regval &= ~SW_COLLAPSE_MASK;
			writel_relaxed(regval, sc->gdscr);

			ret = readl_tight_poll_timeout(sc->gdscr, regval,
					regval & PWR_ON_MASK, TIMEOUT_US);
			if (ret) {
				dev_err(&pdev->dev, "%s enable timed out\n",
						sc->rdesc.name);
				return ret;
			}
		} else {
			pr_info("%s: %s is enabled only at first by lge workaround\n",
					__func__, sc->rdesc.name);
			ret = lge_gdsc_enable(sc);
			if (ret) {
				dev_err(&pdev->dev, "%s enable timed out\n",
						sc->rdesc.name);
				return ret;
			}
		}
#else /* qmc */
		regval &= ~SW_COLLAPSE_MASK;
		writel_relaxed(regval, sc->gdscr);

		ret = readl_tight_poll_timeout(sc->gdscr, regval,
					regval & PWR_ON_MASK, TIMEOUT_US);
		if (ret) {
			dev_err(&pdev->dev, "%s enable timed out\n",
				sc->rdesc.name);
			return ret;
		}
#endif
	}

	for (i = 0; i < sc->clock_count; i++) {
		if (retain_mem || (regval & PWR_ON_MASK))
			clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_MEM);
		else
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM);

		if (retain_periph || (regval & PWR_ON_MASK))
			clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_PERIPH);
		else
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH);
	}

	sc->rdev = regulator_register(&sc->rdesc, &pdev->dev, init_data, sc,
				      pdev->dev.of_node);
	if (IS_ERR(sc->rdev)) {
		dev_err(&pdev->dev, "regulator_register(\"%s\") failed.\n",
			sc->rdesc.name);
		return PTR_ERR(sc->rdev);
	}

	return 0;
}
コード例 #29
0
static int __devinit pil_q6v3_driver_probe(struct platform_device *pdev)
{
	struct q6v3_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	drv->base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->base)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	drv->wk_base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->wk_base)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	drv->wd_base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->wd_base)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
	if (!res)
		return -EINVAL;
	drv->cbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!drv->cbase)
		return -ENOMEM;

	drv->irq = platform_get_irq(pdev, 0);
	if (drv->irq < 0)
		return drv->irq;

	drv->pll = devm_clk_get(&pdev->dev, "pll4");
	if (IS_ERR(drv->pll))
		return PTR_ERR(drv->pll);

	desc = &drv->pil_desc;
	desc->name = "q6";
	desc->dev = &pdev->dev;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = 10000;

	if (pas_supported(PAS_Q6) > 0) {
		desc->ops = &pil_q6v3_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_q6v3_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}

	ret = pil_desc_init(desc);
	if (ret)
		return ret;

	drv->subsys_desc.name = "adsp";
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.shutdown = lpass_q6_shutdown;
	drv->subsys_desc.powerup = lpass_q6_powerup;
	drv->subsys_desc.ramdump = lpass_q6_ramdump;
	drv->subsys_desc.crash_shutdown = lpass_q6_crash_shutdown;

	INIT_WORK(&drv->fatal_wrk, q6_fatal_fn);

	drv->ramdump_dev = create_ramdump_device("lpass", &pdev->dev);
	if (!drv->ramdump_dev) {
		ret = -ENOMEM;
		goto err_ramdump;
	}

	drv->subsys = subsys_register(&drv->subsys_desc);
	if (IS_ERR(drv->subsys)) {
		ret = PTR_ERR(drv->subsys);
		goto err_subsys;
	}

	scm_pas_init(MSM_BUS_MASTER_SPS);

	ret = devm_request_irq(&pdev->dev, drv->irq, lpass_wdog_bite_irq,
			       IRQF_TRIGGER_RISING, "lpass_wdog", drv);
	if (ret) {
		dev_err(&pdev->dev, "Unable to request wdog irq.\n");
		goto err_irq;
	}
	disable_irq(drv->irq);

	return 0;
err_irq:
	subsys_unregister(drv->subsys);
err_subsys:
	destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
	pil_desc_release(desc);
	return ret;
}
コード例 #30
0
ファイル: at91_cf.c プロジェクト: 383530895/linux
static int at91_cf_probe(struct platform_device *pdev)
{
	struct at91_cf_socket	*cf;
	struct at91_cf_data	*board = pdev->dev.platform_data;
	struct resource		*io;
	int			status;

	if (!board) {
		status = at91_cf_dt_init(pdev);
		if (status)
			return status;

		board = pdev->dev.platform_data;
	}

	if (!gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin))
		return -ENODEV;

	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!io)
		return -ENODEV;

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

	cf->board = board;
	cf->pdev = pdev;
	cf->phys_baseaddr = io->start;
	platform_set_drvdata(pdev, cf);

	/* must be a GPIO; ergo must trigger on both edges */
	status = devm_gpio_request(&pdev->dev, board->det_pin, "cf_det");
	if (status < 0)
		return status;

	status = devm_request_irq(&pdev->dev, gpio_to_irq(board->det_pin),
					at91_cf_irq, 0, "at91_cf detect", cf);
	if (status < 0)
		return status;

	device_init_wakeup(&pdev->dev, 1);

	status = devm_gpio_request(&pdev->dev, board->rst_pin, "cf_rst");
	if (status < 0)
		goto fail0a;

	if (gpio_is_valid(board->vcc_pin)) {
		status = devm_gpio_request(&pdev->dev, board->vcc_pin, "cf_vcc");
		if (status < 0)
			goto fail0a;
	}

	/*
	 * The card driver will request this irq later as needed.
	 * but it causes lots of "irqNN: nobody cared" messages
	 * unless we report that we handle everything (sigh).
	 * (Note:  DK board doesn't wire the IRQ pin...)
	 */
	if (gpio_is_valid(board->irq_pin)) {
		status = devm_gpio_request(&pdev->dev, board->irq_pin, "cf_irq");
		if (status < 0)
			goto fail0a;

		status = devm_request_irq(&pdev->dev, gpio_to_irq(board->irq_pin),
					at91_cf_irq, IRQF_SHARED, "at91_cf", cf);
		if (status < 0)
			goto fail0a;
		cf->socket.pci_irq = gpio_to_irq(board->irq_pin);
	} else
		cf->socket.pci_irq = nr_irqs + 1;

	/* pcmcia layer only remaps "real" memory not iospace */
	cf->socket.io_offset = (unsigned long) devm_ioremap(&pdev->dev,
					cf->phys_baseaddr + CF_IO_PHYS, SZ_2K);
	if (!cf->socket.io_offset) {
		status = -ENXIO;
		goto fail0a;
	}

	/* reserve chip-select regions */
	if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io), "at91_cf")) {
		status = -ENXIO;
		goto fail0a;
	}

	dev_info(&pdev->dev, "irqs det #%d, io #%d\n",
		gpio_to_irq(board->det_pin), gpio_to_irq(board->irq_pin));

	cf->socket.owner = THIS_MODULE;
	cf->socket.dev.parent = &pdev->dev;
	cf->socket.ops = &at91_cf_ops;
	cf->socket.resource_ops = &pccard_static_ops;
	cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
				| SS_CAP_MEM_ALIGN;
	cf->socket.map_size = SZ_2K;
	cf->socket.io[0].res = io;

	status = pcmcia_register_socket(&cf->socket);
	if (status < 0)
		goto fail0a;

	return 0;

fail0a:
	device_init_wakeup(&pdev->dev, 0);
	return status;
}