1
0
Fork 0
alistair23-linux/drivers/staging/fsl_qbman/dpa_sys.h

259 lines
7.4 KiB
C

/* Copyright 2008-2012 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DPA_SYS_H
#define DPA_SYS_H
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/kthread.h>
#include <linux/memblock.h>
#include <linux/completion.h>
#include <linux/log2.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/device.h>
#include <linux/uio_driver.h>
#include <linux/smp.h>
#include <linux/fsl_hypervisor.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#include <linux/math64.h>
#include <linux/bitops.h>
#include <linux/fsl_usdpaa.h>
/* When copying aligned words or shorts, try to avoid memcpy() */
#define CONFIG_TRY_BETTER_MEMCPY
/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
#define DPA_PORTAL_CE 0
#define DPA_PORTAL_CI 1
/***********************/
/* Misc inline assists */
/***********************/
#if defined CONFIG_PPC32
#include "dpa_sys_ppc32.h"
#elif defined CONFIG_PPC64
#include "dpa_sys_ppc64.h"
#elif defined CONFIG_ARM
#include "dpa_sys_arm.h"
#elif defined CONFIG_ARM64
#include "dpa_sys_arm64.h"
#endif
#ifdef CONFIG_FSL_DPA_CHECKING
#define DPA_ASSERT(x) \
do { \
if (!(x)) { \
pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
__stringify_1(x)); \
dump_stack(); \
panic("assertion failure"); \
} \
} while (0)
#else
#define DPA_ASSERT(x)
#endif
/* memcpy() stuff - when you know alignments in advance */
#ifdef CONFIG_TRY_BETTER_MEMCPY
static inline void copy_words(void *dest, const void *src, size_t sz)
{
u32 *__dest = dest;
const u32 *__src = src;
size_t __sz = sz >> 2;
BUG_ON((unsigned long)dest & 0x3);
BUG_ON((unsigned long)src & 0x3);
BUG_ON(sz & 0x3);
while (__sz--)
*(__dest++) = *(__src++);
}
static inline void copy_shorts(void *dest, const void *src, size_t sz)
{
u16 *__dest = dest;
const u16 *__src = src;
size_t __sz = sz >> 1;
BUG_ON((unsigned long)dest & 0x1);
BUG_ON((unsigned long)src & 0x1);
BUG_ON(sz & 0x1);
while (__sz--)
*(__dest++) = *(__src++);
}
static inline void copy_bytes(void *dest, const void *src, size_t sz)
{
u8 *__dest = dest;
const u8 *__src = src;
while (sz--)
*(__dest++) = *(__src++);
}
#else
#define copy_words memcpy
#define copy_shorts memcpy
#define copy_bytes memcpy
#endif
/************/
/* RB-trees */
/************/
/* We encapsulate RB-trees so that its easier to use non-linux forms in
* non-linux systems. This also encapsulates the extra plumbing that linux code
* usually provides when using RB-trees. This encapsulation assumes that the
* data type held by the tree is u32. */
struct dpa_rbtree {
struct rb_root root;
};
#define DPA_RBTREE { .root = RB_ROOT }
static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
{
tree->root = RB_ROOT;
}
#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
{ \
struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
while (*p) { \
u32 item; \
parent = *p; \
item = rb_entry(parent, type, node_field)->val_field; \
if (obj->val_field < item) \
p = &parent->rb_left; \
else if (obj->val_field > item) \
p = &parent->rb_right; \
else \
return -EBUSY; \
} \
rb_link_node(&obj->node_field, parent, p); \
rb_insert_color(&obj->node_field, &tree->root); \
return 0; \
} \
static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
{ \
rb_erase(&obj->node_field, &tree->root); \
} \
static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
{ \
type *ret; \
struct rb_node *p = tree->root.rb_node; \
while (p) { \
ret = rb_entry(p, type, node_field); \
if (val < ret->val_field) \
p = p->rb_left; \
else if (val > ret->val_field) \
p = p->rb_right; \
else \
return ret; \
} \
return NULL; \
}
/************/
/* Bootargs */
/************/
/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
* though; a comma-separated list of items, each item being a cpu index and/or a
* range of cpu indices, and each item optionally be prefixed by "s" to indicate
* that the portal associated with that cpu should be shared. See bman_driver.c
* for more specifics. */
static int __parse_portals_cpu(const char **s, unsigned int *cpu)
{
*cpu = 0;
if (!isdigit(**s))
return -EINVAL;
while (isdigit(**s))
*cpu = *cpu * 10 + (*((*s)++) - '0');
return 0;
}
static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
struct cpumask *want_unshared,
const char *argname)
{
const char *s = str;
unsigned int shared, cpu1, cpu2, loop;
keep_going:
if (*s == 's') {
shared = 1;
s++;
} else
shared = 0;
if (__parse_portals_cpu(&s, &cpu1))
goto err;
if (*s == '-') {
s++;
if (__parse_portals_cpu(&s, &cpu2))
goto err;
if (cpu2 < cpu1)
goto err;
} else
cpu2 = cpu1;
for (loop = cpu1; loop <= cpu2; loop++)
cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
if (*s == ',') {
s++;
goto keep_going;
} else if ((*s == '\0') || isspace(*s))
return 0;
err:
pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
(unsigned long)s - (unsigned long)str);
return -EINVAL;
}
#ifdef CONFIG_FSL_USDPAA
/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
int usdpaa_get_portal_config(struct file *filp, void *cinh,
enum usdpaa_portal_type ptype, unsigned int *irq,
void **iir_reg);
#endif
#endif /* DPA_SYS_H */