linux/arch/tile/gxio/usb_host.c
Chris Metcalf d1cc1732cc arch/tile: provide kernel support for the tilegx USB shim
This change adds support for accessing the USB shim from within the
kernel.  Note that this change by itself does not allow the kernel
to act as a host or as a device; it merely exposes the built-in on-chip
hardware to the kernel.

The <arch/usb_host.h> and <arch/usb_host_def.h> headers are empty at
the moment because the kernel does not require any types or definitions
specific to the tilegx USB shim; the generic USB core code is all we need.
The headers are left in as stubs so that we don't need to modify the
hypervisor header (drv_usb_host_intf.h) from upstream.

Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
2012-07-18 16:40:24 -04:00

91 lines
2 KiB
C

/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, version 2.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/*
*
* Implementation of USB gxio calls.
*/
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <gxio/iorpc_globals.h>
#include <gxio/iorpc_usb_host.h>
#include <gxio/kiorpc.h>
#include <gxio/usb_host.h>
int gxio_usb_host_init(gxio_usb_host_context_t * context, int usb_index,
int is_ehci)
{
char file[32];
int fd;
if (is_ehci)
snprintf(file, sizeof(file), "usb_host/%d/iorpc/ehci",
usb_index);
else
snprintf(file, sizeof(file), "usb_host/%d/iorpc/ohci",
usb_index);
fd = hv_dev_open((HV_VirtAddr) file, 0);
if (fd < 0) {
if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
return fd;
else
return -ENODEV;
}
context->fd = fd;
// Map in the MMIO space.
context->mmio_base =
(void __force *)iorpc_ioremap(fd, 0, HV_USB_HOST_MMIO_SIZE);
if (context->mmio_base == NULL) {
hv_dev_close(context->fd);
return -ENODEV;
}
return 0;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_init);
int gxio_usb_host_destroy(gxio_usb_host_context_t * context)
{
iounmap((void __force __iomem *)(context->mmio_base));
hv_dev_close(context->fd);
context->mmio_base = NULL;
context->fd = -1;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_destroy);
void *gxio_usb_host_get_reg_start(gxio_usb_host_context_t * context)
{
return context->mmio_base;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_get_reg_start);
size_t gxio_usb_host_get_reg_len(gxio_usb_host_context_t * context)
{
return HV_USB_HOST_MMIO_SIZE;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_get_reg_len);