16ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf/* 26ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * Copyright 2013 Tilera Corporation. All Rights Reserved. 36ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * 46ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * This program is free software; you can redistribute it and/or 56ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * modify it under the terms of the GNU General Public License 66ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * as published by the Free Software Foundation, version 2. 76ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * 86ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * This program is distributed in the hope that it will be useful, but 96ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * WITHOUT ANY WARRANTY; without even the implied warranty of 106ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 116ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * NON INFRINGEMENT. See the GNU General Public License for 126ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * more details. 136ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf */ 146ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 156ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf/* 166ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf * Implementation of UART gxio calls. 176ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf */ 186ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 196ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf#include <linux/io.h> 206ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf#include <linux/errno.h> 216ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf#include <linux/module.h> 226ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 236ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf#include <gxio/uart.h> 246ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf#include <gxio/iorpc_globals.h> 256ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf#include <gxio/iorpc_uart.h> 266ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf#include <gxio/kiorpc.h> 276ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 286ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalfint gxio_uart_init(gxio_uart_context_t *context, int uart_index) 296ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf{ 306ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf char file[32]; 316ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf int fd; 326ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 336ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf snprintf(file, sizeof(file), "uart/%d/iorpc", uart_index); 346ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf fd = hv_dev_open((HV_VirtAddr) file, 0); 356ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf if (fd < 0) { 366ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX) 376ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf return fd; 386ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf else 396ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf return -ENODEV; 406ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf } 416ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 426ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf context->fd = fd; 436ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 446ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf /* Map in the MMIO space. */ 456ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf context->mmio_base = (void __force *) 466ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf iorpc_ioremap(fd, HV_UART_MMIO_OFFSET, HV_UART_MMIO_SIZE); 476ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 486ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf if (context->mmio_base == NULL) { 496ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf hv_dev_close(context->fd); 506ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf context->fd = -1; 516ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf return -ENODEV; 526ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf } 536ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 546ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf return 0; 556ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf} 566ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 576ec006ede5e0526c20cd7ed5e20df637ea592b1fChris MetcalfEXPORT_SYMBOL_GPL(gxio_uart_init); 586ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 596ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalfint gxio_uart_destroy(gxio_uart_context_t *context) 606ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf{ 616ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf iounmap((void __force __iomem *)(context->mmio_base)); 626ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf hv_dev_close(context->fd); 636ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 646ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf context->mmio_base = NULL; 656ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf context->fd = -1; 666ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 676ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf return 0; 686ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf} 696ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 706ec006ede5e0526c20cd7ed5e20df637ea592b1fChris MetcalfEXPORT_SYMBOL_GPL(gxio_uart_destroy); 716ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 726ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf/* UART register write wrapper. */ 736ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalfvoid gxio_uart_write(gxio_uart_context_t *context, uint64_t offset, 746ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf uint64_t word) 756ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf{ 766ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf __gxio_mmio_write(context->mmio_base + offset, word); 776ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf} 786ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 796ec006ede5e0526c20cd7ed5e20df637ea592b1fChris MetcalfEXPORT_SYMBOL_GPL(gxio_uart_write); 806ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 816ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf/* UART register read wrapper. */ 826ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalfuint64_t gxio_uart_read(gxio_uart_context_t *context, uint64_t offset) 836ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf{ 846ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf return __gxio_mmio_read(context->mmio_base + offset); 856ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf} 866ec006ede5e0526c20cd7ed5e20df637ea592b1fChris Metcalf 876ec006ede5e0526c20cd7ed5e20df637ea592b1fChris MetcalfEXPORT_SYMBOL_GPL(gxio_uart_read); 88