summaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/boards/board-ap325rxa.c11
-rw-r--r--arch/sh/configs/ap325rxa_defconfig27
-rw-r--r--arch/sh/configs/migor_defconfig42
-rw-r--r--arch/sh/include/asm/mutex-llsc.h21
-rw-r--r--arch/sh/include/asm/syscall_32.h22
-rw-r--r--arch/sh/include/asm/syscall_64.h22
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c4
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c2
-rw-r--r--arch/sh/kernel/setup.c8
-rw-r--r--arch/sh/kernel/signal_32.c4
-rw-r--r--arch/sh/kernel/signal_64.c4
-rw-r--r--arch/sh/lib/checksum.S69
12 files changed, 137 insertions, 99 deletions
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index caf4c33f4e84..15b6d450fbf0 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -22,6 +22,7 @@
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
+#include <media/soc_camera.h>
#include <media/soc_camera_platform.h>
#include <media/sh_mobile_ceu.h>
#include <video/sh_mobile_lcdc.h>
@@ -216,6 +217,12 @@ static struct platform_device lcdc_device = {
},
};
+static void camera_power(int val)
+{
+ gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
+ mdelay(10);
+}
+
#ifdef CONFIG_I2C
static unsigned char camera_ncm03j_magic[] =
{
@@ -245,9 +252,11 @@ static int camera_set_capture(struct soc_camera_platform_info *info,
int ret = 0;
int i;
+ camera_power(0);
if (!enable)
return 0; /* no disable for now */
+ camera_power(1);
for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
u_int8_t buf[8];
@@ -426,7 +435,7 @@ static int __init ap325rxa_devices_setup(void)
gpio_request(GPIO_PTZ6, NULL);
gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
gpio_request(GPIO_PTZ5, NULL);
- gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */
+ gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
gpio_request(GPIO_PTZ4, NULL);
gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 5c423fa8e6b8..352f87d50fdc 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:54:19 2009
+# Linux kernel version: 2.6.29-rc2
+# Tue Jan 27 11:45:08 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -45,12 +45,12 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -378,6 +378,7 @@ CONFIG_WIRELESS=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -400,6 +401,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
@@ -447,9 +449,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xffffffff
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -480,6 +480,12 @@ CONFIG_MTD_NAND_SH_FLCTL=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
# UBI - Unsorted block images
#
CONFIG_MTD_UBI=y
@@ -607,6 +613,10 @@ CONFIG_SMSC911X=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -790,6 +800,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -837,7 +848,7 @@ CONFIG_SOC_CAMERA=y
# CONFIG_SOC_CAMERA_MT9V022 is not set
# CONFIG_SOC_CAMERA_TW9910 is not set
CONFIG_SOC_CAMERA_PLATFORM=y
-# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_SOC_CAMERA_OV772X=y
CONFIG_VIDEO_SH_MOBILE_CEU=y
# CONFIG_RADIO_ADAPTERS is not set
# CONFIG_DAB is not set
@@ -1012,6 +1023,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1060,6 +1072,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_JFFS2_FS is not set
# CONFIG_UBIFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index 7758263514bc..678576796bdf 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:09:35 2009
+# Linux kernel version: 2.6.29-rc1
+# Thu Jan 22 09:16:16 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -45,8 +45,12 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+
+#
+# Control Group support
+#
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -389,6 +393,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -411,6 +416,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
@@ -458,9 +464,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xffffffff
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -488,6 +492,12 @@ CONFIG_MTD_NAND_PLATFORM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -587,6 +597,10 @@ CONFIG_SMC91X=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -761,6 +775,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -806,9 +821,9 @@ CONFIG_SOC_CAMERA=y
# CONFIG_SOC_CAMERA_MT9M111 is not set
# CONFIG_SOC_CAMERA_MT9T031 is not set
# CONFIG_SOC_CAMERA_MT9V022 is not set
-# CONFIG_SOC_CAMERA_TW9910 is not set
-CONFIG_SOC_CAMERA_PLATFORM=y
-# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_SOC_CAMERA_TW9910=y
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+CONFIG_SOC_CAMERA_OV772X=y
CONFIG_VIDEO_SH_MOBILE_CEU=y
# CONFIG_RADIO_ADAPTERS is not set
# CONFIG_DAB is not set
@@ -866,11 +881,13 @@ CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_PXA25X is not set
# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
CONFIG_USB_GADGET_M66592=y
CONFIG_USB_M66592=y
CONFIG_SUPERH_BUILT_IN_M66592=y
# CONFIG_USB_GADGET_AMD5536UDC is not set
# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
# CONFIG_USB_GADGET_NET2280 is not set
# CONFIG_USB_GADGET_GOKU is not set
# CONFIG_USB_GADGET_DUMMY_HCD is not set
@@ -883,6 +900,11 @@ CONFIG_USB_G_SERIAL=y
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -961,6 +983,7 @@ CONFIG_UIO_PDRV_GENIRQ=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -1004,6 +1027,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
diff --git a/arch/sh/include/asm/mutex-llsc.h b/arch/sh/include/asm/mutex-llsc.h
index ee839ee58ac8..090358a7e1bb 100644
--- a/arch/sh/include/asm/mutex-llsc.h
+++ b/arch/sh/include/asm/mutex-llsc.h
@@ -21,38 +21,36 @@
static inline void
__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
{
- int __ex_flag, __res;
+ int __done, __res;
__asm__ __volatile__ (
"movli.l @%2, %0 \n"
"add #-1, %0 \n"
"movco.l %0, @%2 \n"
"movt %1 \n"
- : "=&z" (__res), "=&r" (__ex_flag)
+ : "=&z" (__res), "=&r" (__done)
: "r" (&(count)->counter)
: "t");
- __res |= !__ex_flag;
- if (unlikely(__res != 0))
+ if (unlikely(!__done || __res != 0))
fail_fn(count);
}
static inline int
__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
{
- int __ex_flag, __res;
+ int __done, __res;
__asm__ __volatile__ (
"movli.l @%2, %0 \n"
"add #-1, %0 \n"
"movco.l %0, @%2 \n"
"movt %1 \n"
- : "=&z" (__res), "=&r" (__ex_flag)
+ : "=&z" (__res), "=&r" (__done)
: "r" (&(count)->counter)
: "t");
- __res |= !__ex_flag;
- if (unlikely(__res != 0))
+ if (unlikely(!__done || __res != 0))
__res = fail_fn(count);
return __res;
@@ -61,19 +59,18 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
static inline void
__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
{
- int __ex_flag, __res;
+ int __done, __res;
__asm__ __volatile__ (
"movli.l @%2, %0 \n\t"
"add #1, %0 \n\t"
"movco.l %0, @%2 \n\t"
"movt %1 \n\t"
- : "=&z" (__res), "=&r" (__ex_flag)
+ : "=&z" (__res), "=&r" (__done)
: "r" (&(count)->counter)
: "t");
- __res |= !__ex_flag;
- if (unlikely(__res <= 0))
+ if (unlikely(!__done || __res <= 0))
fail_fn(count);
}
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 05a868a71ef5..5bc34681d994 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -21,23 +21,10 @@ static inline void syscall_rollback(struct task_struct *task,
*/
}
-static inline bool syscall_has_error(struct pt_regs *regs)
-{
- return (regs->sr & 0x1) ? true : false;
-}
-static inline void syscall_set_error(struct pt_regs *regs)
-{
- regs->sr |= 0x1;
-}
-static inline void syscall_clear_error(struct pt_regs *regs)
-{
- regs->sr &= ~0x1;
-}
-
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
- return syscall_has_error(regs) ? regs->regs[0] : 0;
+ return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0;
}
static inline long syscall_get_return_value(struct task_struct *task,
@@ -50,13 +37,10 @@ static inline void syscall_set_return_value(struct task_struct *task,
struct pt_regs *regs,
int error, long val)
{
- if (error) {
- syscall_set_error(regs);
+ if (error)
regs->regs[0] = -error;
- } else {
- syscall_clear_error(regs);
+ else
regs->regs[0] = val;
- }
}
static inline void syscall_get_arguments(struct task_struct *task,
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h
index e1143b9784d6..c3561ca72bee 100644
--- a/arch/sh/include/asm/syscall_64.h
+++ b/arch/sh/include/asm/syscall_64.h
@@ -21,23 +21,10 @@ static inline void syscall_rollback(struct task_struct *task,
*/
}
-static inline bool syscall_has_error(struct pt_regs *regs)
-{
- return (regs->sr & 0x1) ? true : false;
-}
-static inline void syscall_set_error(struct pt_regs *regs)
-{
- regs->sr |= 0x1;
-}
-static inline void syscall_clear_error(struct pt_regs *regs)
-{
- regs->sr &= ~0x1;
-}
-
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
- return syscall_has_error(regs) ? regs->regs[9] : 0;
+ return IS_ERR_VALUE(regs->regs[9]) ? regs->regs[9] : 0;
}
static inline long syscall_get_return_value(struct task_struct *task,
@@ -50,13 +37,10 @@ static inline void syscall_set_return_value(struct task_struct *task,
struct pt_regs *regs,
int error, long val)
{
- if (error) {
- syscall_set_error(regs);
+ if (error)
regs->regs[9] = -error;
- } else {
- syscall_clear_error(regs);
+ else
regs->regs[9] = val;
- }
}
static inline void syscall_get_arguments(struct task_struct *task,
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
index 020a96fe961a..4a5e59732334 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -18,8 +18,8 @@
#include <asm/freq.h>
#include <asm/io.h>
-const static int pll1rate[]={1,2,3,4,6,8};
-const static int pfc_divisors[]={1,2,3,4,6,8,12};
+static const int pll1rate[]={1,2,3,4,6,8};
+static const int pfc_divisors[]={1,2,3,4,6,8,12};
#define ifc_divisors pfc_divisors
#if (CONFIG_SH_CLK_MD == 0)
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index 2780917c0088..e3ea5411da6d 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -423,7 +423,7 @@ static int ieee_fpe_handler(struct pt_regs *regs)
int m;
unsigned int hx;
- m = (finsn >> 9) & 0x7;
+ m = (finsn >> 8) & 0x7;
hx = tsk->thread.fpu.hard.fp_regs[m];
if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 534247508572..370d2cfa34eb 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -262,11 +262,11 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
BOOTMEM_DEFAULT);
/*
- * reserve physical page 0 - it's a special BIOS page on many boxes,
- * enabling clean reboots, SMP operation, laptop functions.
+ * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
*/
- reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
- BOOTMEM_DEFAULT);
+ if (CONFIG_ZERO_PAGE_OFFSET != 0)
+ reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
+ BOOTMEM_DEFAULT);
sparse_memory_present_with_active_regions(0);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 77c21bde376a..17784e19ae34 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -510,7 +510,6 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
case -ERESTARTNOHAND:
no_system_call_restart:
regs->regs[0] = -EINTR;
- regs->sr |= 1;
break;
case -ERESTARTSYS:
@@ -589,8 +588,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
- if (regs->sr & 1)
- handle_syscall_restart(save_r0, regs, &ka.sa);
+ handle_syscall_restart(save_r0, regs, &ka.sa);
/* Whee! Actually deliver the signal. */
if (handle_signal(signr, &ka, &info, oldset,
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index b22fdfaaa191..0663a0ee6021 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -60,7 +60,6 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
case -ERESTARTNOHAND:
no_system_call_restart:
regs->regs[REG_RET] = -EINTR;
- regs->sr |= 1;
break;
case -ERESTARTSYS:
@@ -109,8 +108,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
signr = get_signal_to_deliver(&info, &ka, regs, 0);
if (signr > 0) {
- if (regs->sr & 1)
- handle_syscall_restart(regs, &ka.sa);
+ handle_syscall_restart(regs, &ka.sa);
/* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S
index cbdd0d40e545..356c8ec92893 100644
--- a/arch/sh/lib/checksum.S
+++ b/arch/sh/lib/checksum.S
@@ -36,8 +36,7 @@
*/
/*
- * unsigned int csum_partial(const unsigned char *buf, int len,
- * unsigned int sum);
+ * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum);
*/
.text
@@ -49,11 +48,31 @@ ENTRY(csum_partial)
* Fortunately, it is easy to convert 2-byte alignment to 4-byte
* alignment for the unrolled loop.
*/
- mov r5, r1
mov r4, r0
- tst #2, r0 ! Check alignment.
- bt 2f ! Jump if alignment is ok.
+ tst #3, r0 ! Check alignment.
+ bt/s 2f ! Jump if alignment is ok.
+ mov r4, r7 ! Keep a copy to check for alignment
!
+ tst #1, r0 ! Check alignment.
+ bt 21f ! Jump if alignment is boundary of 2bytes.
+
+ ! buf is odd
+ tst r5, r5
+ add #-1, r5
+ bt 9f
+ mov.b @r4+, r0
+ extu.b r0, r0
+ addc r0, r6 ! t=0 from previous tst
+ mov r6, r0
+ shll8 r6
+ shlr16 r0
+ shlr8 r0
+ or r0, r6
+ mov r4, r0
+ tst #2, r0
+ bt 2f
+21:
+ ! buf is 2 byte aligned (len could be 0)
add #-2, r5 ! Alignment uses up two bytes.
cmp/pz r5 !
bt/s 1f ! Jump if we had at least two bytes.
@@ -61,16 +80,17 @@ ENTRY(csum_partial)
bra 6f
add #2, r5 ! r5 was < 2. Deal with it.
1:
- mov r5, r1 ! Save new len for later use.
mov.w @r4+, r0
extu.w r0, r0
addc r0, r6
bf 2f
add #1, r6
2:
+ ! buf is 4 byte aligned (len could be 0)
+ mov r5, r1
mov #-5, r0
- shld r0, r5
- tst r5, r5
+ shld r0, r1
+ tst r1, r1
bt/s 4f ! if it's =0, go to 4f
clrt
.align 2
@@ -92,30 +112,31 @@ ENTRY(csum_partial)
addc r0, r6
addc r2, r6
movt r0
- dt r5
+ dt r1
bf/s 3b
cmp/eq #1, r0
- ! here, we know r5==0
- addc r5, r6 ! add carry to r6
+ ! here, we know r1==0
+ addc r1, r6 ! add carry to r6
4:
- mov r1, r0
+ mov r5, r0
and #0x1c, r0
tst r0, r0
- bt/s 6f
- mov r0, r5
- shlr2 r5
+ bt 6f
+ ! 4 bytes or more remaining
+ mov r0, r1
+ shlr2 r1
mov #0, r2
5:
addc r2, r6
mov.l @r4+, r2
movt r0
- dt r5
+ dt r1
bf/s 5b
cmp/eq #1, r0
addc r2, r6
- addc r5, r6 ! r5==0 here, so it means add carry-bit
+ addc r1, r6 ! r1==0 here, so it means add carry-bit
6:
- mov r1, r5
+ ! 3 bytes or less remaining
mov #3, r0
and r0, r5
tst r5, r5
@@ -139,8 +160,18 @@ ENTRY(csum_partial)
8:
addc r0, r6
mov #0, r0
- addc r0, r6
+ addc r0, r6
9:
+ ! Check if the buffer was misaligned, if so realign sum
+ mov r7, r0
+ tst #1, r0
+ bt 10f
+ mov r6, r0
+ shll8 r6
+ shlr16 r0
+ shlr8 r0
+ or r0, r6
+10:
rts
mov r6, r0