linux/drivers/staging/vme_user/vme_tsi148.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Support for the Tundra TSI148 VME-PCI Bridge Chip
 *
 * Author: Martyn Welch <[email protected]>
 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
 *
 * Based on work by Tom Armistead and Ajit Prem
 * Copyright 2004 Motorola Inc.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
#include <linux/poll.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/byteorder/generic.h>

#include "vme.h"
#include "vme_bridge.h"
#include "vme_tsi148.h"

static int tsi148_probe(struct pci_dev *, const struct pci_device_id *);
static void tsi148_remove(struct pci_dev *);

/* Module parameter */
static bool err_chk;
static u32 geoid;

static const char driver_name[] =;

static const struct pci_device_id tsi148_ids[] =;

MODULE_DEVICE_TABLE(pci, tsi148_ids);

static struct pci_driver tsi148_driver =;

static void reg_join(unsigned int high, unsigned int low,
		     unsigned long long *variable)
{}

static void reg_split(unsigned long long variable, unsigned int *high,
		      unsigned int *low)
{}

/*
 * Wakes up DMA queue.
 */
static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge,
				 int channel_mask)
{}

/*
 * Wake up location monitor queue
 */
static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat)
{}

/*
 * Wake up mail box queue.
 *
 * XXX This functionality is not exposed up though API.
 */
static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat)
{}

/*
 * Display error & status message when PERR (PCI) exception interrupt occurs.
 */
static u32 tsi148_PERR_irqhandler(struct vme_bridge *tsi148_bridge)
{}

/*
 * Save address and status when VME error interrupt occurs.
 */
static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge)
{}

/*
 * Wake up IACK queue.
 */
static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge)
{}

/*
 * Calling VME bus interrupt callback if provided.
 */
static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge,
				  u32 stat)
{}

/*
 * Top level interrupt handler.  Clears appropriate interrupt status bits and
 * then calls appropriate sub handler(s).
 */
static irqreturn_t tsi148_irqhandler(int irq, void *ptr)
{}

static int tsi148_irq_init(struct vme_bridge *tsi148_bridge)
{}

static void tsi148_irq_exit(struct vme_bridge *tsi148_bridge,
			    struct pci_dev *pdev)
{}

/*
 * Check to see if an IACk has been received, return true (1) or false (0).
 */
static int tsi148_iack_received(struct tsi148_driver *bridge)
{}

/*
 * Configure VME interrupt
 */
static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level,
			   int state, int sync)
{}

/*
 * Generate a VME bus interrupt at the requested level & vector. Wait for
 * interrupt to be acked.
 */
static int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level,
			       int statid)
{}

/*
 * Initialize a slave window with the requested attributes.
 */
static int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
			    unsigned long long vme_base, unsigned long long size,
			    dma_addr_t pci_base, u32 aspace, u32 cycle)
{}

/*
 * Get slave window configuration.
 */
static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
			    unsigned long long *vme_base, unsigned long long *size,
			    dma_addr_t *pci_base, u32 *aspace, u32 *cycle)
{}

/*
 * Allocate and map PCI Resource
 */
static int tsi148_alloc_resource(struct vme_master_resource *image,
				 unsigned long long size)
{}

/*
 * Free and unmap PCI Resource
 */
static void tsi148_free_resource(struct vme_master_resource *image)
{}

/*
 * Set the attributes of an outbound window.
 */
static int tsi148_master_set(struct vme_master_resource *image, int enabled,
			     unsigned long long vme_base, unsigned long long size,
			     u32 aspace, u32 cycle, u32 dwidth)
{}

/*
 * Set the attributes of an outbound window.
 *
 * XXX Not parsing prefetch information.
 */
static int __tsi148_master_get(struct vme_master_resource *image, int *enabled,
			       unsigned long long *vme_base, unsigned long long *size,
			       u32 *aspace, u32 *cycle, u32 *dwidth)
{}

static int tsi148_master_get(struct vme_master_resource *image, int *enabled,
			     unsigned long long *vme_base, unsigned long long *size,
			     u32 *aspace, u32 *cycle, u32 *dwidth)
{}

static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
				  size_t count, loff_t offset)
{}

static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
				   size_t count, loff_t offset)
{}

/*
 * Perform an RMW cycle on the VME bus.
 *
 * Requires a previously configured master window, returns final value.
 */
static unsigned int tsi148_master_rmw(struct vme_master_resource *image, unsigned int mask,
				      unsigned int compare, unsigned int swap, loff_t offset)
{}

static int tsi148_dma_set_vme_src_attributes(struct device *dev, __be32 *attr,
					     u32 aspace, u32 cycle, u32 dwidth)
{}

static int tsi148_dma_set_vme_dest_attributes(struct device *dev, __be32 *attr,
					      u32 aspace, u32 cycle, u32 dwidth)
{}

/*
 * Add a link list descriptor to the list
 *
 * Note: DMA engine expects the DMA descriptor to be big endian.
 */
static int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
			       struct vme_dma_attr *dest, size_t count)
{}

/*
 * Check to see if the provided DMA channel is busy.
 */
static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel)
{}

/*
 * Execute a previously generated link list
 *
 * XXX Need to provide control register configuration.
 */
static int tsi148_dma_list_exec(struct vme_dma_list *list)
{}

/*
 * Clean up a previously generated link list
 *
 * We have a separate function, don't assume that the chain can't be reused.
 */
static int tsi148_dma_list_empty(struct vme_dma_list *list)
{}

/*
 * All 4 location monitors reside at the same base - this is therefore a
 * system wide configuration.
 *
 * This does not enable the LM monitor - that should be done when the first
 * callback is attached and disabled when the last callback is removed.
 */
static int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
			 u32 aspace, u32 cycle)
{}

/* Get configuration of the callback monitor and return whether it is enabled
 * or disabled.
 */
static int tsi148_lm_get(struct vme_lm_resource *lm,
			 unsigned long long *lm_base, u32 *aspace, u32 *cycle)
{}

/*
 * Attach a callback to a specific location monitor.
 *
 * Callback will be passed the monitor triggered.
 */
static int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
			    void (*callback)(void *), void *data)
{}

/*
 * Detach a callback function forn a specific location monitor.
 */
static int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
{}

/*
 * Determine Geographical Addressing
 */
static int tsi148_slot_get(struct vme_bridge *tsi148_bridge)
{}

static void *tsi148_alloc_consistent(struct device *parent, size_t size,
				     dma_addr_t *dma)
{}

static void tsi148_free_consistent(struct device *parent, size_t size,
				   void *vaddr, dma_addr_t dma)
{}

/*
 * Configure CR/CSR space
 *
 * Access to the CR/CSR can be configured at power-up. The location of the
 * CR/CSR registers in the CR/CSR address space is determined by the boards
 * Auto-ID or Geographic address. This function ensures that the window is
 * enabled at an offset consistent with the boards geopgraphic address.
 *
 * Each board has a 512kB window, with the highest 4kB being used for the
 * boards registers, this means there is a fix length 508kB window which must
 * be mapped onto PCI memory.
 */
static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge,
			     struct pci_dev *pdev)
{}

static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge,
			      struct pci_dev *pdev)
{}

static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{}

static void tsi148_remove(struct pci_dev *pdev)
{}

module_pci_driver();

MODULE_PARM_DESC();
module_param(err_chk, bool, 0);

MODULE_PARM_DESC();
module_param(geoid, uint, 0);

MODULE_DESCRIPTION();
MODULE_LICENSE();