diff options
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/boards/board-ap325rxa.c | 63 | ||||
-rw-r--r-- | arch/sh/configs/ap325rxa_defconfig | 27 | ||||
-rw-r--r-- | arch/sh/configs/migor_defconfig | 42 | ||||
-rw-r--r-- | arch/sh/include/asm/mutex-llsc.h | 21 | ||||
-rw-r--r-- | arch/sh/include/asm/syscall_32.h | 22 | ||||
-rw-r--r-- | arch/sh/include/asm/syscall_64.h | 22 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/fpu.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/sh/kernel/signal_32.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/signal_64.c | 4 | ||||
-rw-r--r-- | arch/sh/lib/checksum.S | 69 |
11 files changed, 184 insertions, 100 deletions
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index caf4c33..7c35787 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/ov772x.h> #include <media/soc_camera_platform.h> #include <media/sh_mobile_ceu.h> #include <video/sh_mobile_lcdc.h> @@ -216,7 +217,14 @@ 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 +/* support for the old ncm03j camera */ static unsigned char camera_ncm03j_magic[] = { 0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8, @@ -237,6 +245,23 @@ static unsigned char camera_ncm03j_magic[] = 0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F, }; +static int camera_probe(void) +{ + struct i2c_adapter *a = i2c_get_adapter(0); + struct i2c_msg msg; + int ret; + + camera_power(1); + msg.addr = 0x6e; + msg.buf = camera_ncm03j_magic; + msg.len = 2; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + camera_power(0); + + return ret; +} + static int camera_set_capture(struct soc_camera_platform_info *info, int enable) { @@ -245,9 +270,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]; @@ -286,8 +313,35 @@ static struct platform_device camera_device = { .platform_data = &camera_info, }, }; + +static int __init camera_setup(void) +{ + if (camera_probe() > 0) + platform_device_register(&camera_device); + + return 0; +} +late_initcall(camera_setup); + #endif /* CONFIG_I2C */ +static int ov7725_power(struct device *dev, int mode) +{ + camera_power(0); + if (mode) + camera_power(1); + + return 0; +} + +static struct ov772x_camera_info ov7725_info = { + .buswidth = SOCAM_DATAWIDTH_8, + .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, + .link = { + .power = ov7725_power, + }, +}; + static struct sh_mobile_ceu_info sh_mobile_ceu_info = { .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, @@ -338,9 +392,6 @@ static struct platform_device *ap325rxa_devices[] __initdata = { &ap325rxa_nor_flash_device, &lcdc_device, &ceu_device, -#ifdef CONFIG_I2C - &camera_device, -#endif &nand_flash_device, &sdcard_cn3_device, }; @@ -349,6 +400,10 @@ static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = { { I2C_BOARD_INFO("pcf8563", 0x51), }, + { + I2C_BOARD_INFO("ov772x", 0x21), + .platform_data = &ov7725_info, + }, }; static struct spi_board_info ap325rxa_spi_devices[] = { @@ -426,7 +481,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 5c423fa..352f87d 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 7758263..6785767 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 ee839ee..090358a 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 05a868a..5bc3468 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 e1143b9..c3561ca 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/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c index 2780917..e3ea541 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 5342475..370d2cf 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 77c21bd..17784e1 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 b22fdfa..0663a0e 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 cbdd0d4..356c8ec 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 |