src/sys/dev/pci/drm/include/linux/iosys-map.h

139 lines
2.9 KiB
C

/* Public domain. */
#ifndef _LINUX_IOSYS_MAP_H
#define _LINUX_IOSYS_MAP_H
#include <linux/io.h>
#include <linux/string.h>
struct iosys_map {
union {
void *vaddr_iomem;
void *vaddr;
};
bool is_iomem;
bus_space_handle_t bsh;
bus_size_t size;
};
static inline void
iosys_map_incr(struct iosys_map *ism, size_t n)
{
if (ism->is_iomem)
ism->vaddr_iomem += n;
else
ism->vaddr += n;
}
static inline void
iosys_map_memcpy_to(struct iosys_map *ism, size_t off, const void *src,
size_t len)
{
if (ism->is_iomem)
memcpy_toio(ism->vaddr_iomem + off, src, len);
else
memcpy(ism->vaddr + off, src, len);
}
static inline void
iosys_map_memset(struct iosys_map *ism, size_t off, int c, size_t len)
{
if (ism->is_iomem)
memset_io(ism->vaddr_iomem + off, c, len);
else
memset(ism->vaddr + off, c, len);
}
static inline bool
iosys_map_is_null(const struct iosys_map *ism)
{
if (ism->is_iomem)
return (ism->vaddr_iomem == NULL);
else
return (ism->vaddr == NULL);
}
static inline bool
iosys_map_is_set(const struct iosys_map *ism)
{
if (ism->is_iomem)
return (ism->vaddr_iomem != NULL);
else
return (ism->vaddr != NULL);
}
static inline void
iosys_map_clear(struct iosys_map *ism)
{
if (ism->is_iomem) {
ism->vaddr_iomem = NULL;
ism->is_iomem = false;
} else {
ism->vaddr = NULL;
}
}
static inline void
iosys_map_set_vaddr_iomem(struct iosys_map *ism, void *addr)
{
ism->vaddr_iomem = addr;
ism->is_iomem = true;
}
static inline void
iosys_map_set_vaddr(struct iosys_map *ism, void *addr)
{
ism->vaddr = addr;
ism->is_iomem = false;
}
static inline struct iosys_map
IOSYS_MAP_INIT_OFFSET(struct iosys_map *ism, size_t off)
{
struct iosys_map nism = *ism;
iosys_map_incr(&nism, off);
return nism;
}
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112
#define iosys_map_rd(_ism, _o, _t) ({ \
_t v; \
if ((_ism)->is_iomem) { \
void *addr = (_ism)->vaddr_iomem + (_o); \
v = _Generic(v, \
uint8_t : ioread8(addr), \
uint16_t: ioread16(addr), \
uint32_t: ioread32(addr), \
uint64_t: ioread64(addr)); \
} else \
v = READ_ONCE(*(_t *)((_ism)->vaddr + (_o))); \
v; \
})
#define iosys_map_wr(_ism, _o, _t, _v) ({ \
_t v = (_v); \
if ((_ism)->is_iomem) { \
void *addr = (_ism)->vaddr_iomem + (_o); \
_Generic(v, \
uint8_t : iowrite8(v, addr), \
uint16_t: iowrite16(v, addr), \
uint32_t: iowrite32(v, addr), \
uint64_t: iowrite64(v, addr)); \
} else \
WRITE_ONCE(*(_t *)((_ism)->vaddr + (_o)), v); \
})
#define iosys_map_rd_field(_ism, _o, _t, _f) ({ \
_t *t; \
iosys_map_rd(_ism, _o + offsetof(_t, _f), __typeof(t->_f)); \
})
#define iosys_map_wr_field(_ism, _o, _t, _f, _v) ({ \
_t *t; \
iosys_map_wr(_ism, _o + offsetof(_t, _f), __typeof(t->_f), _v); \
})
#endif /* C11 */
#endif