|
@@ -366,3 +366,152 @@ struct el_apecs_procdata
|
|
|
* I/O---everything goes over the PCI bus.
|
|
|
*
|
|
|
* There is plenty room for optimization here. In particular,
|
|
|
+ * the Alpha's insb/insw/extb/extw should be useful in moving
|
|
|
+ * data to/from the right byte-lanes.
|
|
|
+ */
|
|
|
+
|
|
|
+#define vip volatile int __force *
|
|
|
+#define vuip volatile unsigned int __force *
|
|
|
+#define vulp volatile unsigned long __force *
|
|
|
+
|
|
|
+#define APECS_SET_HAE \
|
|
|
+ do { \
|
|
|
+ if (addr >= (1UL << 24)) { \
|
|
|
+ unsigned long msb = addr & 0xf8000000; \
|
|
|
+ addr -= msb; \
|
|
|
+ set_hae(msb); \
|
|
|
+ } \
|
|
|
+ } while (0)
|
|
|
+
|
|
|
+__EXTERN_INLINE unsigned int apecs_ioread8(void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
+ unsigned long result, base_and_type;
|
|
|
+
|
|
|
+ if (addr >= APECS_DENSE_MEM) {
|
|
|
+ addr -= APECS_DENSE_MEM;
|
|
|
+ APECS_SET_HAE;
|
|
|
+ base_and_type = APECS_SPARSE_MEM + 0x00;
|
|
|
+ } else {
|
|
|
+ addr -= APECS_IO;
|
|
|
+ base_and_type = APECS_IO + 0x00;
|
|
|
+ }
|
|
|
+
|
|
|
+ result = *(vip) ((addr << 5) + base_and_type);
|
|
|
+ return __kernel_extbl(result, addr & 3);
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void apecs_iowrite8(u8 b, void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
+ unsigned long w, base_and_type;
|
|
|
+
|
|
|
+ if (addr >= APECS_DENSE_MEM) {
|
|
|
+ addr -= APECS_DENSE_MEM;
|
|
|
+ APECS_SET_HAE;
|
|
|
+ base_and_type = APECS_SPARSE_MEM + 0x00;
|
|
|
+ } else {
|
|
|
+ addr -= APECS_IO;
|
|
|
+ base_and_type = APECS_IO + 0x00;
|
|
|
+ }
|
|
|
+
|
|
|
+ w = __kernel_insbl(b, addr & 3);
|
|
|
+ *(vuip) ((addr << 5) + base_and_type) = w;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE unsigned int apecs_ioread16(void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
+ unsigned long result, base_and_type;
|
|
|
+
|
|
|
+ if (addr >= APECS_DENSE_MEM) {
|
|
|
+ addr -= APECS_DENSE_MEM;
|
|
|
+ APECS_SET_HAE;
|
|
|
+ base_and_type = APECS_SPARSE_MEM + 0x08;
|
|
|
+ } else {
|
|
|
+ addr -= APECS_IO;
|
|
|
+ base_and_type = APECS_IO + 0x08;
|
|
|
+ }
|
|
|
+
|
|
|
+ result = *(vip) ((addr << 5) + base_and_type);
|
|
|
+ return __kernel_extwl(result, addr & 3);
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void apecs_iowrite16(u16 b, void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
+ unsigned long w, base_and_type;
|
|
|
+
|
|
|
+ if (addr >= APECS_DENSE_MEM) {
|
|
|
+ addr -= APECS_DENSE_MEM;
|
|
|
+ APECS_SET_HAE;
|
|
|
+ base_and_type = APECS_SPARSE_MEM + 0x08;
|
|
|
+ } else {
|
|
|
+ addr -= APECS_IO;
|
|
|
+ base_and_type = APECS_IO + 0x08;
|
|
|
+ }
|
|
|
+
|
|
|
+ w = __kernel_inswl(b, addr & 3);
|
|
|
+ *(vuip) ((addr << 5) + base_and_type) = w;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE unsigned int apecs_ioread32(void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
+ if (addr < APECS_DENSE_MEM)
|
|
|
+ addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
|
|
|
+ return *(vuip)addr;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr;
|
|
|
+ if (addr < APECS_DENSE_MEM)
|
|
|
+ addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
|
|
|
+ *(vuip)addr = b;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr)
|
|
|
+{
|
|
|
+ return (void __iomem *)(addr + APECS_IO);
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void __iomem *apecs_ioremap(unsigned long addr,
|
|
|
+ unsigned long size)
|
|
|
+{
|
|
|
+ return (void __iomem *)(addr + APECS_DENSE_MEM);
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE int apecs_is_ioaddr(unsigned long addr)
|
|
|
+{
|
|
|
+ return addr >= IDENT_ADDR + 0x180000000UL;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE int apecs_is_mmio(const volatile void __iomem *addr)
|
|
|
+{
|
|
|
+ return (unsigned long)addr >= APECS_DENSE_MEM;
|
|
|
+}
|
|
|
+
|
|
|
+#undef APECS_SET_HAE
|
|
|
+
|
|
|
+#undef vip
|
|
|
+#undef vuip
|
|
|
+#undef vulp
|
|
|
+
|
|
|
+#undef __IO_PREFIX
|
|
|
+#define __IO_PREFIX apecs
|
|
|
+#define apecs_trivial_io_bw 0
|
|
|
+#define apecs_trivial_io_lq 0
|
|
|
+#define apecs_trivial_rw_bw 2
|
|
|
+#define apecs_trivial_rw_lq 1
|
|
|
+#define apecs_trivial_iounmap 1
|
|
|
+#include <asm/io_trivial.h>
|
|
|
+
|
|
|
+#ifdef __IO_EXTERN_INLINE
|
|
|
+#undef __EXTERN_INLINE
|
|
|
+#undef __IO_EXTERN_INLINE
|
|
|
+#endif
|
|
|
+
|
|
|
+#endif /* __KERNEL__ */
|
|
|
+
|
|
|
+#endif /* __ALPHA_APECS__H__ */
|