Exemple #1
0
/*
 * Release kernel resources if it is the last close, disable the port,
 * free IRQ and close the port.
 */
static void tilegx_shutdown(struct uart_port *port)
{
	int err;
	UART_INTERRUPT_MASK_t intr_mask;
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;
	int cpu;

	tile_uart = container_of(port, struct tile_uart_port, uart);
	if (mutex_lock_interruptible(&tile_uart->mutex))
		return;
	context = &tile_uart->context;

	/* Disable UART Tx/Rx Interrupt. */
	intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
	intr_mask.wfifo_re = 1;
	intr_mask.rfifo_we = 1;
	gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);

	/* Request that the hardware stop sending us interrupts. */
	cpu = tile_uart->irq_cpu;
	err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
				      KERNEL_PL, -1);

	if (port->irq > 0) {
		free_irq(port->irq, port);
		irq_free_hwirq(port->irq);
		port->irq = 0;
	}

	gxio_uart_destroy(context);

	mutex_unlock(&tile_uart->mutex);
}
static int hvc_tile_remove(struct platform_device *pdev)
{
	int rc;
	struct hvc_struct *hp = dev_get_drvdata(&pdev->dev);

	rc = hvc_remove(hp);
	if (rc == 0)
		irq_free_hwirq(hp->data);

	return rc;
}
Exemple #3
0
static int ohci_hcd_tilegx_drv_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);
	struct tilegx_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);

	usb_remove_hcd(hcd);
	usb_put_hcd(hcd);
	tilegx_stop_ohc();
	gxio_usb_host_destroy(&pdata->usb_ctx);
	irq_free_hwirq(pdata->irq);

	return 0;
}
static int hvc_tile_probe(struct platform_device *pdev)
{
	struct hvc_struct *hp;
	int tile_hvc_irq;

	/* Create our IRQ and register it. */
	tile_hvc_irq = irq_alloc_hwirq(-1);
	if (!tile_hvc_irq)
		return -ENXIO;

	tile_irq_activate(tile_hvc_irq, TILE_IRQ_PERCPU);
	hp = hvc_alloc(0, tile_hvc_irq, &hvc_tile_get_put_ops, 128);
	if (IS_ERR(hp)) {
		irq_free_hwirq(tile_hvc_irq);
		return PTR_ERR(hp);
	}
	dev_set_drvdata(&pdev->dev, hp);

	return 0;
}
Exemple #5
0
static int ohci_hcd_tilegx_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct tilegx_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);
	pte_t pte = { 0 };
	int my_cpu = smp_processor_id();
	int ret;

	if (usb_disabled())
		return -ENODEV;

	/*
	 * Try to initialize our GXIO context; if we can't, the device
	 * doesn't exist.
	 */
	if (gxio_usb_host_init(&pdata->usb_ctx, pdata->dev_index, 0) != 0)
		return -ENXIO;

	hcd = usb_create_hcd(&ohci_tilegx_hc_driver, &pdev->dev,
			     dev_name(&pdev->dev));
	if (!hcd) {
		ret = -ENOMEM;
		goto err_hcd;
	}

	/*
	 * We don't use rsrc_start to map in our registers, but seems like
	 * we ought to set it to something, so we use the register VA.
	 */
	hcd->rsrc_start =
		(ulong) gxio_usb_host_get_reg_start(&pdata->usb_ctx);
	hcd->rsrc_len = gxio_usb_host_get_reg_len(&pdata->usb_ctx);
	hcd->regs = gxio_usb_host_get_reg_start(&pdata->usb_ctx);

	tilegx_start_ohc();

	/* Create our IRQs and register them. */
	pdata->irq = irq_alloc_hwirq(-1);
	if (!pdata->irq) {
		ret = -ENXIO;
		goto err_no_irq;
	}

	tile_irq_activate(pdata->irq, TILE_IRQ_PERCPU);

	/* Configure interrupts. */
	ret = gxio_usb_host_cfg_interrupt(&pdata->usb_ctx,
					  cpu_x(my_cpu), cpu_y(my_cpu),
					  KERNEL_PL, pdata->irq);
	if (ret) {
		ret = -ENXIO;
		goto err_have_irq;
	}

	/* Register all of our memory. */
	pte = pte_set_home(pte, PAGE_HOME_HASH);
	ret = gxio_usb_host_register_client_memory(&pdata->usb_ctx, pte, 0);
	if (ret) {
		ret = -ENXIO;
		goto err_have_irq;
	}

	ohci_hcd_init(hcd_to_ohci(hcd));

	ret = usb_add_hcd(hcd, pdata->irq, IRQF_SHARED);
	if (ret == 0) {
		platform_set_drvdata(pdev, hcd);
		device_wakeup_enable(hcd->self.controller);
		return ret;
	}

err_have_irq:
	irq_free_hwirq(pdata->irq);
err_no_irq:
	tilegx_stop_ohc();
	usb_put_hcd(hcd);
err_hcd:
	gxio_usb_host_destroy(&pdata->usb_ctx);
	return ret;
}
Exemple #6
0
/*
 * Perform initialization and enable port for reception.
 */
static int tilegx_startup(struct uart_port *port)
{
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;
	int ret = 0;
	int cpu = raw_smp_processor_id();  /* pick an arbitrary cpu */

	tile_uart = container_of(port, struct tile_uart_port, uart);
	if (mutex_lock_interruptible(&tile_uart->mutex))
		return -EBUSY;
	context = &tile_uart->context;

	/* Now open the hypervisor device if we haven't already. */
	if (context->fd < 0) {
		UART_INTERRUPT_MASK_t intr_mask;

		/* Initialize UART device. */
		ret = gxio_uart_init(context, port->line);
		if (ret) {
			ret = -ENXIO;
			goto err;
		}

		/* Create our IRQs. */
		port->irq = irq_alloc_hwirq(-1);
		if (!port->irq)
			goto err_uart_dest;
		tile_irq_activate(port->irq, TILE_IRQ_PERCPU);

		/* Register our IRQs. */
		ret = request_irq(port->irq, tilegx_interrupt, 0,
				  tilegx_uart_driver.driver_name, port);
		if (ret)
			goto err_dest_irq;

		/* Request that the hardware start sending us interrupts. */
		tile_uart->irq_cpu = cpu;
		ret = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
					      KERNEL_PL, port->irq);
		if (ret)
			goto err_free_irq;

		/* Enable UART Tx/Rx Interrupt. */
		intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
		intr_mask.wfifo_re = 0;
		intr_mask.rfifo_we = 0;
		gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);

		/* Reset the Tx/Rx interrupt in case it's set. */
		gxio_uart_write(context, UART_INTERRUPT_STATUS,
				UART_INTERRUPT_MASK__WFIFO_RE_MASK |
				UART_INTERRUPT_MASK__RFIFO_WE_MASK);
	}

	mutex_unlock(&tile_uart->mutex);
	return ret;

err_free_irq:
	free_irq(port->irq, port);
err_dest_irq:
	irq_free_hwirq(port->irq);
err_uart_dest:
	gxio_uart_destroy(context);
	ret = -ENXIO;
err:
	mutex_unlock(&tile_uart->mutex);
	return ret;
}