diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-24 00:24:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-24 00:24:07 -0400 |
| commit | d762f4383100c2a87b1a3f2d678cd3b5425655b4 (patch) | |
| tree | e2a982fea165e77d3f7098717e887dbb28efc6d1 | |
| parent | 5214638384a968574a5ea3df1d3b3194da32a496 (diff) | |
| parent | 78207ffd0e00d39238f0a8a455a31a12659b30b3 (diff) | |
Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (23 commits)
sh: Ignore R_SH_NONE module relocations.
SH: SE7751: Fix pcibios_map_platform_irq prototype.
sh: remove warning and warning_symbol from struct stacktrace_ops
sh: wire up sys_sendmmsg.
clocksource: sh_tmu: Runtime PM support
clocksource: sh_tmu: __clocksource_updatefreq_hz() update
clocksource: sh_cmt: Runtime PM support
clocksource: sh_cmt: __clocksource_updatefreq_hz() update
dmaengine: shdma: synchronize RCU before freeing, simplify spinlock
dmaengine: shdma: add runtime- and system-level power management
dmaengine: shdma: fix locking
sh: sh-sci: sh7377 and sh73a0 build fixes
sh: cosmetic improvement: use an existing pointer
serial: sh-sci: suspend/resume wakeup support V2
serial: sh-sci: Runtime PM support
sh: select IRQ_FORCED_THREADING.
sh: intc: Set virtual IRQs as nothread.
sh: fixup fpu.o compile order
i2c: add a module alias to the sh-mobile driver
ALSA: add a module alias to the FSI driver
...
26 files changed, 235 insertions, 157 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index bc439de48cd1..b44e37753b9a 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
| @@ -21,6 +21,7 @@ config SUPERH | |||
| 21 | select HAVE_REGS_AND_STACK_ACCESS_API | 21 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 22 | select HAVE_GENERIC_HARDIRQS | 22 | select HAVE_GENERIC_HARDIRQS |
| 23 | select HAVE_SPARSE_IRQ | 23 | select HAVE_SPARSE_IRQ |
| 24 | select IRQ_FORCED_THREADING | ||
| 24 | select RTC_LIB | 25 | select RTC_LIB |
| 25 | select GENERIC_ATOMIC64 | 26 | select GENERIC_ATOMIC64 |
| 26 | select GENERIC_IRQ_SHOW | 27 | select GENERIC_IRQ_SHOW |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 86a0d565aded..bb13d0e1b964 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
| @@ -482,7 +482,7 @@ static struct i2c_board_info ts_i2c_clients = { | |||
| 482 | .irq = IRQ0, | 482 | .irq = IRQ0, |
| 483 | }; | 483 | }; |
| 484 | 484 | ||
| 485 | #if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE) | 485 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
| 486 | /* SDHI0 */ | 486 | /* SDHI0 */ |
| 487 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) | 487 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) |
| 488 | { | 488 | { |
| @@ -522,7 +522,7 @@ static struct platform_device sdhi0_device = { | |||
| 522 | }, | 522 | }, |
| 523 | }; | 523 | }; |
| 524 | 524 | ||
| 525 | #if !defined(CONFIG_MMC_SH_MMCIF) | 525 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 526 | /* SDHI1 */ | 526 | /* SDHI1 */ |
| 527 | static void sdhi1_set_pwr(struct platform_device *pdev, int state) | 527 | static void sdhi1_set_pwr(struct platform_device *pdev, int state) |
| 528 | { | 528 | { |
| @@ -836,7 +836,7 @@ static struct platform_device vou_device = { | |||
| 836 | }, | 836 | }, |
| 837 | }; | 837 | }; |
| 838 | 838 | ||
| 839 | #if defined(CONFIG_MMC_SH_MMCIF) | 839 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 840 | /* SH_MMCIF */ | 840 | /* SH_MMCIF */ |
| 841 | static void mmcif_set_pwr(struct platform_device *pdev, int state) | 841 | static void mmcif_set_pwr(struct platform_device *pdev, int state) |
| 842 | { | 842 | { |
| @@ -898,9 +898,9 @@ static struct platform_device *ecovec_devices[] __initdata = { | |||
| 898 | &ceu0_device, | 898 | &ceu0_device, |
| 899 | &ceu1_device, | 899 | &ceu1_device, |
| 900 | &keysc_device, | 900 | &keysc_device, |
| 901 | #if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE) | 901 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
| 902 | &sdhi0_device, | 902 | &sdhi0_device, |
| 903 | #if !defined(CONFIG_MMC_SH_MMCIF) | 903 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 904 | &sdhi1_device, | 904 | &sdhi1_device, |
| 905 | #endif | 905 | #endif |
| 906 | #else | 906 | #else |
| @@ -912,7 +912,7 @@ static struct platform_device *ecovec_devices[] __initdata = { | |||
| 912 | &fsi_device, | 912 | &fsi_device, |
| 913 | &irda_device, | 913 | &irda_device, |
| 914 | &vou_device, | 914 | &vou_device, |
| 915 | #if defined(CONFIG_MMC_SH_MMCIF) | 915 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 916 | &sh_mmcif_device, | 916 | &sh_mmcif_device, |
| 917 | #endif | 917 | #endif |
| 918 | }; | 918 | }; |
| @@ -1180,7 +1180,7 @@ static int __init arch_setup(void) | |||
| 1180 | gpio_direction_input(GPIO_PTR5); | 1180 | gpio_direction_input(GPIO_PTR5); |
| 1181 | gpio_direction_input(GPIO_PTR6); | 1181 | gpio_direction_input(GPIO_PTR6); |
| 1182 | 1182 | ||
| 1183 | #if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE) | 1183 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
| 1184 | /* enable SDHI0 on CN11 (needs DS2.4 set to ON) */ | 1184 | /* enable SDHI0 on CN11 (needs DS2.4 set to ON) */ |
| 1185 | gpio_request(GPIO_FN_SDHI0CD, NULL); | 1185 | gpio_request(GPIO_FN_SDHI0CD, NULL); |
| 1186 | gpio_request(GPIO_FN_SDHI0WP, NULL); | 1186 | gpio_request(GPIO_FN_SDHI0WP, NULL); |
| @@ -1193,7 +1193,7 @@ static int __init arch_setup(void) | |||
| 1193 | gpio_request(GPIO_PTB6, NULL); | 1193 | gpio_request(GPIO_PTB6, NULL); |
| 1194 | gpio_direction_output(GPIO_PTB6, 0); | 1194 | gpio_direction_output(GPIO_PTB6, 0); |
| 1195 | 1195 | ||
| 1196 | #if !defined(CONFIG_MMC_SH_MMCIF) | 1196 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 1197 | /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */ | 1197 | /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */ |
| 1198 | gpio_request(GPIO_FN_SDHI1CD, NULL); | 1198 | gpio_request(GPIO_FN_SDHI1CD, NULL); |
| 1199 | gpio_request(GPIO_FN_SDHI1WP, NULL); | 1199 | gpio_request(GPIO_FN_SDHI1WP, NULL); |
| @@ -1284,7 +1284,7 @@ static int __init arch_setup(void) | |||
| 1284 | gpio_request(GPIO_PTU5, NULL); | 1284 | gpio_request(GPIO_PTU5, NULL); |
| 1285 | gpio_direction_output(GPIO_PTU5, 0); | 1285 | gpio_direction_output(GPIO_PTU5, 0); |
| 1286 | 1286 | ||
| 1287 | #if defined(CONFIG_MMC_SH_MMCIF) | 1287 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 1288 | /* enable MMCIF (needs DS2.6,7 set to OFF,ON) */ | 1288 | /* enable MMCIF (needs DS2.6,7 set to OFF,ON) */ |
| 1289 | gpio_request(GPIO_FN_MMC_D7, NULL); | 1289 | gpio_request(GPIO_FN_MMC_D7, NULL); |
| 1290 | gpio_request(GPIO_FN_MMC_D6, NULL); | 1290 | gpio_request(GPIO_FN_MMC_D6, NULL); |
diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 8d13e8a5a750..911e30c9abfd 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig | |||
| @@ -115,7 +115,7 @@ CONFIG_USB_GADGET=y | |||
| 115 | CONFIG_USB_FILE_STORAGE=m | 115 | CONFIG_USB_FILE_STORAGE=m |
| 116 | CONFIG_MMC=y | 116 | CONFIG_MMC=y |
| 117 | CONFIG_MMC_SPI=y | 117 | CONFIG_MMC_SPI=y |
| 118 | CONFIG_MMC_TMIO=y | 118 | CONFIG_MMC_SDHI=y |
| 119 | CONFIG_RTC_CLASS=y | 119 | CONFIG_RTC_CLASS=y |
| 120 | CONFIG_RTC_DRV_RS5C372=y | 120 | CONFIG_RTC_DRV_RS5C372=y |
| 121 | CONFIG_UIO=y | 121 | CONFIG_UIO=y |
diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig index fa0ecf87034c..33ddb130a7c8 100644 --- a/arch/sh/configs/sh7757lcr_defconfig +++ b/arch/sh/configs/sh7757lcr_defconfig | |||
| @@ -70,7 +70,7 @@ CONFIG_USB_EHCI_HCD=y | |||
| 70 | CONFIG_USB_OHCI_HCD=y | 70 | CONFIG_USB_OHCI_HCD=y |
| 71 | CONFIG_USB_STORAGE=y | 71 | CONFIG_USB_STORAGE=y |
| 72 | CONFIG_MMC=y | 72 | CONFIG_MMC=y |
| 73 | CONFIG_MMC_TMIO=y | 73 | CONFIG_MMC_SDHI=y |
| 74 | CONFIG_MMC_SH_MMCIF=y | 74 | CONFIG_MMC_SH_MMCIF=y |
| 75 | CONFIG_EXT2_FS=y | 75 | CONFIG_EXT2_FS=y |
| 76 | CONFIG_EXT3_FS=y | 76 | CONFIG_EXT3_FS=y |
diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index a4c7d3a4efca..fd3e6b02f289 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include <linux/io.h> | 6 | #include <linux/io.h> |
| 7 | #include "pci-sh4.h" | 7 | #include "pci-sh4.h" |
| 8 | 8 | ||
| 9 | int __init pcibios_map_platform_irq(u8 slot, u8 pin) | 9 | int __init pcibios_map_platform_irq(struct pci_dev *, u8 slot, u8 pin) |
| 10 | { | 10 | { |
| 11 | switch (slot) { | 11 | switch (slot) { |
| 12 | case 0: return 13; | 12 | case 0: return 13; |
diff --git a/arch/sh/include/asm/stacktrace.h b/arch/sh/include/asm/stacktrace.h index 797018213718..a7e2d4dfd087 100644 --- a/arch/sh/include/asm/stacktrace.h +++ b/arch/sh/include/asm/stacktrace.h | |||
| @@ -10,9 +10,6 @@ | |||
| 10 | /* Generic stack tracer with callbacks */ | 10 | /* Generic stack tracer with callbacks */ |
| 11 | 11 | ||
| 12 | struct stacktrace_ops { | 12 | struct stacktrace_ops { |
| 13 | void (*warning)(void *data, char *msg); | ||
| 14 | /* msg must contain %s for the symbol */ | ||
| 15 | void (*warning_symbol)(void *data, char *msg, unsigned long symbol); | ||
| 16 | void (*address)(void *data, unsigned long address, int reliable); | 13 | void (*address)(void *data, unsigned long address, int reliable); |
| 17 | /* On negative return stop dumping */ | 14 | /* On negative return stop dumping */ |
| 18 | int (*stack)(void *data, char *name); | 15 | int (*stack)(void *data, char *name); |
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index ca7765e5f967..bb7d2702c2c9 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h | |||
| @@ -373,8 +373,9 @@ | |||
| 373 | #define __NR_open_by_handle_at 360 | 373 | #define __NR_open_by_handle_at 360 |
| 374 | #define __NR_clock_adjtime 361 | 374 | #define __NR_clock_adjtime 361 |
| 375 | #define __NR_syncfs 362 | 375 | #define __NR_syncfs 362 |
| 376 | #define __NR_sendmmsg 363 | ||
| 376 | 377 | ||
| 377 | #define NR_syscalls 363 | 378 | #define NR_syscalls 364 |
| 378 | 379 | ||
| 379 | #ifdef __KERNEL__ | 380 | #ifdef __KERNEL__ |
| 380 | 381 | ||
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h index a694009bb816..46327cea1e5c 100644 --- a/arch/sh/include/asm/unistd_64.h +++ b/arch/sh/include/asm/unistd_64.h | |||
| @@ -394,10 +394,11 @@ | |||
| 394 | #define __NR_open_by_handle_at 371 | 394 | #define __NR_open_by_handle_at 371 |
| 395 | #define __NR_clock_adjtime 372 | 395 | #define __NR_clock_adjtime 372 |
| 396 | #define __NR_syncfs 373 | 396 | #define __NR_syncfs 373 |
| 397 | #define __NR_sendmmsg 374 | ||
| 397 | 398 | ||
| 398 | #ifdef __KERNEL__ | 399 | #ifdef __KERNEL__ |
| 399 | 400 | ||
| 400 | #define NR_syscalls 374 | 401 | #define NR_syscalls 375 |
| 401 | 402 | ||
| 402 | #define __ARCH_WANT_IPC_PARSE_VERSION | 403 | #define __ARCH_WANT_IPC_PARSE_VERSION |
| 403 | #define __ARCH_WANT_OLD_READDIR | 404 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index d49c2135fd48..ae95935d93cd 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile | |||
| @@ -17,7 +17,5 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/ | |||
| 17 | 17 | ||
| 18 | obj-$(CONFIG_SH_ADC) += adc.o | 18 | obj-$(CONFIG_SH_ADC) += adc.o |
| 19 | obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o | 19 | obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o |
| 20 | obj-$(CONFIG_SH_FPU) += fpu.o | ||
| 21 | obj-$(CONFIG_SH_FPU_EMU) += fpu.o | ||
| 22 | 20 | ||
| 23 | obj-y += irq/ init.o clock.o hwblk.o proc.o | 21 | obj-y += irq/ init.o clock.o fpu.o hwblk.o proc.o |
diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c index 22db127afa7b..64c807c39208 100644 --- a/arch/sh/kernel/cpu/shmobile/pm_runtime.c +++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c | |||
| @@ -157,7 +157,7 @@ static int default_platform_runtime_suspend(struct device *dev) | |||
| 157 | might_sleep(); | 157 | might_sleep(); |
| 158 | 158 | ||
| 159 | /* catch misconfigured drivers not starting with resume */ | 159 | /* catch misconfigured drivers not starting with resume */ |
| 160 | if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags)) { | 160 | if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &ad->flags)) { |
| 161 | ret = -EINVAL; | 161 | ret = -EINVAL; |
| 162 | goto out; | 162 | goto out; |
| 163 | } | 163 | } |
| @@ -170,8 +170,8 @@ static int default_platform_runtime_suspend(struct device *dev) | |||
| 170 | 170 | ||
| 171 | /* put device on idle list */ | 171 | /* put device on idle list */ |
| 172 | spin_lock_irqsave(&hwblk_lock, flags); | 172 | spin_lock_irqsave(&hwblk_lock, flags); |
| 173 | list_add_tail(&pdev->archdata.entry, &hwblk_idle_list); | 173 | list_add_tail(&ad->entry, &hwblk_idle_list); |
| 174 | __set_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags); | 174 | __set_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags); |
| 175 | spin_unlock_irqrestore(&hwblk_lock, flags); | 175 | spin_unlock_irqrestore(&hwblk_lock, flags); |
| 176 | 176 | ||
| 177 | /* increase idle count */ | 177 | /* increase idle count */ |
diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c index 6f5ad1513409..694158b9a50f 100644 --- a/arch/sh/kernel/dumpstack.c +++ b/arch/sh/kernel/dumpstack.c | |||
| @@ -69,19 +69,6 @@ stack_reader_dump(struct task_struct *task, struct pt_regs *regs, | |||
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static void | ||
| 73 | print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) | ||
| 74 | { | ||
| 75 | printk(data); | ||
| 76 | print_symbol(msg, symbol); | ||
| 77 | printk("\n"); | ||
| 78 | } | ||
| 79 | |||
| 80 | static void print_trace_warning(void *data, char *msg) | ||
| 81 | { | ||
| 82 | printk("%s%s\n", (char *)data, msg); | ||
| 83 | } | ||
| 84 | |||
| 85 | static int print_trace_stack(void *data, char *name) | 72 | static int print_trace_stack(void *data, char *name) |
| 86 | { | 73 | { |
| 87 | printk("%s <%s> ", (char *)data, name); | 74 | printk("%s <%s> ", (char *)data, name); |
| @@ -98,8 +85,6 @@ static void print_trace_address(void *data, unsigned long addr, int reliable) | |||
| 98 | } | 85 | } |
| 99 | 86 | ||
| 100 | static const struct stacktrace_ops print_trace_ops = { | 87 | static const struct stacktrace_ops print_trace_ops = { |
| 101 | .warning = print_trace_warning, | ||
| 102 | .warning_symbol = print_trace_warning_symbol, | ||
| 103 | .stack = print_trace_stack, | 88 | .stack = print_trace_stack, |
| 104 | .address = print_trace_address, | 89 | .address = print_trace_address, |
| 105 | }; | 90 | }; |
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c index ae0be697a89e..19b1f8826aef 100644 --- a/arch/sh/kernel/module.c +++ b/arch/sh/kernel/module.c | |||
| @@ -93,6 +93,8 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
| 93 | #endif | 93 | #endif |
| 94 | 94 | ||
| 95 | switch (ELF32_R_TYPE(rel[i].r_info)) { | 95 | switch (ELF32_R_TYPE(rel[i].r_info)) { |
| 96 | case R_SH_NONE: | ||
| 97 | break; | ||
| 96 | case R_SH_DIR32: | 98 | case R_SH_DIR32: |
| 97 | value = get_unaligned(location); | 99 | value = get_unaligned(location); |
| 98 | value += relocation; | 100 | value += relocation; |
diff --git a/arch/sh/kernel/perf_callchain.c b/arch/sh/kernel/perf_callchain.c index d5ca1ef50fa9..cc80b614b5fa 100644 --- a/arch/sh/kernel/perf_callchain.c +++ b/arch/sh/kernel/perf_callchain.c | |||
| @@ -14,16 +14,6 @@ | |||
| 14 | #include <asm/unwinder.h> | 14 | #include <asm/unwinder.h> |
| 15 | #include <asm/ptrace.h> | 15 | #include <asm/ptrace.h> |
| 16 | 16 | ||
| 17 | |||
| 18 | static void callchain_warning(void *data, char *msg) | ||
| 19 | { | ||
| 20 | } | ||
| 21 | |||
| 22 | static void | ||
| 23 | callchain_warning_symbol(void *data, char *msg, unsigned long symbol) | ||
| 24 | { | ||
| 25 | } | ||
| 26 | |||
| 27 | static int callchain_stack(void *data, char *name) | 17 | static int callchain_stack(void *data, char *name) |
| 28 | { | 18 | { |
| 29 | return 0; | 19 | return 0; |
| @@ -38,8 +28,6 @@ static void callchain_address(void *data, unsigned long addr, int reliable) | |||
| 38 | } | 28 | } |
| 39 | 29 | ||
| 40 | static const struct stacktrace_ops callchain_ops = { | 30 | static const struct stacktrace_ops callchain_ops = { |
| 41 | .warning = callchain_warning, | ||
| 42 | .warning_symbol = callchain_warning_symbol, | ||
| 43 | .stack = callchain_stack, | 31 | .stack = callchain_stack, |
| 44 | .address = callchain_address, | 32 | .address = callchain_address, |
| 45 | }; | 33 | }; |
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c index c2e45c48409c..bf989e063a0c 100644 --- a/arch/sh/kernel/stacktrace.c +++ b/arch/sh/kernel/stacktrace.c | |||
| @@ -17,15 +17,6 @@ | |||
| 17 | #include <asm/ptrace.h> | 17 | #include <asm/ptrace.h> |
| 18 | #include <asm/stacktrace.h> | 18 | #include <asm/stacktrace.h> |
| 19 | 19 | ||
| 20 | static void save_stack_warning(void *data, char *msg) | ||
| 21 | { | ||
| 22 | } | ||
| 23 | |||
| 24 | static void | ||
| 25 | save_stack_warning_symbol(void *data, char *msg, unsigned long symbol) | ||
| 26 | { | ||
| 27 | } | ||
| 28 | |||
| 29 | static int save_stack_stack(void *data, char *name) | 20 | static int save_stack_stack(void *data, char *name) |
| 30 | { | 21 | { |
| 31 | return 0; | 22 | return 0; |
| @@ -51,8 +42,6 @@ static void save_stack_address(void *data, unsigned long addr, int reliable) | |||
| 51 | } | 42 | } |
| 52 | 43 | ||
| 53 | static const struct stacktrace_ops save_stack_ops = { | 44 | static const struct stacktrace_ops save_stack_ops = { |
| 54 | .warning = save_stack_warning, | ||
| 55 | .warning_symbol = save_stack_warning_symbol, | ||
| 56 | .stack = save_stack_stack, | 45 | .stack = save_stack_stack, |
| 57 | .address = save_stack_address, | 46 | .address = save_stack_address, |
| 58 | }; | 47 | }; |
| @@ -88,8 +77,6 @@ save_stack_address_nosched(void *data, unsigned long addr, int reliable) | |||
| 88 | } | 77 | } |
| 89 | 78 | ||
| 90 | static const struct stacktrace_ops save_stack_ops_nosched = { | 79 | static const struct stacktrace_ops save_stack_ops_nosched = { |
| 91 | .warning = save_stack_warning, | ||
| 92 | .warning_symbol = save_stack_warning_symbol, | ||
| 93 | .stack = save_stack_stack, | 80 | .stack = save_stack_stack, |
| 94 | .address = save_stack_address_nosched, | 81 | .address = save_stack_address_nosched, |
| 95 | }; | 82 | }; |
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 030966a9305c..7c486f3e3a3c 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S | |||
| @@ -380,3 +380,4 @@ ENTRY(sys_call_table) | |||
| 380 | .long sys_open_by_handle_at /* 360 */ | 380 | .long sys_open_by_handle_at /* 360 */ |
| 381 | .long sys_clock_adjtime | 381 | .long sys_clock_adjtime |
| 382 | .long sys_syncfs | 382 | .long sys_syncfs |
| 383 | .long sys_sendmmsg | ||
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index ca0a6142ab63..ba1a737afe80 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S | |||
| @@ -400,3 +400,4 @@ sys_call_table: | |||
| 400 | .long sys_open_by_handle_at | 400 | .long sys_open_by_handle_at |
| 401 | .long sys_clock_adjtime | 401 | .long sys_clock_adjtime |
| 402 | .long sys_syncfs | 402 | .long sys_syncfs |
| 403 | .long sys_sendmmsg | ||
diff --git a/arch/sh/oprofile/backtrace.c b/arch/sh/oprofile/backtrace.c index 37f3a75ea6cb..9c88dcd56e86 100644 --- a/arch/sh/oprofile/backtrace.c +++ b/arch/sh/oprofile/backtrace.c | |||
| @@ -23,17 +23,6 @@ | |||
| 23 | #include <asm/sections.h> | 23 | #include <asm/sections.h> |
| 24 | #include <asm/stacktrace.h> | 24 | #include <asm/stacktrace.h> |
| 25 | 25 | ||
| 26 | static void backtrace_warning_symbol(void *data, char *msg, | ||
| 27 | unsigned long symbol) | ||
| 28 | { | ||
| 29 | /* Ignore warnings */ | ||
| 30 | } | ||
| 31 | |||
| 32 | static void backtrace_warning(void *data, char *msg) | ||
| 33 | { | ||
| 34 | /* Ignore warnings */ | ||
| 35 | } | ||
| 36 | |||
| 37 | static int backtrace_stack(void *data, char *name) | 26 | static int backtrace_stack(void *data, char *name) |
| 38 | { | 27 | { |
| 39 | /* Yes, we want all stacks */ | 28 | /* Yes, we want all stacks */ |
| @@ -49,8 +38,6 @@ static void backtrace_address(void *data, unsigned long addr, int reliable) | |||
| 49 | } | 38 | } |
| 50 | 39 | ||
| 51 | static struct stacktrace_ops backtrace_ops = { | 40 | static struct stacktrace_ops backtrace_ops = { |
| 52 | .warning = backtrace_warning, | ||
| 53 | .warning_symbol = backtrace_warning_symbol, | ||
| 54 | .stack = backtrace_stack, | 41 | .stack = backtrace_stack, |
| 55 | .address = backtrace_address, | 42 | .address = backtrace_address, |
| 56 | }; | 43 | }; |
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index f975d24890fa..036e5865eb40 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/ioport.h> | 24 | #include <linux/ioport.h> |
| 25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
| 27 | #include <linux/pm_runtime.h> | ||
| 27 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
| 28 | #include <linux/err.h> | 29 | #include <linux/err.h> |
| 29 | #include <linux/clocksource.h> | 30 | #include <linux/clocksource.h> |
| @@ -152,10 +153,12 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) | |||
| 152 | { | 153 | { |
| 153 | int ret; | 154 | int ret; |
| 154 | 155 | ||
| 155 | /* enable clock */ | 156 | /* wake up device and enable clock */ |
| 157 | pm_runtime_get_sync(&p->pdev->dev); | ||
| 156 | ret = clk_enable(p->clk); | 158 | ret = clk_enable(p->clk); |
| 157 | if (ret) { | 159 | if (ret) { |
| 158 | dev_err(&p->pdev->dev, "cannot enable clock\n"); | 160 | dev_err(&p->pdev->dev, "cannot enable clock\n"); |
| 161 | pm_runtime_put_sync(&p->pdev->dev); | ||
| 159 | return ret; | 162 | return ret; |
| 160 | } | 163 | } |
| 161 | 164 | ||
| @@ -187,8 +190,9 @@ static void sh_cmt_disable(struct sh_cmt_priv *p) | |||
| 187 | /* disable interrupts in CMT block */ | 190 | /* disable interrupts in CMT block */ |
| 188 | sh_cmt_write(p, CMCSR, 0); | 191 | sh_cmt_write(p, CMCSR, 0); |
| 189 | 192 | ||
| 190 | /* stop clock */ | 193 | /* stop clock and mark device as idle */ |
| 191 | clk_disable(p->clk); | 194 | clk_disable(p->clk); |
| 195 | pm_runtime_put_sync(&p->pdev->dev); | ||
| 192 | } | 196 | } |
| 193 | 197 | ||
| 194 | /* private flags */ | 198 | /* private flags */ |
| @@ -416,11 +420,15 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) | |||
| 416 | 420 | ||
| 417 | static int sh_cmt_clocksource_enable(struct clocksource *cs) | 421 | static int sh_cmt_clocksource_enable(struct clocksource *cs) |
| 418 | { | 422 | { |
| 423 | int ret; | ||
| 419 | struct sh_cmt_priv *p = cs_to_sh_cmt(cs); | 424 | struct sh_cmt_priv *p = cs_to_sh_cmt(cs); |
| 420 | 425 | ||
| 421 | p->total_cycles = 0; | 426 | p->total_cycles = 0; |
| 422 | 427 | ||
| 423 | return sh_cmt_start(p, FLAG_CLOCKSOURCE); | 428 | ret = sh_cmt_start(p, FLAG_CLOCKSOURCE); |
| 429 | if (!ret) | ||
| 430 | __clocksource_updatefreq_hz(cs, p->rate); | ||
| 431 | return ret; | ||
| 424 | } | 432 | } |
| 425 | 433 | ||
| 426 | static void sh_cmt_clocksource_disable(struct clocksource *cs) | 434 | static void sh_cmt_clocksource_disable(struct clocksource *cs) |
| @@ -448,19 +456,10 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, | |||
| 448 | cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); | 456 | cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); |
| 449 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; | 457 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; |
| 450 | 458 | ||
| 451 | /* clk_get_rate() needs an enabled clock */ | ||
| 452 | clk_enable(p->clk); | ||
| 453 | p->rate = clk_get_rate(p->clk) / ((p->width == 16) ? 512 : 8); | ||
| 454 | clk_disable(p->clk); | ||
| 455 | |||
| 456 | /* TODO: calculate good shift from rate and counter bit width */ | ||
| 457 | cs->shift = 0; | ||
| 458 | cs->mult = clocksource_hz2mult(p->rate, cs->shift); | ||
| 459 | |||
| 460 | dev_info(&p->pdev->dev, "used as clock source\n"); | 459 | dev_info(&p->pdev->dev, "used as clock source\n"); |
| 461 | 460 | ||
| 462 | clocksource_register(cs); | 461 | /* Register with dummy 1 Hz value, gets updated in ->enable() */ |
| 463 | 462 | clocksource_register_hz(cs, 1); | |
| 464 | return 0; | 463 | return 0; |
| 465 | } | 464 | } |
| 466 | 465 | ||
| @@ -665,6 +664,7 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) | |||
| 665 | 664 | ||
| 666 | if (p) { | 665 | if (p) { |
| 667 | dev_info(&pdev->dev, "kept as earlytimer\n"); | 666 | dev_info(&pdev->dev, "kept as earlytimer\n"); |
| 667 | pm_runtime_enable(&pdev->dev); | ||
| 668 | return 0; | 668 | return 0; |
| 669 | } | 669 | } |
| 670 | 670 | ||
| @@ -679,6 +679,9 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) | |||
| 679 | kfree(p); | 679 | kfree(p); |
| 680 | platform_set_drvdata(pdev, NULL); | 680 | platform_set_drvdata(pdev, NULL); |
| 681 | } | 681 | } |
| 682 | |||
| 683 | if (!is_early_platform_device(pdev)) | ||
| 684 | pm_runtime_enable(&pdev->dev); | ||
| 682 | return ret; | 685 | return ret; |
| 683 | } | 686 | } |
| 684 | 687 | ||
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 36aba9923060..17296288a205 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
| 26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
| 27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
| 28 | #include <linux/pm_runtime.h> | ||
| 28 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
| 29 | #include <linux/err.h> | 30 | #include <linux/err.h> |
| 30 | #include <linux/clocksource.h> | 31 | #include <linux/clocksource.h> |
| @@ -109,10 +110,12 @@ static int sh_tmu_enable(struct sh_tmu_priv *p) | |||
| 109 | { | 110 | { |
| 110 | int ret; | 111 | int ret; |
| 111 | 112 | ||
| 112 | /* enable clock */ | 113 | /* wake up device and enable clock */ |
| 114 | pm_runtime_get_sync(&p->pdev->dev); | ||
| 113 | ret = clk_enable(p->clk); | 115 | ret = clk_enable(p->clk); |
| 114 | if (ret) { | 116 | if (ret) { |
| 115 | dev_err(&p->pdev->dev, "cannot enable clock\n"); | 117 | dev_err(&p->pdev->dev, "cannot enable clock\n"); |
| 118 | pm_runtime_put_sync(&p->pdev->dev); | ||
| 116 | return ret; | 119 | return ret; |
| 117 | } | 120 | } |
| 118 | 121 | ||
| @@ -141,8 +144,9 @@ static void sh_tmu_disable(struct sh_tmu_priv *p) | |||
| 141 | /* disable interrupts in TMU block */ | 144 | /* disable interrupts in TMU block */ |
| 142 | sh_tmu_write(p, TCR, 0x0000); | 145 | sh_tmu_write(p, TCR, 0x0000); |
| 143 | 146 | ||
| 144 | /* stop clock */ | 147 | /* stop clock and mark device as idle */ |
| 145 | clk_disable(p->clk); | 148 | clk_disable(p->clk); |
| 149 | pm_runtime_put_sync(&p->pdev->dev); | ||
| 146 | } | 150 | } |
| 147 | 151 | ||
| 148 | static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, | 152 | static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, |
| @@ -199,8 +203,12 @@ static cycle_t sh_tmu_clocksource_read(struct clocksource *cs) | |||
| 199 | static int sh_tmu_clocksource_enable(struct clocksource *cs) | 203 | static int sh_tmu_clocksource_enable(struct clocksource *cs) |
| 200 | { | 204 | { |
| 201 | struct sh_tmu_priv *p = cs_to_sh_tmu(cs); | 205 | struct sh_tmu_priv *p = cs_to_sh_tmu(cs); |
| 206 | int ret; | ||
| 202 | 207 | ||
| 203 | return sh_tmu_enable(p); | 208 | ret = sh_tmu_enable(p); |
| 209 | if (!ret) | ||
| 210 | __clocksource_updatefreq_hz(cs, p->rate); | ||
| 211 | return ret; | ||
| 204 | } | 212 | } |
| 205 | 213 | ||
| 206 | static void sh_tmu_clocksource_disable(struct clocksource *cs) | 214 | static void sh_tmu_clocksource_disable(struct clocksource *cs) |
| @@ -221,17 +229,10 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p, | |||
| 221 | cs->mask = CLOCKSOURCE_MASK(32); | 229 | cs->mask = CLOCKSOURCE_MASK(32); |
| 222 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; | 230 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; |
| 223 | 231 | ||
| 224 | /* clk_get_rate() needs an enabled clock */ | ||
| 225 | clk_enable(p->clk); | ||
| 226 | /* channel will be configured at parent clock / 4 */ | ||
| 227 | p->rate = clk_get_rate(p->clk) / 4; | ||
| 228 | clk_disable(p->clk); | ||
| 229 | /* TODO: calculate good shift from rate and counter bit width */ | ||
| 230 | cs->shift = 10; | ||
| 231 | cs->mult = clocksource_hz2mult(p->rate, cs->shift); | ||
| 232 | |||
| 233 | dev_info(&p->pdev->dev, "used as clock source\n"); | 232 | dev_info(&p->pdev->dev, "used as clock source\n"); |
| 234 | clocksource_register(cs); | 233 | |
| 234 | /* Register with dummy 1 Hz value, gets updated in ->enable() */ | ||
| 235 | clocksource_register_hz(cs, 1); | ||
| 235 | return 0; | 236 | return 0; |
| 236 | } | 237 | } |
| 237 | 238 | ||
| @@ -414,6 +415,7 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev) | |||
| 414 | 415 | ||
| 415 | if (p) { | 416 | if (p) { |
| 416 | dev_info(&pdev->dev, "kept as earlytimer\n"); | 417 | dev_info(&pdev->dev, "kept as earlytimer\n"); |
| 418 | pm_runtime_enable(&pdev->dev); | ||
| 417 | return 0; | 419 | return 0; |
| 418 | } | 420 | } |
| 419 | 421 | ||
| @@ -428,6 +430,9 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev) | |||
| 428 | kfree(p); | 430 | kfree(p); |
| 429 | platform_set_drvdata(pdev, NULL); | 431 | platform_set_drvdata(pdev, NULL); |
| 430 | } | 432 | } |
| 433 | |||
| 434 | if (!is_early_platform_device(pdev)) | ||
| 435 | pm_runtime_enable(&pdev->dev); | ||
| 431 | return ret; | 436 | return ret; |
| 432 | } | 437 | } |
| 433 | 438 | ||
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index d50da41ac328..dcc1b2139fff 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
| @@ -48,7 +48,7 @@ enum sh_dmae_desc_status { | |||
| 48 | 48 | ||
| 49 | /* | 49 | /* |
| 50 | * Used for write-side mutual exclusion for the global device list, | 50 | * Used for write-side mutual exclusion for the global device list, |
| 51 | * read-side synchronization by way of RCU. | 51 | * read-side synchronization by way of RCU, and per-controller data. |
| 52 | */ | 52 | */ |
| 53 | static DEFINE_SPINLOCK(sh_dmae_lock); | 53 | static DEFINE_SPINLOCK(sh_dmae_lock); |
| 54 | static LIST_HEAD(sh_dmae_devices); | 54 | static LIST_HEAD(sh_dmae_devices); |
| @@ -85,22 +85,35 @@ static void dmaor_write(struct sh_dmae_device *shdev, u16 data) | |||
| 85 | */ | 85 | */ |
| 86 | static void sh_dmae_ctl_stop(struct sh_dmae_device *shdev) | 86 | static void sh_dmae_ctl_stop(struct sh_dmae_device *shdev) |
| 87 | { | 87 | { |
| 88 | unsigned short dmaor = dmaor_read(shdev); | 88 | unsigned short dmaor; |
| 89 | unsigned long flags; | ||
| 90 | |||
| 91 | spin_lock_irqsave(&sh_dmae_lock, flags); | ||
| 89 | 92 | ||
| 93 | dmaor = dmaor_read(shdev); | ||
| 90 | dmaor_write(shdev, dmaor & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME)); | 94 | dmaor_write(shdev, dmaor & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME)); |
| 95 | |||
| 96 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | ||
| 91 | } | 97 | } |
| 92 | 98 | ||
| 93 | static int sh_dmae_rst(struct sh_dmae_device *shdev) | 99 | static int sh_dmae_rst(struct sh_dmae_device *shdev) |
| 94 | { | 100 | { |
| 95 | unsigned short dmaor; | 101 | unsigned short dmaor; |
| 102 | unsigned long flags; | ||
| 96 | 103 | ||
| 97 | sh_dmae_ctl_stop(shdev); | 104 | spin_lock_irqsave(&sh_dmae_lock, flags); |
| 98 | dmaor = dmaor_read(shdev) | shdev->pdata->dmaor_init; | ||
| 99 | 105 | ||
| 100 | dmaor_write(shdev, dmaor); | 106 | dmaor = dmaor_read(shdev) & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME); |
| 101 | if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) { | 107 | |
| 102 | pr_warning("dma-sh: Can't initialize DMAOR.\n"); | 108 | dmaor_write(shdev, dmaor | shdev->pdata->dmaor_init); |
| 103 | return -EINVAL; | 109 | |
| 110 | dmaor = dmaor_read(shdev); | ||
| 111 | |||
| 112 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | ||
| 113 | |||
| 114 | if (dmaor & (DMAOR_AE | DMAOR_NMIF)) { | ||
| 115 | dev_warn(shdev->common.dev, "Can't initialize DMAOR.\n"); | ||
| 116 | return -EIO; | ||
| 104 | } | 117 | } |
| 105 | return 0; | 118 | return 0; |
| 106 | } | 119 | } |
| @@ -184,7 +197,7 @@ static void dmae_init(struct sh_dmae_chan *sh_chan) | |||
| 184 | 197 | ||
| 185 | static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) | 198 | static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) |
| 186 | { | 199 | { |
| 187 | /* When DMA was working, can not set data to CHCR */ | 200 | /* If DMA is active, cannot set CHCR. TODO: remove this superfluous check */ |
| 188 | if (dmae_is_busy(sh_chan)) | 201 | if (dmae_is_busy(sh_chan)) |
| 189 | return -EBUSY; | 202 | return -EBUSY; |
| 190 | 203 | ||
| @@ -374,7 +387,12 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) | |||
| 374 | LIST_HEAD(list); | 387 | LIST_HEAD(list); |
| 375 | int descs = sh_chan->descs_allocated; | 388 | int descs = sh_chan->descs_allocated; |
| 376 | 389 | ||
| 390 | /* Protect against ISR */ | ||
| 391 | spin_lock_irq(&sh_chan->desc_lock); | ||
| 377 | dmae_halt(sh_chan); | 392 | dmae_halt(sh_chan); |
| 393 | spin_unlock_irq(&sh_chan->desc_lock); | ||
| 394 | |||
| 395 | /* Now no new interrupts will occur */ | ||
| 378 | 396 | ||
| 379 | /* Prepared and not submitted descriptors can still be on the queue */ | 397 | /* Prepared and not submitted descriptors can still be on the queue */ |
| 380 | if (!list_empty(&sh_chan->ld_queue)) | 398 | if (!list_empty(&sh_chan->ld_queue)) |
| @@ -384,6 +402,7 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) | |||
| 384 | /* The caller is holding dma_list_mutex */ | 402 | /* The caller is holding dma_list_mutex */ |
| 385 | struct sh_dmae_slave *param = chan->private; | 403 | struct sh_dmae_slave *param = chan->private; |
| 386 | clear_bit(param->slave_id, sh_dmae_slave_used); | 404 | clear_bit(param->slave_id, sh_dmae_slave_used); |
| 405 | chan->private = NULL; | ||
| 387 | } | 406 | } |
| 388 | 407 | ||
| 389 | spin_lock_bh(&sh_chan->desc_lock); | 408 | spin_lock_bh(&sh_chan->desc_lock); |
| @@ -563,8 +582,6 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy( | |||
| 563 | if (!chan || !len) | 582 | if (!chan || !len) |
| 564 | return NULL; | 583 | return NULL; |
| 565 | 584 | ||
| 566 | chan->private = NULL; | ||
| 567 | |||
| 568 | sh_chan = to_sh_chan(chan); | 585 | sh_chan = to_sh_chan(chan); |
| 569 | 586 | ||
| 570 | sg_init_table(&sg, 1); | 587 | sg_init_table(&sg, 1); |
| @@ -620,9 +637,9 @@ static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
| 620 | if (!chan) | 637 | if (!chan) |
| 621 | return -EINVAL; | 638 | return -EINVAL; |
| 622 | 639 | ||
| 640 | spin_lock_bh(&sh_chan->desc_lock); | ||
| 623 | dmae_halt(sh_chan); | 641 | dmae_halt(sh_chan); |
| 624 | 642 | ||
| 625 | spin_lock_bh(&sh_chan->desc_lock); | ||
| 626 | if (!list_empty(&sh_chan->ld_queue)) { | 643 | if (!list_empty(&sh_chan->ld_queue)) { |
| 627 | /* Record partial transfer */ | 644 | /* Record partial transfer */ |
| 628 | struct sh_desc *desc = list_entry(sh_chan->ld_queue.next, | 645 | struct sh_desc *desc = list_entry(sh_chan->ld_queue.next, |
| @@ -716,6 +733,14 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all | |||
| 716 | list_move(&desc->node, &sh_chan->ld_free); | 733 | list_move(&desc->node, &sh_chan->ld_free); |
| 717 | } | 734 | } |
| 718 | } | 735 | } |
| 736 | |||
| 737 | if (all && !callback) | ||
| 738 | /* | ||
| 739 | * Terminating and the loop completed normally: forgive | ||
| 740 | * uncompleted cookies | ||
| 741 | */ | ||
| 742 | sh_chan->completed_cookie = sh_chan->common.cookie; | ||
| 743 | |||
| 719 | spin_unlock_bh(&sh_chan->desc_lock); | 744 | spin_unlock_bh(&sh_chan->desc_lock); |
| 720 | 745 | ||
| 721 | if (callback) | 746 | if (callback) |
| @@ -733,10 +758,6 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) | |||
| 733 | { | 758 | { |
| 734 | while (__ld_cleanup(sh_chan, all)) | 759 | while (__ld_cleanup(sh_chan, all)) |
| 735 | ; | 760 | ; |
| 736 | |||
| 737 | if (all) | ||
| 738 | /* Terminating - forgive uncompleted cookies */ | ||
| 739 | sh_chan->completed_cookie = sh_chan->common.cookie; | ||
| 740 | } | 761 | } |
| 741 | 762 | ||
| 742 | static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) | 763 | static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) |
| @@ -782,8 +803,10 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, | |||
| 782 | 803 | ||
| 783 | sh_dmae_chan_ld_cleanup(sh_chan, false); | 804 | sh_dmae_chan_ld_cleanup(sh_chan, false); |
| 784 | 805 | ||
| 785 | last_used = chan->cookie; | 806 | /* First read completed cookie to avoid a skew */ |
| 786 | last_complete = sh_chan->completed_cookie; | 807 | last_complete = sh_chan->completed_cookie; |
| 808 | rmb(); | ||
| 809 | last_used = chan->cookie; | ||
| 787 | BUG_ON(last_complete < 0); | 810 | BUG_ON(last_complete < 0); |
| 788 | dma_set_tx_state(txstate, last_complete, last_used, 0); | 811 | dma_set_tx_state(txstate, last_complete, last_used, 0); |
| 789 | 812 | ||
| @@ -813,8 +836,12 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, | |||
| 813 | static irqreturn_t sh_dmae_interrupt(int irq, void *data) | 836 | static irqreturn_t sh_dmae_interrupt(int irq, void *data) |
| 814 | { | 837 | { |
| 815 | irqreturn_t ret = IRQ_NONE; | 838 | irqreturn_t ret = IRQ_NONE; |
| 816 | struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data; | 839 | struct sh_dmae_chan *sh_chan = data; |
| 817 | u32 chcr = sh_dmae_readl(sh_chan, CHCR); | 840 | u32 chcr; |
| 841 | |||
| 842 | spin_lock(&sh_chan->desc_lock); | ||
| 843 | |||
| 844 | chcr = sh_dmae_readl(sh_chan, CHCR); | ||
| 818 | 845 | ||
| 819 | if (chcr & CHCR_TE) { | 846 | if (chcr & CHCR_TE) { |
| 820 | /* DMA stop */ | 847 | /* DMA stop */ |
| @@ -824,10 +851,13 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data) | |||
| 824 | tasklet_schedule(&sh_chan->tasklet); | 851 | tasklet_schedule(&sh_chan->tasklet); |
| 825 | } | 852 | } |
| 826 | 853 | ||
| 854 | spin_unlock(&sh_chan->desc_lock); | ||
| 855 | |||
| 827 | return ret; | 856 | return ret; |
| 828 | } | 857 | } |
| 829 | 858 | ||
| 830 | static unsigned int sh_dmae_reset(struct sh_dmae_device *shdev) | 859 | /* Called from error IRQ or NMI */ |
| 860 | static bool sh_dmae_reset(struct sh_dmae_device *shdev) | ||
| 831 | { | 861 | { |
| 832 | unsigned int handled = 0; | 862 | unsigned int handled = 0; |
| 833 | int i; | 863 | int i; |
| @@ -839,22 +869,32 @@ static unsigned int sh_dmae_reset(struct sh_dmae_device *shdev) | |||
| 839 | for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) { | 869 | for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) { |
| 840 | struct sh_dmae_chan *sh_chan = shdev->chan[i]; | 870 | struct sh_dmae_chan *sh_chan = shdev->chan[i]; |
| 841 | struct sh_desc *desc; | 871 | struct sh_desc *desc; |
| 872 | LIST_HEAD(dl); | ||
| 842 | 873 | ||
| 843 | if (!sh_chan) | 874 | if (!sh_chan) |
| 844 | continue; | 875 | continue; |
| 845 | 876 | ||
| 877 | spin_lock(&sh_chan->desc_lock); | ||
| 878 | |||
| 846 | /* Stop the channel */ | 879 | /* Stop the channel */ |
| 847 | dmae_halt(sh_chan); | 880 | dmae_halt(sh_chan); |
| 848 | 881 | ||
| 882 | list_splice_init(&sh_chan->ld_queue, &dl); | ||
| 883 | |||
| 884 | spin_unlock(&sh_chan->desc_lock); | ||
| 885 | |||
| 849 | /* Complete all */ | 886 | /* Complete all */ |
| 850 | list_for_each_entry(desc, &sh_chan->ld_queue, node) { | 887 | list_for_each_entry(desc, &dl, node) { |
| 851 | struct dma_async_tx_descriptor *tx = &desc->async_tx; | 888 | struct dma_async_tx_descriptor *tx = &desc->async_tx; |
| 852 | desc->mark = DESC_IDLE; | 889 | desc->mark = DESC_IDLE; |
| 853 | if (tx->callback) | 890 | if (tx->callback) |
| 854 | tx->callback(tx->callback_param); | 891 | tx->callback(tx->callback_param); |
| 855 | } | 892 | } |
| 856 | 893 | ||
| 857 | list_splice_init(&sh_chan->ld_queue, &sh_chan->ld_free); | 894 | spin_lock(&sh_chan->desc_lock); |
| 895 | list_splice(&dl, &sh_chan->ld_free); | ||
| 896 | spin_unlock(&sh_chan->desc_lock); | ||
| 897 | |||
| 858 | handled++; | 898 | handled++; |
| 859 | } | 899 | } |
| 860 | 900 | ||
| @@ -867,10 +907,11 @@ static irqreturn_t sh_dmae_err(int irq, void *data) | |||
| 867 | { | 907 | { |
| 868 | struct sh_dmae_device *shdev = data; | 908 | struct sh_dmae_device *shdev = data; |
| 869 | 909 | ||
| 870 | if (dmaor_read(shdev) & DMAOR_AE) | 910 | if (!(dmaor_read(shdev) & DMAOR_AE)) |
| 871 | return IRQ_RETVAL(sh_dmae_reset(data)); | ||
| 872 | else | ||
| 873 | return IRQ_NONE; | 911 | return IRQ_NONE; |
| 912 | |||
| 913 | sh_dmae_reset(data); | ||
| 914 | return IRQ_HANDLED; | ||
| 874 | } | 915 | } |
| 875 | 916 | ||
| 876 | static void dmae_do_tasklet(unsigned long data) | 917 | static void dmae_do_tasklet(unsigned long data) |
| @@ -902,17 +943,11 @@ static void dmae_do_tasklet(unsigned long data) | |||
| 902 | 943 | ||
| 903 | static bool sh_dmae_nmi_notify(struct sh_dmae_device *shdev) | 944 | static bool sh_dmae_nmi_notify(struct sh_dmae_device *shdev) |
| 904 | { | 945 | { |
| 905 | unsigned int handled; | ||
| 906 | |||
| 907 | /* Fast path out if NMIF is not asserted for this controller */ | 946 | /* Fast path out if NMIF is not asserted for this controller */ |
| 908 | if ((dmaor_read(shdev) & DMAOR_NMIF) == 0) | 947 | if ((dmaor_read(shdev) & DMAOR_NMIF) == 0) |
| 909 | return false; | 948 | return false; |
| 910 | 949 | ||
| 911 | handled = sh_dmae_reset(shdev); | 950 | return sh_dmae_reset(shdev); |
| 912 | if (handled) | ||
| 913 | return true; | ||
| 914 | |||
| 915 | return false; | ||
| 916 | } | 951 | } |
| 917 | 952 | ||
| 918 | static int sh_dmae_nmi_handler(struct notifier_block *self, | 953 | static int sh_dmae_nmi_handler(struct notifier_block *self, |
| @@ -982,9 +1017,6 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, | |||
| 982 | tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet, | 1017 | tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet, |
| 983 | (unsigned long)new_sh_chan); | 1018 | (unsigned long)new_sh_chan); |
| 984 | 1019 | ||
| 985 | /* Init the channel */ | ||
| 986 | dmae_init(new_sh_chan); | ||
| 987 | |||
| 988 | spin_lock_init(&new_sh_chan->desc_lock); | 1020 | spin_lock_init(&new_sh_chan->desc_lock); |
| 989 | 1021 | ||
| 990 | /* Init descripter manage list */ | 1022 | /* Init descripter manage list */ |
| @@ -1045,7 +1077,6 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
| 1045 | struct sh_dmae_pdata *pdata = pdev->dev.platform_data; | 1077 | struct sh_dmae_pdata *pdata = pdev->dev.platform_data; |
| 1046 | unsigned long irqflags = IRQF_DISABLED, | 1078 | unsigned long irqflags = IRQF_DISABLED, |
| 1047 | chan_flag[SH_DMAC_MAX_CHANNELS] = {}; | 1079 | chan_flag[SH_DMAC_MAX_CHANNELS] = {}; |
| 1048 | unsigned long flags; | ||
| 1049 | int errirq, chan_irq[SH_DMAC_MAX_CHANNELS]; | 1080 | int errirq, chan_irq[SH_DMAC_MAX_CHANNELS]; |
| 1050 | int err, i, irq_cnt = 0, irqres = 0; | 1081 | int err, i, irq_cnt = 0, irqres = 0; |
| 1051 | struct sh_dmae_device *shdev; | 1082 | struct sh_dmae_device *shdev; |
| @@ -1111,11 +1142,11 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
| 1111 | pm_runtime_enable(&pdev->dev); | 1142 | pm_runtime_enable(&pdev->dev); |
| 1112 | pm_runtime_get_sync(&pdev->dev); | 1143 | pm_runtime_get_sync(&pdev->dev); |
| 1113 | 1144 | ||
| 1114 | spin_lock_irqsave(&sh_dmae_lock, flags); | 1145 | spin_lock_irq(&sh_dmae_lock); |
| 1115 | list_add_tail_rcu(&shdev->node, &sh_dmae_devices); | 1146 | list_add_tail_rcu(&shdev->node, &sh_dmae_devices); |
| 1116 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | 1147 | spin_unlock_irq(&sh_dmae_lock); |
| 1117 | 1148 | ||
| 1118 | /* reset dma controller */ | 1149 | /* reset dma controller - only needed as a test */ |
| 1119 | err = sh_dmae_rst(shdev); | 1150 | err = sh_dmae_rst(shdev); |
| 1120 | if (err) | 1151 | if (err) |
| 1121 | goto rst_err; | 1152 | goto rst_err; |
| @@ -1218,15 +1249,18 @@ eirqres: | |||
| 1218 | eirq_err: | 1249 | eirq_err: |
| 1219 | #endif | 1250 | #endif |
| 1220 | rst_err: | 1251 | rst_err: |
| 1221 | spin_lock_irqsave(&sh_dmae_lock, flags); | 1252 | spin_lock_irq(&sh_dmae_lock); |
| 1222 | list_del_rcu(&shdev->node); | 1253 | list_del_rcu(&shdev->node); |
| 1223 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | 1254 | spin_unlock_irq(&sh_dmae_lock); |
| 1224 | 1255 | ||
| 1225 | pm_runtime_put(&pdev->dev); | 1256 | pm_runtime_put(&pdev->dev); |
| 1257 | pm_runtime_disable(&pdev->dev); | ||
| 1258 | |||
| 1226 | if (dmars) | 1259 | if (dmars) |
| 1227 | iounmap(shdev->dmars); | 1260 | iounmap(shdev->dmars); |
| 1228 | emapdmars: | 1261 | emapdmars: |
| 1229 | iounmap(shdev->chan_reg); | 1262 | iounmap(shdev->chan_reg); |
| 1263 | synchronize_rcu(); | ||
| 1230 | emapchan: | 1264 | emapchan: |
| 1231 | kfree(shdev); | 1265 | kfree(shdev); |
| 1232 | ealloc: | 1266 | ealloc: |
| @@ -1242,7 +1276,6 @@ static int __exit sh_dmae_remove(struct platform_device *pdev) | |||
| 1242 | { | 1276 | { |
| 1243 | struct sh_dmae_device *shdev = platform_get_drvdata(pdev); | 1277 | struct sh_dmae_device *shdev = platform_get_drvdata(pdev); |
| 1244 | struct resource *res; | 1278 | struct resource *res; |
| 1245 | unsigned long flags; | ||
| 1246 | int errirq = platform_get_irq(pdev, 0); | 1279 | int errirq = platform_get_irq(pdev, 0); |
| 1247 | 1280 | ||
| 1248 | dma_async_device_unregister(&shdev->common); | 1281 | dma_async_device_unregister(&shdev->common); |
| @@ -1250,9 +1283,9 @@ static int __exit sh_dmae_remove(struct platform_device *pdev) | |||
| 1250 | if (errirq > 0) | 1283 | if (errirq > 0) |
| 1251 | free_irq(errirq, shdev); | 1284 | free_irq(errirq, shdev); |
| 1252 | 1285 | ||
| 1253 | spin_lock_irqsave(&sh_dmae_lock, flags); | 1286 | spin_lock_irq(&sh_dmae_lock); |
| 1254 | list_del_rcu(&shdev->node); | 1287 | list_del_rcu(&shdev->node); |
| 1255 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | 1288 | spin_unlock_irq(&sh_dmae_lock); |
| 1256 | 1289 | ||
| 1257 | /* channel data remove */ | 1290 | /* channel data remove */ |
| 1258 | sh_dmae_chan_remove(shdev); | 1291 | sh_dmae_chan_remove(shdev); |
| @@ -1263,6 +1296,7 @@ static int __exit sh_dmae_remove(struct platform_device *pdev) | |||
| 1263 | iounmap(shdev->dmars); | 1296 | iounmap(shdev->dmars); |
| 1264 | iounmap(shdev->chan_reg); | 1297 | iounmap(shdev->chan_reg); |
| 1265 | 1298 | ||
| 1299 | synchronize_rcu(); | ||
| 1266 | kfree(shdev); | 1300 | kfree(shdev); |
| 1267 | 1301 | ||
| 1268 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1302 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -1281,12 +1315,78 @@ static void sh_dmae_shutdown(struct platform_device *pdev) | |||
| 1281 | sh_dmae_ctl_stop(shdev); | 1315 | sh_dmae_ctl_stop(shdev); |
| 1282 | } | 1316 | } |
| 1283 | 1317 | ||
| 1318 | static int sh_dmae_runtime_suspend(struct device *dev) | ||
| 1319 | { | ||
| 1320 | return 0; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | static int sh_dmae_runtime_resume(struct device *dev) | ||
| 1324 | { | ||
| 1325 | struct sh_dmae_device *shdev = dev_get_drvdata(dev); | ||
| 1326 | |||
| 1327 | return sh_dmae_rst(shdev); | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | #ifdef CONFIG_PM | ||
| 1331 | static int sh_dmae_suspend(struct device *dev) | ||
| 1332 | { | ||
| 1333 | struct sh_dmae_device *shdev = dev_get_drvdata(dev); | ||
| 1334 | int i; | ||
| 1335 | |||
| 1336 | for (i = 0; i < shdev->pdata->channel_num; i++) { | ||
| 1337 | struct sh_dmae_chan *sh_chan = shdev->chan[i]; | ||
| 1338 | if (sh_chan->descs_allocated) | ||
| 1339 | sh_chan->pm_error = pm_runtime_put_sync(dev); | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | return 0; | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | static int sh_dmae_resume(struct device *dev) | ||
| 1346 | { | ||
| 1347 | struct sh_dmae_device *shdev = dev_get_drvdata(dev); | ||
| 1348 | int i; | ||
| 1349 | |||
| 1350 | for (i = 0; i < shdev->pdata->channel_num; i++) { | ||
| 1351 | struct sh_dmae_chan *sh_chan = shdev->chan[i]; | ||
| 1352 | struct sh_dmae_slave *param = sh_chan->common.private; | ||
| 1353 | |||
| 1354 | if (!sh_chan->descs_allocated) | ||
| 1355 | continue; | ||
| 1356 | |||
| 1357 | if (!sh_chan->pm_error) | ||
| 1358 | pm_runtime_get_sync(dev); | ||
| 1359 | |||
| 1360 | if (param) { | ||
| 1361 | const struct sh_dmae_slave_config *cfg = param->config; | ||
| 1362 | dmae_set_dmars(sh_chan, cfg->mid_rid); | ||
| 1363 | dmae_set_chcr(sh_chan, cfg->chcr); | ||
| 1364 | } else { | ||
| 1365 | dmae_init(sh_chan); | ||
| 1366 | } | ||
| 1367 | } | ||
| 1368 | |||
| 1369 | return 0; | ||
| 1370 | } | ||
| 1371 | #else | ||
| 1372 | #define sh_dmae_suspend NULL | ||
| 1373 | #define sh_dmae_resume NULL | ||
| 1374 | #endif | ||
| 1375 | |||
| 1376 | const struct dev_pm_ops sh_dmae_pm = { | ||
| 1377 | .suspend = sh_dmae_suspend, | ||
| 1378 | .resume = sh_dmae_resume, | ||
| 1379 | .runtime_suspend = sh_dmae_runtime_suspend, | ||
| 1380 | .runtime_resume = sh_dmae_runtime_resume, | ||
| 1381 | }; | ||
| 1382 | |||
| 1284 | static struct platform_driver sh_dmae_driver = { | 1383 | static struct platform_driver sh_dmae_driver = { |
| 1285 | .remove = __exit_p(sh_dmae_remove), | 1384 | .remove = __exit_p(sh_dmae_remove), |
| 1286 | .shutdown = sh_dmae_shutdown, | 1385 | .shutdown = sh_dmae_shutdown, |
| 1287 | .driver = { | 1386 | .driver = { |
| 1288 | .owner = THIS_MODULE, | 1387 | .owner = THIS_MODULE, |
| 1289 | .name = "sh-dma-engine", | 1388 | .name = "sh-dma-engine", |
| 1389 | .pm = &sh_dmae_pm, | ||
| 1290 | }, | 1390 | }, |
| 1291 | }; | 1391 | }; |
| 1292 | 1392 | ||
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 52e4fb173805..3f9d3cd06584 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h | |||
| @@ -37,6 +37,7 @@ struct sh_dmae_chan { | |||
| 37 | int id; /* Raw id of this channel */ | 37 | int id; /* Raw id of this channel */ |
| 38 | u32 __iomem *base; | 38 | u32 __iomem *base; |
| 39 | char dev_id[16]; /* unique name per DMAC of channel */ | 39 | char dev_id[16]; /* unique name per DMAC of channel */ |
| 40 | int pm_error; | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | struct sh_dmae_device { | 43 | struct sh_dmae_device { |
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 2707f5e17158..81ccd7875627 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
| @@ -729,3 +729,4 @@ module_exit(sh_mobile_i2c_adap_exit); | |||
| 729 | MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver"); | 729 | MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver"); |
| 730 | MODULE_AUTHOR("Magnus Damm"); | 730 | MODULE_AUTHOR("Magnus Damm"); |
| 731 | MODULE_LICENSE("GPL v2"); | 731 | MODULE_LICENSE("GPL v2"); |
| 732 | MODULE_ALIAS("platform:i2c-sh_mobile"); | ||
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 6172335ae323..82dd6fb17838 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c | |||
| @@ -105,7 +105,7 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) | |||
| 105 | 105 | ||
| 106 | /* Rebuild the frequency table */ | 106 | /* Rebuild the frequency table */ |
| 107 | clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, | 107 | clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, |
| 108 | table, &clk->arch_flags); | 108 | table, NULL); |
| 109 | 109 | ||
| 110 | return 0; | 110 | return 0; |
| 111 | } | 111 | } |
diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index ce5f81d7cc6b..1e6e2d0353ea 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c | |||
| @@ -235,6 +235,11 @@ restart: | |||
| 235 | 235 | ||
| 236 | irq_set_handler_data(irq, (void *)entry->handle); | 236 | irq_set_handler_data(irq, (void *)entry->handle); |
| 237 | 237 | ||
| 238 | /* | ||
| 239 | * Set the virtual IRQ as non-threadable. | ||
| 240 | */ | ||
| 241 | irq_set_nothread(irq); | ||
| 242 | |||
| 238 | irq_set_chained_handler(entry->pirq, intc_virq_handler); | 243 | irq_set_chained_handler(entry->pirq, intc_virq_handler); |
| 239 | add_virq_to_pirq(entry->pirq, irq); | 244 | add_virq_to_pirq(entry->pirq, irq); |
| 240 | 245 | ||
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index f35b8fb94b83..ebd8629c108d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
| 42 | #include <linux/serial_sci.h> | 42 | #include <linux/serial_sci.h> |
| 43 | #include <linux/notifier.h> | 43 | #include <linux/notifier.h> |
| 44 | #include <linux/pm_runtime.h> | ||
| 44 | #include <linux/cpufreq.h> | 45 | #include <linux/cpufreq.h> |
| 45 | #include <linux/clk.h> | 46 | #include <linux/clk.h> |
| 46 | #include <linux/ctype.h> | 47 | #include <linux/ctype.h> |
| @@ -560,6 +561,9 @@ static void sci_break_timer(unsigned long data) | |||
| 560 | { | 561 | { |
| 561 | struct sci_port *port = (struct sci_port *)data; | 562 | struct sci_port *port = (struct sci_port *)data; |
| 562 | 563 | ||
| 564 | if (port->enable) | ||
| 565 | port->enable(&port->port); | ||
| 566 | |||
| 563 | if (sci_rxd_in(&port->port) == 0) { | 567 | if (sci_rxd_in(&port->port) == 0) { |
| 564 | port->break_flag = 1; | 568 | port->break_flag = 1; |
| 565 | sci_schedule_break_timer(port); | 569 | sci_schedule_break_timer(port); |
| @@ -569,6 +573,9 @@ static void sci_break_timer(unsigned long data) | |||
| 569 | sci_schedule_break_timer(port); | 573 | sci_schedule_break_timer(port); |
| 570 | } else | 574 | } else |
| 571 | port->break_flag = 0; | 575 | port->break_flag = 0; |
| 576 | |||
| 577 | if (port->disable) | ||
| 578 | port->disable(&port->port); | ||
| 572 | } | 579 | } |
| 573 | 580 | ||
| 574 | static int sci_handle_errors(struct uart_port *port) | 581 | static int sci_handle_errors(struct uart_port *port) |
| @@ -837,6 +844,8 @@ static void sci_clk_enable(struct uart_port *port) | |||
| 837 | { | 844 | { |
| 838 | struct sci_port *sci_port = to_sci_port(port); | 845 | struct sci_port *sci_port = to_sci_port(port); |
| 839 | 846 | ||
| 847 | pm_runtime_get_sync(port->dev); | ||
| 848 | |||
| 840 | clk_enable(sci_port->iclk); | 849 | clk_enable(sci_port->iclk); |
| 841 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); | 850 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
| 842 | clk_enable(sci_port->fclk); | 851 | clk_enable(sci_port->fclk); |
| @@ -848,6 +857,8 @@ static void sci_clk_disable(struct uart_port *port) | |||
| 848 | 857 | ||
| 849 | clk_disable(sci_port->fclk); | 858 | clk_disable(sci_port->fclk); |
| 850 | clk_disable(sci_port->iclk); | 859 | clk_disable(sci_port->iclk); |
| 860 | |||
| 861 | pm_runtime_put_sync(port->dev); | ||
| 851 | } | 862 | } |
| 852 | 863 | ||
| 853 | static int sci_request_irq(struct sci_port *port) | 864 | static int sci_request_irq(struct sci_port *port) |
| @@ -1756,6 +1767,8 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
| 1756 | sci_port->enable = sci_clk_enable; | 1767 | sci_port->enable = sci_clk_enable; |
| 1757 | sci_port->disable = sci_clk_disable; | 1768 | sci_port->disable = sci_clk_disable; |
| 1758 | port->dev = &dev->dev; | 1769 | port->dev = &dev->dev; |
| 1770 | |||
| 1771 | pm_runtime_enable(&dev->dev); | ||
| 1759 | } | 1772 | } |
| 1760 | 1773 | ||
| 1761 | sci_port->break_timer.data = (unsigned long)sci_port; | 1774 | sci_port->break_timer.data = (unsigned long)sci_port; |
| @@ -1775,7 +1788,7 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
| 1775 | * | 1788 | * |
| 1776 | * For the muxed case there's nothing more to do. | 1789 | * For the muxed case there's nothing more to do. |
| 1777 | */ | 1790 | */ |
| 1778 | port->irq = p->irqs[SCIx_TXI_IRQ]; | 1791 | port->irq = p->irqs[SCIx_RXI_IRQ]; |
| 1779 | 1792 | ||
| 1780 | if (p->dma_dev) | 1793 | if (p->dma_dev) |
| 1781 | dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n", | 1794 | dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n", |
| @@ -1936,6 +1949,7 @@ static int sci_remove(struct platform_device *dev) | |||
| 1936 | clk_put(port->iclk); | 1949 | clk_put(port->iclk); |
| 1937 | clk_put(port->fclk); | 1950 | clk_put(port->fclk); |
| 1938 | 1951 | ||
| 1952 | pm_runtime_disable(&dev->dev); | ||
| 1939 | return 0; | 1953 | return 0; |
| 1940 | } | 1954 | } |
| 1941 | 1955 | ||
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index 5fefed53fa42..b04d937c9110 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
| @@ -270,12 +270,12 @@ | |||
| 270 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 270 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
| 271 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 271 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
| 272 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 272 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
| 273 | defined(CONFIG_ARCH_SH73A0) || \ | 273 | defined(CONFIG_ARCH_SH7367) |
| 274 | defined(CONFIG_ARCH_SH7367) || \ | ||
| 275 | defined(CONFIG_ARCH_SH7377) | ||
| 276 | #define SCIF_FNS(name, scif_offset, scif_size) \ | 274 | #define SCIF_FNS(name, scif_offset, scif_size) \ |
| 277 | CPU_SCIF_FNS(name, scif_offset, scif_size) | 275 | CPU_SCIF_FNS(name, scif_offset, scif_size) |
| 278 | #elif defined(CONFIG_ARCH_SH7372) | 276 | #elif defined(CONFIG_ARCH_SH7377) || \ |
| 277 | defined(CONFIG_ARCH_SH7372) || \ | ||
| 278 | defined(CONFIG_ARCH_SH73A0) | ||
| 279 | #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \ | 279 | #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \ |
| 280 | CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) | 280 | CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) |
| 281 | #define SCIF_FNS(name, scif_offset, scif_size) \ | 281 | #define SCIF_FNS(name, scif_offset, scif_size) \ |
| @@ -313,9 +313,7 @@ | |||
| 313 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 313 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
| 314 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 314 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
| 315 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 315 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
| 316 | defined(CONFIG_ARCH_SH73A0) || \ | 316 | defined(CONFIG_ARCH_SH7367) |
| 317 | defined(CONFIG_ARCH_SH7367) || \ | ||
| 318 | defined(CONFIG_ARCH_SH7377) | ||
| 319 | 317 | ||
| 320 | SCIF_FNS(SCSMR, 0x00, 16) | 318 | SCIF_FNS(SCSMR, 0x00, 16) |
| 321 | SCIF_FNS(SCBRR, 0x04, 8) | 319 | SCIF_FNS(SCBRR, 0x04, 8) |
| @@ -326,7 +324,9 @@ SCIF_FNS(SCFDR, 0x1c, 16) | |||
| 326 | SCIF_FNS(SCxTDR, 0x20, 8) | 324 | SCIF_FNS(SCxTDR, 0x20, 8) |
| 327 | SCIF_FNS(SCxRDR, 0x24, 8) | 325 | SCIF_FNS(SCxRDR, 0x24, 8) |
| 328 | SCIF_FNS(SCLSR, 0x00, 0) | 326 | SCIF_FNS(SCLSR, 0x00, 0) |
| 329 | #elif defined(CONFIG_ARCH_SH7372) | 327 | #elif defined(CONFIG_ARCH_SH7377) || \ |
| 328 | defined(CONFIG_ARCH_SH7372) || \ | ||
| 329 | defined(CONFIG_ARCH_SH73A0) | ||
| 330 | SCIF_FNS(SCSMR, 0x00, 16) | 330 | SCIF_FNS(SCSMR, 0x00, 16) |
| 331 | SCIF_FNS(SCBRR, 0x04, 8) | 331 | SCIF_FNS(SCBRR, 0x04, 8) |
| 332 | SCIF_FNS(SCSCR, 0x08, 16) | 332 | SCIF_FNS(SCSCR, 0x08, 16) |
