Exemplo n.º 1
0
static int xhci_plat_probe(struct platform_device *pdev)
{
	const struct hc_driver	*driver;
	struct xhci_hcd		*xhci;
	struct resource         *res;
	struct usb_hcd		*hcd;
	int			ret;
	int			irq;

	if (usb_disabled())
		return -ENODEV;

	driver = &xhci_plat_xhci_driver;

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

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

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd)
		return -ENOMEM;

	hcd_to_bus(hcd)->skip_resume = true;
	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");
		ret = -EBUSY;
		goto put_hcd;
	}

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

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto unmap_registers;

	/* USB 2.0 roothub is stored in the platform_device now. */
	hcd = dev_get_drvdata(&pdev->dev);
	xhci = hcd_to_xhci(hcd);
	xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
			dev_name(&pdev->dev), hcd);
	if (!xhci->shared_hcd) {
		ret = -ENOMEM;
		goto dealloc_usb2_hcd;
	}

	hcd_to_bus(xhci->shared_hcd)->skip_resume = true;
	/*
	 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
	 * is called by usb_add_hcd().
	 */
	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;

	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
	if (ret)
		goto put_usb3_hcd;

	phy = usb_get_transceiver();
	/* Register with OTG if present, ignore USB2 OTG using other PHY */
	if (phy && phy->otg && !(phy->flags & ENABLE_SECONDARY_PHY)) {
		dev_dbg(&pdev->dev, "%s otg support available\n", __func__);
		ret = otg_set_host(phy->otg, &hcd->self);
		if (ret) {
			dev_err(&pdev->dev, "%s otg_set_host failed\n",
				__func__);
			usb_put_transceiver(phy);
			goto put_usb3_hcd;
		}
	} else {
		pm_runtime_no_callbacks(&pdev->dev);
	}

	pm_runtime_put(&pdev->dev);

	return 0;

put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);

dealloc_usb2_hcd:
	usb_remove_hcd(hcd);

unmap_registers:
	iounmap(hcd->regs);

release_mem_region:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);

put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
Exemplo n.º 2
0
static int __devinit dwc3_probe(struct platform_device *pdev)
{
	const struct platform_device_id *id = platform_get_device_id(pdev);
	struct resource		*res;
	struct dwc3		*dwc;
	void __iomem		*regs;
	unsigned int		features = id->driver_data;
	int			ret = -ENOMEM;
	int			irq;
	void			*mem;

	mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
	if (!mem) {
		dev_err(&pdev->dev, "not enough memory\n");
		goto err0;
	}
	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
	dwc->mem = mem;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "missing resource\n");
		goto err1;
	}

	res = request_mem_region(res->start, resource_size(res),
			dev_name(&pdev->dev));
	if (!res) {
		dev_err(&pdev->dev, "can't request mem region\n");
		goto err1;
	}

	regs = ioremap(res->start, resource_size(res));
	if (!regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		goto err2;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "missing IRQ\n");
		goto err3;
	}

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

	dwc->regs	= regs;
	dwc->regs_size	= resource_size(res);
	dwc->dev	= &pdev->dev;
	dwc->irq	= irq;

	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);
	pm_runtime_forbid(&pdev->dev);

	ret = dwc3_core_init(dwc);
	if (ret) {
		dev_err(&pdev->dev, "failed to initialize core\n");
		goto err3;
	}

	if (features & DWC3_HAS_PERIPHERAL) {
		ret = dwc3_gadget_init(dwc);
		if (ret) {
			dev_err(&pdev->dev, "failed to initialized gadget\n");
			goto err4;
		}
	}

	ret = dwc3_debugfs_init(dwc);
	if (ret) {
		dev_err(&pdev->dev, "failed to initialize debugfs\n");
		goto err5;
	}

	pm_runtime_allow(&pdev->dev);

	return 0;

err5:
	if (features & DWC3_HAS_PERIPHERAL)
		dwc3_gadget_exit(dwc);

err4:
	dwc3_core_exit(dwc);

err3:
	iounmap(regs);

err2:
	release_mem_region(res->start, resource_size(res));

err1:
	kfree(dwc->mem);

err0:
	return ret;
}
Exemplo n.º 3
0
static __devinit int msm_afe_probe(struct platform_device *pdev)
{
    pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
    return snd_soc_register_platform(&pdev->dev,
                                     &msm_soc_platform);
}
Exemplo n.º 4
0
static int INITSECTION
cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
{
	struct cmos_rtc_board_info	*info = dev->platform_data;
	int				retval = 0;
	unsigned char			rtc_control;
	unsigned			address_space;

	/* there can be only one ... */
	if (cmos_rtc.dev)
		return -EBUSY;

	if (!ports)
		return -ENODEV;

	/* Claim I/O ports ASAP, minimizing conflict with legacy driver.
	 *
	 * REVISIT non-x86 systems may instead use memory space resources
	 * (needing ioremap etc), not i/o space resources like this ...
	 */
	ports = request_region(ports->start,
			ports->end + 1 - ports->start,
			driver_name);
	if (!ports) {
		dev_dbg(dev, "i/o registers already in use\n");
		return -EBUSY;
	}

	cmos_rtc.irq = rtc_irq;
	cmos_rtc.iomem = ports;

	/* Heuristic to deduce NVRAM size ... do what the legacy NVRAM
	 * driver did, but don't reject unknown configs.   Old hardware
	 * won't address 128 bytes.  Newer chips have multiple banks,
	 * though they may not be listed in one I/O resource.
	 */
#if	defined(CONFIG_ATARI)
	address_space = 64;
#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__sparc__)
	address_space = 128;
#else
#warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
	address_space = 128;
#endif
	if (can_bank2 && ports->end > (ports->start + 1))
		address_space = 256;

	/* For ACPI systems extension info comes from the FADT.  On others,
	 * board specific setup provides it as appropriate.  Systems where
	 * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and
	 * some almost-clones) can provide hooks to make that behave.
	 *
	 * Note that ACPI doesn't preclude putting these registers into
	 * "extended" areas of the chip, including some that we won't yet
	 * expect CMOS_READ and friends to handle.
	 */
	if (info) {
		if (info->rtc_day_alarm && info->rtc_day_alarm < 128)
			cmos_rtc.day_alrm = info->rtc_day_alarm;
		if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128)
			cmos_rtc.mon_alrm = info->rtc_mon_alarm;
		if (info->rtc_century && info->rtc_century < 128)
			cmos_rtc.century = info->rtc_century;

		if (info->wake_on && info->wake_off) {
			cmos_rtc.wake_on = info->wake_on;
			cmos_rtc.wake_off = info->wake_off;
		}
	}

	cmos_rtc.rtc = rtc_device_register(driver_name, dev,
				&cmos_rtc_ops, THIS_MODULE);
	if (IS_ERR(cmos_rtc.rtc)) {
		retval = PTR_ERR(cmos_rtc.rtc);
		goto cleanup0;
	}

	cmos_rtc.dev = dev;
	dev_set_drvdata(dev, &cmos_rtc);
	rename_region(ports, dev_name(&cmos_rtc.rtc->dev));

	spin_lock_irq(&rtc_lock);

	/* force periodic irq to CMOS reset default of 1024Hz;
	 *
	 * REVISIT it's been reported that at least one x86_64 ALI mobo
	 * doesn't use 32KHz here ... for portability we might need to
	 * do something about other clock frequencies.
	 */
	cmos_rtc.rtc->irq_freq = 1024;
	hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
	CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT);

	/* disable irqs */
	cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE);

	rtc_control = CMOS_READ(RTC_CONTROL);

	spin_unlock_irq(&rtc_lock);

	/* FIXME teach the alarm code how to handle binary mode;
	 * <asm-generic/rtc.h> doesn't know 12-hour mode either.
	 */
	if (is_valid_irq(rtc_irq) &&
	    (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) {
		dev_dbg(dev, "only 24-hr BCD mode supported\n");
		retval = -ENXIO;
		goto cleanup1;
	}

	if (is_valid_irq(rtc_irq)) {
		irq_handler_t rtc_cmos_int_handler;

		if (is_hpet_enabled()) {
			int err;

			rtc_cmos_int_handler = hpet_rtc_interrupt;
			err = hpet_register_irq_handler(cmos_interrupt);
			if (err != 0) {
				printk(KERN_WARNING "hpet_register_irq_handler "
						" failed in rtc_init().");
				goto cleanup1;
			}
		} else
			rtc_cmos_int_handler = cmos_interrupt;

		retval = request_irq(rtc_irq, rtc_cmos_int_handler,
				IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev),
				cmos_rtc.rtc);
		if (retval < 0) {
			dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
			goto cleanup1;
		}
	}
	hpet_rtc_timer_init();

	/* export at least the first block of NVRAM */
	nvram.size = address_space - NVRAM_OFFSET;
	retval = sysfs_create_bin_file(&dev->kobj, &nvram);
	if (retval < 0) {
		dev_dbg(dev, "can't create nvram file? %d\n", retval);
		goto cleanup2;
	}

	pr_info("%s: %s%s, %zd bytes nvram%s\n",
		dev_name(&cmos_rtc.rtc->dev),
		!is_valid_irq(rtc_irq) ? "no alarms" :
			cmos_rtc.mon_alrm ? "alarms up to one year" :
			cmos_rtc.day_alrm ? "alarms up to one month" :
			"alarms up to one day",
		cmos_rtc.century ? ", y3k" : "",
		nvram.size,
		is_hpet_enabled() ? ", hpet irqs" : "");

	return 0;

cleanup2:
	if (is_valid_irq(rtc_irq))
		free_irq(rtc_irq, cmos_rtc.rtc);
cleanup1:
	cmos_rtc.dev = NULL;
	rtc_device_unregister(cmos_rtc.rtc);
cleanup0:
	release_region(ports->start, ports->end + 1 - ports->start);
	return retval;
}
Exemplo n.º 5
0
/*
 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
 * 730 has only 2 McBSP, and both of them are MPU peripherals.
 */
int __devinit omap_mcbsp_init(struct platform_device *pdev)
{
	struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
	struct resource *res;
	int ret = 0;

	spin_lock_init(&mcbsp->lock);
	mcbsp->free = true;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
	if (!res) {
		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		if (!res) {
			dev_err(mcbsp->dev, "invalid memory resource\n");
			return -ENOMEM;
		}
	}
	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
				     dev_name(&pdev->dev))) {
		dev_err(mcbsp->dev, "memory region already claimed\n");
		return -ENODEV;
	}

	mcbsp->phys_base = res->start;
	mcbsp->reg_cache_size = resource_size(res);
	mcbsp->io_base = devm_ioremap(&pdev->dev, res->start,
				      resource_size(res));
	if (!mcbsp->io_base)
		return -ENOMEM;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
	if (!res)
		mcbsp->phys_dma_base = mcbsp->phys_base;
	else
		mcbsp->phys_dma_base = res->start;

	/*
	 * OMAP1, 2 uses two interrupt lines: TX, RX
	 * OMAP2430, OMAP3 SoC have combined IRQ line as well.
	 * OMAP4 and newer SoC only have the combined IRQ line.
	 * Use the combined IRQ if available since it gives better debugging
	 * possibilities.
	 */
	mcbsp->irq = platform_get_irq_byname(pdev, "common");
	if (mcbsp->irq == -ENXIO) {
		mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");

		if (mcbsp->tx_irq == -ENXIO) {
			mcbsp->irq = platform_get_irq(pdev, 0);
			mcbsp->tx_irq = 0;
		} else {
			mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
			mcbsp->irq = 0;
		}
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
	if (!res) {
		dev_err(&pdev->dev, "invalid rx DMA channel\n");
		return -ENODEV;
	}
	/* RX DMA request number, and port address configuration */
	mcbsp->dma_data[1].name = "Audio Capture";
	mcbsp->dma_data[1].dma_req = res->start;
	mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1);

	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
	if (!res) {
		dev_err(&pdev->dev, "invalid tx DMA channel\n");
		return -ENODEV;
	}
	/* TX DMA request number, and port address configuration */
	mcbsp->dma_data[0].name = "Audio Playback";
	mcbsp->dma_data[0].dma_req = res->start;
	mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0);

	mcbsp->fclk = clk_get(&pdev->dev, "fck");
	if (IS_ERR(mcbsp->fclk)) {
		ret = PTR_ERR(mcbsp->fclk);
		dev_err(mcbsp->dev, "unable to get fck: %d\n", ret);
		return ret;
	}

	mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
	if (mcbsp->pdata->buffer_size) {
		/*
		 * Initially configure the maximum thresholds to a safe value.
		 * The McBSP FIFO usage with these values should not go under
		 * 16 locations.
		 * If the whole FIFO without safety buffer is used, than there
		 * is a possibility that the DMA will be not able to push the
		 * new data on time, causing channel shifts in runtime.
		 */
		mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
		mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;

		ret = sysfs_create_group(&mcbsp->dev->kobj,
					 &additional_attr_group);
		if (ret) {
			dev_err(mcbsp->dev,
				"Unable to create additional controls\n");
			goto err_thres;
		}
	} else {
		mcbsp->max_tx_thres = -EINVAL;
		mcbsp->max_rx_thres = -EINVAL;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
	if (res) {
		ret = omap_st_add(mcbsp, res);
		if (ret) {
			dev_err(mcbsp->dev,
				"Unable to create sidetone controls\n");
			goto err_st;
		}
	}

	return 0;

err_st:
	if (mcbsp->pdata->buffer_size)
		sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
err_thres:
	clk_put(mcbsp->fclk);
	return ret;
}
Exemplo n.º 6
0
int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
{
	struct stat buf;
	const char *name;
	int need_excl = 0, need_rw = 0;

	if ((flags & O_ACCMODE) == O_RDWR)
		need_rw = 1;

	if ((flags & O_EXCL))
		need_excl = 1;

	if (dev->fd >= 0) {
		if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
		    ((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
			dev->open_count++;
			return 1;
		}

		if (dev->open_count && !need_excl) {
			log_debug_devs("%s already opened read-only. Upgrading "
				       "to read-write.", dev_name(dev));
			dev->open_count++;
		}

		dev_close_immediate(dev);
		// FIXME: dev with DEV_ALLOCED is released
		// but code is referencing it
	}

	if (critical_section())
		/* FIXME Make this log_error */
		log_verbose("dev_open(%s) called while suspended",
			    dev_name(dev));

	if (dev->flags & DEV_REGULAR)
		name = dev_name(dev);
	else if (!(name = dev_name_confirmed(dev, quiet)))
		return_0;

#ifdef O_DIRECT_SUPPORT
	if (direct) {
		if (!(dev->flags & DEV_O_DIRECT_TESTED))
			dev->flags |= DEV_O_DIRECT;

		if ((dev->flags & DEV_O_DIRECT))
			flags |= O_DIRECT;
	}
#endif

#ifdef O_NOATIME
	/* Don't update atime on device inodes */
	if (!(dev->flags & DEV_REGULAR))
		flags |= O_NOATIME;
#endif

	if ((dev->fd = open(name, flags, 0777)) < 0) {
#ifdef O_DIRECT_SUPPORT
		if (direct && !(dev->flags & DEV_O_DIRECT_TESTED)) {
			flags &= ~O_DIRECT;
			if ((dev->fd = open(name, flags, 0777)) >= 0) {
				dev->flags &= ~DEV_O_DIRECT;
				log_debug_devs("%s: Not using O_DIRECT", name);
				goto opened;
			}
		}
#endif
		if (quiet)
			log_sys_debug("open", name);
		else
			log_sys_error("open", name);
		return 0;
	}

#ifdef O_DIRECT_SUPPORT
      opened:
	if (direct)
		dev->flags |= DEV_O_DIRECT_TESTED;
#endif
	dev->open_count++;
	dev->flags &= ~DEV_ACCESSED_W;

	if (need_rw)
		dev->flags |= DEV_OPENED_RW;
	else
		dev->flags &= ~DEV_OPENED_RW;

	if (need_excl)
		dev->flags |= DEV_OPENED_EXCL;
	else
		dev->flags &= ~DEV_OPENED_EXCL;

	if (!(dev->flags & DEV_REGULAR) &&
	    ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
		log_error("%s: fstat failed: Has device name changed?", name);
		dev_close_immediate(dev);
		return 0;
	}

#ifndef O_DIRECT_SUPPORT
	if (!(dev->flags & DEV_REGULAR))
		dev_flush(dev);
#endif

	if ((flags & O_CREAT) && !(flags & O_TRUNC))
		dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);

	dm_list_add(&_open_devices, &dev->open_list);

	log_debug_devs("Opened %s %s%s%s", dev_name(dev),
		       dev->flags & DEV_OPENED_RW ? "RW" : "RO",
		       dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
		       dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");

	return 1;
}
Exemplo n.º 7
0
static int arizona_ldo1_probe(struct platform_device *pdev)
{
	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
	const struct regulator_desc *desc;
	struct regulator_config config = { };
	struct arizona_ldo1 *ldo1;
	int ret;

	arizona->external_dcvdd = false;

	ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
	if (ldo1 == NULL) {
		dev_err(&pdev->dev, "Unable to allocate private data\n");
		return -ENOMEM;
	}

	ldo1->arizona = arizona;

	/*
	 * Since the chip usually supplies itself we provide some
	 * default init_data for it.  This will be overridden with
	 * platform data if provided.
	 */
	switch (arizona->type) {
	case WM5102:
	case WM8997:
		desc = &arizona_ldo1_hc;
		ldo1->init_data = arizona_ldo1_dvfs;
		break;
	default:
		desc = &arizona_ldo1;
		ldo1->init_data = arizona_ldo1_default;
		break;
	}

	ldo1->init_data.consumer_supplies = &ldo1->supply;
	ldo1->supply.supply = "DCVDD";
	ldo1->supply.dev_name = dev_name(arizona->dev);

	config.dev = arizona->dev;
	config.driver_data = ldo1;
	config.regmap = arizona->regmap;

	if (!dev_get_platdata(arizona->dev)) {
		ret = arizona_ldo1_of_get_pdata(arizona, &config);
		if (ret < 0)
			return ret;
	}

	config.ena_gpio = arizona->pdata.ldoena;

	if (arizona->pdata.ldo1)
		config.init_data = arizona->pdata.ldo1;
	else
		config.init_data = &ldo1->init_data;

	/*
	 * LDO1 can only be used to supply DCVDD so if it has no
	 * consumers then DCVDD is supplied externally.
	 */
	if (config.init_data->num_consumer_supplies == 0)
		arizona->external_dcvdd = true;

	ldo1->regulator = regulator_register(desc, &config);
	if (IS_ERR(ldo1->regulator)) {
		ret = PTR_ERR(ldo1->regulator);
		dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n",
			ret);
		return ret;
	}

	if (!dev_get_platdata(arizona->dev))
		arizona_ldo1_of_put_pdata(&config);

	platform_set_drvdata(pdev, ldo1);

	return 0;
}
Exemplo n.º 8
0
static char *
spm_devnode(struct device *dev, mode_t *mode)
{
	return kasprintf(GFP_KERNEL, "spm/%s", dev_name(dev));
}
Exemplo n.º 9
0
static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct resource *res;
	struct msm_hsic_hcd *mehci;
	struct msm_hsic_host_platform_data *pdata;
	int ret;

	dev_dbg(&pdev->dev, "ehci_msm-hsic probe\n");

	/* After parent device's probe is executed, it will be put in suspend
	 * mode. When child device's probe is called, driver core is not
	 * resuming parent device due to which parent will be in suspend even
	 * though child is active. Hence resume the parent device explicitly.
	 */
	if (pdev->dev.parent)
		pm_runtime_get_sync(pdev->dev.parent);

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

	hcd->irq = platform_get_irq(pdev, 0);
	if (hcd->irq < 0) {
		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
		ret = hcd->irq;
		goto put_hcd;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Unable to get memory resource\n");
		ret = -ENODEV;
		goto put_hcd;
	}

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto put_hcd;
	}

	mehci = hcd_to_hsic(hcd);
	mehci->dev = &pdev->dev;
	pdata = mehci->dev->platform_data;

	mehci->ehci.susp_sof_bug = 1;
	mehci->ehci.reset_sof_bug = 1;

	mehci->ehci.resume_sof_bug = 1;

	if (pdata)
		mehci->ehci.log2_irq_thresh = pdata->log2_irq_thresh;

	res = platform_get_resource_byname(pdev,
			IORESOURCE_IRQ,
			"peripheral_status_irq");
	if (res)
		mehci->peripheral_status_irq = res->start;

	res = platform_get_resource_byname(pdev, IORESOURCE_IO, "wakeup");
	if (res) {
		mehci->wakeup_gpio = res->start;
		mehci->wakeup_irq = MSM_GPIO_TO_INT(res->start);
		dev_dbg(mehci->dev, "wakeup_irq: %d\n", mehci->wakeup_irq);
	}

	ret = msm_hsic_init_clocks(mehci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize clocks\n");
		ret = -ENODEV;
		goto unmap;
	}

	ret = msm_hsic_init_vddcx(mehci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize VDDCX\n");
		ret = -ENODEV;
		goto deinit_clocks;
	}

	init_completion(&mehci->rt_completion);
	init_completion(&mehci->gpt0_completion);
	ret = msm_hsic_reset(mehci);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize PHY\n");
		goto deinit_vddcx;
	}

	ehci_wq = create_singlethread_workqueue("ehci_wq");
	if (!ehci_wq) {
		dev_err(&pdev->dev, "unable to create workqueue\n");
		ret = -ENOMEM;
		goto deinit_vddcx;
	}

	INIT_WORK(&mehci->bus_vote_w, ehci_hsic_bus_vote_w);

	ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
	if (ret) {
		dev_err(&pdev->dev, "unable to register HCD\n");
		goto unconfig_gpio;
	}

	device_init_wakeup(&pdev->dev, 1);
	wake_lock_init(&mehci->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
	wake_lock(&mehci->wlock);

	if (mehci->peripheral_status_irq) {
		ret = request_threaded_irq(mehci->peripheral_status_irq,
			NULL, hsic_peripheral_status_change,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
						| IRQF_SHARED,
			"hsic_peripheral_status", mehci);
		if (ret)
			dev_err(&pdev->dev, "%s:request_irq:%d failed:%d",
				__func__, mehci->peripheral_status_irq, ret);
	}

	/* configure wakeup irq */
	if (mehci->wakeup_irq) {
		ret = request_irq(mehci->wakeup_irq, msm_hsic_wakeup_irq,
				IRQF_TRIGGER_HIGH,
				"msm_hsic_wakeup", mehci);
		if (!ret) {
			disable_irq_nosync(mehci->wakeup_irq);
		} else {
			dev_err(&pdev->dev, "request_irq(%d) failed: %d\n",
					mehci->wakeup_irq, ret);
			mehci->wakeup_irq = 0;
		}
	}

	ret = ehci_hsic_msm_debugfs_init(mehci);
	if (ret)
		dev_dbg(&pdev->dev, "mode debugfs file is"
			"not available\n");

	if (pdata && pdata->bus_scale_table) {
		mehci->bus_perf_client =
		    msm_bus_scale_register_client(pdata->bus_scale_table);
		/* Configure BUS performance parameters for MAX bandwidth */
		if (mehci->bus_perf_client) {
			mehci->bus_vote = true;
			queue_work(ehci_wq, &mehci->bus_vote_w);
		} else {
			dev_err(&pdev->dev, "%s: Failed to register BUS "
						"scaling client!!\n", __func__);
		}
	}

	__mehci = mehci;

	/*
	 * This pdev->dev is assigned parent of root-hub by USB core,
	 * hence, runtime framework automatically calls this driver's
	 * runtime APIs based on root-hub's state.
	 */
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	/* Decrement the parent device's counter after probe.
	 * As child is active, parent will not be put into
	 * suspend mode.
	 */
	if (pdev->dev.parent)
		pm_runtime_put_sync(pdev->dev.parent);

	return 0;

unconfig_gpio:
	destroy_workqueue(ehci_wq);
	msm_hsic_config_gpios(mehci, 0);
deinit_vddcx:
	msm_hsic_init_vddcx(mehci, 0);
deinit_clocks:
	msm_hsic_init_clocks(mehci, 0);
unmap:
	iounmap(hcd->regs);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
Exemplo n.º 10
0
static int __init bbswitch_init(void) {
    struct proc_dir_entry *acpi_entry;
    struct pci_dev *pdev = NULL;
    acpi_handle igd_handle = NULL;

    pr_info("version %s\n", BBSWITCH_VERSION);

    while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
        struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
        acpi_handle handle;
        int pci_class = pdev->class >> 8;

        if (pci_class != PCI_CLASS_DISPLAY_VGA &&
            pci_class != PCI_CLASS_DISPLAY_3D)
            continue;

#ifdef ACPI_HANDLE
        /* since Linux 3.8 */
        handle = ACPI_HANDLE(&pdev->dev);
#else
        /* removed since Linux 3.13 */
        handle = DEVICE_ACPI_HANDLE(&pdev->dev);
#endif
        if (!handle) {
            pr_warn("cannot find ACPI handle for VGA device %s\n",
                dev_name(&pdev->dev));
            continue;
        }

        acpi_get_name(handle, ACPI_FULL_PATHNAME, &buf);

        if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
            igd_handle = handle;
            pr_info("Found integrated VGA device %s: %s\n",
                dev_name(&pdev->dev), (char *)buf.pointer);
        } else {
            dis_dev = pdev;
            dis_handle = handle;
            pr_info("Found discrete VGA device %s: %s\n",
                dev_name(&pdev->dev), (char *)buf.pointer);
        }
        kfree(buf.pointer);
    }

    if (dis_dev == NULL) {
        pr_err("No discrete VGA device found\n");
        return -ENODEV;
    }

    if (!skip_optimus_dsm &&
            has_dsm_func(acpi_optimus_dsm_muid, 0x100, 0x1A)) {
        dsm_type = DSM_TYPE_OPTIMUS;
        pr_info("detected an Optimus _DSM function\n");
    } else if (has_dsm_func(acpi_nvidia_dsm_muid, 0x102, 0x3)) {
        dsm_type = DSM_TYPE_NVIDIA;
        pr_info("detected a nVidia _DSM function\n");
    } else {
       /* At least two Acer machines are known to use the intel ACPI handle
        * with the legacy nvidia DSM */
        dis_handle = igd_handle;
        if (dis_handle && has_dsm_func(acpi_nvidia_dsm_muid, 0x102, 0x3)) {
            dsm_type = DSM_TYPE_NVIDIA;
            pr_info("detected a nVidia _DSM function on the"
                " integrated video card\n");
        } else {
            pr_err("No suitable _DSM call found.\n");
            return -ENODEV;
        }
    }

    acpi_entry = proc_create("bbswitch", 0664, acpi_root_dir, &bbswitch_fops);
    if (acpi_entry == NULL) {
        pr_err("Couldn't create proc entry\n");
        return -ENOMEM;
    }

    dis_dev_get();

    if (!is_card_disabled()) {
        /* We think the card is enabled, so ensure the kernel does as well */
        if (pci_enable_device(dis_dev))
            pr_warn("failed to enable %s\n", dev_name(&dis_dev->dev));
    }

    if (load_state == CARD_ON)
        bbswitch_on();
    else if (load_state == CARD_OFF)
        bbswitch_off();

    pr_info("Succesfully loaded. Discrete card %s is %s\n",
        dev_name(&dis_dev->dev), is_card_disabled() ? "off" : "on");

    dis_dev_put();

    register_pm_notifier(&nb);

    return 0;
}
Exemplo n.º 11
0
/**
 * ehci_hcd_omap_probe - initialize TI-based HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int ehci_hcd_omap_probe(struct platform_device *pdev)
{
	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
	struct ehci_hcd_omap *omap;
	struct resource *res;
	struct usb_hcd *hcd;

	int irq = platform_get_irq(pdev, 0);
	int ret = -ENODEV;

	printk(KERN_DEBUG " ehci_hcd_omap_probe\n");

	if (!pdata) {
		dev_dbg(&pdev->dev, "missing platform_data\n");
		goto err_pdata;
	}

	if (usb_disabled())
	{
		printk(KERN_DEBUG " usb_disabled\n");
		goto err_disabled;
	}

	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	printk(KERN_DEBUG " kzalloc done\n");
	
	if (!omap) {
		printk(KERN_DEBUG " problem with memory allocation\n");
		ret = -ENOMEM;
		goto err_disabled;
	}

	hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
			dev_name(&pdev->dev));
	printk(KERN_DEBUG " usb_create hcd done\n");
	if (!hcd) {
		printk(KERN_DEBUG " failed to create HCD\n");
		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	platform_set_drvdata(pdev, omap);
	omap->dev		= &pdev->dev;
	omap->phy_reset		= pdata->phy_reset;
	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
	omap->port_mode[0]		= pdata->port_mode[0];
	omap->port_mode[1]		= pdata->port_mode[1];
	omap->port_mode[2]		= pdata->port_mode[2];
	omap->ehci		= hcd_to_ehci(hcd);
	omap->ehci->sbrn	= 0x20;
	omap->suspended = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	printk(KERN_DEBUG " platform get ressources 0 done\n");

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		printk(KERN_DEBUG " EHCI ioremap failed\n");
		dev_err(&pdev->dev, "EHCI ioremap failed\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	/* we know this is the memory we want, no need to ioremap again */
	omap->ehci->caps = hcd->regs;
	omap->ehci_base = hcd->regs;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	printk(KERN_DEBUG " platform get ressources 1 done\n");
	
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		printk(KERN_DEBUG " UHH ioremap failed\n");
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err_uhh_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	printk(KERN_DEBUG " platform get ressources 2 done\n");
	

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to start ehci\n");
		printk(KERN_DEBUG " failed to start ehci\n");
		goto err_start;
	}

	omap->ehci->regs = hcd->regs
		+ HC_LENGTH(readl(&omap->ehci->caps->hc_capbase));

	dbg_hcs_params(omap->ehci, "reset");
	dbg_hcc_params(omap->ehci, "reset");

	/* cache this readonly data; minimize chip reads */
	omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params);

	/* SET 1 micro-frame Interrupt interval */
	writel(readl(&omap->ehci->regs->command) | (1 << 16),
			&omap->ehci->regs->command);

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err_add_hcd;
	}
   EP10_HW_ID=ep_get_hardware_id();
   if(EP10_HW_ID==BOARD_VERSION_UNKNOWN)
   {
      EP10_HW_ID = BOARD_ID_DVT1 ;
   }
	printk(KERN_DEBUG " add hcd done\n");

	return 0;

err_add_hcd:
	omap_stop_ehc(omap, hcd);

err_start:
	//iounmap(omap->tll_base);

err_tll_ioremap:
	iounmap(omap->uhh_base);

err_uhh_ioremap:
	iounmap(hcd->regs);

err_ioremap:
	usb_put_hcd(hcd);

err_create_hcd:
	kfree(omap);
err_disabled:
err_pdata:
	return ret;
}
Exemplo n.º 12
0
/**
 * intel_mid_i2s_probe - probing function for the pci selected
 * @pdev : pci_dev pointer that is probed
 * @ent : pci_device_id
 *
 * Output parameters
 *      NA
 */
static int intel_mid_i2s_probe(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	struct intel_mid_i2s_hdl *drv_data;
	int status = 0;
	enum intel_mid_i2s_ssp_usage usage;

	drv_data = kzalloc(sizeof(struct intel_mid_i2s_hdl), GFP_KERNEL);
	dev_dbg(&(pdev->dev), "%s Probe, drv_data =%p\n",
						DRIVER_NAME, drv_data);
	if (!drv_data) {
		dev_err((&pdev->dev), "Can't alloc driver data in probe\n");
		status = -ENOMEM;
		goto leave;
	}
	dev_info((&pdev->dev), "Detected PCI SSP (ID: %04x:%04x)\n",
						pdev->vendor, pdev->device);
	status = intel_mid_i2s_find_usage(pdev, drv_data, &usage);
	if (status)
		goto err_i2s_probe0;
	mutex_init(&drv_data->mutex);
	drv_data->pdev = pdev;
	drv_data->usage = usage;
	/*
	 * Get basic io resource and map it for SSP1 [BAR=0]
	 */
	if ((pdev->device == MFLD_SSP1_DEVICE_ID) ||
	    (pdev->device == MFLD_SSP0_DEVICE_ID)) {
		drv_data->paddr = pci_resource_start(pdev, MRST_SSP_BAR);
		drv_data->iolen = pci_resource_len(pdev, MRST_SSP_BAR);
		status = pci_request_region(pdev, MRST_SSP_BAR,
						dev_name(&pdev->dev));
		/* map bus memory into CPU space */
		drv_data->ioaddr = pci_ioremap_bar(pdev, MRST_SSP_BAR);
	} else {
		dev_err(&pdev->dev,
			"Don't know which BAR to usefor this SSP PCDID=%x\n",
			pdev->device);
		status = -ENODEV;
		goto err_i2s_probe1;
	}
	dev_dbg(&(pdev->dev), "paddr = : %x\n", (unsigned int) drv_data->paddr);
	dev_dbg(&(pdev->dev), "iolen = : %d\n", drv_data->iolen);
	if (status) {
		dev_err((&pdev->dev), "Can't request region. err=%d\n", status);
		goto err_i2s_probe1;
	}
	if (!drv_data->ioaddr) {
		dev_err((&pdev->dev), "ioremap_nocache error\n");
		status = -ENOMEM;
		goto err_i2s_probe2;
	}
	dev_dbg(&(pdev->dev), "ioaddr = : %p\n", drv_data->ioaddr);
	/* prepare for DMA channel allocation */
	/* get the pci_dev structure pointer */
	/* Check the SSP, if SSP3, then another DMA is used (GPDMA..) */
	if ((pdev->device == MFLD_SSP1_DEVICE_ID) ||
	    (pdev->device == MFLD_SSP0_DEVICE_ID)) {
		drv_data->dmac1 = pci_get_device(PCI_VENDOR_ID_INTEL,
						 MFLD_LPE_DMA_DEVICE_ID,
						 NULL);
	} else {
		dev_err(&pdev->dev,
			"Don't know dma device ID for this SSP PCDID=%x\n",
			pdev->device);
		goto err_i2s_probe3;
	}
	/* in case the stop dma have to wait for end of callbacks   */
	/* This will be removed when TERMINATE_ALL available in DMA */
	init_waitqueue_head(&drv_data->wq_chan_closing);
	if (!drv_data->dmac1) {
		dev_err(&(drv_data->pdev->dev), "Can't find DMAC1, dma init failed\n");
		status = -ENODEV;
		goto err_i2s_probe3;
	}
	/* increment ref count of pci device structure already done by */
	/* pci_get_device. will do a pci_dev_put when exiting the module */
	pci_set_drvdata(pdev, drv_data);
	/* set SSP FrameSync and CLK direction in INPUT mode in order
	 * to avoid disturbing peripherals
	 */
	write_SSCR1((SSCR1_SFRMDIR_MASK<<SSCR1_SFRMDIR_SHIFT)
		  | (SSCR1_SCLKDIR_MASK<<SSCR1_SCLKDIR_SHIFT),
	drv_data->ioaddr);
	/* Attach to IRQ */
	drv_data->irq = pdev->irq;
	dev_dbg(&(pdev->dev), "attaching to IRQ: %04x\n", pdev->irq);

	status = request_irq(drv_data->irq, i2s_int, IRQF_SHARED,
							"i2s ssp", drv_data);
	if (status < 0)	{
		dev_err(&pdev->dev, "can not get IRQ. status err=%d\n", status);
		goto err_i2s_probe3;
	}
	pm_runtime_put_noidle(&pdev->dev);
	pm_runtime_allow(&(drv_data->pdev->dev));

	goto leave;
err_i2s_probe3:
	iounmap(drv_data->ioaddr);
err_i2s_probe2:
	pci_release_region(pdev, MRST_SSP_BAR);
err_i2s_probe1:
	pci_disable_device(pdev);
err_i2s_probe0:
	kfree(drv_data);
leave:
	return status;
}