@@ -548,11 +548,15 @@ struct gs_siglblid {
#define GS_DECLARE_VALID_REG(reg) \
bool gs_valid_##reg(void)
+#define GS_DECLARE_RQ_REG(reg) \
+ u64 gs_readq_##reg(void)
+
#define GS_DECLARE_WQ_REG(reg) \
void gs_writeq_##reg(u64 value)
#define GS_DECLARE_RW_REG(reg) \
GS_DECLARE_VALID_REG(reg); \
+ GS_DECLARE_RQ_REG(reg); \
GS_DECLARE_WQ_REG(reg)
/**
@@ -562,6 +566,7 @@ struct gs_siglblid {
* pattern. For example, the CSR register has the following functions::
*
* bool gs_valid_csr(void);
+ * u64 gs_readq_csr(void);
* void gs_writeq_csr(u64 value);
*
* gs_valid_csr() indicates whether CSR is readable, which is always true,
@@ -52,6 +52,14 @@ static struct {
} \
EXPORT_SYMBOL_GPL(gs_valid_##reg)
+/* Read-write registers are not shadowed and trivially read. */
+#define GS_DEFINE_RQ_RW_REG(reg, addr) \
+ u64 gs_readq_##reg(void) \
+ { \
+ return inq(addr); \
+ } \
+ EXPORT_SYMBOL_GPL(gs_readq_##reg)
+
/* Read-write registers are not shadowed and trivially write. */
#define GS_DEFINE_WQ_RW_REG(reg, addr) \
void gs_writeq_##reg(u64 value) \
@@ -73,6 +81,20 @@ static struct {
} \
EXPORT_SYMBOL_GPL(gs_valid_##reg)
+/* Write-only registers are shadowed and reading requires a previous write. */
+#define GS_DEFINE_RQ_WO_REG(reg, addr) \
+ u64 gs_readq_##reg(void) \
+ { \
+ unsigned long flags; \
+ u64 value; \
+ spin_lock_irqsave(&gs_registers.lock, flags); \
+ WARN_ON_ONCE(!gs_registers.reg.valid); \
+ value = gs_registers.reg.value; \
+ spin_unlock_irqrestore(&gs_registers.lock, flags); \
+ return value; \
+ } \
+ EXPORT_SYMBOL_GPL(gs_readq_##reg)
+
/* Write-only registers are shadowed and reading requires a previous write. */
#define GS_DEFINE_WQ_WO_REG(reg, addr) \
void gs_writeq_##reg(u64 value) \
@@ -89,11 +111,13 @@ static struct {
/* Only CSR and SIGLBLID are read-write (RW) with hardware. */
#define GS_DEFINE_RW_REG(reg, addr) \
GS_DEFINE_VALID_RW_REG(reg, addr); \
+ GS_DEFINE_RQ_RW_REG(reg, addr); \
GS_DEFINE_WQ_RW_REG(reg, addr)
/* The rest are write-only (WO) with reading emulated by shadow registers. */
#define GS_DEFINE_WO_REG(reg, addr) \
GS_DEFINE_VALID_WO_REG(reg, addr); \
+ GS_DEFINE_RQ_WO_REG(reg, addr); \
GS_DEFINE_WQ_WO_REG(reg, addr)
GS_DEFINE_WO_REG(pmode, GS_PMODE);
All privileged Graphics Synthesizer register functions follow the same pattern. For example, the reading the CSR register: u64 gs_readq_csr(void); Signed-off-by: Fredrik Noring <noring@nocrew.org> --- arch/mips/include/asm/mach-ps2/gs-registers.h | 5 ++++ drivers/ps2/gs-registers.c | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+)