Ejemplo n.º 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);
}
Ejemplo n.º 2
0
static ssize_t hv_stats_store(struct device *dev,
			      struct device_attribute *attr,
			      const char *page,
			      size_t count)
{
	int cpu = dev->id;
	long lotar = HV_XY_TO_LOTAR(cpu_x(cpu), cpu_y(cpu));

	ssize_t n = hv_confstr(HV_CONFSTR_HV_STATS, 0, 0, lotar, 1);
	return n < 0 ? n : count;
}
Ejemplo n.º 3
0
static ssize_t hv_stats_show(struct device *dev,
			     struct device_attribute *attr,
			     char *page)
{
	int cpu = dev->id;
	long lotar = HV_XY_TO_LOTAR(cpu_x(cpu), cpu_y(cpu));

	ssize_t n = hv_confstr(HV_CONFSTR_HV_STATS,
			       (unsigned long)page, PAGE_SIZE - 1,
			       lotar, 0);
	n = n < 0 ? 0 : min(n, (ssize_t)PAGE_SIZE - 1);
	page[n] = '\0';
	return n;
}
Ejemplo n.º 4
0
static int __init create_sysfs_entries(void)
{
	int err = 0;

#define create_cpu_attr(name)						\
	if (!err)							\
		err = device_create_file(cpu_subsys.dev_root, &dev_attr_##name);
	create_cpu_attr(chip_width);
	create_cpu_attr(chip_height);
	create_cpu_attr(chip_serial);
	create_cpu_attr(chip_revision);

#define create_hv_attr(name)						\
	if (!err)							\
		err = sysfs_create_file(hypervisor_kobj, &dev_attr_##name.attr);
	create_hv_attr(type);
	create_hv_attr(version);
	create_hv_attr(config_version);

	if (!err)
		err = sysfs_create_group(hypervisor_kobj, &board_attr_group);

	if (!err) {
		sysfs_bin_attr_init(&hvconfig_bin);
		hvconfig_bin.attr.name = "hvconfig";
		hvconfig_bin.attr.mode = S_IRUGO;
		hvconfig_bin.read = hvconfig_bin_read;
		hvconfig_bin.size = PAGE_SIZE;
		err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin);
	}

	if (!err) {
		/*
		 * Don't bother adding the hv_stats files on each CPU if
		 * our hypervisor doesn't supply statistics.
		 */
		int cpu = raw_smp_processor_id();
		long lotar = HV_XY_TO_LOTAR(cpu_x(cpu), cpu_y(cpu));
		char dummy;
		ssize_t n = hv_confstr(HV_CONFSTR_HV_STATS,
				       (unsigned long) &dummy, 1,
				       lotar, 0);
		if (n >= 0)
			err = subsys_interface_register(&hv_stats_interface);
	}

	return err;
}
Ejemplo n.º 5
0
/*
 * Stop receiving - port is in process of being closed.
 */
static void tilegx_stop_rx(struct uart_port *port)
{
	int err;
	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_trylock(&tile_uart->mutex))
		return;

	context = &tile_uart->context;
	cpu = tile_uart->irq_cpu;
	err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
				      KERNEL_PL, -1);
	mutex_unlock(&tile_uart->mutex);
}
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 = create_irq();
	if (pdata->irq < 0) {
		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);
		return ret;
	}

err_have_irq:
	destroy_irq(pdata->irq);
err_no_irq:
	tilegx_stop_ohc();
	usb_put_hcd(hcd);
err_hcd:
	gxio_usb_host_destroy(&pdata->usb_ctx);
	return ret;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
static int ehci_hcd_tilegx_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	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, 1) != 0)
		return -ENXIO;

	hcd = usb_create_hcd(&ehci_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_ehc();

	ehci = hcd_to_ehci(hcd);
	ehci->caps = hcd->regs;
	ehci->regs =
		hcd->regs + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase));
	/* cache this readonly data; minimize chip reads */
	ehci->hcs_params = readl(&ehci->caps->hcs_params);

	/* 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;
	}

	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_ehc();
	usb_put_hcd(hcd);
err_hcd:
	gxio_usb_host_destroy(&pdata->usb_ctx);
	return ret;
}