static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
{
	const struct platform_device_id *platid = platform_get_device_id(pdev);
	const struct of_device_id *dtid = sdhci_get_of_device_id(pdev);
	struct sdhci_pltfm_data *pdata;
	struct sdhci_host *host;
	struct sdhci_pltfm_host *pltfm_host;
	struct resource *iomem;
	int ret;

	if (platid && platid->driver_data)
		pdata = (void *)platid->driver_data;
	else if (dtid && dtid->data)
		pdata = dtid->data;
	else
		pdata = pdev->dev.platform_data;

	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!iomem) {
		ret = -ENOMEM;
		goto err;
	}

	if (resource_size(iomem) < 0x100)
		dev_err(&pdev->dev, "Invalid iomem size. You may "
			"experience problems.\n");

	/* Some PCI-based MFD need the parent here */
	if (pdev->dev.parent != &platform_bus)
		host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host));
	else
		host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));

	if (IS_ERR(host)) {
		ret = PTR_ERR(host);
		goto err;
	}

	pltfm_host = sdhci_priv(host);

	host->hw_name = "platform";
	if (pdata && pdata->ops)
		host->ops = pdata->ops;
	else
		host->ops = &sdhci_pltfm_ops;
	if (pdata)
		host->quirks = pdata->quirks;
	host->irq = platform_get_irq(pdev, 0);

	if (!request_mem_region(iomem->start, resource_size(iomem),
		mmc_hostname(host->mmc))) {
		dev_err(&pdev->dev, "cannot request region\n");
		ret = -EBUSY;
		goto err_request;
	}

	host->ioaddr = ioremap(iomem->start, resource_size(iomem));
	if (!host->ioaddr) {
		dev_err(&pdev->dev, "failed to remap registers\n");
		ret = -ENOMEM;
		goto err_remap;
	}

	if (pdata && pdata->init) {
		ret = pdata->init(host, pdata);
		if (ret)
			goto err_plat_init;
	}

	ret = sdhci_add_host(host);
	if (ret)
		goto err_add_host;

	platform_set_drvdata(pdev, host);

	return 0;

err_add_host:
	if (pdata && pdata->exit)
		pdata->exit(host);
err_plat_init:
	iounmap(host->ioaddr);
err_remap:
	release_mem_region(iomem->start, resource_size(iomem));
err_request:
	sdhci_free_host(host);
err:
	printk(KERN_ERR"Probing of sdhci-pltfm failed: %d\n", ret);
	return ret;
}
예제 #2
0
static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
{
	int result;
	struct usb_hcd *hcd;
	unsigned int virq;
	static u64 dummy_mask = DMA_BIT_MASK(32);

	if (usb_disabled()) {
		result = -ENODEV;
		goto fail_start;
	}

	result = ps3_open_hv_device(dev);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
			__func__, __LINE__);
		goto fail_open;
	}

	result = ps3_dma_region_create(dev->d_region);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
			"(%d)\n", __func__, __LINE__, result);
		BUG_ON("check region type");
		goto fail_dma_region;
	}

	result = ps3_mmio_region_create(dev->m_region);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
			__func__, __LINE__);
		result = -EPERM;
		goto fail_mmio_region;
	}

	dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
		__LINE__, dev->m_region->lpar_addr);

	result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n",
			__func__, __LINE__, virq);
		result = -EPERM;
		goto fail_irq;
	}

	dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */

	hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev_name(&dev->core));

	if (!hcd) {
		dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__,
			__LINE__);
		result = -ENOMEM;
		goto fail_create_hcd;
	}

	hcd->rsrc_start = dev->m_region->lpar_addr;
	hcd->rsrc_len = dev->m_region->len;

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
		dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
			__func__, __LINE__);

	hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);

	if (!hcd->regs) {
		dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__,
			__LINE__);
		result = -EPERM;
		goto fail_ioremap;
	}

	dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__,
		(unsigned long)hcd->rsrc_start);
	dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len   %lxh\n", __func__, __LINE__,
		(unsigned long)hcd->rsrc_len);
	dev_dbg(&dev->core, "%s:%d: hcd->regs       %lxh\n", __func__, __LINE__,
		(unsigned long)hcd->regs);
	dev_dbg(&dev->core, "%s:%d: virq            %lu\n", __func__, __LINE__,
		(unsigned long)virq);

	ps3_system_bus_set_drvdata(dev, hcd);

	result = usb_add_hcd(hcd, virq, 0);

	if (result) {
		dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n",
			__func__, __LINE__, result);
		goto fail_add_hcd;
	}

	return result;

fail_add_hcd:
	iounmap(hcd->regs);
fail_ioremap:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);
fail_create_hcd:
	ps3_io_irq_destroy(virq);
fail_irq:
	ps3_free_mmio_region(dev->m_region);
fail_mmio_region:
	ps3_dma_region_free(dev->d_region);
fail_dma_region:
	ps3_close_hv_device(dev);
fail_open:
fail_start:
	return result;
}
static void __devexit voodoo3_remove(struct pci_dev *dev)
{
	i2c_del_adapter(&voodoo3_i2c_adapter);
	i2c_del_adapter(&voodoo3_ddc_adapter);
	iounmap(ioaddr);
}
예제 #4
0
파일: ftmac100.c 프로젝트: 020gzh/linux
/******************************************************************************
 * struct platform_driver functions
 *****************************************************************************/
static int ftmac100_probe(struct platform_device *pdev)
{
	struct resource *res;
	int irq;
	struct net_device *netdev;
	struct ftmac100 *priv;
	int err;

	if (!pdev)
		return -ENODEV;

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

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

	/* setup net_device */
	netdev = alloc_etherdev(sizeof(*priv));
	if (!netdev) {
		err = -ENOMEM;
		goto err_alloc_etherdev;
	}

	SET_NETDEV_DEV(netdev, &pdev->dev);
	netdev->ethtool_ops = &ftmac100_ethtool_ops;
	netdev->netdev_ops = &ftmac100_netdev_ops;

	platform_set_drvdata(pdev, netdev);

	/* setup private data */
	priv = netdev_priv(netdev);
	priv->netdev = netdev;
	priv->dev = &pdev->dev;

	spin_lock_init(&priv->tx_lock);

	/* initialize NAPI */
	netif_napi_add(netdev, &priv->napi, ftmac100_poll, 64);

	/* map io memory */
	priv->res = request_mem_region(res->start, resource_size(res),
				       dev_name(&pdev->dev));
	if (!priv->res) {
		dev_err(&pdev->dev, "Could not reserve memory region\n");
		err = -ENOMEM;
		goto err_req_mem;
	}

	priv->base = ioremap(res->start, resource_size(res));
	if (!priv->base) {
		dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n");
		err = -EIO;
		goto err_ioremap;
	}

	priv->irq = irq;

	/* initialize struct mii_if_info */
	priv->mii.phy_id	= 0;
	priv->mii.phy_id_mask	= 0x1f;
	priv->mii.reg_num_mask	= 0x1f;
	priv->mii.dev		= netdev;
	priv->mii.mdio_read	= ftmac100_mdio_read;
	priv->mii.mdio_write	= ftmac100_mdio_write;

	/* register network device */
	err = register_netdev(netdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to register netdev\n");
		goto err_register_netdev;
	}

	netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base);

	if (!is_valid_ether_addr(netdev->dev_addr)) {
		eth_hw_addr_random(netdev);
		netdev_info(netdev, "generated random MAC address %pM\n",
			    netdev->dev_addr);
	}

	return 0;

err_register_netdev:
	iounmap(priv->base);
err_ioremap:
	release_resource(priv->res);
err_req_mem:
	netif_napi_del(&priv->napi);
	free_netdev(netdev);
err_alloc_etherdev:
	return err;
}
예제 #5
0
void __init
mpc83xx_setup_hose(void)
{
	u32 val32;
	volatile immr_clk_t * clk;
	struct pci_controller * hose1;
#ifdef CONFIG_MPC83xx_PCI2
	struct pci_controller * hose2;
#endif
	bd_t * binfo = (bd_t *)__res;

	clk = ioremap(binfo->bi_immr_base + 0xA00,
			sizeof(immr_clk_t));

	/*
	 * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
	 */
	val32 = clk->occr;
	udelay(2000);
	clk->occr = 0xff000000;
	udelay(2000);

	iounmap(clk);

	hose1 = pcibios_alloc_controller();
	if(!hose1)
		return;

	ppc_md.pci_swizzle = common_swizzle;
	ppc_md.pci_map_irq = mpc83xx_map_irq;

	hose1->bus_offset = 0;
	hose1->first_busno = 0;
	hose1->last_busno = 0xff;

	setup_indirect_pci(hose1, binfo->bi_immr_base + PCI1_CFG_ADDR_OFFSET,
			binfo->bi_immr_base + PCI1_CFG_DATA_OFFSET);
	hose1->set_cfg_type = 1;

	mpc83xx_setup_pci1(hose1);

	hose1->pci_mem_offset = MPC83xx_PCI1_MEM_OFFSET;
	hose1->mem_space.start = MPC83xx_PCI1_LOWER_MEM;
	hose1->mem_space.end = MPC83xx_PCI1_UPPER_MEM;

	hose1->io_base_phys = MPC83xx_PCI1_IO_BASE;
	hose1->io_space.start = MPC83xx_PCI1_LOWER_IO;
	hose1->io_space.end = MPC83xx_PCI1_UPPER_IO;
#ifdef CONFIG_MPC83xx_PCI2
	isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
			MPC83xx_PCI1_IO_SIZE + MPC83xx_PCI2_IO_SIZE);
#else
	isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
			MPC83xx_PCI1_IO_SIZE);
#endif /* CONFIG_MPC83xx_PCI2 */
	hose1->io_base_virt = (void *)isa_io_base;
	/* setup resources */
	pci_init_resource(&hose1->io_resource,
			MPC83xx_PCI1_LOWER_IO,
			MPC83xx_PCI1_UPPER_IO,
			IORESOURCE_IO, "PCI host bridge 1");
	pci_init_resource(&hose1->mem_resources[0],
			MPC83xx_PCI1_LOWER_MEM,
			MPC83xx_PCI1_UPPER_MEM,
			IORESOURCE_MEM, "PCI host bridge 1");

	ppc_md.pci_exclude_device = mpc83xx_exclude_device;
	hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);

#ifdef CONFIG_MPC83xx_PCI2
	hose2 = pcibios_alloc_controller();
	if(!hose2)
		return;

	hose2->bus_offset = hose1->last_busno + 1;
	hose2->first_busno = hose1->last_busno + 1;
	hose2->last_busno = 0xff;
	setup_indirect_pci(hose2, binfo->bi_immr_base + PCI2_CFG_ADDR_OFFSET,
			binfo->bi_immr_base + PCI2_CFG_DATA_OFFSET);
	hose2->set_cfg_type = 1;

	mpc83xx_setup_pci2(hose2);

	hose2->pci_mem_offset = MPC83xx_PCI2_MEM_OFFSET;
	hose2->mem_space.start = MPC83xx_PCI2_LOWER_MEM;
	hose2->mem_space.end = MPC83xx_PCI2_UPPER_MEM;

	hose2->io_base_phys = MPC83xx_PCI2_IO_BASE;
	hose2->io_space.start = MPC83xx_PCI2_LOWER_IO;
	hose2->io_space.end = MPC83xx_PCI2_UPPER_IO;
	hose2->io_base_virt = (void *)(isa_io_base + MPC83xx_PCI1_IO_SIZE);
	/* setup resources */
	pci_init_resource(&hose2->io_resource,
			MPC83xx_PCI2_LOWER_IO,
			MPC83xx_PCI2_UPPER_IO,
			IORESOURCE_IO, "PCI host bridge 2");
	pci_init_resource(&hose2->mem_resources[0],
			MPC83xx_PCI2_LOWER_MEM,
			MPC83xx_PCI2_UPPER_MEM,
			IORESOURCE_MEM, "PCI host bridge 2");

	hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
#endif /* CONFIG_MPC83xx_PCI2 */
}
예제 #6
0
파일: uar.c 프로젝트: 383530895/linux
int mlx5_alloc_uuars(struct mlx5_core_dev *dev, struct mlx5_uuar_info *uuari)
{
	int tot_uuars = NUM_DRIVER_UARS * MLX5_BF_REGS_PER_PAGE;
	struct mlx5_bf *bf;
	phys_addr_t addr;
	int err;
	int i;

	uuari->num_uars = NUM_DRIVER_UARS;
	uuari->num_low_latency_uuars = NUM_LOW_LAT_UUARS;

	mutex_init(&uuari->lock);
	uuari->uars = kcalloc(uuari->num_uars, sizeof(*uuari->uars), GFP_KERNEL);
	if (!uuari->uars)
		return -ENOMEM;

	uuari->bfs = kcalloc(tot_uuars, sizeof(*uuari->bfs), GFP_KERNEL);
	if (!uuari->bfs) {
		err = -ENOMEM;
		goto out_uars;
	}

	uuari->bitmap = kcalloc(BITS_TO_LONGS(tot_uuars), sizeof(*uuari->bitmap),
				GFP_KERNEL);
	if (!uuari->bitmap) {
		err = -ENOMEM;
		goto out_bfs;
	}

	uuari->count = kcalloc(tot_uuars, sizeof(*uuari->count), GFP_KERNEL);
	if (!uuari->count) {
		err = -ENOMEM;
		goto out_bitmap;
	}

	for (i = 0; i < uuari->num_uars; i++) {
		err = mlx5_cmd_alloc_uar(dev, &uuari->uars[i].index);
		if (err)
			goto out_count;

		addr = dev->iseg_base + ((phys_addr_t)(uuari->uars[i].index) << PAGE_SHIFT);
		uuari->uars[i].map = ioremap(addr, PAGE_SIZE);
		if (!uuari->uars[i].map) {
			mlx5_cmd_free_uar(dev, uuari->uars[i].index);
			err = -ENOMEM;
			goto out_count;
		}
		mlx5_core_dbg(dev, "allocated uar index 0x%x, mmaped at %p\n",
			      uuari->uars[i].index, uuari->uars[i].map);
	}

	for (i = 0; i < tot_uuars; i++) {
		bf = &uuari->bfs[i];

		bf->buf_size = dev->caps.gen.bf_reg_size / 2;
		bf->uar = &uuari->uars[i / MLX5_BF_REGS_PER_PAGE];
		bf->regreg = uuari->uars[i / MLX5_BF_REGS_PER_PAGE].map;
		bf->reg = NULL; /* Add WC support */
		bf->offset = (i % MLX5_BF_REGS_PER_PAGE) * dev->caps.gen.bf_reg_size +
			MLX5_BF_OFFSET;
		bf->need_lock = need_uuar_lock(i);
		spin_lock_init(&bf->lock);
		spin_lock_init(&bf->lock32);
		bf->uuarn = i;
	}

	return 0;

out_count:
	for (i--; i >= 0; i--) {
		iounmap(uuari->uars[i].map);
		mlx5_cmd_free_uar(dev, uuari->uars[i].index);
	}
	kfree(uuari->count);

out_bitmap:
	kfree(uuari->bitmap);

out_bfs:
	kfree(uuari->bfs);

out_uars:
	kfree(uuari->uars);
	return err;
}
예제 #7
0
파일: osl.c 프로젝트: sarnobat/knoppix
void
acpi_os_unmap_memory(void *virt, acpi_size size)
{
	iounmap(virt);
}
static int hifi_dump_dsp_thread(void *p)
{
	#define HIFI_TIME_STAMP_1S	  32768
	#define HIFI_DUMPLOG_TIMESPAN (10 * HIFI_TIME_STAMP_1S)

	unsigned int exception_no = 0;
	unsigned int time_now = 0;
	unsigned int time_diff = 0;
	unsigned int* hifi_info_addr = NULL;
	unsigned int hifi_stack_addr = 0;
	int i;

	IN_FUNCTION;

	while (!kthread_should_stop()) {
		if (down_interruptible(&hifi_log_sema) != 0) {
			loge("hifi_dump_dsp_thread wake up err.\n");
		}
		time_now = (unsigned int)readl(g_om_data.dsp_time_stamp);
		time_diff = time_now - g_om_data.pre_dump_timestamp;
		g_om_data.pre_dump_timestamp = time_now;


		hifi_info_addr = (unsigned char*)ioremap_wc(DRV_DSP_STACK_TO_MEM, DRV_DSP_STACK_TO_MEM_SIZE);
		if (NULL == hifi_info_addr) {
			loge("dsp log ioremap_wc hifi_info_addr fail.\n");
			continue;
		}

		exception_no = *(unsigned int*)(hifi_info_addr + 3);
		hifi_stack_addr = *(unsigned int*)(hifi_info_addr + 4);
		logi("errno:%x pre_errno:%x is_first:%d is_force:%d time_diff:%d ms.\n", exception_no, g_om_data.pre_exception_no, g_om_data.first_dump_log, g_om_data.force_dump_log, (time_diff * 1000) / HIFI_TIME_STAMP_1S);

		if (exception_no < 40 && (exception_no != g_om_data.pre_exception_no)) {
			logi("panic addr:0x%x, cur_pc:0x%x, pre_pc:0x%x, cause:0x%x\n", *(unsigned int*)(hifi_info_addr), *(unsigned int*)(hifi_info_addr+1), *(unsigned int*)(hifi_info_addr+2), *(unsigned int*)(hifi_info_addr+3));
			for( i = 0; i < (DRV_DSP_STACK_TO_MEM_SIZE/2)/sizeof(int)/4; i+=4){
				logi("0x%x: 0x%08x 0x%08x 0x%08x 0x%08x\n", (hifi_stack_addr+i*4), *(hifi_info_addr+i),*(hifi_info_addr+1+i),*(hifi_info_addr+2+i),*(hifi_info_addr+i+3));
			}

			hifi_dump_dsp(PANIC_LOG);
			hifi_dump_dsp(PANIC_BIN);

			g_om_data.pre_exception_no = exception_no;
		} else if (g_om_data.first_dump_log || g_om_data.force_dump_log || time_diff > HIFI_DUMPLOG_TIMESPAN){
			hifi_dump_dsp(NORMAL_LOG);
			hifi_dump_dsp(NORMAL_BIN);
			g_om_data.first_dump_log = false;
		}

		iounmap(hifi_info_addr);
		hifi_info_addr = NULL;

		if (hifi_is_power_on()) {
			logi("hifi is power on, now dump ocram and tcm \n");
			hifi_dump_dsp(OCRAM_BIN);
			hifi_dump_dsp(TCM_BIN);
		}
	}
	OUT_FUNCTION;
	return 0;
}
예제 #9
0
static int __devinit tegra_rtc_probe(struct platform_device *pdev)
{
	struct tegra_rtc_info *info;
	struct resource *res;
	int ret;

	info = kzalloc(sizeof(struct tegra_rtc_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev,
			"Unable to allocate resources for device.\n");
		ret = -EBUSY;
		goto err_free_info;
	}

	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
		dev_err(&pdev->dev,
			"Unable to request mem region for device.\n");
		ret = -EBUSY;
		goto err_free_info;
	}

	info->tegra_rtc_irq = platform_get_irq(pdev, 0);
	if (info->tegra_rtc_irq <= 0) {
		ret = -EBUSY;
		goto err_release_mem_region;
	}

	info->rtc_base = ioremap_nocache(res->start, resource_size(res));
	if (!info->rtc_base) {
		dev_err(&pdev->dev, "Unable to grab IOs for device.\n");
		ret = -EBUSY;
		goto err_release_mem_region;
	}

	/* set context info. */
	info->pdev = pdev;
	info->tegra_rtc_lock = __SPIN_LOCK_UNLOCKED(info->tegra_rtc_lock);

	platform_set_drvdata(pdev, info);

	/* clear out the hardware. */
	writel(0, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0);
	writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS);
	writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK);

	device_init_wakeup(&pdev->dev, 1);

	info->rtc_dev = rtc_device_register(
		pdev->name, &pdev->dev, &tegra_rtc_ops, THIS_MODULE);
	if (IS_ERR(info->rtc_dev)) {
		ret = PTR_ERR(info->rtc_dev);
		info->rtc_dev = NULL;
		dev_err(&pdev->dev,
			"Unable to register device (err=%d).\n",
			ret);
		goto err_iounmap;
	}

	ret = request_irq(info->tegra_rtc_irq, tegra_rtc_irq_handler,
		IRQF_TRIGGER_HIGH, "rtc alarm", &pdev->dev);
	if (ret) {
		dev_err(&pdev->dev,
			"Unable to request interrupt for device (err=%d).\n",
			ret);
		goto err_dev_unreg;
	}

	dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n");

	return 0;

err_dev_unreg:
	rtc_device_unregister(info->rtc_dev);
err_iounmap:
	iounmap(info->rtc_base);
err_release_mem_region:
	release_mem_region(res->start, resource_size(res));
err_free_info:
	kfree(info);

	return ret;
}
예제 #10
0
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
{
	iounmap(addr);
}
static void hifi_dump_dsp(DUMP_DSP_INDEX index)
{
	int ret = 0;

	mm_segment_t fs = 0;
	struct file *fp = NULL;
	int file_flag = O_RDWR;
	struct kstat file_stat;
	int write_size = 0;
	unsigned int err_no = 0xFFFFFFFF;

	char tmp_buf[64] = {0};
	unsigned long tmp_len = 0;
	struct rtc_time cur_tm;
	struct timespec now;

	char* file_name		= s_dsp_dump_info[index].file_name;
	char* data_addr		= NULL;
	unsigned int data_len = s_dsp_dump_info[index].data_len;

	char* is_panic		= "i'm panic.\n";
	char* is_exception	= "i'm exception.\n";
	char* not_panic		= "i'm ok.\n";
	if ((index != NORMAL_LOG) && (index != PANIC_LOG) && g_om_data.is_watchdog_coming) {
		logi("watchdog is coming,so don't dump %s\n", file_name);
		return;
	}

	if (rdr_nv_get_value(RDR_NV_HIFI) != 1) {
		loge("do not save hifi log in nv config \n");
		return;
	}

	if (down_interruptible(&g_om_data.dsp_dump_sema) < 0) {
		loge("acquire the semaphore error.\n");
		return;
	}

	IN_FUNCTION;

	hifi_get_log_signal();

	g_om_data.dsp_log_addr = (char*)ioremap_wc(DRV_DSP_UART_TO_MEM, DRV_DSP_UART_TO_MEM_SIZE);
	if (NULL == g_om_data.dsp_log_addr) {
		loge("dsp log ioremap_wc fail.\n");
		goto END;
	}

	s_dsp_dump_info[NORMAL_LOG].data_addr = g_om_data.dsp_log_addr + DRV_DSP_UART_TO_MEM_RESERVE_SIZE;
	s_dsp_dump_info[PANIC_LOG].data_addr  = g_om_data.dsp_log_addr + DRV_DSP_UART_TO_MEM_RESERVE_SIZE;

	if(index == OCRAM_BIN)
	{
		s_dsp_dump_info[index].data_addr = (unsigned char*)ioremap_wc(HIFI_OCRAM_BASE_ADDR, HIFI_IMAGE_OCRAMBAK_SIZE);
	}
	if(index == TCM_BIN)
	{
		s_dsp_dump_info[index].data_addr = (unsigned char*)ioremap_wc(HIFI_TCM_BASE_ADDR, HIFI_IMAGE_TCMBAK_SIZE);
	}

	if (NULL == s_dsp_dump_info[index].data_addr) {
		loge("dsp log ioremap_wc fail.\n");
		goto END;
	}

	data_addr = s_dsp_dump_info[index].data_addr;

	fs = get_fs();
	set_fs(KERNEL_DS);

	ret = hifi_create_dir(HIFI_LOG_PATH_PARENT);
	if (0 != ret) {
		goto END;
	}

	ret = hifi_create_dir(HIFI_LOG_PATH);
	if (0 != ret) {
		goto END;
	}

	ret = vfs_stat(file_name, &file_stat);
	if (ret < 0) {
		logi("there isn't a dsp log file:%s, and need to create.\n", file_name);
		file_flag |= O_CREAT;
	}

	fp = filp_open(file_name, file_flag, 0664);
	if (IS_ERR(fp)) {
		loge("open file fail: %s.\n", file_name);
		fp = NULL;
		goto END;
	}

	/*write from file start*/
	vfs_llseek(fp, 0, SEEK_SET);

	/*write file head*/
	if (DUMP_DSP_LOG == s_dsp_dump_info[index].dump_type) {
		/*write dump log time*/
		now = current_kernel_time();
		rtc_time_to_tm(now.tv_sec, &cur_tm);
		memset(tmp_buf, 0, 64);
		tmp_len = sprintf(tmp_buf, "%04d-%02d-%02d %02d:%02d:%02d.\n",
								cur_tm.tm_year+1900, cur_tm.tm_mon+1,
								cur_tm.tm_mday, cur_tm.tm_hour,
								cur_tm.tm_min, cur_tm.tm_sec);
		vfs_write(fp, tmp_buf, tmp_len, &fp->f_pos);

		/*write exception no*/
		memset(tmp_buf, 0, 64);
		err_no = (unsigned int)(*(g_om_data.dsp_exception_no));
		if (err_no != 0xFFFFFFFF) {
			tmp_len = sprintf(tmp_buf, "the exception no: %u.\n", err_no);
		} else {
			tmp_len = sprintf(tmp_buf, "%s", "hifi is fine, just dump log.\n");
		}
		vfs_write(fp, tmp_buf, tmp_len, &fp->f_pos);

		/*write error type*/
		if (0xdeadbeaf == *g_om_data.dsp_panic_mark) {
			vfs_write(fp, is_panic, strlen(is_panic), &fp->f_pos);
		} else if(0xbeafdead == *g_om_data.dsp_panic_mark){
			vfs_write(fp, is_exception, strlen(is_exception), &fp->f_pos);
		} else {
			vfs_write(fp, not_panic, strlen(not_panic), &fp->f_pos);
		}
	}

	/*write dsp info*/
	if((write_size = vfs_write(fp, data_addr, data_len, &fp->f_pos)) < 0) {
		loge("write file fail.\n");
	}

	logi("write file size: %d.\n", write_size);

END:
	if (fp) {
		filp_close(fp, 0);
	}
	set_fs(fs);

	if (NULL != g_om_data.dsp_log_addr) {
		iounmap(g_om_data.dsp_log_addr);
		g_om_data.dsp_log_addr = NULL;
	}

	if((index == OCRAM_BIN || index == TCM_BIN) && (NULL != s_dsp_dump_info[index].data_addr))
	{
		iounmap(s_dsp_dump_info[index].data_addr);
		s_dsp_dump_info[index].data_addr = NULL;
	}

	hifi_release_log_signal();

	up(&g_om_data.dsp_dump_sema);
	OUT_FUNCTION;

	return;
}
예제 #12
0
int sps_dma_device_init(u32 h)
{
	struct bamdma_device *dev;
	struct sps_bam_props *props;
	u32 chan;
	int result = SPS_ERROR;

	mutex_lock(&bam_dma_lock);

	
	dev = NULL;
	if (bam_dma_dev[0].bam != NULL) {
		SPS_ERR("sps:BAM-DMA BAM device is already initialized.");
		goto exit_err;
	} else {
		dev = &bam_dma_dev[0];
	}

	
	memset(dev, 0, sizeof(*dev));
	dev->h = h;
	dev->bam = sps_h2bam(h);

	if (dev->bam == NULL) {
		SPS_ERR("sps:BAM-DMA BAM device is not found "
				"from the handle.");
		goto exit_err;
	}

	
	props = &dev->bam->props;
	dev->phys_addr = props->periph_phys_addr;
	if (props->periph_virt_addr != NULL) {
		dev->virt_addr = props->periph_virt_addr;
		dev->virtual_mapped = false;
	} else {
		if (props->periph_virt_size == 0) {
			SPS_ERR("sps:Unable to map BAM DMA IO memory: %x %x",
			 dev->phys_addr, props->periph_virt_size);
			goto exit_err;
		}

		dev->virt_addr = ioremap(dev->phys_addr,
					  props->periph_virt_size);
		if (dev->virt_addr == NULL) {
			SPS_ERR("sps:Unable to map BAM DMA IO memory: %x %x",
				dev->phys_addr, props->periph_virt_size);
			goto exit_err;
		}
		dev->virtual_mapped = true;
	}
	dev->hwio = (void *) dev->virt_addr;

	
	if ((props->manage & SPS_BAM_MGR_DEVICE_REMOTE) == 0) {
		SPS_DBG2("sps:BAM-DMA is controlled locally: %x",
			dev->phys_addr);
		dev->local = true;
	} else {
		SPS_DBG2("sps:BAM-DMA is controlled remotely: %x",
			dev->phys_addr);
		dev->local = false;
	}

	if (sps_dma_device_enable(dev))
		goto exit_err;

	dev->num_pipes = dev->bam->props.num_pipes;

	
	if (dev->local)
		for (chan = 0; chan < (dev->num_pipes / 2); chan++) {
			dma_write_reg_field(dev->virt_addr,
					    DMA_CHNL_CONFIG(chan),
					    DMA_CHNL_ENABLE, 0);
		}

	result = 0;
exit_err:
	if (result) {
		if (dev != NULL) {
			if (dev->virtual_mapped)
				iounmap(dev->virt_addr);

			dev->bam = NULL;
		}
	}

	mutex_unlock(&bam_dma_lock);

	return result;
}
예제 #13
0
static int ixp4xx_ehci_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	const struct hc_driver *driver = &ixp4xx_ehci_hc_driver;
	struct resource *res;
	int irq;
	int retval;

	if (usb_disabled())
		return -ENODEV;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev,
			"Found HC with no IRQ. Check %s setup!\n",
			dev_name(&pdev->dev));
		return -ENODEV;
	}
	irq = res->start;

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto fail_create_hcd;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev,
			"Found HC with no register addr. Check %s setup!\n",
			dev_name(&pdev->dev));
		retval = -ENODEV;
		goto fail_request_resource;
	}
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
				driver->description)) {
		dev_dbg(&pdev->dev, "controller already in use\n");
		retval = -EBUSY;
		goto fail_request_resource;
	}

	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
	if (hcd->regs == NULL) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		retval = -EFAULT;
		goto fail_ioremap;
	}

	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (retval)
		goto fail_add_hcd;

	return retval;

fail_add_hcd:
	iounmap(hcd->regs);
fail_ioremap:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
fail_request_resource:
	usb_put_hcd(hcd);
fail_create_hcd:
	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
	return retval;
}
예제 #14
0
int __init init_cyclone_clock(void)
{
	u64* reg;
	u64 base;	/* saved cyclone base address */
	u64 offset;	/* offset from pageaddr to cyclone_timer register */
	int i;

	if (!use_cyclone)
		return -ENODEV;

	printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n");

	/* find base address */
	offset = (CYCLONE_CBAR_ADDR);
	reg = (u64*)ioremap_nocache(offset, sizeof(u64));
	if(!reg){
		printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n");
		use_cyclone = 0;
		return -ENODEV;
	}
	base = readq(reg);
	if(!base){
		printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n");
		use_cyclone = 0;
		return -ENODEV;
	}
	iounmap(reg);

	/* setup PMCC */
	offset = (base + CYCLONE_PMCC_OFFSET);
	reg = (u64*)ioremap_nocache(offset, sizeof(u64));
	if(!reg){
		printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n");
		use_cyclone = 0;
		return -ENODEV;
	}
	writel(0x00000001,reg);
	iounmap(reg);

	/* setup MPCS */
	offset = (base + CYCLONE_MPCS_OFFSET);
	reg = (u64*)ioremap_nocache(offset, sizeof(u64));
	if(!reg){
		printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n");
		use_cyclone = 0;
		return -ENODEV;
	}
	writel(0x00000001,reg);
	iounmap(reg);

	/* map in cyclone_timer */
	offset = (base + CYCLONE_MPMC_OFFSET);
	cyclone_timer = (u32*)ioremap_nocache(offset, sizeof(u32));
	if(!cyclone_timer){
		printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n");
		use_cyclone = 0;
		return -ENODEV;
	}

	/*quick test to make sure its ticking*/
	for(i=0; i<3; i++){
		u32 old = readl(cyclone_timer);
		int stall = 100;
		while(stall--) barrier();
		if(readl(cyclone_timer) == old){
			printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n");
			iounmap(cyclone_timer);
			cyclone_timer = 0;
			use_cyclone = 0;
			return -ENODEV;
		}
	}
	/* initialize last tick */
	last_update_cyclone = readl(cyclone_timer);
	register_time_interpolator(&cyclone_interpolator);

	return 0;
}
/****************************************************************
**
*   Utility function to retrieve full CP RAM dump log for crash log
*
*
*******************************************************************/
void DUMP_CPMemoryByList(struct T_RAMDUMP_BLOCK *mem_dump)
{
	UInt32 i, offset;
	void __iomem *RamDumpBlockVAddr = NULL;
	struct T_RAMDUMP_BLOCK *pBlockVAddr = NULL;

	RamDumpBlockVAddr =
	    ioremap_nocache((UInt32) (mem_dump),
			    (MAX_RAMDUMP_BLOCKS *
			     sizeof(struct T_RAMDUMP_BLOCK)));
	if (NULL == RamDumpBlockVAddr) {
		IPC_DEBUG(DBG_ERROR, "failed to remap RAM dump block addr\n");
		return;
	}

	pBlockVAddr = (struct T_RAMDUMP_BLOCK *)RamDumpBlockVAddr;

	BCMLOG_LogCPCrashDumpString("===== COMMS PROCESSOR memory dump =====");

	i = 0;
	while (i < MAX_RAMDUMP_BLOCKS && pBlockVAddr[i].name[0] != '\0'
	       && pBlockVAddr[i].mem_size != 0) {
		if (pBlockVAddr[i].mem_start == SIM_DEBUG_DATA) {
			offset =
			    (pBlockVAddr[i].name[4] << 24) +
			    (pBlockVAddr[i].name[5] << 16) +
			    (pBlockVAddr[i].name[6] << 8) +
			    pBlockVAddr[i].name[7];
			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "FLASH DUMP: %8s, start=0x%08x, size=0x%08x, image_start=0x%08x, offset_in_image=0x%08x",
				 pBlockVAddr[i].name, pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size, 0, (int)offset);
		} else if (pBlockVAddr[i].mem_start == SIM_AP_DEBUG_DATA) {
			offset =
			    (pBlockVAddr[i].name[4] << 24) +
			    (pBlockVAddr[i].name[5] << 16) +
			    (pBlockVAddr[i].name[6] << 8) +
			    pBlockVAddr[i].name[7];
			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "FLASH DUMP: %8s, start=0x%08x, size=0x%08x, image_start=0x%08x, offset_in_image=0x%08x",
				 pBlockVAddr[i].name, pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size, 0, (int)offset);
		} else {
			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "RAM   DUMP: %8s, start=0x%08x, size=0x%08x, buffer_in_main=0x%08x",
				 pBlockVAddr[i].name,
				 pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size,
				 pBlockVAddr[i].buffer_in_main);
		}
		BCMLOG_LogCPCrashDumpString(assert_buf);
		i++;
	}
	i = 0;
	while (i < MAX_RAMDUMP_BLOCKS && pBlockVAddr[i].name[0] != '\0'
	       && pBlockVAddr[i].mem_size != 0) {
		if (pBlockVAddr[i].mem_start == SIM_DEBUG_DATA) {
			offset =
			    (pBlockVAddr[i].name[4] << 24) +
			    (pBlockVAddr[i].name[5] << 16) +
			    (pBlockVAddr[i].name[6] << 8) +
			    pBlockVAddr[i].name[7];
			BCMLOG_LogCPCrashDumpString(pBlockVAddr[i].name);
			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "FLASH DUMP Begin: 0x%08x, 0x%08x",
				 pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size);
			BCMLOG_LogCPCrashDumpString(assert_buf);
			/* **FIXME** MAG - flash dump not supported yet... */
			/* DUMP_CompressedFlash(cpu, pBlockVAddr[i].mem_start,
			   pBlockVAddr[i].mem_size, MSP_IMAGE_ADDR, offset); */
			BCMLOG_LogCPCrashDumpString
			    ("*** FLASH DUMP NOT SUPPORTED YET ***");
			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "FLASH DUMP End: 0x%08x, 0x%08x",
				 pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size);
			BCMLOG_LogCPCrashDumpString(assert_buf);
		} else if (pBlockVAddr[i].mem_start == SIM_AP_DEBUG_DATA) {
			offset =
			    (pBlockVAddr[i].name[4] << 24) +
			    (pBlockVAddr[i].name[5] << 16) +
			    (pBlockVAddr[i].name[6] << 8) +
			    pBlockVAddr[i].name[7];
			BCMLOG_LogCPCrashDumpString(pBlockVAddr[i].name);
			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "FLASH DUMP Begin: 0x%08x, 0x%08x",
				 pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size);
			BCMLOG_LogCPCrashDumpString(assert_buf);
			/* **FIXME** MAG - flash dump not supported yet... */
			BCMLOG_LogCPCrashDumpString
			    ("*** FLASH DUMP NOT SUPPORTED YET ***");
			/* DUMP_CompressedFlash(cpu, pBlockVAddr[i].mem_start,
			   pBlockVAddr[i].mem_size, AP_IMAGE_ADDR, offset); */
			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "FLASH DUMP End: 0x%08x, 0x%08x",
				 pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size);
			BCMLOG_LogCPCrashDumpString(assert_buf);
		} else if (pBlockVAddr[i].buffer_in_main == 0xFFFFFFFF) {
			BCMLOG_LogCPCrashDumpString(pBlockVAddr[i].name);
			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "RAM DUMP Begin: 0x%08x, 0x%08x",
				 pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size);
			BCMLOG_LogCPCrashDumpString(assert_buf);

			/* BCMLOG_HandleCpCrashMemDumpData takes
			   physical address... */
			BCMLOG_HandleCpCrashMemDumpData((const char *)
							pBlockVAddr[i].
							mem_start,
							pBlockVAddr[i].
							mem_size);

			snprintf(assert_buf, ASSERT_BUF_SIZE,
				 "RAM DUMP End: 0x%08x, 0x%08x",
				 pBlockVAddr[i].mem_start,
				 pBlockVAddr[i].mem_size);
			BCMLOG_LogCPCrashDumpString(assert_buf);
		}
		i++;
	}

	iounmap(RamDumpBlockVAddr);

}
예제 #16
0
/* Main entry */
static int r592_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	int error = -ENOMEM;
	struct memstick_host *host;
	struct r592_device *dev;

	/* Allocate memory */
	host = memstick_alloc_host(sizeof(struct r592_device), &pdev->dev);
	if (!host)
		goto error1;

	dev = memstick_priv(host);
	dev->host = host;
	dev->pci_dev = pdev;
	pci_set_drvdata(pdev, dev);

	/* pci initialization */
	error = pci_enable_device(pdev);
	if (error)
		goto error2;

	pci_set_master(pdev);
	error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
	if (error)
		goto error3;

	error = pci_request_regions(pdev, DRV_NAME);
	if (error)
		goto error3;

	dev->mmio = pci_ioremap_bar(pdev, 0);
	if (!dev->mmio)
		goto error4;

	dev->irq = pdev->irq;
	spin_lock_init(&dev->irq_lock);
	spin_lock_init(&dev->io_thread_lock);
	init_completion(&dev->dma_done);
	INIT_KFIFO(dev->pio_fifo);
	setup_timer(&dev->detect_timer,
		r592_detect_timer, (long unsigned int)dev);

	/* Host initialization */
	host->caps = MEMSTICK_CAP_PAR4;
	host->request = r592_submit_req;
	host->set_param = r592_set_param;
	r592_check_dma(dev);

	dev->io_thread = kthread_run(r592_process_thread, dev, "r592_io");
	if (IS_ERR(dev->io_thread)) {
		error = PTR_ERR(dev->io_thread);
		goto error5;
	}

	/* This is just a precation, so don't fail */
	dev->dummy_dma_page = pci_alloc_consistent(pdev, PAGE_SIZE,
		&dev->dummy_dma_page_physical_address);
	r592_stop_dma(dev , 0);

	if (request_irq(dev->irq, &r592_irq, IRQF_SHARED,
			  DRV_NAME, dev))
		goto error6;

	r592_update_card_detect(dev);
	if (memstick_add_host(host))
		goto error7;

	message("driver successfully loaded");
	return 0;
error7:
	free_irq(dev->irq, dev);
error6:
	if (dev->dummy_dma_page)
		pci_free_consistent(pdev, PAGE_SIZE, dev->dummy_dma_page,
			dev->dummy_dma_page_physical_address);

	kthread_stop(dev->io_thread);
error5:
	iounmap(dev->mmio);
error4:
	pci_release_regions(pdev);
error3:
	pci_disable_device(pdev);
error2:
	memstick_free_host(host);
error1:
	return error;
}
예제 #17
0
static int __init i2c_imx_probe(struct platform_device *pdev)
{
	struct imx_i2c_struct *i2c_imx;
	struct resource *res;
	struct imxi2c_platform_data *pdata;
	void __iomem *base;
	resource_size_t res_size;
	int irq;
	int ret;

	dev_dbg(&pdev->dev, "<%s>\n", __func__);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "can't get device resources\n");
		return -ENOENT;
	}
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "can't get irq number\n");
		return -ENOENT;
	}

	pdata = pdev->dev.platform_data;

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

	res_size = resource_size(res);
	base = ioremap(res->start, res_size);
	if (!base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -EIO;
		goto fail0;
	}

	i2c_imx = kzalloc(sizeof(struct imx_i2c_struct), GFP_KERNEL);
	if (!i2c_imx) {
		dev_err(&pdev->dev, "can't allocate interface\n");
		ret = -ENOMEM;
		goto fail1;
	}

	if (!request_mem_region(res->start, res_size, DRIVER_NAME)) {
		ret = -EBUSY;
		goto fail2;
	}

	/* Setup i2c_imx driver structure */
	strcpy(i2c_imx->adapter.name, pdev->name);
	i2c_imx->adapter.owner		= THIS_MODULE;
	i2c_imx->adapter.algo		= &i2c_imx_algo;
	i2c_imx->adapter.dev.parent	= &pdev->dev;
	i2c_imx->adapter.nr 		= pdev->id;
	i2c_imx->irq			= irq;
	i2c_imx->base			= base;
	i2c_imx->res			= res;

	/* Get I2C clock */
	i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk");
	if (IS_ERR(i2c_imx->clk)) {
		ret = PTR_ERR(i2c_imx->clk);
		dev_err(&pdev->dev, "can't get I2C clock\n");
		goto fail3;
	}
	clk_enable(i2c_imx->clk);

	/* Request IRQ */
	ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx);
	if (ret) {
		dev_err(&pdev->dev, "can't claim irq %d\n", i2c_imx->irq);
		goto fail4;
	}

	/* Init queue */
	init_waitqueue_head(&i2c_imx->queue);

	/* Set up adapter data */
	i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);

	/* Set up clock divider */
	if (pdata && pdata->bitrate)
		i2c_imx_set_clk(i2c_imx, pdata->bitrate);
	else
		i2c_imx_set_clk(i2c_imx, IMX_I2C_BIT_RATE);

	/* Set up chip registers to defaults */
	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
	writeb(0, i2c_imx->base + IMX_I2C_I2SR);

	/* Add I2C adapter */
	ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
	if (ret < 0) {
		dev_err(&pdev->dev, "registration failed\n");
		goto fail5;
	}

	/* Set up platform driver data */
	platform_set_drvdata(pdev, i2c_imx);

	dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", i2c_imx->irq);
	dev_dbg(&i2c_imx->adapter.dev, "device resources from 0x%x to 0x%x\n",
		i2c_imx->res->start, i2c_imx->res->end);
	dev_dbg(&i2c_imx->adapter.dev, "allocated %d bytes at 0x%x \n",
		res_size, i2c_imx->res->start);
	dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
		i2c_imx->adapter.name);
	dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");

	return 0;   /* Return OK */

fail5:
	free_irq(i2c_imx->irq, i2c_imx);
fail4:
	clk_disable(i2c_imx->clk);
	clk_put(i2c_imx->clk);
fail3:
	release_mem_region(i2c_imx->res->start, resource_size(res));
fail2:
	kfree(i2c_imx);
fail1:
	iounmap(base);
fail0:
	if (pdata && pdata->exit)
		pdata->exit(&pdev->dev);
	return ret; /* Return error number */
}
예제 #18
0
파일: c2.c 프로젝트: 12019/kernel_zte_u880
static int __devinit c2_probe(struct pci_dev *pcidev,
			      const struct pci_device_id *ent)
{
	int ret = 0, i;
	unsigned long reg0_start, reg0_flags, reg0_len;
	unsigned long reg2_start, reg2_flags, reg2_len;
	unsigned long reg4_start, reg4_flags, reg4_len;
	unsigned kva_map_size;
	struct net_device *netdev = NULL;
	struct c2_dev *c2dev = NULL;
	void __iomem *mmio_regs = NULL;

	printk(KERN_INFO PFX "AMSO1100 Gigabit Ethernet driver v%s loaded\n",
		DRV_VERSION);

	/* Enable PCI device */
	ret = pci_enable_device(pcidev);
	if (ret) {
		printk(KERN_ERR PFX "%s: Unable to enable PCI device\n",
			pci_name(pcidev));
		goto bail0;
	}

	reg0_start = pci_resource_start(pcidev, BAR_0);
	reg0_len = pci_resource_len(pcidev, BAR_0);
	reg0_flags = pci_resource_flags(pcidev, BAR_0);

	reg2_start = pci_resource_start(pcidev, BAR_2);
	reg2_len = pci_resource_len(pcidev, BAR_2);
	reg2_flags = pci_resource_flags(pcidev, BAR_2);

	reg4_start = pci_resource_start(pcidev, BAR_4);
	reg4_len = pci_resource_len(pcidev, BAR_4);
	reg4_flags = pci_resource_flags(pcidev, BAR_4);

	pr_debug("BAR0 size = 0x%lX bytes\n", reg0_len);
	pr_debug("BAR2 size = 0x%lX bytes\n", reg2_len);
	pr_debug("BAR4 size = 0x%lX bytes\n", reg4_len);

	/* Make sure PCI base addr are MMIO */
	if (!(reg0_flags & IORESOURCE_MEM) ||
	    !(reg2_flags & IORESOURCE_MEM) || !(reg4_flags & IORESOURCE_MEM)) {
		printk(KERN_ERR PFX "PCI regions not an MMIO resource\n");
		ret = -ENODEV;
		goto bail1;
	}

	/* Check for weird/broken PCI region reporting */
	if ((reg0_len < C2_REG0_SIZE) ||
	    (reg2_len < C2_REG2_SIZE) || (reg4_len < C2_REG4_SIZE)) {
		printk(KERN_ERR PFX "Invalid PCI region sizes\n");
		ret = -ENODEV;
		goto bail1;
	}

	/* Reserve PCI I/O and memory resources */
	ret = pci_request_regions(pcidev, DRV_NAME);
	if (ret) {
		printk(KERN_ERR PFX "%s: Unable to request regions\n",
			pci_name(pcidev));
		goto bail1;
	}

	if ((sizeof(dma_addr_t) > 4)) {
		ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
		if (ret < 0) {
			printk(KERN_ERR PFX "64b DMA configuration failed\n");
			goto bail2;
		}
	} else {
		ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
		if (ret < 0) {
			printk(KERN_ERR PFX "32b DMA configuration failed\n");
			goto bail2;
		}
	}

	/* Enables bus-mastering on the device */
	pci_set_master(pcidev);

	/* Remap the adapter PCI registers in BAR4 */
	mmio_regs = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET,
				    sizeof(struct c2_adapter_pci_regs));
	if (!mmio_regs) {
		printk(KERN_ERR PFX
			"Unable to remap adapter PCI registers in BAR4\n");
		ret = -EIO;
		goto bail2;
	}

	/* Validate PCI regs magic */
	for (i = 0; i < sizeof(c2_magic); i++) {
		if (c2_magic[i] != readb(mmio_regs + C2_REGS_MAGIC + i)) {
			printk(KERN_ERR PFX "Downlevel Firmware boot loader "
				"[%d/%Zd: got 0x%x, exp 0x%x]. Use the cc_flash "
			       "utility to update your boot loader\n",
				i + 1, sizeof(c2_magic),
				readb(mmio_regs + C2_REGS_MAGIC + i),
				c2_magic[i]);
			printk(KERN_ERR PFX "Adapter not claimed\n");
			iounmap(mmio_regs);
			ret = -EIO;
			goto bail2;
		}
	}

	/* Validate the adapter version */
	if (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_VERS)) != C2_VERSION) {
		printk(KERN_ERR PFX "Version mismatch "
			"[fw=%u, c2=%u], Adapter not claimed\n",
			be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_VERS)),
			C2_VERSION);
		ret = -EINVAL;
		iounmap(mmio_regs);
		goto bail2;
	}

	/* Validate the adapter IVN */
	if (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_IVN)) != C2_IVN) {
		printk(KERN_ERR PFX "Downlevel FIrmware level. You should be using "
		       "the OpenIB device support kit. "
		       "[fw=0x%x, c2=0x%x], Adapter not claimed\n",
		       be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_IVN)),
		       C2_IVN);
		ret = -EINVAL;
		iounmap(mmio_regs);
		goto bail2;
	}

	/* Allocate hardware structure */
	c2dev = (struct c2_dev *) ib_alloc_device(sizeof(*c2dev));
	if (!c2dev) {
		printk(KERN_ERR PFX "%s: Unable to alloc hardware struct\n",
			pci_name(pcidev));
		ret = -ENOMEM;
		iounmap(mmio_regs);
		goto bail2;
	}

	memset(c2dev, 0, sizeof(*c2dev));
	spin_lock_init(&c2dev->lock);
	c2dev->pcidev = pcidev;
	c2dev->cur_tx = 0;

	/* Get the last RX index */
	c2dev->cur_rx =
	    (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_HRX_CUR)) -
	     0xffffc000) / sizeof(struct c2_rxp_desc);

	/* Request an interrupt line for the driver */
	ret = request_irq(pcidev->irq, c2_interrupt, IRQF_SHARED, DRV_NAME, c2dev);
	if (ret) {
		printk(KERN_ERR PFX "%s: requested IRQ %u is busy\n",
			pci_name(pcidev), pcidev->irq);
		iounmap(mmio_regs);
		goto bail3;
	}

	/* Set driver specific data */
	pci_set_drvdata(pcidev, c2dev);

	/* Initialize network device */
	if ((netdev = c2_devinit(c2dev, mmio_regs)) == NULL) {
		iounmap(mmio_regs);
		goto bail4;
	}

	/* Save off the actual size prior to unmapping mmio_regs */
	kva_map_size = be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_PCI_WINSIZE));

	/* Unmap the adapter PCI registers in BAR4 */
	iounmap(mmio_regs);

	/* Register network device */
	ret = register_netdev(netdev);
	if (ret) {
		printk(KERN_ERR PFX "Unable to register netdev, ret = %d\n",
			ret);
		goto bail5;
	}

	/* Disable network packets */
	netif_stop_queue(netdev);

	/* Remap the adapter HRXDQ PA space to kernel VA space */
	c2dev->mmio_rxp_ring = ioremap_nocache(reg4_start + C2_RXP_HRXDQ_OFFSET,
					       C2_RXP_HRXDQ_SIZE);
	if (!c2dev->mmio_rxp_ring) {
		printk(KERN_ERR PFX "Unable to remap MMIO HRXDQ region\n");
		ret = -EIO;
		goto bail6;
	}

	/* Remap the adapter HTXDQ PA space to kernel VA space */
	c2dev->mmio_txp_ring = ioremap_nocache(reg4_start + C2_TXP_HTXDQ_OFFSET,
					       C2_TXP_HTXDQ_SIZE);
	if (!c2dev->mmio_txp_ring) {
		printk(KERN_ERR PFX "Unable to remap MMIO HTXDQ region\n");
		ret = -EIO;
		goto bail7;
	}

	/* Save off the current RX index in the last 4 bytes of the TXP Ring */
	C2_SET_CUR_RX(c2dev, c2dev->cur_rx);

	/* Remap the PCI registers in adapter BAR0 to kernel VA space */
	c2dev->regs = ioremap_nocache(reg0_start, reg0_len);
	if (!c2dev->regs) {
		printk(KERN_ERR PFX "Unable to remap BAR0\n");
		ret = -EIO;
		goto bail8;
	}

	/* Remap the PCI registers in adapter BAR4 to kernel VA space */
	c2dev->pa = reg4_start + C2_PCI_REGS_OFFSET;
	c2dev->kva = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET,
				     kva_map_size);
	if (!c2dev->kva) {
		printk(KERN_ERR PFX "Unable to remap BAR4\n");
		ret = -EIO;
		goto bail9;
	}

	/* Print out the MAC address */
	c2_print_macaddr(netdev);

	ret = c2_rnic_init(c2dev);
	if (ret) {
		printk(KERN_ERR PFX "c2_rnic_init failed: %d\n", ret);
		goto bail10;
	}

	if (c2_register_device(c2dev))
		goto bail10;

	return 0;

 bail10:
	iounmap(c2dev->kva);

 bail9:
	iounmap(c2dev->regs);

 bail8:
	iounmap(c2dev->mmio_txp_ring);

 bail7:
	iounmap(c2dev->mmio_rxp_ring);

 bail6:
	unregister_netdev(netdev);

 bail5:
	free_netdev(netdev);

 bail4:
	free_irq(pcidev->irq, c2dev);

 bail3:
	ib_dealloc_device(&c2dev->ibdev);

 bail2:
	pci_release_regions(pcidev);

 bail1:
	pci_disable_device(pcidev);

 bail0:
	return ret;
}
예제 #19
0
파일: docprobe.c 프로젝트: nhanh0/hah
static void __init DoC_Probe(unsigned long physadr)
{
	unsigned long docptr;
	struct DiskOnChip *this;
	struct mtd_info *mtd;
	int ChipID;
	char namebuf[15];
	char *name = namebuf;
	char *im_funcname = NULL;
	char *im_modname = NULL;
	void (*initroutine)(struct mtd_info *) = NULL;

	docptr = (unsigned long)ioremap(physadr, DOC_IOREMAP_LEN);
	
	if (!docptr)
		return;
	
	if ((ChipID = doccheck(docptr, physadr))) {
		docfound = 1;
		mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);

		if (!mtd) {
			printk(KERN_WARNING "Cannot allocate memory for data structures. Dropping.\n");
			iounmap((void *)docptr);
			return;
		}
		
		this = (struct DiskOnChip *)(&mtd[1]);
		
		memset((char *)mtd,0, sizeof(struct mtd_info));
		memset((char *)this, 0, sizeof(struct DiskOnChip));

		mtd->priv = this;
		this->virtadr = docptr;
		this->physadr = physadr;
		this->ChipID = ChipID;
		sprintf(namebuf, "with ChipID %2.2X", ChipID);

		switch(ChipID) {
		case DOC_ChipID_Doc2k:
			name="2000";
			im_funcname = "DoC2k_init";
			im_modname = "doc2000";
			break;
			
		case DOC_ChipID_DocMil:
			name="Millennium";
#ifdef DOC_SINGLE_DRIVER
			im_funcname = "DoC2k_init";
			im_modname = "doc2000";
#else
			im_funcname = "DoCMil_init";
			im_modname = "doc2001";
#endif /* DOC_SINGLE_DRIVER */
			break;
		}

		if (im_funcname)
			initroutine = inter_module_get_request(im_funcname, im_modname);

		if (initroutine) {
			(*initroutine)(mtd);
			inter_module_put(im_funcname);
			return;
		}
		printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
	}
	iounmap((void *)docptr);
}
예제 #20
0
/* Function containing the "meat" of the probe mechanism - this is used by
 * the OpenFirmware probe as well as the standard platform device mechanism.
 * This is exported to allow polymorphic drivers to invoke it.
 * @param name - Name of the instance
 * @param pdev - Platform device structure
 * @param addressRange  - Resource describing the hardware's I/O range
 * @param numChannels   - Number of channels of output
 */
int labx_audio_meters_probe(const char *name, 
                           struct platform_device *pdev,
                           struct resource *addressRange,
                           u32 numChannels) {
  struct labx_audio_meters_pdev *audio_meters_pdev;
  uint32_t deviceIndex;
  int32_t ret;

  /* Create and populate a device structure */
  audio_meters_pdev = (struct labx_audio_meters_pdev*) kzalloc(sizeof(struct labx_audio_meters_pdev), GFP_KERNEL);
  if(!audio_meters_pdev) return(-ENOMEM);

  /* Request and map the device's I/O memory region into uncacheable space */
  audio_meters_pdev->physicalAddress = addressRange->start;
  audio_meters_pdev->addressRangeSize = ((addressRange->end - addressRange->start) + 1);

  snprintf(audio_meters_pdev->name, NAME_MAX_SIZE, "%s%d", name, instanceCount++);
  audio_meters_pdev->name[NAME_MAX_SIZE - 1] = '\0';
  if(request_mem_region(audio_meters_pdev->physicalAddress, audio_meters_pdev->addressRangeSize,
                        audio_meters_pdev->name) == NULL) {
    ret = -ENOMEM;
    goto free;
  }

  audio_meters_pdev->virtualAddress = 
    (void*) ioremap_nocache(audio_meters_pdev->physicalAddress, audio_meters_pdev->addressRangeSize);
  if(!audio_meters_pdev->virtualAddress) {
    ret = -ENOMEM;
    goto release;
  }
  printk("AM virtualAddress = 0x%08X, phys = 0x%08X, size = 0x%08X\n", 
         (uint32_t) audio_meters_pdev->virtualAddress,
         (uint32_t) audio_meters_pdev->physicalAddress,
         audio_meters_pdev->addressRangeSize);

  audio_meters_pdev->numChannels = numChannels;
  printk(" Audio Meters interface found at 0x%08X: %d channels\n", 
         (uint32_t) audio_meters_pdev->physicalAddress,
         audio_meters_pdev->numChannels);
  audio_meters_pdev->miscdev.minor = MISC_DYNAMIC_MINOR;
  audio_meters_pdev->miscdev.name = audio_meters_pdev->name;
  audio_meters_pdev->miscdev.fops = &labx_audio_meters_fops;
  ret = misc_register(&audio_meters_pdev->miscdev);
  if (ret) {
    printk(KERN_WARNING DRIVER_NAME ": Unable to register misc device.\n");
    goto unmap;
  }
  platform_set_drvdata(pdev, audio_meters_pdev);
  audio_meters_pdev->pdev = pdev;
  dev_set_drvdata(audio_meters_pdev->miscdev.this_device, audio_meters_pdev);

  /* Locate and occupy the first available device index for future navigation in
   * the call to labx_audio_meters_open()
   */
  for (deviceIndex = 0; deviceIndex < MAX_AM_DEVICES; deviceIndex++) {
    if (NULL == devices[deviceIndex]) {
      devices[deviceIndex] = audio_meters_pdev;
      break;
    }
  }

  /* Ensure that we haven't been asked to probe for too many devices */
  if(deviceIndex >= MAX_AM_DEVICES) {
    printk(KERN_WARNING DRIVER_NAME ": Maximum device count (%d) exceeded during probe\n",
           MAX_AM_DEVICES);
    goto unmap;
  }

  /* Return success */
  return(0);

 unmap:
  iounmap(audio_meters_pdev->virtualAddress);
 release:
  release_mem_region(audio_meters_pdev->physicalAddress, 
                     audio_meters_pdev->addressRangeSize);
 free:
  kfree(audio_meters_pdev);
  return(ret);
}
예제 #21
0
파일: pm_da9053.c 프로젝트: itsai/i.mx53
void pm_da9053_i2c_deinit(void)
{
	iounmap(base);
}
예제 #22
0
static int spear_adc_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device *dev = &pdev->dev;
	struct spear_adc_state *st;
	struct iio_dev *indio_dev = NULL;
	int ret = -ENODEV;
	int irq;

	indio_dev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_state));
	if (!indio_dev) {
		dev_err(dev, "failed allocating iio device\n");
		return -ENOMEM;
	}

	st = iio_priv(indio_dev);
	st->np = np;

	/*
	 * SPEAr600 has a different register layout than other SPEAr SoC's
	 * (e.g. SPEAr3xx). Let's provide two register base addresses
	 * to support multi-arch kernels.
	 */
	st->adc_base_spear6xx = of_iomap(np, 0);
	if (!st->adc_base_spear6xx) {
		dev_err(dev, "failed mapping memory\n");
		return -ENOMEM;
	}
	st->adc_base_spear3xx =
		(struct adc_regs_spear3xx __iomem *)st->adc_base_spear6xx;

	st->clk = clk_get(dev, NULL);
	if (IS_ERR(st->clk)) {
		dev_err(dev, "failed getting clock\n");
		goto errout1;
	}

	ret = clk_prepare_enable(st->clk);
	if (ret) {
		dev_err(dev, "failed enabling clock\n");
		goto errout2;
	}

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

	ret = devm_request_irq(dev, irq, spear_adc_isr, 0, SPEAR_ADC_MOD_NAME,
			       st);
	if (ret < 0) {
		dev_err(dev, "failed requesting interrupt\n");
		goto errout3;
	}

	if (of_property_read_u32(np, "sampling-frequency",
				 &st->sampling_freq)) {
		dev_err(dev, "sampling-frequency missing in DT\n");
		ret = -EINVAL;
		goto errout3;
	}

	/*
	 * Optional avg_samples defaults to 0, resulting in single data
	 * conversion
	 */
	of_property_read_u32(np, "average-samples", &st->avg_samples);

	/*
	 * Optional vref_external defaults to 0, resulting in internal vref
	 * selection
	 */
	of_property_read_u32(np, "vref-external", &st->vref_external);

	spear_adc_configure(st);

	platform_set_drvdata(pdev, indio_dev);

	init_completion(&st->completion);

	indio_dev->name = SPEAR_ADC_MOD_NAME;
	indio_dev->dev.parent = dev;
	indio_dev->info = &spear_adc_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = spear_adc_iio_channels;
	indio_dev->num_channels = ARRAY_SIZE(spear_adc_iio_channels);

	ret = iio_device_register(indio_dev);
	if (ret)
		goto errout3;

	dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);

	return 0;

errout3:
	clk_disable_unprepare(st->clk);
errout2:
	clk_put(st->clk);
errout1:
	iounmap(st->adc_base_spear6xx);
	return ret;
}
예제 #23
0
static void __init st_of_clkgena_divmux_setup(struct device_node *np)
{
	const struct of_device_id *match;
	const struct clkgena_divmux_data *data;
	struct clk_onecell_data *clk_data;
	void __iomem *reg;
	const char **parents;
	int num_parents = 0, i;

	match = of_match_node(clkgena_divmux_of_match, np);
	if (WARN_ON(!match))
		return;

	data = match->data;

	reg = clkgen_get_register_base(np);
	if (!reg)
		return;

	parents = clkgen_mux_get_parents(np, &num_parents);
	if (IS_ERR(parents))
		goto err_parents;

	clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
	if (!clk_data)
		goto err_alloc;

	clk_data->clk_num = data->num_outputs;
	clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
				 GFP_KERNEL);

	if (!clk_data->clks)
		goto err_alloc_clks;

	for (i = 0; i < clk_data->clk_num; i++) {
		struct clk *clk;
		const char *clk_name;

		if (of_property_read_string_index(np, "clock-output-names",
						  i, &clk_name))
			break;

		/*
		 * If we read an empty clock name then the output is unused
		 */
		if (*clk_name == '\0')
			continue;

		clk = clk_register_genamux(clk_name, parents, num_parents,
					   reg, data, i);

		if (IS_ERR(clk))
			goto err;

		clk_data->clks[i] = clk;
	}

	kfree(parents);

	of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
	return;
err:
	kfree(clk_data->clks);
err_alloc_clks:
	kfree(clk_data);
err_alloc:
	kfree(parents);
err_parents:
	iounmap(reg);
}
/**
*   Loads the image with the given name into RAM.
*
*	@param	p_device	(in) The kernel device.
*	@param	p_name		(in) The image name. This image file must be located
*							in /vendor/firmware.
*	@param	addr		(in) The RAM address to load the image into.
*	@param	expectedSize (in) The expected size of the image file, or 0
*                             if the size is to be calculated.
*
******************************************************************************/
static int32_t LoadFirmware(struct device *p_device, const char *p_name,
				int addr, int expectedSize)
{
	const struct firmware *fw;
	int32_t err;
	int imgSize;

	IPC_DEBUG(DBG_INFO, "calling request_firmware for %s, device=%p\n",
			p_name, p_device);

	/** call kernel to start firmware load **/
	/* request_firmware(const struct firmware **fw,
	*                  const char *name,
	*                  struct device *device);
	*/
	err = request_firmware(&fw, p_name, p_device);
	if (err) {
		IPC_DEBUG(DBG_ERROR, "firmware request failed (%d)\n",
			err);
		return err;
	}

	if (fw)
		IPC_DEBUG(DBG_INFO, "fw->size=%d\n", fw->size);
	else {
		/*Coverity Complaint: FORWARD_NULL */
		IPC_DEBUG(DBG_INFO, "fw = NULL!\n");
		return err;
	}

	imgSize = fw->size;
	if (expectedSize == 0) {
		UInt8 *ptr;

		/* This is the main CP image */
		if (IsCommsImageValid(fw->data))
			IPC_DEBUG(DBG_INFO, "verified CP image\n");
		else
			IPC_DEBUG(DBG_ERROR, "failed to verify main image\n");

		ptr = ((UInt8 *) fw->data) + CP_IMAGE_SIZE_OFFSET;

		imgSize = (ptr[3] << 24) |
					(ptr[2] << 16) |
					(ptr[1] << 8) |
					ptr[0];
		IPC_DEBUG(DBG_INFO, "calculated CP image size = 0x%x\n",
			imgSize);
	} else if (expectedSize != imgSize) {
		if (imgSize > expectedSize) {
			IPC_DEBUG(DBG_ERROR,
					"ERROR: fw->size > expected (0x%x > 0x%x)\n",
					fw->size, expectedSize);
			imgSize = expectedSize;
		} else
			IPC_DEBUG(DBG_ERROR,
				"ERROR: fw->size < expected (0x%x < 0x%x)\n",
				fw->size, expectedSize);
	}

	/** download to chip **/
	err = DownloadFirmware(imgSize, fw->data, addr);

	/* Verify CP image @ RAM addr */
	if (expectedSize == 0) {
		void __iomem *virtAddr;

		virtAddr = ioremap_nocache(addr, fw->size);
		if (virtAddr) {
			int retval;
			/* This is the main CP image */
			if (IsCommsImageValid(virtAddr))
				IPC_DEBUG(DBG_INFO,
				"verified CP image @ %p\n",
				(void *)addr);
			else
				IPC_DEBUG(DBG_ERROR,
					"failed to verify main image @ %p\n",
					(void *)addr);
			retval = memcmp(fw->data, virtAddr, imgSize);
			IPC_DEBUG(DBG_INFO, "memcmp(%p, %p, 0x%x) = %d\n",
				(void *)fw->data, virtAddr, imgSize, retval);
			iounmap(virtAddr);
		} else {
			IPC_DEBUG(DBG_ERROR,
				"ioremap_nocache FAILED for addr %p\n",
				(void *)addr);
		}
	}

	/** free kernel structure */
	release_firmware(fw);

	return err;
}
예제 #25
0
static int g2d_probe(struct platform_device *pdev)
{
	struct resource *res;
	int ret;
	struct clk *parent;
	struct clk *sclk;

	FIMG2D_DEBUG("start probe : name=%s num=%d res[0].start=0x%x res[1].start=0x%x\n",
	        			pdev->name, pdev->num_resources,
	        			pdev->resource[0].start, pdev->resource[1].start);

	/* alloc g2d global */
	g2d_dev = kzalloc(sizeof(*g2d_dev), GFP_KERNEL);
	if (!g2d_dev) {
		FIMG2D_ERROR( "not enough memory\n");
		return -ENOENT;
		goto probe_out;
	}

	/* get the memory region */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if(res == NULL) {
		FIMG2D_ERROR("failed to get memory region resouce\n");
		return -ENOENT;
		goto err_get_res;
	}

	/* request momory region */
	g2d_dev->mem = request_mem_region(res->start,
					          res->end - res->start + 1,
					          pdev->name);
	if(g2d_dev->mem == NULL) {
		FIMG2D_ERROR("failed to reserve memory region\n");
		return -ENOENT;
		goto err_mem_req;
	}

	/* ioremap */
	g2d_dev->base = ioremap(g2d_dev->mem->start,
				g2d_dev->mem->end - res->start + 1);
	if(g2d_dev->base == NULL) {
		FIMG2D_ERROR("failed ioremap\n");
		ret = -ENOENT;
		goto err_mem_map;
	}

	/* get irq */
	g2d_dev->irq_num = platform_get_irq(pdev, 0);
	if(g2d_dev->irq_num <= 0) {
		FIMG2D_ERROR("failed to get irq resouce\n");
		ret = -ENOENT;
		goto err_irq_req;
	}

	/* request irq */
	ret = request_irq(g2d_dev->irq_num, g2d_irq,
			IRQF_DISABLED, pdev->name, NULL);
	if (ret) {
		FIMG2D_ERROR("request_irq(g2d) failed.\n");
		ret = -ENOENT;
		goto err_irq_req;
	}

	/* clock domain setting*/
	parent = clk_get(&pdev->dev, "mout_mpll");
	if (IS_ERR(parent)) {
		FIMG2D_ERROR("failed to get parent clock\n");
		ret = -ENOENT;
		goto err_clk_get1;
	}

	sclk = clk_get(&pdev->dev, "sclk_fimg2d");
	if (IS_ERR(sclk)) {
		FIMG2D_ERROR("failed to get sclk_g2d clock\n");
		ret = -ENOENT;
		goto err_clk_get2;
	}

	clk_set_parent(sclk, parent);
	clk_set_rate(sclk, 250 * MHZ);

	/* clock for gating  */
	g2d_dev->clock = clk_get(&pdev->dev, "fimg2d");
	if (IS_ERR(g2d_dev->clock)) {
		FIMG2D_ERROR("failed to get clock clock\n");
		ret = -ENOENT;
		goto err_clk_get3;
	}

	ret = g2d_init_mem(&pdev->dev, &g2d_dev->reserved_mem.base, &g2d_dev->reserved_mem.size);

	if (ret != 0) {
		FIMG2D_ERROR("failed to init. fimg2d mem");
		ret = -ENOMEM;
		goto err_mem;
	}

	/* blocking I/O */
	init_waitqueue_head(&g2d_dev->waitq);

	/* atomic init */
	atomic_set(&g2d_dev->in_use, 0);
	atomic_set(&g2d_dev->num_of_object, 0);
	atomic_set(&g2d_dev->is_mmu_faulted, 0);
	g2d_dev->faulted_addr = 0;

	/* misc register */
	ret = misc_register(&fimg2d_dev);
	if (ret) {
		FIMG2D_ERROR("cannot register miscdev on minor=%d (%d)\n",
			G2D_MINOR, ret);
		goto err_misc_reg;
	}

	mutex_init(&g2d_dev->lock);

	g2d_sysmmu_on(g2d_dev);



#if defined(CONFIG_S5PV310_DEV_PD)
	/* to use the runtime PM helper functions */
	pm_runtime_enable(&pdev->dev);
	/* enable the power domain */
	pm_runtime_get_sync(&pdev->dev);
#endif

#if defined(CONFIG_HAS_EARLYSUSPEND)
	g2d_dev->early_suspend.suspend = g2d_early_suspend;
	g2d_dev->early_suspend.resume = g2d_late_resume;
	g2d_dev->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 3;
	register_early_suspend(&g2d_dev->early_suspend);
#endif

	g2d_dev->dev = &pdev->dev;
	atomic_set(&g2d_dev->ready_to_run, 1);

	FIMG2D_DEBUG("g2d_probe ok!\n");

	return 0;

err_misc_reg:
	clk_put(g2d_dev->clock);
	g2d_dev->clock = NULL;
err_mem:
err_clk_get3:
	clk_put(sclk);
err_clk_get2:
	clk_put(parent);
err_clk_get1:
	free_irq(g2d_dev->irq_num, NULL);
err_irq_req:
	iounmap(g2d_dev->base);
err_mem_map:
	release_resource(g2d_dev->mem);
	kfree(g2d_dev->mem);
err_mem_req:
err_get_res:
	kfree(g2d_dev);
probe_out:
	FIMG2D_ERROR("g2d: sec_g2d_probe fail!\n");
	return ret;
}
/*************************************************
*
*   Worker thread to dump CP crash log information.
*
*
*****************************************************/
void ProcessCPCrashedDump(struct work_struct *work)
{
	char crashReason[40] = { 0 };
	char crashFile[40] = { 0 };
	char crashThread[40] = { 0 };
	char outString[512] = { 0 };
	IPC_U32 *Dump;
	void __iomem *DumpVAddr;

#ifdef CONFIG_FB_BRCM_CP_CRASH_DUMP_IMAGE_SUPPORT
	rhea_display_crash_image(CP_CRASH_DUMP_START);
#endif

#ifdef CONFIG_BCM_AP_PANIC_ON_CPCRASH
	if (BCMLOG_OUTDEV_SDCARD == BCMLOG_GetCpCrashLogDevice()
#ifdef CONFIG_CDEBUGGER
		&& ramdump_enable == 1
#endif
#ifdef CONFIG_APANIC_ON_MMC
		&& ap_triggered == 0
#endif
		) {
		/* we kill AP when CP crashes */
		IPC_DEBUG(DBG_ERROR, "Crashing AP for Ramdump ...\n\n");
		#ifdef CONFIG_SEC_DEBUG
			cp_abort();
		#else
		abort();
		#endif /* CONFIG_SEC_DEBUG */
	}
	if ((BCMLOG_OUTDEV_NONE == BCMLOG_GetCpCrashLogDevice() ||
		BCMLOG_OUTDEV_PANIC == BCMLOG_GetCpCrashLogDevice() ||
		BCMLOG_OUTDEV_STM == BCMLOG_GetCpCrashLogDevice() ||
		BCMLOG_OUTDEV_RNDIS == BCMLOG_GetCpCrashLogDevice())
#ifdef CONFIG_APANIC_ON_MMC
		&& ap_triggered == 0
#endif
	    ) {
		/* we kill AP when CP crashes */
		IPC_DEBUG(DBG_ERROR, "Crashing AP now ...\n\n");
		#ifdef CONFIG_SEC_DEBUG
			cp_abort();
		#else
		abort();
		#endif /* CONFIG_SEC_DEBUG */
	}
#endif
	/* check for CP Reset here? Assuming CP Reset is just signified by
	a different crash code
	*/
	if (SmLocalControl.SmControl->CrashCode ==
			IPC_CP_SILENT_RESET_READY) {
		HandleCPResetStart();
		return;
	}

	IPC_Dump();

	RpcDbgDumpHistoryLogging(0, 0);

#if defined(CONFIG_BRCM_CP_CRASH_DUMP) \
	|| defined(CONFIG_BRCM_CP_CRASH_DUMP_EMMC) \
	|| defined(CONFIG_BCM_AP_PANIC_ON_CPCRASH)
	while (SmLocalControl.SmControl->CrashDump == NULL)
		; /* No op */
#endif

	/* **NOTE** for now, continue doing simple dump out IPC_DEBUG so there
	 * is some indication of CP crash in console
	 * (in case user not running MTT) */
	Dump = (void *)SmLocalControl.SmControl->CrashDump;

	IPC_DEBUG(DBG_ERROR, "ioremap_nocache\n");
	DumpVAddr = ioremap_nocache((UInt32) Dump,
				    sizeof(struct T_CRASH_SUMMARY));
	if (NULL == DumpVAddr) {
		IPC_DEBUG(DBG_ERROR, "VirtualAlloc failed\n");
		goto cleanUp;
	}

	IPC_DEBUG(DBG_ERROR, "Crash Summary Virtual Addr: 0x%08X\n",
		  (unsigned int)DumpVAddr);

	dumped_crash_summary_ptr = (struct T_CRASH_SUMMARY *)DumpVAddr;

	IPC_DEBUG(DBG_ERROR, "===== COMMS_PROCESSOR crash summary =====\r\n");

	if (dumped_crash_summary_ptr->link_signature) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->
				link_signature, outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->project_version) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->
				project_version, outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->DSP_version) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->DSP_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->FW_version) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->FW_version,
				outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	if (dumped_crash_summary_ptr->decoder_version) {
		GetStringFromPA((UInt32) dumped_crash_summary_ptr->
				decoder_version, outString, 128);
		IPC_DEBUG(DBG_ERROR, "%s\r\n", outString);
	}

	GetStringFromPA((UInt32) dumped_crash_summary_ptr->reason, crashReason,
			40);

	GetStringFromPA((UInt32) dumped_crash_summary_ptr->file, crashFile, 40);

	GetStringFromPA((UInt32) dumped_crash_summary_ptr->thread, crashThread,
			40);

	IPC_DEBUG(DBG_ERROR, "%s f=%s l=%d v=%d/0x%x t=%s TS=%d\r\n",
		  crashReason,
		  crashFile,
		  dumped_crash_summary_ptr->line,
		  dumped_crash_summary_ptr->value,
		  dumped_crash_summary_ptr->value,
		  crashThread, dumped_crash_summary_ptr->time);

#ifndef CONFIG_BCM_AP_PANIC_ON_CPCRASH
	/* done with "simple" dump, so now pull the full assert
	 * log from CP and dump out to MTT */
	DUMP_CP_assert_log();
#endif

cleanUp:

	if (NULL != DumpVAddr)
		iounmap(DumpVAddr);

#ifdef CONFIG_HAS_WAKELOCK
	wake_unlock(&ipc_wake_lock);
#endif

#ifdef CONFIG_BCM_AP_PANIC_ON_CPCRASH

#ifdef CONFIG_SEC_DEBUG
	cp_abort();
#endif /* CONFIG_SEC_DEBUG */

#endif /* CONFIG_AP_PANIC_ON_CPCRASH */

}
예제 #27
0
static int pxa930_trkball_probe(struct platform_device *pdev)
{
	struct pxa930_trkball *trkball;
	struct input_dev *input;
	struct resource *res;
	int irq, error;

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

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

	trkball = kzalloc(sizeof(struct pxa930_trkball), GFP_KERNEL);
	if (!trkball)
		return -ENOMEM;

	trkball->pdata = pdev->dev.platform_data;
	if (!trkball->pdata) {
		dev_err(&pdev->dev, "no platform data defined\n");
		error = -EINVAL;
		goto failed;
	}

	trkball->mmio_base = ioremap_nocache(res->start, resource_size(res));
	if (!trkball->mmio_base) {
		dev_err(&pdev->dev, "failed to ioremap registers\n");
		error = -ENXIO;
		goto failed;
	}

	/* held the module in reset, will be enabled in open() */
	pxa930_trkball_disable(trkball);

	error = request_irq(irq, pxa930_trkball_interrupt, 0,
			    pdev->name, trkball);
	if (error) {
		dev_err(&pdev->dev, "failed to request irq: %d\n", error);
		goto failed_free_io;
	}

	platform_set_drvdata(pdev, trkball);

	input = input_allocate_device();
	if (!input) {
		dev_err(&pdev->dev, "failed to allocate input device\n");
		error = -ENOMEM;
		goto failed_free_irq;
	}

	input->name = pdev->name;
	input->id.bustype = BUS_HOST;
	input->open = pxa930_trkball_open;
	input->close = pxa930_trkball_close;
	input->dev.parent = &pdev->dev;
	input_set_drvdata(input, trkball);

	trkball->input = input;

	input_set_capability(input, EV_REL, REL_X);
	input_set_capability(input, EV_REL, REL_Y);

	error = input_register_device(input);
	if (error) {
		dev_err(&pdev->dev, "unable to register input device\n");
		goto failed_free_input;
	}

	return 0;

failed_free_input:
	input_free_device(input);
failed_free_irq:
	free_irq(irq, trkball);
failed_free_io:
	iounmap(trkball->mmio_base);
failed:
	kfree(trkball);
	return error;
}
/******************************************************************
*   Utility function to retrieve full crash log from CP via simple
*   handshake protocol.
*
*
********************************************************************/
void DUMP_CP_assert_log(void)
{
	UInt32 t0, t1, i, size, retryCount;
	UInt8 *p;
	UInt32 packetCount = 0;
	void __iomem *AssertLogVAddr = NULL;
	struct file *sdDumpFile = NULL;

	/* put logging driver into crash dump mode; messages will be sent
	 * straight out to MTT via RNDIS (or dump file) instead of buffering
	 * in RING buffer (flood of crash dump info overloads ring buffer
	 * otherwise,and we lose a lot of crash dump info)
	 * NOTE: crash dump is put into SD by default; if SD file fails to open,
	 * then we'll try sending it out RNDIS */

	BCMLOG_StartCpCrashDump(sdDumpFile);

	retryCount = 0;
	t0 = TIMER_GetValue();
	while (1) {
		t1 = TIMER_GetValue();

		/* signal to CP that we're ready to receive crash log... */
		SmLocalControl.SmControl->CrashCode = IPC_AP_CLEAR_TO_SEND;

		/* wait for CP to "dump"; CrashCode field will be
		 * set to physical address of current assert buf */
		while (SmLocalControl.SmControl->CrashCode ==
		       IPC_AP_CLEAR_TO_SEND) {
			for (i = 0; i < 256; i++)
				;
			if (TIMER_GetValue() - t1 > TICKS_ONE_SECOND * 20)
				break;
		}

		/* check for time out */
		if (SmLocalControl.SmControl->CrashCode ==
			IPC_AP_CLEAR_TO_SEND) {
			if (retryCount < MAX_CP_DUMP_RETRIES) {
				retryCount++;
				IPC_DEBUG(DBG_TRACE,
					  "timeout %d, trying again...\n",
					  (int)retryCount);
				continue;
			} else {
				/* no response from CP, so get out of here */
				IPC_DEBUG(DBG_ERROR,
					  "Abort --- max retries %d reached\n",
					  (int)retryCount);
				break;
			}
		}
		/* reset retry counter */
		retryCount = 0;

		/* get virtual address of CP assert buffer */
		AssertLogVAddr = ioremap_nocache((UInt32)
						 (SmLocalControl.SmControl->
						  CrashCode), ASSERT_BUF_SIZE);
		if (NULL == AssertLogVAddr) {
			IPC_DEBUG(DBG_ERROR,
				  "ioremap_nocache failed in DUMP_CP_assert_log\n");
			break;
		}

		p = (UInt8 *) AssertLogVAddr;

		/* number of bytes in assert buffer */
		size = (p[0] << 8) + p[1];

		/* size of 0 means CP is done dumping assert log */
		if (size == 0) {
			IPC_DEBUG(DBG_ERROR,
				  "assert log size 0, exiting, packetCount:0x%x\n",
				  (int)packetCount);
			iounmap(AssertLogVAddr);
			AssertLogVAddr = NULL;
			break;
		}
		/* sanity check for too beaucoup... */
		if (size > ASSERT_BUF_SIZE - 2) {
			IPC_DEBUG(DBG_ERROR,
				  "Abort --- improper size [%08x]=%d\n",
				  SmLocalControl.SmControl->CrashCode,
				  (int)size);
			iounmap(AssertLogVAddr);
			AssertLogVAddr = NULL;
			break;
		}
		/* send packet out to log (MTT via RNDIS or crash dump file) */
		BCMLOG_HandleCpCrashDumpData((const char *)(p + 2), size);

		packetCount++;
		iounmap(AssertLogVAddr);
		AssertLogVAddr = NULL;

#if 0
		/* **FIXME** this is Nucleus timeout code - do we want
		 * something similar for Android? Maybe if we get to the
		 * point of restarting CP with restarting AP
		 */
		if (TIMER_GetValue() - t0 > TICKS_ONE_SECOND * 10 * 60) {
			IPC_DEBUG(DBG_ERROR,
				  "Abort --- CP assertion log too long\n");
			break;
		}
#endif
	}

	RpcDbgDumpHistoryLogging(2, 1);

	IPC_DEBUG(DBG_ERROR, "Starting CP RAM dump - do not power down...\n");

	/* dump all CP memory to log */
	DUMP_CPMemoryByList(dumped_crash_summary_ptr->mem_dump);

	IPC_DEBUG(DBG_ERROR, "CP RAM dump complete\n");
	/* resume normal logging activities... */
	BCMLOG_EndCpCrashDump();

#ifdef CONFIG_FB_BRCM_CP_CRASH_DUMP_IMAGE_SUPPORT
	rhea_display_crash_image(CP_CRASH_DUMP_END);
#endif

	if (BCMLOG_OUTDEV_SDCARD == BCMLOG_GetCpCrashLogDevice())
		sys_sync();

	IPC_DEBUG(DBG_ERROR, "CP crash dump complete\n");

#ifdef CONFIG_BCM_AP_PANIC_ON_CPCRASH
		if ((BCMLOG_OUTDEV_SDCARD == BCMLOG_GetCpCrashLogDevice())
			&& cp_crashed == 1)
		#ifdef CONFIG_SEC_DEBUG
			cp_abort();
		#else
			abort();
		#endif /* CONFIG_SEC_DEBUG */
#endif

}
예제 #29
0
/*!
 * This function is called by the driver framework to initialize the LDB
 * device.
 *
 * @param	dev	The device structure for the LDB passed in by the
 *			driver framework.
 *
 * @return      Returns 0 on success or negative error code on error
 */
static int ldb_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct resource *res;
	struct ldb_platform_data *plat_data = pdev->dev.platform_data;
	uint32_t reg;
	struct device *temp;
	int mxc_ldb_major;
	struct class *mxc_ldb_class;

	if ((plat_data->boot_enable & (MXC_LDBDI0 | MXC_LDBDI1))
		&& !g_enable_ldb) {
		g_enable_ldb = MXC_ENABLE;
		if (plat_data->boot_enable & MXC_LDBDI0)
			g_di0_used = true;
		if (plat_data->boot_enable & MXC_LDBDI1)
			g_di1_used = true;
	}

	if (!g_enable_ldb)
		g_enable_ldb = MXC_DISABLE;

	if (g_enable_ldb == MXC_DISABLE) {
		printk(KERN_WARNING "By setting, LDB driver will not be enabled\n");
		return -ENODEV;
	}

	spin_lock_init(&ldb_lock);

	g_ldb_dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (IS_ERR(res))
		return -ENODEV;

	memset(&ldb, 0, sizeof(struct ldb_data));
	ldb.chan_mode_opt = g_chan_mode_opt;
	ldb.chan_bit_map[0] = g_chan_bit_map[0];
	ldb.chan_bit_map[1] = g_chan_bit_map[1];

	ldb.base_addr = res->start;
	ldb_reg = ioremap(ldb.base_addr, res->end - res->start + 1);
	ldb.control_reg = ldb_reg + 2;

	ldb.bgref_rmode = plat_data->ext_ref;
	ldb.lvds_bg_reg = regulator_get(&pdev->dev, plat_data->lvds_bg_reg);
	if (!IS_ERR(ldb.lvds_bg_reg)) {
		regulator_set_voltage(ldb.lvds_bg_reg, 2500000, 2500000);
		regulator_enable(ldb.lvds_bg_reg);
	}

	reg = __raw_readl(ldb.control_reg);
	if (ldb.bgref_rmode == LDB_EXT_REF)
		__raw_writel((reg & ~LDB_BGREF_RMODE_MASK) |
			      LDB_BGREF_RMODE_EXT, ldb.control_reg);
	else
		__raw_writel((reg & ~LDB_BGREF_RMODE_MASK) |
			      LDB_BGREF_RMODE_INT, ldb.control_reg);

	mxc_ldb_major = register_chrdev(0, "mxc_ldb", &mxc_ldb_fops);
	if (mxc_ldb_major < 0) {
		dev_err(g_ldb_dev, "Unable to register MXC LDB as a char "
				   "device\n");
		ret = mxc_ldb_major;
		goto err0;
	}

	mxc_ldb_class = class_create(THIS_MODULE, "mxc_ldb");
	if (IS_ERR(mxc_ldb_class)) {
		dev_err(g_ldb_dev, "Unable to create class for MXC LDB\n");
		ret = PTR_ERR(mxc_ldb_class);
		goto err1;
	}

	temp = device_create(mxc_ldb_class, NULL, MKDEV(mxc_ldb_major, 0),
			NULL, "mxc_ldb");
	if (IS_ERR(temp)) {
		dev_err(g_ldb_dev, "Unable to create class device for "
				   "MXC LDB\n");
		ret = PTR_ERR(temp);
		goto err2;
	}

	if (g_di0_used) {
		mxcfb_register_mode(0, mxcfb_ldb_modedb,
				mxcfb_ldb_modedb_sz,
				MXC_DISP_SPEC_DEV);
		mxcfb_register_presetup(0, ldb_fb_pre_setup);
	}
	if (g_di1_used) {
		mxcfb_register_mode(1, mxcfb_ldb_modedb,
				mxcfb_ldb_modedb_sz,
				MXC_DISP_SPEC_DEV);
		mxcfb_register_presetup(1, ldb_fb_pre_setup);
	}

	ret = fb_register_client(&nb);
	if (ret < 0)
		goto err2;

	ldb.blank[0] = ldb.blank[1] = -1;

	return ret;
err2:
	class_destroy(mxc_ldb_class);
err1:
	unregister_chrdev(mxc_ldb_major, "mxc_ldb");
err0:
	iounmap(ldb_reg);
	return ret;
}
예제 #30
0
/******************************************************************************
 * struct platform_driver functions
 *****************************************************************************/
static int ftiic010_probe(struct platform_device *pdev)
{
	struct ftiic010 *ftiic010;
	struct resource *res;
	struct clk *clk;
	int irq;
	int ret;

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

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

	ftiic010 = kzalloc(sizeof(*ftiic010), GFP_KERNEL);
	if (!ftiic010) {
		dev_err(&pdev->dev, "Could not allocate private data\n");
		ret = -ENOMEM;
		goto err_alloc;
	}

	ftiic010->res = request_mem_region(res->start,
			res->end - res->start, dev_name(&pdev->dev));
	if (ftiic010->res == NULL) {
		dev_err(&pdev->dev, "Could not reserve memory region\n");
		ret = -ENOMEM;
		goto err_req_mem;
	}

	ftiic010->base = ioremap(res->start, res->end - res->start);
	if (ftiic010->base == NULL) {
		dev_err(&pdev->dev, "Failed to ioremap\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	ret = request_irq(irq, ftiic010_interrupt, IRQF_SHARED, pdev->name, ftiic010);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request irq %d\n", irq);
		goto err_req_irq;
	}

	ftiic010->irq = irq;

	clk = clk_get(NULL, "pclk");
	if (!clk) {
		dev_err(&pdev->dev, "Failed to get pclk\n");
		goto err_clk;
	}

	clk_enable(clk);
	ftiic010->clk = clk;

	/*
	 * initialize i2c adapter
	 */
	ftiic010->adapter.owner 	= THIS_MODULE;
	ftiic010->adapter.algo		= &ftiic010_algorithm;
	ftiic010->adapter.timeout	= 1;
	ftiic010->adapter.dev.parent	= &pdev->dev;

	/*
	 * If "dev->id" is negative we consider it as zero.
	 * The reason to do so is to avoid sysfs names that only make
	 * sense when there are multiple adapters.
	 */
	ftiic010->adapter.nr		= pdev->id != -1 ? pdev->id : 0;
	strcpy(ftiic010->adapter.name, "ftiic010 adapter");

	i2c_set_adapdata(&ftiic010->adapter, ftiic010);

	ftiic010_hw_init(ftiic010);

	ret = i2c_add_numbered_adapter(&ftiic010->adapter);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add i2c adapter\n");
		goto err_add_adapter;
	}

	platform_set_drvdata(pdev, ftiic010);

	dev_info(&pdev->dev, "irq %d, mapped at %p\n", irq, ftiic010->base);

	return 0;

err_add_adapter:
	clk_disable(clk);
	clk_put(clk);
err_clk:
	free_irq(ftiic010->irq, ftiic010);
err_req_irq:
	iounmap(ftiic010->base);
err_ioremap:
	release_resource(ftiic010->res);
err_req_mem:
	kfree(ftiic010);
err_alloc:
	return ret;
};