162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * arch/sh/lib/io.c - SH32 optimized I/O routines 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2000 Stuart Menefy 662306a36Sopenharmony_ci * Copyright (C) 2005 Paul Mundt 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Provide real functions which expand to whatever the header file defined. 962306a36Sopenharmony_ci * Also definitions of machine independent IO functions. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#include <linux/module.h> 1262306a36Sopenharmony_ci#include <linux/io.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_civoid __raw_readsl(const void __iomem *addr, void *datap, int len) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci u32 *data; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci for (data = datap; (len != 0) && (((u32)data & 0x1f) != 0); len--) 1962306a36Sopenharmony_ci *data++ = __raw_readl(addr); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci if (likely(len >= (0x20 >> 2))) { 2262306a36Sopenharmony_ci int tmp2, tmp3, tmp4, tmp5, tmp6; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci __asm__ __volatile__( 2562306a36Sopenharmony_ci "1: \n\t" 2662306a36Sopenharmony_ci "mov.l @%7, r0 \n\t" 2762306a36Sopenharmony_ci "mov.l @%7, %2 \n\t" 2862306a36Sopenharmony_ci#ifdef CONFIG_CPU_SH4 2962306a36Sopenharmony_ci "movca.l r0, @%0 \n\t" 3062306a36Sopenharmony_ci#else 3162306a36Sopenharmony_ci "mov.l r0, @%0 \n\t" 3262306a36Sopenharmony_ci#endif 3362306a36Sopenharmony_ci "mov.l @%7, %3 \n\t" 3462306a36Sopenharmony_ci "mov.l @%7, %4 \n\t" 3562306a36Sopenharmony_ci "mov.l @%7, %5 \n\t" 3662306a36Sopenharmony_ci "mov.l @%7, %6 \n\t" 3762306a36Sopenharmony_ci "mov.l @%7, r7 \n\t" 3862306a36Sopenharmony_ci "mov.l @%7, r0 \n\t" 3962306a36Sopenharmony_ci "mov.l %2, @(0x04,%0) \n\t" 4062306a36Sopenharmony_ci "mov #0x20>>2, %2 \n\t" 4162306a36Sopenharmony_ci "mov.l %3, @(0x08,%0) \n\t" 4262306a36Sopenharmony_ci "sub %2, %1 \n\t" 4362306a36Sopenharmony_ci "mov.l %4, @(0x0c,%0) \n\t" 4462306a36Sopenharmony_ci "cmp/hi %1, %2 ! T if 32 > len \n\t" 4562306a36Sopenharmony_ci "mov.l %5, @(0x10,%0) \n\t" 4662306a36Sopenharmony_ci "mov.l %6, @(0x14,%0) \n\t" 4762306a36Sopenharmony_ci "mov.l r7, @(0x18,%0) \n\t" 4862306a36Sopenharmony_ci "mov.l r0, @(0x1c,%0) \n\t" 4962306a36Sopenharmony_ci "bf.s 1b \n\t" 5062306a36Sopenharmony_ci " add #0x20, %0 \n\t" 5162306a36Sopenharmony_ci : "=&r" (data), "=&r" (len), 5262306a36Sopenharmony_ci "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4), 5362306a36Sopenharmony_ci "=&r" (tmp5), "=&r" (tmp6) 5462306a36Sopenharmony_ci : "r"(addr), "0" (data), "1" (len) 5562306a36Sopenharmony_ci : "r0", "r7", "t", "memory"); 5662306a36Sopenharmony_ci } 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci for (; len != 0; len--) 5962306a36Sopenharmony_ci *data++ = __raw_readl(addr); 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ciEXPORT_SYMBOL(__raw_readsl); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_civoid __raw_writesl(void __iomem *addr, const void *data, int len) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci if (likely(len != 0)) { 6662306a36Sopenharmony_ci int tmp1; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci __asm__ __volatile__ ( 6962306a36Sopenharmony_ci "1: \n\t" 7062306a36Sopenharmony_ci "mov.l @%0+, %1 \n\t" 7162306a36Sopenharmony_ci "dt %3 \n\t" 7262306a36Sopenharmony_ci "bf.s 1b \n\t" 7362306a36Sopenharmony_ci " mov.l %1, @%4 \n\t" 7462306a36Sopenharmony_ci : "=&r" (data), "=&r" (tmp1) 7562306a36Sopenharmony_ci : "0" (data), "r" (len), "r"(addr) 7662306a36Sopenharmony_ci : "t", "memory"); 7762306a36Sopenharmony_ci } 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ciEXPORT_SYMBOL(__raw_writesl); 80