···1616 select HAVE_IOREMAP_PROT if MMU1717 select HAVE_ARCH_TRACEHOOK1818 select HAVE_DMA_API_DEBUG1919+ select HAVE_DMA_ATTRS1920 select HAVE_PERF_EVENTS2121+ select PERF_USE_VMALLOC2022 select HAVE_KERNEL_GZIP2123 select HAVE_KERNEL_BZIP22224 select HAVE_KERNEL_LZMA···3937 select HAVE_FTRACE_MCOUNT_RECORD4038 select HAVE_DYNAMIC_FTRACE4139 select HAVE_FUNCTION_TRACE_MCOUNT_TEST4040+ select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE4241 select HAVE_FUNCTION_GRAPH_TRACER4342 select HAVE_ARCH_KGDB4443 select ARCH_HIBERNATION_POSSIBLE if MMU···173170config IO_TRAPPED174171 bool175172173173+config DMA_COHERENT174174+ bool175175+176176+config DMA_NONCOHERENT177177+ def_bool !DMA_COHERENT178178+176179source "init/Kconfig"177180178181source "kernel/Kconfig.freezer"···229220230221config CPU_SHX3231222 bool223223+ select DMA_COHERENT232224233225config ARCH_SHMOBILE234226 bool···771761 default "0x00010000" if PAGE_SIZE_64KB772762 default "0x00000000"773763774774-config UBC_WAKEUP775775- bool "Wakeup UBC on startup"776776- depends on CPU_SH4 && !CPU_SH4A777777- help778778- Selecting this option will wakeup the User Break Controller (UBC) on779779- startup. Although the UBC is left in an awake state when the processor780780- comes up, some boot loaders misbehave by putting the UBC to sleep in a781781- power saving state, which causes issues with things like ptrace().782782-783783- If unsure, say N.784784-785764choice786765 prompt "Kernel command line"787766 optional···817818 Dreamcast with a serial line terminal or a remote network818819 connection.819820820820-source "arch/sh/drivers/pci/Kconfig"821821+config PCI822822+ bool "PCI support"823823+ depends on SYS_SUPPORTS_PCI824824+ help825825+ Find out whether you have a PCI motherboard. PCI is the name of a826826+ bus system, i.e. the way the CPU talks to the other stuff inside827827+ your box. If you have PCI, say Y, otherwise N.821828822829source "drivers/pci/pcie/Kconfig"823830
···11#22# Specific board support, not covered by a mach group.33#44-obj-$(CONFIG_SH_AP325RXA) += board-ap325rxa.o54obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o65obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o76obj-$(CONFIG_SH_URQUELL) += board-urquell.o
···11+/*22+ * AP325RXA sdram self/auto-refresh setup code33+ *44+ * Copyright (C) 2009 Magnus Damm55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+1111+#include <linux/sys.h>1212+#include <linux/errno.h>1313+#include <linux/linkage.h>1414+#include <asm/asm-offsets.h>1515+#include <asm/suspend.h>1616+#include <asm/romimage-macros.h>1717+1818+/* code to enter and leave self-refresh. must be self-contained.1919+ * this code will be copied to on-chip memory and executed from there.2020+ */2121+ .balign 42222+ENTRY(ap325rxa_sdram_enter_start)2323+2424+ /* SBSC: disable power down and put in self-refresh mode */2525+ mov.l 1f, r42626+ mov.l 2f, r12727+ mov.l @r4, r22828+ or r1, r22929+ mov.l 3f, r33030+ and r3, r23131+ mov.l r2, @r43232+3333+ rts3434+ nop3535+3636+ .balign 43737+1: .long 0xfe400008 /* SDCR0 */3838+2: .long 0x000004003939+3: .long 0xffff7fff4040+ENTRY(ap325rxa_sdram_enter_end)4141+4242+ .balign 44343+ENTRY(ap325rxa_sdram_leave_start)4444+4545+ /* SBSC: set auto-refresh mode */4646+ mov.l 1f, r44747+ mov.l @r4, r04848+ mov.l 4f, r14949+ and r1, r05050+ mov.l r0, @r45151+ mov.l 6f, r45252+ mov.l 8f, r05353+ mov.l @r4, r15454+ mov #-1, r45555+ add r4, r15656+ or r1, r05757+ mov.l 7f, r15858+ mov.l r0, @r15959+6060+ rts6161+ nop6262+6363+ .balign 46464+1: .long 0xfe400008 /* SDCR0 */6565+4: .long 0xfffffbff6666+6: .long 0xfe40001c /* RTCOR */6767+7: .long 0xfe400018 /* RTCNT */6868+8: .long 0xa55a00006969+ENTRY(ap325rxa_sdram_leave_end)
+1-1
arch/sh/boards/mach-ecovec24/Makefile
···66# for more details.77#8899-obj-y := setup.o99+obj-y := setup.o sdram.o
+52
arch/sh/boards/mach-ecovec24/sdram.S
···11+/*22+ * Ecovec24 sdram self/auto-refresh setup code33+ *44+ * Copyright (C) 2009 Magnus Damm55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+1111+#include <linux/sys.h>1212+#include <linux/errno.h>1313+#include <linux/linkage.h>1414+#include <asm/asm-offsets.h>1515+#include <asm/suspend.h>1616+#include <asm/romimage-macros.h>1717+1818+/* code to enter and leave self-refresh. must be self-contained.1919+ * this code will be copied to on-chip memory and executed from there.2020+ */2121+ .balign 42222+ENTRY(ecovec24_sdram_enter_start)2323+2424+ /* DBSC: put memory in self-refresh mode */2525+2626+ ED 0xFD000010, 0x00000000 /* DBEN */2727+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */2828+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */2929+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */3030+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */3131+3232+ rts3333+ nop3434+3535+ENTRY(ecovec24_sdram_enter_end)3636+3737+ .balign 43838+ENTRY(ecovec24_sdram_leave_start)3939+4040+ /* DBSC: put memory in auto-refresh mode */4141+4242+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */4343+ WAIT 14444+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */4545+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */4646+ ED 0xFD000010, 0x00000001 /* DBEN */4747+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */4848+4949+ rts5050+ nop5151+5252+ENTRY(ecovec24_sdram_leave_end)
···11+/*22+ * KFR2R09 sdram self/auto-refresh setup code33+ *44+ * Copyright (C) 2009 Magnus Damm55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+1111+#include <linux/sys.h>1212+#include <linux/errno.h>1313+#include <linux/linkage.h>1414+#include <asm/asm-offsets.h>1515+#include <asm/suspend.h>1616+#include <asm/romimage-macros.h>1717+1818+/* code to enter and leave self-refresh. must be self-contained.1919+ * this code will be copied to on-chip memory and executed from there.2020+ */2121+ .balign 42222+ENTRY(kfr2r09_sdram_enter_start)2323+2424+ /* DBSC: put memory in self-refresh mode */2525+2626+ ED 0xFD000010, 0x00000000 /* DBEN */2727+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */2828+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */2929+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */3030+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */3131+3232+ rts3333+ nop3434+3535+ENTRY(kfr2r09_sdram_enter_end)3636+3737+ .balign 43838+ENTRY(kfr2r09_sdram_leave_start)3939+4040+ /* DBSC: put memory in auto-refresh mode */4141+4242+ mov.l @(SH_SLEEP_MODE, r5), r04343+ tst #SUSP_SH_RSTANDBY, r04444+ bf resume_rstandby4545+4646+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */4747+ WAIT 14848+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */4949+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */5050+ ED 0xFD000010, 0x00000001 /* DBEN */5151+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */5252+5353+ rts5454+ nop5555+5656+resume_rstandby:5757+5858+ /* DBSC: re-initialize and put in auto-refresh */5959+6060+ ED 0xFD000108, 0x40000301 /* DBPDCNT0 */6161+ ED 0xFD000020, 0x011B0002 /* DBCONF */6262+ ED 0xFD000030, 0x03060E02 /* DBTR0 */6363+ ED 0xFD000034, 0x01020102 /* DBTR1 */6464+ ED 0xFD000038, 0x01090406 /* DBTR2 */6565+ ED 0xFD000008, 0x00000004 /* DBKIND */6666+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */6767+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */6868+ ED 0xFD000018, 0x00000001 /* DBCKECNT */6969+ WAIT 17070+ ED 0xFD000010, 0x00000001 /* DBEN */7171+ ED 0xFD000044, 0x000004AF /* DBRFPDN1 */7272+ ED 0xFD000048, 0x20CF0037 /* DBRFPDN2 */7373+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */7474+ ED 0xFD000108, 0x40000300 /* DBPDCNT0 */7575+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */7676+7777+ rts7878+ nop7979+8080+ENTRY(kfr2r09_sdram_leave_end)
···11+/*22+ * Migo-R sdram self/auto-refresh setup code33+ *44+ * Copyright (C) 2009 Magnus Damm55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+1111+#include <linux/sys.h>1212+#include <linux/errno.h>1313+#include <linux/linkage.h>1414+#include <asm/asm-offsets.h>1515+#include <asm/suspend.h>1616+#include <asm/romimage-macros.h>1717+1818+/* code to enter and leave self-refresh. must be self-contained.1919+ * this code will be copied to on-chip memory and executed from there.2020+ */2121+ .balign 42222+ENTRY(migor_sdram_enter_start)2323+2424+ /* SBSC: disable power down and put in self-refresh mode */2525+ mov.l 1f, r42626+ mov.l 2f, r12727+ mov.l @r4, r22828+ or r1, r22929+ mov.l 3f, r33030+ and r3, r23131+ mov.l r2, @r43232+3333+ rts3434+ nop3535+3636+ .balign 43737+1: .long 0xfe400008 /* SDCR0 */3838+2: .long 0x000004003939+3: .long 0xffff7fff4040+ENTRY(migor_sdram_enter_end)4141+4242+ .balign 44343+ENTRY(migor_sdram_leave_start)4444+4545+ /* SBSC: set auto-refresh mode */4646+ mov.l 1f, r44747+ mov.l @r4, r04848+ mov.l 4f, r14949+ and r1, r05050+ mov.l r0, @r45151+ mov.l 6f, r45252+ mov.l 8f, r05353+ mov.l @r4, r15454+ mov #-1, r45555+ add r4, r15656+ or r1, r05757+ mov.l 7f, r15858+ mov.l r0, @r15959+6060+ rts6161+ nop6262+6363+ .balign 46464+1: .long 0xfe400008 /* SDCR0 */6565+4: .long 0xfffffbff6666+6: .long 0xfe40001c /* RTCOR */6767+7: .long 0xfe400018 /* RTCNT */6868+8: .long 0xa55a00006969+ENTRY(migor_sdram_leave_end)
···11+/*22+ * MS7724SE sdram self/auto-refresh setup code33+ *44+ * Copyright (C) 2009 Magnus Damm55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+1111+#include <linux/sys.h>1212+#include <linux/errno.h>1313+#include <linux/linkage.h>1414+#include <asm/asm-offsets.h>1515+#include <asm/suspend.h>1616+#include <asm/romimage-macros.h>1717+1818+/* code to enter and leave self-refresh. must be self-contained.1919+ * this code will be copied to on-chip memory and executed from there.2020+ */2121+ .balign 42222+ENTRY(ms7724se_sdram_enter_start)2323+2424+ /* DBSC: put memory in self-refresh mode */2525+2626+ ED 0xFD000010, 0x00000000 /* DBEN */2727+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */2828+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */2929+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */3030+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */3131+3232+ rts3333+ nop3434+3535+ENTRY(ms7724se_sdram_enter_end)3636+3737+ .balign 43838+ENTRY(ms7724se_sdram_leave_start)3939+4040+ /* DBSC: put memory in auto-refresh mode */4141+4242+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */4343+ WAIT 14444+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */4545+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */4646+ ED 0xFD000010, 0x00000001 /* DBEN */4747+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */4848+4949+ rts5050+ nop5151+5252+ENTRY(ms7724se_sdram_leave_end)
···11-config PCI22- bool "PCI support"33- depends on SYS_SUPPORTS_PCI44- help55- Find out whether you have a PCI motherboard. PCI is the name of a66- bus system, i.e. the way the CPU talks to the other stuff inside77- your box. If you have PCI, say Y, otherwise N.88-99-config SH_PCIDMA_NONCOHERENT1010- bool "Cache and PCI noncoherent"1111- depends on PCI1212- default y1313- help1414- Enable this option if your platform does not have a CPU cache which1515- remains coherent with PCI DMA. It is safest to say 'Y', although you1616- will see better performance if you can say 'N', because the PCI DMA1717- code will not have to flush the CPU's caches. If you have a PCI host1818- bridge integrated with your SH CPU, refer carefully to the chip specs1919- to see if you can say 'N' here. Otherwise, leave it as 'Y'.
+6-3
arch/sh/include/asm/addrspace.h
···2828/* Returns the privileged segment base of a given address */2929#define PXSEG(a) (((unsigned long)(a)) & 0xe0000000)30303131-/* Returns the physical address of a PnSEG (n=1,2) address */3232-#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff)3333-3431#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED)3532/*3633 * Map an address to a certain privileged segment···5659#else5760#define P3_ADDR_MAX P4SEG5861#endif6262+6363+#ifndef __ASSEMBLY__6464+#ifdef CONFIG_PMB6565+extern int __in_29bit_mode(void);6666+#endif /* CONFIG_PMB */6767+#endif /* __ASSEMBLY__ */59686069#endif /* __KERNEL__ */6170#endif /* __ASM_SH_ADDRSPACE_H */
···2626/*2727 * clear_bit() doesn't provide any barrier for the compiler.2828 */2929-#define smp_mb__before_clear_bit() barrier()3030-#define smp_mb__after_clear_bit() barrier()2929+#define smp_mb__before_clear_bit() smp_mb()3030+#define smp_mb__after_clear_bit() smp_mb()31313232#ifdef CONFIG_SUPERH323333static inline unsigned long ffz(unsigned long word)
···11#ifndef __ASM_SH_HARDIRQ_H22#define __ASM_SH_HARDIRQ_H3344-extern void ack_bad_irq(unsigned int irq);55-#define ack_bad_irq ack_bad_irq44+#include <linux/threads.h>55+#include <linux/irq.h>6677-#include <asm-generic/hardirq.h>77+typedef struct {88+ unsigned int __softirq_pending;99+ unsigned int __nmi_count; /* arch dependent */1010+} ____cacheline_aligned irq_cpustat_t;1111+1212+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */1313+1414+extern void ack_bad_irq(unsigned int irq);815916#endif /* __ASM_SH_HARDIRQ_H */
+5-11
arch/sh/include/asm/io.h
···9090#define ctrl_outl __raw_writel9191#define ctrl_outq __raw_writeq92929393+extern unsigned long generic_io_base;9494+9395static inline void ctrl_delay(void)9496{9595-#ifdef CONFIG_CPU_SH49696- __raw_readw(CCN_PVR);9797-#elif defined(P2SEG)9898- __raw_readw(P2SEG);9999-#else100100-#error "Need a dummy address for delay"101101-#endif9797+ __raw_readw(generic_io_base);10298}10399104100#define __BUILD_MEMORY_STRING(bwlq, type) \···182186183187#define IO_SPACE_LIMIT 0xffffffff184188185185-extern unsigned long generic_io_base;186186-187189/*188190 * This function provides a method for the generic case where a189191 * board-specific ioport_map simply needs to return the port + some···240246static inline void __iomem *241247__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)242248{243243-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)249249+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)244250 unsigned long last_addr = offset + size - 1;245251#endif246252 void __iomem *ret;···249255 if (ret)250256 return ret;251257252252-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)258258+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)253259 /*254260 * For P1 and P2 space this is trivial, as everything is already255261 * mapped. Uncached access for P1 addresses are done through P2.
+3-28
arch/sh/include/asm/irqflags.h
···11#ifndef __ASM_SH_IRQFLAGS_H22#define __ASM_SH_IRQFLAGS_H3344-#ifdef CONFIG_SUPERH3255-#include "irqflags_32.h"66-#else77-#include "irqflags_64.h"88-#endif44+#define RAW_IRQ_DISABLED 0xf055+#define RAW_IRQ_ENABLED 0x00961010-#define raw_local_save_flags(flags) \1111- do { (flags) = __raw_local_save_flags(); } while (0)1212-1313-static inline int raw_irqs_disabled_flags(unsigned long flags)1414-{1515- return (flags != 0);1616-}1717-1818-static inline int raw_irqs_disabled(void)1919-{2020- unsigned long flags = __raw_local_save_flags();2121-2222- return raw_irqs_disabled_flags(flags);2323-}2424-2525-#define raw_local_irq_save(flags) \2626- do { (flags) = __raw_local_irq_save(); } while (0)2727-2828-static inline void raw_local_irq_restore(unsigned long flags)2929-{3030- if ((flags & 0xf0) != 0xf0)3131- raw_local_irq_enable();3232-}77+#include <asm-generic/irqflags.h>338349#endif /* __ASM_SH_IRQFLAGS_H */
···22 * include/asm-sh/watchdog.h33 *44 * Copyright (C) 2002, 2003 Paul Mundt55+ * Copyright (C) 2009 Siemens AG66+ * Copyright (C) 2009 Valentin Sitdikov57 *68 * This program is free software; you can redistribute it and/or modify it79 * under the terms of the GNU General Public License as published by the···6361#define WTCSR_CKS_2048 0x066462#define WTCSR_CKS_4096 0x0765636464+#if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780)6565+/**6666+ * sh_wdt_read_cnt - Read from Counter6767+ * Reads back the WTCNT value.6868+ */6969+static inline __u32 sh_wdt_read_cnt(void)7070+{7171+ return ctrl_inl(WTCNT_R);7272+}7373+7474+/**7575+ * sh_wdt_write_cnt - Write to Counter7676+ * @val: Value to write7777+ *7878+ * Writes the given value @val to the lower byte of the timer counter.7979+ * The upper byte is set manually on each write.8080+ */8181+static inline void sh_wdt_write_cnt(__u32 val)8282+{8383+ ctrl_outl((WTCNT_HIGH << 24) | (__u32)val, WTCNT);8484+}8585+8686+/**8787+ * sh_wdt_write_bst - Write to Counter8888+ * @val: Value to write8989+ *9090+ * Writes the given value @val to the lower byte of the timer counter.9191+ * The upper byte is set manually on each write.9292+ */9393+static inline void sh_wdt_write_bst(__u32 val)9494+{9595+ ctrl_outl((WTBST_HIGH << 24) | (__u32)val, WTBST);9696+}9797+/**9898+ * sh_wdt_read_csr - Read from Control/Status Register9999+ *100100+ * Reads back the WTCSR value.101101+ */102102+static inline __u32 sh_wdt_read_csr(void)103103+{104104+ return ctrl_inl(WTCSR_R);105105+}106106+107107+/**108108+ * sh_wdt_write_csr - Write to Control/Status Register109109+ * @val: Value to write110110+ *111111+ * Writes the given value @val to the lower byte of the control/status112112+ * register. The upper byte is set manually on each write.113113+ */114114+static inline void sh_wdt_write_csr(__u32 val)115115+{116116+ ctrl_outl((WTCSR_HIGH << 24) | (__u32)val, WTCSR);117117+}118118+#else66119/**67120 * sh_wdt_read_cnt - Read from Counter68121 * Reads back the WTCNT value.···160103{161104 ctrl_outw((WTCSR_HIGH << 8) | (__u16)val, WTCSR);162105}163163-106106+#endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */164107#endif /* __KERNEL__ */165108#endif /* __ASM_SH_WATCHDOG_H */
+13
arch/sh/include/cpu-sh4/cpu/watchdog.h
···22 * include/asm-sh/cpu-sh4/watchdog.h33 *44 * Copyright (C) 2002, 2003 Paul Mundt55+ * Copyright (C) 2009 Siemens AG66+ * Copyright (C) 2009 Sitdikov Valentin57 *68 * This file is subject to the terms and conditions of the GNU General Public79 * License. See the file "COPYING" in the main directory of this archive···1210#ifndef __ASM_CPU_SH4_WATCHDOG_H1311#define __ASM_CPU_SH4_WATCHDOG_H14121313+#if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780)1414+/* Prefix definition */1515+#define WTBST_HIGH 0x551616+/* Register definitions */1717+#define WTCNT_R 0xffcc0010 /*WDTCNT*/1818+#define WTCSR 0xffcc0004 /*WDTCSR*/1919+#define WTCNT 0xffcc0000 /*WDTST*/2020+#define WTST WTCNT2121+#define WTBST 0xffcc0008 /*WDTBST*/2222+#else1523/* Register definitions */1624#define WTCNT 0xffc000081725#define WTCSR 0xffc0000c2626+#endif18271928/* Bit definitions */2029#define WTCSR_TME 0x80
···15151616# Common interfaces.17171818-obj-$(CONFIG_UBC_WAKEUP) += ubc.o1918obj-$(CONFIG_SH_ADC) += adc.o2019obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o2120
-11
arch/sh/kernel/cpu/init.c
···338338 }339339#endif340340341341- /*342342- * Some brain-damaged loaders decided it would be a good idea to put343343- * the UBC to sleep. This causes some issues when it comes to things344344- * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So ..345345- * we wake it up and hope that all is well.346346- */347347-#ifdef CONFIG_SUPERH32348348- if (raw_smp_processor_id() == 0)349349- ubc_wakeup();350350-#endif351351-352341 speculative_execution_init();353342 expmask_init();354343}
-33
arch/sh/kernel/cpu/sh3/entry.S
···297297!298298 .balign 256,0,256299299general_exception:300300-#ifndef CONFIG_CPU_SUBTYPE_SHX3301300 bra handle_exception302301 sts pr, k3 ! save original pr value in k3303303-#else304304- mov.l 1f, k4305305- mov.l @k4, k4306306-307307- ! Is EXPEVT larger than 0x800?308308- mov #0x8, k0309309- shll8 k0310310- cmp/hs k0, k4311311- bf 0f312312-313313- ! then add 0x580 (k2 is 0xd80 or 0xda0)314314- mov #0x58, k0315315- shll2 k0316316- shll2 k0317317- add k0, k4318318-0:319319- ! Setup stack and save DSP context (k0 contains original r15 on return)320320- bsr prepare_stack321321- nop322322-323323- ! Save registers / Switch to bank 0324324- mov k4, k2 ! keep vector in k2325325- mov.l 1f, k4 ! SR bits to clear in k4326326- bsr save_regs ! needs original pr value in k3327327- nop328328-329329- bra handle_exception_special330330- nop331331-332332- .align 2333333-1: .long EXPEVT334334-#endif335302336303! prepare_stack()337304! - roll back gRB
···11-/*22- * arch/sh/kernel/cpu/ubc.S33- *44- * Set of management routines for the User Break Controller (UBC)55- *66- * Copyright (C) 2002 Paul Mundt77- *88- * This program is free software; you can redistribute it and/or modify it99- * under the terms of the GNU General Public License as published by the1010- * Free Software Foundation; either version 2 of the License, or (at your1111- * option) any later version.1212- */1313-#include <linux/linkage.h>1414-#include <asm/ubc.h>1515-1616-#define STBCR2 0xffc000101717-1818-ENTRY(ubc_sleep)1919- mov #0, r02020-2121- mov.l 1f, r1 ! Zero out UBC_BBRA ..2222- mov.w r0, @r12323-2424- mov.l 2f, r1 ! .. same for BBRB ..2525- mov.w r0, @r12626-2727- mov.l 3f, r1 ! .. and again for BRCR.2828- mov.w r0, @r12929-3030- mov.w @r1, r0 ! Dummy read BRCR3131-3232- mov.l 4f, r1 ! Set MSTP5 in STBCR23333- mov.b @r1, r03434- or #0x01, r03535- mov.b r0, @r13636-3737- mov.b @r1, r0 ! Two dummy reads ..3838- mov.b @r1, r03939-4040- rts4141- nop4242-4343-ENTRY(ubc_wakeup)4444- mov.l 4f, r1 ! Clear MSTP54545- mov.b @r1, r04646- and #0xfe, r04747- mov.b r0, @r14848-4949- mov.b @r1, r0 ! Two more dummy reads ..5050- mov.b @r1, r05151-5252- rts5353- nop5454-5555-1: .long UBC_BBRA5656-2: .long UBC_BBRB5757-3: .long UBC_BRCR5858-4: .long STBCR25959-
+82
arch/sh/kernel/dma-nommu.c
···11+/*22+ * DMA mapping support for platforms lacking IOMMUs.33+ *44+ * Copyright (C) 2009 Paul Mundt55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+#include <linux/dma-mapping.h>1111+#include <linux/io.h>1212+1313+static dma_addr_t nommu_map_page(struct device *dev, struct page *page,1414+ unsigned long offset, size_t size,1515+ enum dma_data_direction dir,1616+ struct dma_attrs *attrs)1717+{1818+ dma_addr_t addr = page_to_phys(page) + offset;1919+2020+ WARN_ON(size == 0);2121+ dma_cache_sync(dev, page_address(page) + offset, size, dir);2222+2323+ return addr;2424+}2525+2626+static int nommu_map_sg(struct device *dev, struct scatterlist *sg,2727+ int nents, enum dma_data_direction dir,2828+ struct dma_attrs *attrs)2929+{3030+ struct scatterlist *s;3131+ int i;3232+3333+ WARN_ON(nents == 0 || sg[0].length == 0);3434+3535+ for_each_sg(sg, s, nents, i) {3636+ BUG_ON(!sg_page(s));3737+3838+ dma_cache_sync(dev, sg_virt(s), s->length, dir);3939+4040+ s->dma_address = sg_phys(s);4141+ s->dma_length = s->length;4242+ }4343+4444+ return nents;4545+}4646+4747+#ifdef CONFIG_DMA_NONCOHERENT4848+static void nommu_sync_single(struct device *dev, dma_addr_t addr,4949+ size_t size, enum dma_data_direction dir)5050+{5151+ dma_cache_sync(dev, phys_to_virt(addr), size, dir);5252+}5353+5454+static void nommu_sync_sg(struct device *dev, struct scatterlist *sg,5555+ int nelems, enum dma_data_direction dir)5656+{5757+ struct scatterlist *s;5858+ int i;5959+6060+ for_each_sg(sg, s, nelems, i)6161+ dma_cache_sync(dev, sg_virt(s), s->length, dir);6262+}6363+#endif6464+6565+struct dma_map_ops nommu_dma_ops = {6666+ .alloc_coherent = dma_generic_alloc_coherent,6767+ .free_coherent = dma_generic_free_coherent,6868+ .map_page = nommu_map_page,6969+ .map_sg = nommu_map_sg,7070+#ifdef CONFIG_DMA_NONCOHERENT7171+ .sync_single_for_device = nommu_sync_single,7272+ .sync_sg_for_device = nommu_sync_sg,7373+#endif7474+ .is_phys = 1,7575+};7676+7777+void __init no_iommu_init(void)7878+{7979+ if (dma_ops)8080+ return;8181+ dma_ops = &nommu_dma_ops;8282+}
+190-70
arch/sh/kernel/dwarf.c
···2020#include <linux/list.h>2121#include <linux/mempool.h>2222#include <linux/mm.h>2323+#include <linux/elf.h>2324#include <linux/ftrace.h>2425#include <asm/dwarf.h>2526#include <asm/unwinder.h>···531530}532531533532/**534534- * dwarf_unwind_stack - recursively unwind the stack533533+ * dwarf_free_frame - free the memory allocated for @frame534534+ * @frame: the frame to free535535+ */536536+void dwarf_free_frame(struct dwarf_frame *frame)537537+{538538+ dwarf_frame_free_regs(frame);539539+ mempool_free(frame, dwarf_frame_pool);540540+}541541+542542+/**543543+ * dwarf_unwind_stack - unwind the stack544544+ *535545 * @pc: address of the function to unwind536546 * @prev: struct dwarf_frame of the previous stackframe on the callstack537547 *···560548 unsigned long addr;561549562550 /*563563- * If this is the first invocation of this recursive function we564564- * need get the contents of a physical register to get the CFA565565- * in order to begin the virtual unwinding of the stack.551551+ * If we're starting at the top of the stack we need get the552552+ * contents of a physical register to get the CFA in order to553553+ * begin the virtual unwinding of the stack.566554 *567555 * NOTE: the return address is guaranteed to be setup by the568556 * time this function makes its first function call.···605593 fde = dwarf_lookup_fde(pc);606594 if (!fde) {607595 /*608608- * This is our normal exit path - the one that stops the609609- * recursion. There's two reasons why we might exit610610- * here,596596+ * This is our normal exit path. There are two reasons597597+ * why we might exit here,611598 *612599 * a) pc has no asscociated DWARF frame info and so613600 * we don't know how to unwind this frame. This is···648637649638 } else {650639 /*651651- * Again, this is the first invocation of this652652- * recurisve function. We need to physically653653- * read the contents of a register in order to654654- * get the Canonical Frame Address for this640640+ * Again, we're starting from the top of the641641+ * stack. We need to physically read642642+ * the contents of a register in order to get643643+ * the Canonical Frame Address for this655644 * function.656645 */657646 frame->cfa = dwarf_read_arch_reg(frame->cfa_register);···681670 return frame;682671683672bail:684684- dwarf_frame_free_regs(frame);685685- mempool_free(frame, dwarf_frame_pool);673673+ dwarf_free_frame(frame);686674 return NULL;687675}688676689677static int dwarf_parse_cie(void *entry, void *p, unsigned long len,690690- unsigned char *end)678678+ unsigned char *end, struct module *mod)691679{692680 struct dwarf_cie *cie;693681 unsigned long flags;···782772 cie->initial_instructions = p;783773 cie->instructions_end = end;784774775775+ cie->mod = mod;776776+785777 /* Add to list */786778 spin_lock_irqsave(&dwarf_cie_lock, flags);787779 list_add_tail(&cie->link, &dwarf_cie_list);···794782795783static int dwarf_parse_fde(void *entry, u32 entry_type,796784 void *start, unsigned long len,797797- unsigned char *end)785785+ unsigned char *end, struct module *mod)798786{799787 struct dwarf_fde *fde;800788 struct dwarf_cie *cie;···843831 fde->instructions = p;844832 fde->end = end;845833834834+ fde->mod = mod;835835+846836 /* Add to list. */847837 spin_lock_irqsave(&dwarf_fde_lock, flags);848838 list_add_tail(&fde->link, &dwarf_fde_list);···868854 while (1) {869855 frame = dwarf_unwind_stack(return_addr, _frame);870856871871- if (_frame) {872872- dwarf_frame_free_regs(_frame);873873- mempool_free(_frame, dwarf_frame_pool);874874- }857857+ if (_frame)858858+ dwarf_free_frame(_frame);875859876860 _frame = frame;877861···879867 return_addr = frame->return_addr;880868 ops->address(data, return_addr, 1);881869 }870870+871871+ if (frame)872872+ dwarf_free_frame(frame);882873}883874884875static struct unwinder dwarf_unwinder = {···911896}912897913898/**899899+ * dwarf_parse_section - parse DWARF section900900+ * @eh_frame_start: start address of the .eh_frame section901901+ * @eh_frame_end: end address of the .eh_frame section902902+ * @mod: the kernel module containing the .eh_frame section903903+ *904904+ * Parse the information in a .eh_frame section.905905+ */906906+static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,907907+ struct module *mod)908908+{909909+ u32 entry_type;910910+ void *p, *entry;911911+ int count, err = 0;912912+ unsigned long len = 0;913913+ unsigned int c_entries, f_entries;914914+ unsigned char *end;915915+916916+ c_entries = 0;917917+ f_entries = 0;918918+ entry = eh_frame_start;919919+920920+ while ((char *)entry < eh_frame_end) {921921+ p = entry;922922+923923+ count = dwarf_entry_len(p, &len);924924+ if (count == 0) {925925+ /*926926+ * We read a bogus length field value. There is927927+ * nothing we can do here apart from disabling928928+ * the DWARF unwinder. We can't even skip this929929+ * entry and move to the next one because 'len'930930+ * tells us where our next entry is.931931+ */932932+ err = -EINVAL;933933+ goto out;934934+ } else935935+ p += count;936936+937937+ /* initial length does not include itself */938938+ end = p + len;939939+940940+ entry_type = get_unaligned((u32 *)p);941941+ p += 4;942942+943943+ if (entry_type == DW_EH_FRAME_CIE) {944944+ err = dwarf_parse_cie(entry, p, len, end, mod);945945+ if (err < 0)946946+ goto out;947947+ else948948+ c_entries++;949949+ } else {950950+ err = dwarf_parse_fde(entry, entry_type, p, len,951951+ end, mod);952952+ if (err < 0)953953+ goto out;954954+ else955955+ f_entries++;956956+ }957957+958958+ entry = (char *)entry + len + 4;959959+ }960960+961961+ printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",962962+ c_entries, f_entries);963963+964964+ return 0;965965+966966+out:967967+ return err;968968+}969969+970970+#ifdef CONFIG_MODULES971971+int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,972972+ struct module *me)973973+{974974+ unsigned int i, err;975975+ unsigned long start, end;976976+ char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;977977+978978+ start = end = 0;979979+980980+ for (i = 1; i < hdr->e_shnum; i++) {981981+ /* Alloc bit cleared means "ignore it." */982982+ if ((sechdrs[i].sh_flags & SHF_ALLOC)983983+ && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {984984+ start = sechdrs[i].sh_addr;985985+ end = start + sechdrs[i].sh_size;986986+ break;987987+ }988988+ }989989+990990+ /* Did we find the .eh_frame section? */991991+ if (i != hdr->e_shnum) {992992+ err = dwarf_parse_section((char *)start, (char *)end, me);993993+ if (err) {994994+ printk(KERN_WARNING "%s: failed to parse DWARF info\n",995995+ me->name);996996+ return err;997997+ }998998+ }999999+10001000+ return 0;10011001+}10021002+10031003+/**10041004+ * module_dwarf_cleanup - remove FDE/CIEs associated with @mod10051005+ * @mod: the module that is being unloaded10061006+ *10071007+ * Remove any FDEs and CIEs from the global lists that came from10081008+ * @mod's .eh_frame section because @mod is being unloaded.10091009+ */10101010+void module_dwarf_cleanup(struct module *mod)10111011+{10121012+ struct dwarf_fde *fde;10131013+ struct dwarf_cie *cie;10141014+ unsigned long flags;10151015+10161016+ spin_lock_irqsave(&dwarf_cie_lock, flags);10171017+10181018+again_cie:10191019+ list_for_each_entry(cie, &dwarf_cie_list, link) {10201020+ if (cie->mod == mod)10211021+ break;10221022+ }10231023+10241024+ if (&cie->link != &dwarf_cie_list) {10251025+ list_del(&cie->link);10261026+ kfree(cie);10271027+ goto again_cie;10281028+ }10291029+10301030+ spin_unlock_irqrestore(&dwarf_cie_lock, flags);10311031+10321032+ spin_lock_irqsave(&dwarf_fde_lock, flags);10331033+10341034+again_fde:10351035+ list_for_each_entry(fde, &dwarf_fde_list, link) {10361036+ if (fde->mod == mod)10371037+ break;10381038+ }10391039+10401040+ if (&fde->link != &dwarf_fde_list) {10411041+ list_del(&fde->link);10421042+ kfree(fde);10431043+ goto again_fde;10441044+ }10451045+10461046+ spin_unlock_irqrestore(&dwarf_fde_lock, flags);10471047+}10481048+#endif /* CONFIG_MODULES */10491049+10501050+/**9141051 * dwarf_unwinder_init - initialise the dwarf unwinder9151052 *9161053 * Build the data structures describing the .dwarf_frame section to···1073906 */1074907static int __init dwarf_unwinder_init(void)1075908{10761076- u32 entry_type;10771077- void *p, *entry;10781078- int count, err = 0;10791079- unsigned long len;10801080- unsigned int c_entries, f_entries;10811081- unsigned char *end;909909+ int err;1082910 INIT_LIST_HEAD(&dwarf_cie_list);1083911 INIT_LIST_HEAD(&dwarf_fde_list);10841084-10851085- c_entries = 0;10861086- f_entries = 0;10871087- entry = &__start_eh_frame;10889121089913 dwarf_frame_cachep = kmem_cache_create("dwarf_frames",1090914 sizeof(struct dwarf_frame), 0,···1095937 mempool_free_slab,1096938 dwarf_reg_cachep);109793910981098- while ((char *)entry < __stop_eh_frame) {10991099- p = entry;11001100-11011101- count = dwarf_entry_len(p, &len);11021102- if (count == 0) {11031103- /*11041104- * We read a bogus length field value. There is11051105- * nothing we can do here apart from disabling11061106- * the DWARF unwinder. We can't even skip this11071107- * entry and move to the next one because 'len'11081108- * tells us where our next entry is.11091109- */11101110- goto out;11111111- } else11121112- p += count;11131113-11141114- /* initial length does not include itself */11151115- end = p + len;11161116-11171117- entry_type = get_unaligned((u32 *)p);11181118- p += 4;11191119-11201120- if (entry_type == DW_EH_FRAME_CIE) {11211121- err = dwarf_parse_cie(entry, p, len, end);11221122- if (err < 0)11231123- goto out;11241124- else11251125- c_entries++;11261126- } else {11271127- err = dwarf_parse_fde(entry, entry_type, p, len, end);11281128- if (err < 0)11291129- goto out;11301130- else11311131- f_entries++;11321132- }11331133-11341134- entry = (char *)entry + len + 4;11351135- }11361136-11371137- printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",11381138- c_entries, f_entries);940940+ err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL);941941+ if (err)942942+ goto out;11399431140944 err = unwinder_register(&dwarf_unwinder);1141945 if (err)
···6262 return ftrace_replaced_code;6363}64646565+/*6666+ * Modifying code must take extra care. On an SMP machine, if6767+ * the code being modified is also being executed on another CPU6868+ * that CPU will have undefined results and possibly take a GPF.6969+ * We use kstop_machine to stop other CPUS from exectuing code.7070+ * But this does not stop NMIs from happening. We still need7171+ * to protect against that. We separate out the modification of7272+ * the code to take care of this.7373+ *7474+ * Two buffers are added: An IP buffer and a "code" buffer.7575+ *7676+ * 1) Put the instruction pointer into the IP buffer7777+ * and the new code into the "code" buffer.7878+ * 2) Wait for any running NMIs to finish and set a flag that says7979+ * we are modifying code, it is done in an atomic operation.8080+ * 3) Write the code8181+ * 4) clear the flag.8282+ * 5) Wait for any running NMIs to finish.8383+ *8484+ * If an NMI is executed, the first thing it does is to call8585+ * "ftrace_nmi_enter". This will check if the flag is set to write8686+ * and if it is, it will write what is in the IP and "code" buffers.8787+ *8888+ * The trick is, it does not matter if everyone is writing the same8989+ * content to the code location. Also, if a CPU is executing code9090+ * it is OK to write to that code location if the contents being written9191+ * are the same as what exists.9292+ */9393+#define MOD_CODE_WRITE_FLAG (1 << 31) /* set when NMI should do the write */9494+static atomic_t nmi_running = ATOMIC_INIT(0);9595+static int mod_code_status; /* holds return value of text write */9696+static void *mod_code_ip; /* holds the IP to write to */9797+static void *mod_code_newcode; /* holds the text to write to the IP */9898+9999+static unsigned nmi_wait_count;100100+static atomic_t nmi_update_count = ATOMIC_INIT(0);101101+102102+int ftrace_arch_read_dyn_info(char *buf, int size)103103+{104104+ int r;105105+106106+ r = snprintf(buf, size, "%u %u",107107+ nmi_wait_count,108108+ atomic_read(&nmi_update_count));109109+ return r;110110+}111111+112112+static void clear_mod_flag(void)113113+{114114+ int old = atomic_read(&nmi_running);115115+116116+ for (;;) {117117+ int new = old & ~MOD_CODE_WRITE_FLAG;118118+119119+ if (old == new)120120+ break;121121+122122+ old = atomic_cmpxchg(&nmi_running, old, new);123123+ }124124+}125125+126126+static void ftrace_mod_code(void)127127+{128128+ /*129129+ * Yes, more than one CPU process can be writing to mod_code_status.130130+ * (and the code itself)131131+ * But if one were to fail, then they all should, and if one were132132+ * to succeed, then they all should.133133+ */134134+ mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode,135135+ MCOUNT_INSN_SIZE);136136+137137+ /* if we fail, then kill any new writers */138138+ if (mod_code_status)139139+ clear_mod_flag();140140+}141141+142142+void ftrace_nmi_enter(void)143143+{144144+ if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {145145+ smp_rmb();146146+ ftrace_mod_code();147147+ atomic_inc(&nmi_update_count);148148+ }149149+ /* Must have previous changes seen before executions */150150+ smp_mb();151151+}152152+153153+void ftrace_nmi_exit(void)154154+{155155+ /* Finish all executions before clearing nmi_running */156156+ smp_mb();157157+ atomic_dec(&nmi_running);158158+}159159+160160+static void wait_for_nmi_and_set_mod_flag(void)161161+{162162+ if (!atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG))163163+ return;164164+165165+ do {166166+ cpu_relax();167167+ } while (atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG));168168+169169+ nmi_wait_count++;170170+}171171+172172+static void wait_for_nmi(void)173173+{174174+ if (!atomic_read(&nmi_running))175175+ return;176176+177177+ do {178178+ cpu_relax();179179+ } while (atomic_read(&nmi_running));180180+181181+ nmi_wait_count++;182182+}183183+184184+static int185185+do_ftrace_mod_code(unsigned long ip, void *new_code)186186+{187187+ mod_code_ip = (void *)ip;188188+ mod_code_newcode = new_code;189189+190190+ /* The buffers need to be visible before we let NMIs write them */191191+ smp_mb();192192+193193+ wait_for_nmi_and_set_mod_flag();194194+195195+ /* Make sure all running NMIs have finished before we write the code */196196+ smp_mb();197197+198198+ ftrace_mod_code();199199+200200+ /* Make sure the write happens before clearing the bit */201201+ smp_mb();202202+203203+ clear_mod_flag();204204+ wait_for_nmi();205205+206206+ return mod_code_status;207207+}208208+65209static int ftrace_modify_code(unsigned long ip, unsigned char *old_code,66210 unsigned char *new_code)67211{···23086 return -EINVAL;2318723288 /* replace the text with the new text */233233- if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))8989+ if (do_ftrace_mod_code(ip, new_code))23490 return -EPERM;2359123692 flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
···2121#include <asm/atomic.h>22222323static int hlt_counter;2424-void (*pm_idle)(void);2424+void (*pm_idle)(void) = NULL;2525void (*pm_power_off)(void);2626EXPORT_SYMBOL(pm_power_off);2727···3939}4040__setup("hlt", hlt_setup);41414242-void default_idle(void)4242+static inline int hlt_works(void)4343{4444- if (!hlt_counter) {4545- clear_thread_flag(TIF_POLLING_NRFLAG);4646- smp_mb__after_clear_bit();4747- set_bl_bit();4848- stop_critical_timings();4949-5050- while (!need_resched())5151- cpu_sleep();5252-5353- start_critical_timings();5454- clear_bl_bit();5555- set_thread_flag(TIF_POLLING_NRFLAG);5656- } else5757- while (!need_resched())5858- cpu_relax();4444+ return !hlt_counter;5945}60464747+/*4848+ * On SMP it's slightly faster (but much more power-consuming!)4949+ * to poll the ->work.need_resched flag instead of waiting for the5050+ * cross-CPU IPI to arrive. Use this option with caution.5151+ */5252+static void poll_idle(void)5353+{5454+ local_irq_enable();5555+ while (!need_resched())5656+ cpu_relax();5757+}5858+5959+void default_idle(void)6060+{6161+ if (hlt_works()) {6262+ clear_thread_flag(TIF_POLLING_NRFLAG);6363+ smp_mb__after_clear_bit();6464+6565+ if (!need_resched()) {6666+ local_irq_enable();6767+ cpu_sleep();6868+ } else6969+ local_irq_enable();7070+7171+ set_thread_flag(TIF_POLLING_NRFLAG);7272+ } else7373+ poll_idle();7474+}7575+7676+/*7777+ * The idle thread. There's no useful work to be done, so just try to conserve7878+ * power and have a low exit latency (ie sit in a loop waiting for somebody to7979+ * say that they'd like to reschedule)8080+ */6181void cpu_idle(void)6282{8383+ unsigned int cpu = smp_processor_id();8484+6385 set_thread_flag(TIF_POLLING_NRFLAG);64866587 /* endless idle loop with no priority at all */6688 while (1) {6767- void (*idle)(void) = pm_idle;6868-6969- if (!idle)7070- idle = default_idle;7171-7289 tick_nohz_stop_sched_tick(1);7373- while (!need_resched())7474- idle();7575- tick_nohz_restart_sched_tick();76909191+ while (!need_resched() && cpu_online(cpu)) {9292+ check_pgt_cache();9393+ rmb();9494+9595+ local_irq_disable();9696+ /* Don't trace irqs off for idle */9797+ stop_critical_timings();9898+ pm_idle();9999+ /*100100+ * Sanity check to ensure that pm_idle() returns101101+ * with IRQs enabled102102+ */103103+ WARN_ON(irqs_disabled());104104+ start_critical_timings();105105+ }106106+107107+ tick_nohz_restart_sched_tick();77108 preempt_enable_no_resched();78109 schedule();79110 preempt_disable();8080- check_pgt_cache();81111 }112112+}113113+114114+void __cpuinit select_idle_routine(void)115115+{116116+ /*117117+ * If a platform has set its own idle routine, leave it alone.118118+ */119119+ if (pm_idle)120120+ return;121121+122122+ if (hlt_works())123123+ pm_idle = default_idle;124124+ else125125+ pm_idle = poll_idle;82126}8312784128static void do_nothing(void *unused)
+3-1
arch/sh/kernel/io_generic.c
···2424#define dummy_read()2525#endif26262727-unsigned long generic_io_base;2727+unsigned long generic_io_base = 0;28282929u8 generic_inb(unsigned long port)3030{···147147148148void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)149149{150150+#ifdef P1SEG150151 if (PXSEG(addr) >= P1SEG)151152 return (void __iomem *)addr;153153+#endif152154153155 return (void __iomem *)(addr + generic_io_base);154156}
+14
arch/sh/kernel/irq.c
···3737 */3838static int show_other_interrupts(struct seq_file *p, int prec)3939{4040+ int j;4141+4242+ seq_printf(p, "%*s: ", prec, "NMI");4343+ for_each_online_cpu(j)4444+ seq_printf(p, "%10u ", irq_stat[j].__nmi_count);4545+ seq_printf(p, " Non-maskable interrupts\n");4646+4047 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));4848+4149 return 0;4250}4351···262254void __init init_IRQ(void)263255{264256 plat_irq_setup();257257+258258+ /*259259+ * Pin any of the legacy IRQ vectors that haven't already been260260+ * grabbed by the platform261261+ */262262+ reserve_irq_legacy();265263266264 /* Perform the machine specific initialisation */267265 if (sh_mv.mv_init_irq)
+57
arch/sh/kernel/irq_32.c
···11+/*22+ * SHcompact irqflags support33+ *44+ * Copyright (C) 2006 - 2009 Paul Mundt55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+#include <linux/irqflags.h>1111+#include <linux/module.h>1212+1313+void notrace raw_local_irq_restore(unsigned long flags)1414+{1515+ unsigned long __dummy0, __dummy1;1616+1717+ if (flags == RAW_IRQ_DISABLED) {1818+ __asm__ __volatile__ (1919+ "stc sr, %0\n\t"2020+ "or #0xf0, %0\n\t"2121+ "ldc %0, sr\n\t"2222+ : "=&z" (__dummy0)2323+ : /* no inputs */2424+ : "memory"2525+ );2626+ } else {2727+ __asm__ __volatile__ (2828+ "stc sr, %0\n\t"2929+ "and %1, %0\n\t"3030+#ifdef CONFIG_CPU_HAS_SR_RB3131+ "stc r6_bank, %1\n\t"3232+ "or %1, %0\n\t"3333+#endif3434+ "ldc %0, sr\n\t"3535+ : "=&r" (__dummy0), "=r" (__dummy1)3636+ : "1" (~RAW_IRQ_DISABLED)3737+ : "memory"3838+ );3939+ }4040+}4141+EXPORT_SYMBOL(raw_local_irq_restore);4242+4343+unsigned long notrace __raw_local_save_flags(void)4444+{4545+ unsigned long flags;4646+4747+ __asm__ __volatile__ (4848+ "stc sr, %0\n\t"4949+ "and #0xf0, %0\n\t"5050+ : "=&z" (flags)5151+ : /* no inputs */5252+ : "memory"5353+ );5454+5555+ return flags;5656+}5757+EXPORT_SYMBOL(__raw_local_save_flags);
+51
arch/sh/kernel/irq_64.c
···11+/*22+ * SHmedia irqflags support33+ *44+ * Copyright (C) 2006 - 2009 Paul Mundt55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+#include <linux/irqflags.h>1111+#include <linux/module.h>1212+#include <cpu/registers.h>1313+1414+void notrace raw_local_irq_restore(unsigned long flags)1515+{1616+ unsigned long long __dummy;1717+1818+ if (flags == RAW_IRQ_DISABLED) {1919+ __asm__ __volatile__ (2020+ "getcon " __SR ", %0\n\t"2121+ "or %0, %1, %0\n\t"2222+ "putcon %0, " __SR "\n\t"2323+ : "=&r" (__dummy)2424+ : "r" (RAW_IRQ_DISABLED)2525+ );2626+ } else {2727+ __asm__ __volatile__ (2828+ "getcon " __SR ", %0\n\t"2929+ "and %0, %1, %0\n\t"3030+ "putcon %0, " __SR "\n\t"3131+ : "=&r" (__dummy)3232+ : "r" (~RAW_IRQ_DISABLED)3333+ );3434+ }3535+}3636+EXPORT_SYMBOL(raw_local_irq_restore);3737+3838+unsigned long notrace __raw_local_save_flags(void)3939+{4040+ unsigned long flags;4141+4242+ __asm__ __volatile__ (4343+ "getcon " __SR ", %0\n\t"4444+ "and %0, %1, %0"4545+ : "=&r" (flags)4646+ : "r" (RAW_IRQ_DISABLED)4747+ );4848+4949+ return flags;5050+}5151+EXPORT_SYMBOL(__raw_local_save_flags);
-6
arch/sh/kernel/machine_kexec.c
···4646 */4747int machine_kexec_prepare(struct kimage *image)4848{4949- /* older versions of kexec-tools are passing5050- * the zImage entry point as a virtual address.5151- */5252- if (image->start != PHYSADDR(image->start))5353- return -EINVAL; /* upgrade your kexec-tools */5454-5549 return 0;5650}5751
+4
arch/sh/kernel/machvec.c
···135135 if (!sh_mv.mv_nr_irqs)136136 sh_mv.mv_nr_irqs = NR_IRQS;137137138138+#ifdef P2SEG138139 __set_io_port_base(P2SEG);140140+#else141141+ __set_io_port_base(0);142142+#endif139143}
+8-1
arch/sh/kernel/module.c
···3232#include <linux/string.h>3333#include <linux/kernel.h>3434#include <asm/unaligned.h>3535+#include <asm/dwarf.h>35363637void *module_alloc(unsigned long size)3738{···146145 const Elf_Shdr *sechdrs,147146 struct module *me)148147{149149- return module_bug_finalize(hdr, sechdrs, me);148148+ int ret = 0;149149+150150+ ret |= module_dwarf_finalize(hdr, sechdrs, me);151151+ ret |= module_bug_finalize(hdr, sechdrs, me);152152+153153+ return ret;150154}151155152156void module_arch_cleanup(struct module *mod)153157{154158 module_bug_cleanup(mod);159159+ module_dwarf_cleanup(mod);155160}
+98
arch/sh/kernel/perf_callchain.c
···11+/*22+ * Performance event callchain support - SuperH architecture code33+ *44+ * Copyright (C) 2009 Paul Mundt55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file "COPYING" in the main directory of this archive88+ * for more details.99+ */1010+#include <linux/kernel.h>1111+#include <linux/sched.h>1212+#include <linux/perf_event.h>1313+#include <linux/percpu.h>1414+#include <asm/unwinder.h>1515+#include <asm/ptrace.h>1616+1717+static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)1818+{1919+ if (entry->nr < PERF_MAX_STACK_DEPTH)2020+ entry->ip[entry->nr++] = ip;2121+}2222+2323+static void callchain_warning(void *data, char *msg)2424+{2525+}2626+2727+static void2828+callchain_warning_symbol(void *data, char *msg, unsigned long symbol)2929+{3030+}3131+3232+static int callchain_stack(void *data, char *name)3333+{3434+ return 0;3535+}3636+3737+static void callchain_address(void *data, unsigned long addr, int reliable)3838+{3939+ struct perf_callchain_entry *entry = data;4040+4141+ if (reliable)4242+ callchain_store(entry, addr);4343+}4444+4545+static const struct stacktrace_ops callchain_ops = {4646+ .warning = callchain_warning,4747+ .warning_symbol = callchain_warning_symbol,4848+ .stack = callchain_stack,4949+ .address = callchain_address,5050+};5151+5252+static void5353+perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)5454+{5555+ callchain_store(entry, PERF_CONTEXT_KERNEL);5656+ callchain_store(entry, regs->pc);5757+5858+ unwind_stack(NULL, regs, NULL, &callchain_ops, entry);5959+}6060+6161+static void6262+perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)6363+{6464+ int is_user;6565+6666+ if (!regs)6767+ return;6868+6969+ is_user = user_mode(regs);7070+7171+ if (!current || current->pid == 0)7272+ return;7373+7474+ if (is_user && current->state != TASK_RUNNING)7575+ return;7676+7777+ /*7878+ * Only the kernel side is implemented for now.7979+ */8080+ if (!is_user)8181+ perf_callchain_kernel(regs, entry);8282+}8383+8484+/*8585+ * No need for separate IRQ and NMI entries.8686+ */8787+static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);8888+8989+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)9090+{9191+ struct perf_callchain_entry *entry = &__get_cpu_var(callchain);9292+9393+ entry->nr = 0;9494+9595+ perf_do_callchain(regs, entry);9696+9797+ return entry;9898+}
+312
arch/sh/kernel/perf_event.c
···11+/*22+ * Performance event support framework for SuperH hardware counters.33+ *44+ * Copyright (C) 2009 Paul Mundt55+ *66+ * Heavily based on the x86 and PowerPC implementations.77+ *88+ * x86:99+ * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>1010+ * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar1111+ * Copyright (C) 2009 Jaswinder Singh Rajput1212+ * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter1313+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>1414+ * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>1515+ *1616+ * ppc:1717+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.1818+ *1919+ * This file is subject to the terms and conditions of the GNU General Public2020+ * License. See the file "COPYING" in the main directory of this archive2121+ * for more details.2222+ */2323+#include <linux/kernel.h>2424+#include <linux/init.h>2525+#include <linux/io.h>2626+#include <linux/irq.h>2727+#include <linux/perf_event.h>2828+#include <asm/processor.h>2929+3030+struct cpu_hw_events {3131+ struct perf_event *events[MAX_HWEVENTS];3232+ unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];3333+ unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];3434+};3535+3636+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);3737+3838+static struct sh_pmu *sh_pmu __read_mostly;3939+4040+/* Number of perf_events counting hardware events */4141+static atomic_t num_events;4242+/* Used to avoid races in calling reserve/release_pmc_hardware */4343+static DEFINE_MUTEX(pmc_reserve_mutex);4444+4545+/*4646+ * Stub these out for now, do something more profound later.4747+ */4848+int reserve_pmc_hardware(void)4949+{5050+ return 0;5151+}5252+5353+void release_pmc_hardware(void)5454+{5555+}5656+5757+static inline int sh_pmu_initialized(void)5858+{5959+ return !!sh_pmu;6060+}6161+6262+/*6363+ * Release the PMU if this is the last perf_event.6464+ */6565+static void hw_perf_event_destroy(struct perf_event *event)6666+{6767+ if (!atomic_add_unless(&num_events, -1, 1)) {6868+ mutex_lock(&pmc_reserve_mutex);6969+ if (atomic_dec_return(&num_events) == 0)7070+ release_pmc_hardware();7171+ mutex_unlock(&pmc_reserve_mutex);7272+ }7373+}7474+7575+static int hw_perf_cache_event(int config, int *evp)7676+{7777+ unsigned long type, op, result;7878+ int ev;7979+8080+ if (!sh_pmu->cache_events)8181+ return -EINVAL;8282+8383+ /* unpack config */8484+ type = config & 0xff;8585+ op = (config >> 8) & 0xff;8686+ result = (config >> 16) & 0xff;8787+8888+ if (type >= PERF_COUNT_HW_CACHE_MAX ||8989+ op >= PERF_COUNT_HW_CACHE_OP_MAX ||9090+ result >= PERF_COUNT_HW_CACHE_RESULT_MAX)9191+ return -EINVAL;9292+9393+ ev = (*sh_pmu->cache_events)[type][op][result];9494+ if (ev == 0)9595+ return -EOPNOTSUPP;9696+ if (ev == -1)9797+ return -EINVAL;9898+ *evp = ev;9999+ return 0;100100+}101101+102102+static int __hw_perf_event_init(struct perf_event *event)103103+{104104+ struct perf_event_attr *attr = &event->attr;105105+ struct hw_perf_event *hwc = &event->hw;106106+ int config = -1;107107+ int err;108108+109109+ if (!sh_pmu_initialized())110110+ return -ENODEV;111111+112112+ /*113113+ * All of the on-chip counters are "limited", in that they have114114+ * no interrupts, and are therefore unable to do sampling without115115+ * further work and timer assistance.116116+ */117117+ if (hwc->sample_period)118118+ return -EINVAL;119119+120120+ /*121121+ * See if we need to reserve the counter.122122+ *123123+ * If no events are currently in use, then we have to take a124124+ * mutex to ensure that we don't race with another task doing125125+ * reserve_pmc_hardware or release_pmc_hardware.126126+ */127127+ err = 0;128128+ if (!atomic_inc_not_zero(&num_events)) {129129+ mutex_lock(&pmc_reserve_mutex);130130+ if (atomic_read(&num_events) == 0 &&131131+ reserve_pmc_hardware())132132+ err = -EBUSY;133133+ else134134+ atomic_inc(&num_events);135135+ mutex_unlock(&pmc_reserve_mutex);136136+ }137137+138138+ if (err)139139+ return err;140140+141141+ event->destroy = hw_perf_event_destroy;142142+143143+ switch (attr->type) {144144+ case PERF_TYPE_RAW:145145+ config = attr->config & sh_pmu->raw_event_mask;146146+ break;147147+ case PERF_TYPE_HW_CACHE:148148+ err = hw_perf_cache_event(attr->config, &config);149149+ if (err)150150+ return err;151151+ break;152152+ case PERF_TYPE_HARDWARE:153153+ if (attr->config >= sh_pmu->max_events)154154+ return -EINVAL;155155+156156+ config = sh_pmu->event_map(attr->config);157157+ break;158158+ }159159+160160+ if (config == -1)161161+ return -EINVAL;162162+163163+ hwc->config |= config;164164+165165+ return 0;166166+}167167+168168+static void sh_perf_event_update(struct perf_event *event,169169+ struct hw_perf_event *hwc, int idx)170170+{171171+ u64 prev_raw_count, new_raw_count;172172+ s64 delta;173173+ int shift = 0;174174+175175+ /*176176+ * Depending on the counter configuration, they may or may not177177+ * be chained, in which case the previous counter value can be178178+ * updated underneath us if the lower-half overflows.179179+ *180180+ * Our tactic to handle this is to first atomically read and181181+ * exchange a new raw count - then add that new-prev delta182182+ * count to the generic counter atomically.183183+ *184184+ * As there is no interrupt associated with the overflow events,185185+ * this is the simplest approach for maintaining consistency.186186+ */187187+again:188188+ prev_raw_count = atomic64_read(&hwc->prev_count);189189+ new_raw_count = sh_pmu->read(idx);190190+191191+ if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,192192+ new_raw_count) != prev_raw_count)193193+ goto again;194194+195195+ /*196196+ * Now we have the new raw value and have updated the prev197197+ * timestamp already. We can now calculate the elapsed delta198198+ * (counter-)time and add that to the generic counter.199199+ *200200+ * Careful, not all hw sign-extends above the physical width201201+ * of the count.202202+ */203203+ delta = (new_raw_count << shift) - (prev_raw_count << shift);204204+ delta >>= shift;205205+206206+ atomic64_add(delta, &event->count);207207+}208208+209209+static void sh_pmu_disable(struct perf_event *event)210210+{211211+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);212212+ struct hw_perf_event *hwc = &event->hw;213213+ int idx = hwc->idx;214214+215215+ clear_bit(idx, cpuc->active_mask);216216+ sh_pmu->disable(hwc, idx);217217+218218+ barrier();219219+220220+ sh_perf_event_update(event, &event->hw, idx);221221+222222+ cpuc->events[idx] = NULL;223223+ clear_bit(idx, cpuc->used_mask);224224+225225+ perf_event_update_userpage(event);226226+}227227+228228+static int sh_pmu_enable(struct perf_event *event)229229+{230230+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);231231+ struct hw_perf_event *hwc = &event->hw;232232+ int idx = hwc->idx;233233+234234+ if (test_and_set_bit(idx, cpuc->used_mask)) {235235+ idx = find_first_zero_bit(cpuc->used_mask, sh_pmu->num_events);236236+ if (idx == sh_pmu->num_events)237237+ return -EAGAIN;238238+239239+ set_bit(idx, cpuc->used_mask);240240+ hwc->idx = idx;241241+ }242242+243243+ sh_pmu->disable(hwc, idx);244244+245245+ cpuc->events[idx] = event;246246+ set_bit(idx, cpuc->active_mask);247247+248248+ sh_pmu->enable(hwc, idx);249249+250250+ perf_event_update_userpage(event);251251+252252+ return 0;253253+}254254+255255+static void sh_pmu_read(struct perf_event *event)256256+{257257+ sh_perf_event_update(event, &event->hw, event->hw.idx);258258+}259259+260260+static const struct pmu pmu = {261261+ .enable = sh_pmu_enable,262262+ .disable = sh_pmu_disable,263263+ .read = sh_pmu_read,264264+};265265+266266+const struct pmu *hw_perf_event_init(struct perf_event *event)267267+{268268+ int err = __hw_perf_event_init(event);269269+ if (unlikely(err)) {270270+ if (event->destroy)271271+ event->destroy(event);272272+ return ERR_PTR(err);273273+ }274274+275275+ return &pmu;276276+}277277+278278+void hw_perf_event_setup(int cpu)279279+{280280+ struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);281281+282282+ memset(cpuhw, 0, sizeof(struct cpu_hw_events));283283+}284284+285285+void hw_perf_enable(void)286286+{287287+ if (!sh_pmu_initialized())288288+ return;289289+290290+ sh_pmu->enable_all();291291+}292292+293293+void hw_perf_disable(void)294294+{295295+ if (!sh_pmu_initialized())296296+ return;297297+298298+ sh_pmu->disable_all();299299+}300300+301301+int register_sh_pmu(struct sh_pmu *pmu)302302+{303303+ if (sh_pmu)304304+ return -EBUSY;305305+ sh_pmu = pmu;306306+307307+ pr_info("Performance Events: %s support registered\n", pmu->name);308308+309309+ WARN_ON(pmu->num_events > MAX_HWEVENTS);310310+311311+ return 0;312312+}
···335335 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,336336 ®s, 0, NULL, NULL);337337}338338+EXPORT_SYMBOL(kernel_thread);338339339340/*340341 * Free current thread data structures etc..···418417 return 0; /* Task didn't use the fpu at all. */419418#endif420419}420420+EXPORT_SYMBOL(dump_fpu);421421422422asmlinkage void ret_from_fork(void);423423
+54
arch/sh/kernel/return_address.c
···11+/*22+ * arch/sh/kernel/return_address.c33+ *44+ * Copyright (C) 2009 Matt Fleming55+ * Copyright (C) 2009 Paul Mundt66+ *77+ * This file is subject to the terms and conditions of the GNU General Public88+ * License. See the file "COPYING" in the main directory of this archive99+ * for more details.1010+ */1111+#include <linux/kernel.h>1212+#include <asm/dwarf.h>1313+1414+#ifdef CONFIG_DWARF_UNWINDER1515+1616+void *return_address(unsigned int depth)1717+{1818+ struct dwarf_frame *frame;1919+ unsigned long ra;2020+ int i;2121+2222+ for (i = 0, frame = NULL, ra = 0; i <= depth; i++) {2323+ struct dwarf_frame *tmp;2424+2525+ tmp = dwarf_unwind_stack(ra, frame);2626+2727+ if (frame)2828+ dwarf_free_frame(frame);2929+3030+ frame = tmp;3131+3232+ if (!frame || !frame->return_addr)3333+ break;3434+3535+ ra = frame->return_addr;3636+ }3737+3838+ /* Failed to unwind the stack to the specified depth. */3939+ WARN_ON(i != depth + 1);4040+4141+ if (frame)4242+ dwarf_free_frame(frame);4343+4444+ return (void *)ra;4545+}4646+4747+#else4848+4949+void *return_address(unsigned int depth)5050+{5151+ return NULL;5252+}5353+5454+#endif
···2424#include <asm/delay.h>2525#include <asm/irq.h>26262727-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);2828-2929-/* platform dependent support */3030-EXPORT_SYMBOL(dump_fpu);3131-EXPORT_SYMBOL(kernel_thread);3232-3333-#ifdef CONFIG_VT3434-EXPORT_SYMBOL(screen_info);3535-#endif3636-3727EXPORT_SYMBOL(__put_user_asm_b);3828EXPORT_SYMBOL(__put_user_asm_w);3929EXPORT_SYMBOL(__put_user_asm_l);
+14-10
arch/sh/kernel/signal_32.c
···67676868 current->state = TASK_INTERRUPTIBLE;6969 schedule();7070- set_thread_flag(TIF_RESTORE_SIGMASK);7070+ set_restore_sigmask();7171+7172 return -ERESTARTNOHAND;7273}7374···591590 if (try_to_freeze())592591 goto no_signal;593592594594- if (test_thread_flag(TIF_RESTORE_SIGMASK))593593+ if (current_thread_info()->status & TS_RESTORE_SIGMASK)595594 oldset = ¤t->saved_sigmask;596595 else597596 oldset = ¤t->blocked;···603602 /* Whee! Actually deliver the signal. */604603 if (handle_signal(signr, &ka, &info, oldset,605604 regs, save_r0) == 0) {606606- /* a signal was successfully delivered; the saved605605+ /*606606+ * A signal was successfully delivered; the saved607607 * sigmask will have been stored in the signal frame,608608 * and will be restored by sigreturn, so we can simply609609- * clear the TIF_RESTORE_SIGMASK flag */610610- if (test_thread_flag(TIF_RESTORE_SIGMASK))611611- clear_thread_flag(TIF_RESTORE_SIGMASK);609609+ * clear the TS_RESTORE_SIGMASK flag610610+ */611611+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;612612613613 tracehook_signal_handler(signr, &info, &ka, regs,614614 test_thread_flag(TIF_SINGLESTEP));···633631 }634632 }635633636636- /* if there's no signal to deliver, we just put the saved sigmask637637- * back */638638- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {639639- clear_thread_flag(TIF_RESTORE_SIGMASK);634634+ /*635635+ * If there's no signal to deliver, we just put the saved sigmask636636+ * back.637637+ */638638+ if (current_thread_info()->status & TS_RESTORE_SIGMASK) {639639+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;640640 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);641641 }642642}
+6-7
arch/sh/kernel/signal_64.c
···101101 if (try_to_freeze())102102 goto no_signal;103103104104- if (test_thread_flag(TIF_RESTORE_SIGMASK))104104+ if (current_thread_info()->status & TS_RESTORE_SIGMASK)105105 oldset = ¤t->saved_sigmask;106106 else if (!oldset)107107 oldset = ¤t->blocked;···115115 /*116116 * If a signal was successfully delivered, the117117 * saved sigmask is in its frame, and we can118118- * clear the TIF_RESTORE_SIGMASK flag.118118+ * clear the TS_RESTORE_SIGMASK flag.119119 */120120- if (test_thread_flag(TIF_RESTORE_SIGMASK))121121- clear_thread_flag(TIF_RESTORE_SIGMASK);122122-120120+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;123121 tracehook_signal_handler(signr, &info, &ka, regs, 0);124122 return 1;125123 }···144146 }145147146148 /* No signal to deliver -- put the saved sigmask back */147147- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {148148- clear_thread_flag(TIF_RESTORE_SIGMASK);149149+ if (current_thread_info()->status & TS_RESTORE_SIGMASK) {150150+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;149151 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);150152 }151153···174176 while (1) {175177 current->state = TASK_INTERRUPTIBLE;176178 schedule();179179+ set_restore_sigmask();177180 regs->pc += 4; /* because sys_sigreturn decrements the pc */178181 if (do_signal(regs, &saveset)) {179182 /* pc now points at signal handler. Need to decrement
···16161717static DEFINE_PER_CPU(struct cpu, cpu_devices);18181919+cpumask_t cpu_core_map[NR_CPUS];2020+2121+static cpumask_t cpu_coregroup_map(unsigned int cpu)2222+{2323+ /*2424+ * Presently all SH-X3 SMP cores are multi-cores, so just keep it2525+ * simple until we have a method for determining topology..2626+ */2727+ return cpu_possible_map;2828+}2929+3030+const struct cpumask *cpu_coregroup_mask(unsigned int cpu)3131+{3232+ return &cpu_core_map[cpu];3333+}3434+3535+int arch_update_cpu_topology(void)3636+{3737+ unsigned int cpu;3838+3939+ for_each_possible_cpu(cpu)4040+ cpu_core_map[cpu] = cpu_coregroup_map(cpu);4141+4242+ return 0;4343+}4444+1945static int __init topology_init(void)2046{2147 int i, ret;
+5-3
arch/sh/kernel/traps.c
···99#include <asm/unwinder.h>1010#include <asm/system.h>11111212-#ifdef CONFIG_BUG1313-void handle_BUG(struct pt_regs *regs)1212+#ifdef CONFIG_GENERIC_BUG1313+static void handle_BUG(struct pt_regs *regs)1414{1515 const struct bug_entry *bug;1616 unsigned long bugaddr = regs->pc;···8181 SIGTRAP) == NOTIFY_STOP)8282 return;83838484-#ifdef CONFIG_BUG8484+#ifdef CONFIG_GENERIC_BUG8585 if (__kernel_text_address(instruction_pointer(regs))) {8686 insn_size_t insn = *(insn_size_t *)instruction_pointer(regs);8787 if (insn == TRAPA_BUG_OPCODE)···95959696BUILD_TRAP_HANDLER(nmi)9797{9898+ unsigned int cpu = smp_processor_id();9899 TRAP_HANDLER_DECL;99100100101 nmi_enter();102102+ nmi_count(cpu)++;101103102104 switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {103105 case NOTIFY_OK:
···82828383config PMB_ENABLE8484 bool "Support 32-bit physical addressing through PMB"8585- depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)8686- select 32BIT8585+ depends on MMU && EXPERIMENTAL && CPU_SH4A8786 default y8887 help8988 If you say Y here, physical addressing will be extended to···96979798config PMB9899 bool "PMB"9999- depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)100100- select 32BIT100100+ depends on MMU && EXPERIMENTAL && CPU_SH4A101101 help102102 If you say Y here, physical addressing will be extended to103103 32-bits through the SH-4A PMB. If this is not set, legacy···104106105107config PMB_FIXED106108 bool "fixed PMB"107107- depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || \108108- CPU_SUBTYPE_SH7780 || \109109- CPU_SUBTYPE_SH7785)109109+ depends on MMU && EXPERIMENTAL && CPU_SH4A110110 select 32BIT111111 help112112 If this option is enabled, fixed PMB mappings are inherited···253257endchoice254258255259source "mm/Kconfig"260260+261261+config SCHED_MC262262+ bool "Multi-core scheduler support"263263+ depends on SMP264264+ default y265265+ help266266+ Multi-core scheduler support improves the CPU scheduler's decision267267+ making when dealing with multi-core CPU chips at a cost of slightly268268+ increased overhead in some places. If unsure say N here.256269257270endmenu258271
+1-2
arch/sh/mm/Makefile
···3333endif34343535obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o3636-obj-$(CONFIG_PMB) += pmb.o3737-obj-$(CONFIG_PMB_FIXED) += pmb-fixed.o3636+obj-$(CONFIG_PMB_ENABLE) += pmb.o3837obj-$(CONFIG_NUMA) += numa.o39384039# Special flags for fault_64.o. This puts restrictions on the number of
+78-425
arch/sh/mm/cache-sh4.c
···22 * arch/sh/mm/cache-sh4.c33 *44 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka55- * Copyright (C) 2001 - 2007 Paul Mundt55+ * Copyright (C) 2001 - 2009 Paul Mundt66 * Copyright (C) 2003 Richard Curnow77 * Copyright (c) 2007 STMicroelectronics (R&D) Ltd.88 *···1515#include <linux/io.h>1616#include <linux/mutex.h>1717#include <linux/fs.h>1818+#include <linux/highmem.h>1919+#include <asm/pgtable.h>1820#include <asm/mmu_context.h>1921#include <asm/cacheflush.h>2022···2523 * flushing. Anything exceeding this will simply flush the dcache in its2624 * entirety.2725 */2828-#define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */2926#define MAX_ICACHE_PAGES 3230273128static void __flush_cache_one(unsigned long addr, unsigned long phys,3229 unsigned long exec_offset);3333-3434-/*3535- * This is initialised here to ensure that it is not placed in the BSS. If3636- * that were to happen, note that cache_init gets called before the BSS is3737- * cleared, so this would get nulled out which would be hopeless.3838- */3939-static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =4040- (void (*)(unsigned long, unsigned long))0xdeadbeef;41304231/*4332 * Write back the range of D-cache, and purge the I-cache.···9097 unsigned long flags, exec_offset = 0;91989299 /*9393- * All types of SH-4 require PC to be in P2 to operate on the I-cache.9494- * Some types of SH-4 require PC to be in P2 to operate on the D-cache.100100+ * All types of SH-4 require PC to be uncached to operate on the I-cache.101101+ * Some types of SH-4 require PC to be uncached to operate on the D-cache.95102 */96103 if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) ||97104 (start < CACHE_OC_ADDRESS_ARRAY))9898- exec_offset = 0x20000000;105105+ exec_offset = cached_to_uncached;99106100107 local_irq_save(flags);101101- __flush_cache_one(start | SH_CACHE_ASSOC, P1SEGADDR(phys), exec_offset);108108+ __flush_cache_one(start | SH_CACHE_ASSOC, phys, exec_offset);102109 local_irq_restore(flags);103110}104111···117124 else118125#endif119126 {120120- unsigned long phys = PHYSADDR(page_address(page));127127+ unsigned long phys = page_to_phys(page);121128 unsigned long addr = CACHE_OC_ADDRESS_ARRAY;122129 int i, n;123130124131 /* Loop all the D-cache */125132 n = boot_cpu_data.dcache.n_aliases;126126- for (i = 0; i < n; i++, addr += PAGE_SIZE)133133+ for (i = 0; i <= n; i++, addr += PAGE_SIZE)127134 flush_cache_one(addr, phys);128135 }129136···152159 local_irq_restore(flags);153160}154161155155-static inline void flush_dcache_all(void)162162+static void flush_dcache_all(void)156163{157157- (*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size);158158- wmb();164164+ unsigned long addr, end_addr, entry_offset;165165+166166+ end_addr = CACHE_OC_ADDRESS_ARRAY +167167+ (current_cpu_data.dcache.sets <<168168+ current_cpu_data.dcache.entry_shift) *169169+ current_cpu_data.dcache.ways;170170+171171+ entry_offset = 1 << current_cpu_data.dcache.entry_shift;172172+173173+ for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; ) {174174+ __raw_writel(0, addr); addr += entry_offset;175175+ __raw_writel(0, addr); addr += entry_offset;176176+ __raw_writel(0, addr); addr += entry_offset;177177+ __raw_writel(0, addr); addr += entry_offset;178178+ __raw_writel(0, addr); addr += entry_offset;179179+ __raw_writel(0, addr); addr += entry_offset;180180+ __raw_writel(0, addr); addr += entry_offset;181181+ __raw_writel(0, addr); addr += entry_offset;182182+ }159183}160184161185static void sh4_flush_cache_all(void *unused)···181171 flush_icache_all();182172}183173184184-static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,185185- unsigned long end)186186-{187187- unsigned long d = 0, p = start & PAGE_MASK;188188- unsigned long alias_mask = boot_cpu_data.dcache.alias_mask;189189- unsigned long n_aliases = boot_cpu_data.dcache.n_aliases;190190- unsigned long select_bit;191191- unsigned long all_aliases_mask;192192- unsigned long addr_offset;193193- pgd_t *dir;194194- pmd_t *pmd;195195- pud_t *pud;196196- pte_t *pte;197197- int i;198198-199199- dir = pgd_offset(mm, p);200200- pud = pud_offset(dir, p);201201- pmd = pmd_offset(pud, p);202202- end = PAGE_ALIGN(end);203203-204204- all_aliases_mask = (1 << n_aliases) - 1;205205-206206- do {207207- if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) {208208- p &= PMD_MASK;209209- p += PMD_SIZE;210210- pmd++;211211-212212- continue;213213- }214214-215215- pte = pte_offset_kernel(pmd, p);216216-217217- do {218218- unsigned long phys;219219- pte_t entry = *pte;220220-221221- if (!(pte_val(entry) & _PAGE_PRESENT)) {222222- pte++;223223- p += PAGE_SIZE;224224- continue;225225- }226226-227227- phys = pte_val(entry) & PTE_PHYS_MASK;228228-229229- if ((p ^ phys) & alias_mask) {230230- d |= 1 << ((p & alias_mask) >> PAGE_SHIFT);231231- d |= 1 << ((phys & alias_mask) >> PAGE_SHIFT);232232-233233- if (d == all_aliases_mask)234234- goto loop_exit;235235- }236236-237237- pte++;238238- p += PAGE_SIZE;239239- } while (p < end && ((unsigned long)pte & ~PAGE_MASK));240240- pmd++;241241- } while (p < end);242242-243243-loop_exit:244244- addr_offset = 0;245245- select_bit = 1;246246-247247- for (i = 0; i < n_aliases; i++) {248248- if (d & select_bit) {249249- (*__flush_dcache_segment_fn)(addr_offset, PAGE_SIZE);250250- wmb();251251- }252252-253253- select_bit <<= 1;254254- addr_offset += PAGE_SIZE;255255- }256256-}257257-258174/*259175 * Note : (RPC) since the caches are physically tagged, the only point260176 * of flush_cache_mm for SH-4 is to get rid of aliases from the261177 * D-cache. The assumption elsewhere, e.g. flush_cache_range, is that262178 * lines can stay resident so long as the virtual address they were263179 * accessed with (hence cache set) is in accord with the physical264264- * address (i.e. tag). It's no different here. So I reckon we don't265265- * need to flush the I-cache, since aliases don't matter for that. We266266- * should try that.180180+ * address (i.e. tag). It's no different here.267181 *268182 * Caller takes mm->mmap_sem.269183 */···198264 if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT)199265 return;200266201201- /*202202- * If cache is only 4k-per-way, there are never any 'aliases'. Since203203- * the cache is physically tagged, the data can just be left in there.204204- */205205- if (boot_cpu_data.dcache.n_aliases == 0)206206- return;207207-208208- /*209209- * Don't bother groveling around the dcache for the VMA ranges210210- * if there are too many PTEs to make it worthwhile.211211- */212212- if (mm->nr_ptes >= MAX_DCACHE_PAGES)213213- flush_dcache_all();214214- else {215215- struct vm_area_struct *vma;216216-217217- /*218218- * In this case there are reasonably sized ranges to flush,219219- * iterate through the VMA list and take care of any aliases.220220- */221221- for (vma = mm->mmap; vma; vma = vma->vm_next)222222- __flush_cache_mm(mm, vma->vm_start, vma->vm_end);223223- }224224-225225- /* Only touch the icache if one of the VMAs has VM_EXEC set. */226226- if (mm->exec_vm)227227- flush_icache_all();267267+ flush_dcache_all();228268}229269230270/*···211303{212304 struct flusher_data *data = args;213305 struct vm_area_struct *vma;306306+ struct page *page;214307 unsigned long address, pfn, phys;215215- unsigned int alias_mask;308308+ int map_coherent = 0;309309+ pgd_t *pgd;310310+ pud_t *pud;311311+ pmd_t *pmd;312312+ pte_t *pte;313313+ void *vaddr;216314217315 vma = data->vma;218218- address = data->addr1;316316+ address = data->addr1 & PAGE_MASK;219317 pfn = data->addr2;220318 phys = pfn << PAGE_SHIFT;319319+ page = pfn_to_page(pfn);221320222321 if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)223322 return;224323225225- alias_mask = boot_cpu_data.dcache.alias_mask;324324+ pgd = pgd_offset(vma->vm_mm, address);325325+ pud = pud_offset(pgd, address);326326+ pmd = pmd_offset(pud, address);327327+ pte = pte_offset_kernel(pmd, address);226328227227- /* We only need to flush D-cache when we have alias */228228- if ((address^phys) & alias_mask) {229229- /* Loop 4K of the D-cache */230230- flush_cache_one(231231- CACHE_OC_ADDRESS_ARRAY | (address & alias_mask),232232- phys);233233- /* Loop another 4K of the D-cache */234234- flush_cache_one(235235- CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask),236236- phys);329329+ /* If the page isn't present, there is nothing to do here. */330330+ if (!(pte_val(*pte) & _PAGE_PRESENT))331331+ return;332332+333333+ if ((vma->vm_mm == current->active_mm))334334+ vaddr = NULL;335335+ else {336336+ /*337337+ * Use kmap_coherent or kmap_atomic to do flushes for338338+ * another ASID than the current one.339339+ */340340+ map_coherent = (current_cpu_data.dcache.n_aliases &&341341+ !test_bit(PG_dcache_dirty, &page->flags) &&342342+ page_mapped(page));343343+ if (map_coherent)344344+ vaddr = kmap_coherent(page, address);345345+ else346346+ vaddr = kmap_atomic(page, KM_USER0);347347+348348+ address = (unsigned long)vaddr;237349 }238350239239- alias_mask = boot_cpu_data.icache.alias_mask;240240- if (vma->vm_flags & VM_EXEC) {241241- /*242242- * Evict entries from the portion of the cache from which code243243- * may have been executed at this address (virtual). There's244244- * no need to evict from the portion corresponding to the245245- * physical address as for the D-cache, because we know the246246- * kernel has never executed the code through its identity247247- * translation.248248- */249249- flush_cache_one(250250- CACHE_IC_ADDRESS_ARRAY | (address & alias_mask),251251- phys);351351+ if (pages_do_alias(address, phys))352352+ flush_cache_one(CACHE_OC_ADDRESS_ARRAY |353353+ (address & shm_align_mask), phys);354354+355355+ if (vma->vm_flags & VM_EXEC)356356+ flush_icache_all();357357+358358+ if (vaddr) {359359+ if (map_coherent)360360+ kunmap_coherent(vaddr);361361+ else362362+ kunmap_atomic(vaddr, KM_USER0);252363 }253364}254365···300373 if (boot_cpu_data.dcache.n_aliases == 0)301374 return;302375303303- /*304304- * Don't bother with the lookup and alias check if we have a305305- * wide range to cover, just blow away the dcache in its306306- * entirety instead. -- PFM.307307- */308308- if (((end - start) >> PAGE_SHIFT) >= MAX_DCACHE_PAGES)309309- flush_dcache_all();310310- else311311- __flush_cache_mm(vma->vm_mm, start, end);376376+ flush_dcache_all();312377313313- if (vma->vm_flags & VM_EXEC) {314314- /*315315- * TODO: Is this required??? Need to look at how I-cache316316- * coherency is assured when new programs are loaded to see if317317- * this matters.318318- */378378+ if (vma->vm_flags & VM_EXEC)319379 flush_icache_all();320320- }321380}322381323382/**···377464 } while (--way_count != 0);378465}379466380380-/*381381- * Break the 1, 2 and 4 way variants of this out into separate functions to382382- * avoid nearly all the overhead of having the conditional stuff in the function383383- * bodies (+ the 1 and 2 way cases avoid saving any registers too).384384- *385385- * We want to eliminate unnecessary bus transactions, so this code uses386386- * a non-obvious technique.387387- *388388- * Loop over a cache way sized block of, one cache line at a time. For each389389- * line, use movca.a to cause the current cache line contents to be written390390- * back, but without reading anything from main memory. However this has the391391- * side effect that the cache is now caching that memory location. So follow392392- * this with a cache invalidate to mark the cache line invalid. And do all393393- * this with interrupts disabled, to avoid the cache line being accidently394394- * evicted while it is holding garbage.395395- *396396- * This also breaks in a number of circumstances:397397- * - if there are modifications to the region of memory just above398398- * empty_zero_page (for example because a breakpoint has been placed399399- * there), then these can be lost.400400- *401401- * This is because the the memory address which the cache temporarily402402- * caches in the above description is empty_zero_page. So the403403- * movca.l hits the cache (it is assumed that it misses, or at least404404- * isn't dirty), modifies the line and then invalidates it, losing the405405- * required change.406406- *407407- * - If caches are disabled or configured in write-through mode, then408408- * the movca.l writes garbage directly into memory.409409- */410410-static void __flush_dcache_segment_writethrough(unsigned long start,411411- unsigned long extent_per_way)412412-{413413- unsigned long addr;414414- int i;415415-416416- addr = CACHE_OC_ADDRESS_ARRAY | (start & cpu_data->dcache.entry_mask);417417-418418- while (extent_per_way) {419419- for (i = 0; i < cpu_data->dcache.ways; i++)420420- __raw_writel(0, addr + cpu_data->dcache.way_incr * i);421421-422422- addr += cpu_data->dcache.linesz;423423- extent_per_way -= cpu_data->dcache.linesz;424424- }425425-}426426-427427-static void __flush_dcache_segment_1way(unsigned long start,428428- unsigned long extent_per_way)429429-{430430- unsigned long orig_sr, sr_with_bl;431431- unsigned long base_addr;432432- unsigned long way_incr, linesz, way_size;433433- struct cache_info *dcache;434434- register unsigned long a0, a0e;435435-436436- asm volatile("stc sr, %0" : "=r" (orig_sr));437437- sr_with_bl = orig_sr | (1<<28);438438- base_addr = ((unsigned long)&empty_zero_page[0]);439439-440440- /*441441- * The previous code aligned base_addr to 16k, i.e. the way_size of all442442- * existing SH-4 D-caches. Whilst I don't see a need to have this443443- * aligned to any better than the cache line size (which it will be444444- * anyway by construction), let's align it to at least the way_size of445445- * any existing or conceivable SH-4 D-cache. -- RPC446446- */447447- base_addr = ((base_addr >> 16) << 16);448448- base_addr |= start;449449-450450- dcache = &boot_cpu_data.dcache;451451- linesz = dcache->linesz;452452- way_incr = dcache->way_incr;453453- way_size = dcache->way_size;454454-455455- a0 = base_addr;456456- a0e = base_addr + extent_per_way;457457- do {458458- asm volatile("ldc %0, sr" : : "r" (sr_with_bl));459459- asm volatile("movca.l r0, @%0\n\t"460460- "ocbi @%0" : : "r" (a0));461461- a0 += linesz;462462- asm volatile("movca.l r0, @%0\n\t"463463- "ocbi @%0" : : "r" (a0));464464- a0 += linesz;465465- asm volatile("movca.l r0, @%0\n\t"466466- "ocbi @%0" : : "r" (a0));467467- a0 += linesz;468468- asm volatile("movca.l r0, @%0\n\t"469469- "ocbi @%0" : : "r" (a0));470470- asm volatile("ldc %0, sr" : : "r" (orig_sr));471471- a0 += linesz;472472- } while (a0 < a0e);473473-}474474-475475-static void __flush_dcache_segment_2way(unsigned long start,476476- unsigned long extent_per_way)477477-{478478- unsigned long orig_sr, sr_with_bl;479479- unsigned long base_addr;480480- unsigned long way_incr, linesz, way_size;481481- struct cache_info *dcache;482482- register unsigned long a0, a1, a0e;483483-484484- asm volatile("stc sr, %0" : "=r" (orig_sr));485485- sr_with_bl = orig_sr | (1<<28);486486- base_addr = ((unsigned long)&empty_zero_page[0]);487487-488488- /* See comment under 1-way above */489489- base_addr = ((base_addr >> 16) << 16);490490- base_addr |= start;491491-492492- dcache = &boot_cpu_data.dcache;493493- linesz = dcache->linesz;494494- way_incr = dcache->way_incr;495495- way_size = dcache->way_size;496496-497497- a0 = base_addr;498498- a1 = a0 + way_incr;499499- a0e = base_addr + extent_per_way;500500- do {501501- asm volatile("ldc %0, sr" : : "r" (sr_with_bl));502502- asm volatile("movca.l r0, @%0\n\t"503503- "movca.l r0, @%1\n\t"504504- "ocbi @%0\n\t"505505- "ocbi @%1" : :506506- "r" (a0), "r" (a1));507507- a0 += linesz;508508- a1 += linesz;509509- asm volatile("movca.l r0, @%0\n\t"510510- "movca.l r0, @%1\n\t"511511- "ocbi @%0\n\t"512512- "ocbi @%1" : :513513- "r" (a0), "r" (a1));514514- a0 += linesz;515515- a1 += linesz;516516- asm volatile("movca.l r0, @%0\n\t"517517- "movca.l r0, @%1\n\t"518518- "ocbi @%0\n\t"519519- "ocbi @%1" : :520520- "r" (a0), "r" (a1));521521- a0 += linesz;522522- a1 += linesz;523523- asm volatile("movca.l r0, @%0\n\t"524524- "movca.l r0, @%1\n\t"525525- "ocbi @%0\n\t"526526- "ocbi @%1" : :527527- "r" (a0), "r" (a1));528528- asm volatile("ldc %0, sr" : : "r" (orig_sr));529529- a0 += linesz;530530- a1 += linesz;531531- } while (a0 < a0e);532532-}533533-534534-static void __flush_dcache_segment_4way(unsigned long start,535535- unsigned long extent_per_way)536536-{537537- unsigned long orig_sr, sr_with_bl;538538- unsigned long base_addr;539539- unsigned long way_incr, linesz, way_size;540540- struct cache_info *dcache;541541- register unsigned long a0, a1, a2, a3, a0e;542542-543543- asm volatile("stc sr, %0" : "=r" (orig_sr));544544- sr_with_bl = orig_sr | (1<<28);545545- base_addr = ((unsigned long)&empty_zero_page[0]);546546-547547- /* See comment under 1-way above */548548- base_addr = ((base_addr >> 16) << 16);549549- base_addr |= start;550550-551551- dcache = &boot_cpu_data.dcache;552552- linesz = dcache->linesz;553553- way_incr = dcache->way_incr;554554- way_size = dcache->way_size;555555-556556- a0 = base_addr;557557- a1 = a0 + way_incr;558558- a2 = a1 + way_incr;559559- a3 = a2 + way_incr;560560- a0e = base_addr + extent_per_way;561561- do {562562- asm volatile("ldc %0, sr" : : "r" (sr_with_bl));563563- asm volatile("movca.l r0, @%0\n\t"564564- "movca.l r0, @%1\n\t"565565- "movca.l r0, @%2\n\t"566566- "movca.l r0, @%3\n\t"567567- "ocbi @%0\n\t"568568- "ocbi @%1\n\t"569569- "ocbi @%2\n\t"570570- "ocbi @%3\n\t" : :571571- "r" (a0), "r" (a1), "r" (a2), "r" (a3));572572- a0 += linesz;573573- a1 += linesz;574574- a2 += linesz;575575- a3 += linesz;576576- asm volatile("movca.l r0, @%0\n\t"577577- "movca.l r0, @%1\n\t"578578- "movca.l r0, @%2\n\t"579579- "movca.l r0, @%3\n\t"580580- "ocbi @%0\n\t"581581- "ocbi @%1\n\t"582582- "ocbi @%2\n\t"583583- "ocbi @%3\n\t" : :584584- "r" (a0), "r" (a1), "r" (a2), "r" (a3));585585- a0 += linesz;586586- a1 += linesz;587587- a2 += linesz;588588- a3 += linesz;589589- asm volatile("movca.l r0, @%0\n\t"590590- "movca.l r0, @%1\n\t"591591- "movca.l r0, @%2\n\t"592592- "movca.l r0, @%3\n\t"593593- "ocbi @%0\n\t"594594- "ocbi @%1\n\t"595595- "ocbi @%2\n\t"596596- "ocbi @%3\n\t" : :597597- "r" (a0), "r" (a1), "r" (a2), "r" (a3));598598- a0 += linesz;599599- a1 += linesz;600600- a2 += linesz;601601- a3 += linesz;602602- asm volatile("movca.l r0, @%0\n\t"603603- "movca.l r0, @%1\n\t"604604- "movca.l r0, @%2\n\t"605605- "movca.l r0, @%3\n\t"606606- "ocbi @%0\n\t"607607- "ocbi @%1\n\t"608608- "ocbi @%2\n\t"609609- "ocbi @%3\n\t" : :610610- "r" (a0), "r" (a1), "r" (a2), "r" (a3));611611- asm volatile("ldc %0, sr" : : "r" (orig_sr));612612- a0 += linesz;613613- a1 += linesz;614614- a2 += linesz;615615- a3 += linesz;616616- } while (a0 < a0e);617617-}618618-619467extern void __weak sh4__flush_region_init(void);620468621469/*···384710 */385711void __init sh4_cache_init(void)386712{387387- unsigned int wt_enabled = !!(__raw_readl(CCR) & CCR_CACHE_WT);388388-389713 printk("PVR=%08x CVR=%08x PRR=%08x\n",390714 ctrl_inl(CCN_PVR),391715 ctrl_inl(CCN_CVR),392716 ctrl_inl(CCN_PRR));393393-394394- if (wt_enabled)395395- __flush_dcache_segment_fn = __flush_dcache_segment_writethrough;396396- else {397397- switch (boot_cpu_data.dcache.ways) {398398- case 1:399399- __flush_dcache_segment_fn = __flush_dcache_segment_1way;400400- break;401401- case 2:402402- __flush_dcache_segment_fn = __flush_dcache_segment_2way;403403- break;404404- case 4:405405- __flush_dcache_segment_fn = __flush_dcache_segment_4way;406406- break;407407- default:408408- panic("unknown number of cache ways\n");409409- break;410410- }411411- }412717413718 local_flush_icache_range = sh4_flush_icache_range;414719 local_flush_dcache_page = sh4_flush_dcache_page;
···6060 unsigned long bootmem_paddr;61616262 /* Don't allow bogus node assignment */6363- BUG_ON(nid > MAX_NUMNODES || nid == 0);6363+ BUG_ON(nid > MAX_NUMNODES || nid <= 0);64646565 start_pfn = start >> PAGE_SHIFT;6666 end_pfn = end >> PAGE_SHIFT;
-45
arch/sh/mm/pmb-fixed.c
···11-/*22- * arch/sh/mm/fixed_pmb.c33- *44- * Copyright (C) 2009 Renesas Solutions Corp.55- *66- * This file is subject to the terms and conditions of the GNU General Public77- * License. See the file "COPYING" in the main directory of this archive88- * for more details.99- */1010-#include <linux/init.h>1111-#include <linux/mm.h>1212-#include <linux/io.h>1313-#include <asm/mmu.h>1414-#include <asm/mmu_context.h>1515-1616-static int __uses_jump_to_uncached fixed_pmb_init(void)1717-{1818- int i;1919- unsigned long addr, data;2020-2121- jump_to_uncached();2222-2323- for (i = 0; i < PMB_ENTRY_MAX; i++) {2424- addr = PMB_DATA + (i << PMB_E_SHIFT);2525- data = ctrl_inl(addr);2626- if (!(data & PMB_V))2727- continue;2828-2929- if (data & PMB_C) {3030-#if defined(CONFIG_CACHE_WRITETHROUGH)3131- data |= PMB_WT;3232-#elif defined(CONFIG_CACHE_WRITEBACK)3333- data &= ~PMB_WT;3434-#else3535- data &= ~(PMB_C | PMB_WT);3636-#endif3737- }3838- ctrl_outl(data, addr);3939- }4040-4141- back_to_cached();4242-4343- return 0;4444-}4545-arch_initcall(fixed_pmb_init);
+136-136
arch/sh/mm/pmb.c
···35353636static void __pmb_unmap(struct pmb_entry *);37373838-static struct kmem_cache *pmb_cache;3838+static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES];3939static unsigned long pmb_map;4040-4141-static struct pmb_entry pmb_init_map[] = {4242- /* vpn ppn flags (ub/sz/c/wt) */4343-4444- /* P1 Section Mappings */4545- { 0x80000000, 0x00000000, PMB_SZ_64M | PMB_C, },4646- { 0x84000000, 0x04000000, PMB_SZ_64M | PMB_C, },4747- { 0x88000000, 0x08000000, PMB_SZ_128M | PMB_C, },4848- { 0x90000000, 0x10000000, PMB_SZ_64M | PMB_C, },4949- { 0x94000000, 0x14000000, PMB_SZ_64M | PMB_C, },5050- { 0x98000000, 0x18000000, PMB_SZ_64M | PMB_C, },5151-5252- /* P2 Section Mappings */5353- { 0xa0000000, 0x00000000, PMB_UB | PMB_SZ_64M | PMB_WT, },5454- { 0xa4000000, 0x04000000, PMB_UB | PMB_SZ_64M | PMB_WT, },5555- { 0xa8000000, 0x08000000, PMB_UB | PMB_SZ_128M | PMB_WT, },5656- { 0xb0000000, 0x10000000, PMB_UB | PMB_SZ_64M | PMB_WT, },5757- { 0xb4000000, 0x14000000, PMB_UB | PMB_SZ_64M | PMB_WT, },5858- { 0xb8000000, 0x18000000, PMB_UB | PMB_SZ_64M | PMB_WT, },5959-};60406141static inline unsigned long mk_pmb_entry(unsigned int entry)6242{···5373 return mk_pmb_entry(entry) | PMB_DATA;5474}55755656-static DEFINE_SPINLOCK(pmb_list_lock);5757-static struct pmb_entry *pmb_list;5858-5959-static inline void pmb_list_add(struct pmb_entry *pmbe)7676+static int pmb_alloc_entry(void)6077{6161- struct pmb_entry **p, *tmp;7878+ unsigned int pos;62796363- p = &pmb_list;6464- while ((tmp = *p) != NULL)6565- p = &tmp->next;8080+repeat:8181+ pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);66826767- pmbe->next = tmp;6868- *p = pmbe;8383+ if (unlikely(pos > NR_PMB_ENTRIES))8484+ return -ENOSPC;8585+8686+ if (test_and_set_bit(pos, &pmb_map))8787+ goto repeat;8888+8989+ return pos;6990}70917171-static inline void pmb_list_del(struct pmb_entry *pmbe)7272-{7373- struct pmb_entry **p, *tmp;7474-7575- for (p = &pmb_list; (tmp = *p); p = &tmp->next)7676- if (tmp == pmbe) {7777- *p = tmp->next;7878- return;7979- }8080-}8181-8282-struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,8383- unsigned long flags)9292+static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,9393+ unsigned long flags, int entry)8494{8595 struct pmb_entry *pmbe;9696+ int pos;86978787- pmbe = kmem_cache_alloc(pmb_cache, GFP_KERNEL);9898+ if (entry == PMB_NO_ENTRY) {9999+ pos = pmb_alloc_entry();100100+ if (pos < 0)101101+ return ERR_PTR(pos);102102+ } else {103103+ if (test_bit(entry, &pmb_map))104104+ return ERR_PTR(-ENOSPC);105105+ pos = entry;106106+ }107107+108108+ pmbe = &pmb_entry_list[pos];88109 if (!pmbe)89110 return ERR_PTR(-ENOMEM);9011191112 pmbe->vpn = vpn;92113 pmbe->ppn = ppn;93114 pmbe->flags = flags;9494-9595- spin_lock_irq(&pmb_list_lock);9696- pmb_list_add(pmbe);9797- spin_unlock_irq(&pmb_list_lock);115115+ pmbe->entry = pos;9811699117 return pmbe;100118}101119102102-void pmb_free(struct pmb_entry *pmbe)120120+static void pmb_free(struct pmb_entry *pmbe)103121{104104- spin_lock_irq(&pmb_list_lock);105105- pmb_list_del(pmbe);106106- spin_unlock_irq(&pmb_list_lock);122122+ int pos = pmbe->entry;107123108108- kmem_cache_free(pmb_cache, pmbe);124124+ pmbe->vpn = 0;125125+ pmbe->ppn = 0;126126+ pmbe->flags = 0;127127+ pmbe->entry = 0;128128+129129+ clear_bit(pos, &pmb_map);109130}110131111132/*112133 * Must be in P2 for __set_pmb_entry()113134 */114114-int __set_pmb_entry(unsigned long vpn, unsigned long ppn,115115- unsigned long flags, int *entry)135135+static void __set_pmb_entry(unsigned long vpn, unsigned long ppn,136136+ unsigned long flags, int pos)116137{117117- unsigned int pos = *entry;118118-119119- if (unlikely(pos == PMB_NO_ENTRY))120120- pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);121121-122122-repeat:123123- if (unlikely(pos > NR_PMB_ENTRIES))124124- return -ENOSPC;125125-126126- if (test_and_set_bit(pos, &pmb_map)) {127127- pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);128128- goto repeat;129129- }130130-131138 ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos));132139133140#ifdef CONFIG_CACHE_WRITETHROUGH···128161#endif129162130163 ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos));131131-132132- *entry = pos;133133-134134- return 0;135164}136165137137-int __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)166166+static void __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)138167{139139- int ret;140140-141168 jump_to_uncached();142142- ret = __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &pmbe->entry);169169+ __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, pmbe->entry);143170 back_to_cached();144144-145145- return ret;146171}147172148148-void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)173173+static void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)149174{150175 unsigned int entry = pmbe->entry;151176 unsigned long addr;152177153153- /*154154- * Don't allow clearing of wired init entries, P1 or P2 access155155- * without a corresponding mapping in the PMB will lead to reset156156- * by the TLB.157157- */158158- if (unlikely(entry < ARRAY_SIZE(pmb_init_map) ||159159- entry >= NR_PMB_ENTRIES))178178+ if (unlikely(entry >= NR_PMB_ENTRIES))160179 return;161180162181 jump_to_uncached();···155202 ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);156203157204 back_to_cached();158158-159159- clear_bit(entry, &pmb_map);160205}161206162207···190239191240again:192241 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {193193- int ret;194194-195242 if (size < pmb_sizes[i].size)196243 continue;197244198198- pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag);245245+ pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag,246246+ PMB_NO_ENTRY);199247 if (IS_ERR(pmbe)) {200248 err = PTR_ERR(pmbe);201249 goto out;202250 }203251204204- ret = set_pmb_entry(pmbe);205205- if (ret != 0) {206206- pmb_free(pmbe);207207- err = -EBUSY;208208- goto out;209209- }252252+ set_pmb_entry(pmbe);210253211254 phys += pmb_sizes[i].size;212255 vaddr += pmb_sizes[i].size;···237292238293void pmb_unmap(unsigned long addr)239294{240240- struct pmb_entry **p, *pmbe;295295+ struct pmb_entry *pmbe = NULL;296296+ int i;241297242242- for (p = &pmb_list; (pmbe = *p); p = &pmbe->next)243243- if (pmbe->vpn == addr)244244- break;298298+ for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {299299+ if (test_bit(i, &pmb_map)) {300300+ pmbe = &pmb_entry_list[i];301301+ if (pmbe->vpn == addr)302302+ break;303303+ }304304+ }245305246306 if (unlikely(!pmbe))247307 return;···256306257307static void __pmb_unmap(struct pmb_entry *pmbe)258308{259259- WARN_ON(!test_bit(pmbe->entry, &pmb_map));309309+ BUG_ON(!test_bit(pmbe->entry, &pmb_map));260310261311 do {262312 struct pmb_entry *pmblink = pmbe;263313264264- if (pmbe->entry != PMB_NO_ENTRY)265265- clear_pmb_entry(pmbe);314314+ /*315315+ * We may be called before this pmb_entry has been316316+ * entered into the PMB table via set_pmb_entry(), but317317+ * that's OK because we've allocated a unique slot for318318+ * this entry in pmb_alloc() (even if we haven't filled319319+ * it yet).320320+ *321321+ * Therefore, calling clear_pmb_entry() is safe as no322322+ * other mapping can be using that slot.323323+ */324324+ clear_pmb_entry(pmbe);266325267326 pmbe = pmblink->link;268327···279320 } while (pmbe);280321}281322282282-static void pmb_cache_ctor(void *pmb)323323+#ifdef CONFIG_PMB324324+int __uses_jump_to_uncached pmb_init(void)283325{284284- struct pmb_entry *pmbe = pmb;285285-286286- memset(pmb, 0, sizeof(struct pmb_entry));287287-288288- pmbe->entry = PMB_NO_ENTRY;289289-}290290-291291-static int __uses_jump_to_uncached pmb_init(void)292292-{293293- unsigned int nr_entries = ARRAY_SIZE(pmb_init_map);294294- unsigned int entry, i;295295-296296- BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES));297297-298298- pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0,299299- SLAB_PANIC, pmb_cache_ctor);326326+ unsigned int i;327327+ long size, ret;300328301329 jump_to_uncached();302330303331 /*304304- * Ordering is important, P2 must be mapped in the PMB before we305305- * can set PMB.SE, and P1 must be mapped before we jump back to306306- * P1 space.332332+ * Insert PMB entries for the P1 and P2 areas so that, after333333+ * we've switched the MMU to 32-bit mode, the semantics of P1334334+ * and P2 are the same as in 29-bit mode, e.g.335335+ *336336+ * P1 - provides a cached window onto physical memory337337+ * P2 - provides an uncached window onto physical memory307338 */308308- for (entry = 0; entry < nr_entries; entry++) {309309- struct pmb_entry *pmbe = pmb_init_map + entry;339339+ size = __MEMORY_START + __MEMORY_SIZE;310340311311- __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &entry);312312- }341341+ ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C);342342+ BUG_ON(ret != size);343343+344344+ ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB);345345+ BUG_ON(ret != size);313346314347 ctrl_outl(0, PMB_IRMCR);315348316349 /* PMB.SE and UB[7] */317317- ctrl_outl((1 << 31) | (1 << 7), PMB_PASCR);350350+ ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR);318351319352 /* Flush out the TLB */320353 i = ctrl_inl(MMUCR);···317366318367 return 0;319368}320320-arch_initcall(pmb_init);369369+#else370370+int __uses_jump_to_uncached pmb_init(void)371371+{372372+ int i;373373+ unsigned long addr, data;374374+375375+ jump_to_uncached();376376+377377+ for (i = 0; i < PMB_ENTRY_MAX; i++) {378378+ struct pmb_entry *pmbe;379379+ unsigned long vpn, ppn, flags;380380+381381+ addr = PMB_DATA + (i << PMB_E_SHIFT);382382+ data = ctrl_inl(addr);383383+ if (!(data & PMB_V))384384+ continue;385385+386386+ if (data & PMB_C) {387387+#if defined(CONFIG_CACHE_WRITETHROUGH)388388+ data |= PMB_WT;389389+#elif defined(CONFIG_CACHE_WRITEBACK)390390+ data &= ~PMB_WT;391391+#else392392+ data &= ~(PMB_C | PMB_WT);393393+#endif394394+ }395395+ ctrl_outl(data, addr);396396+397397+ ppn = data & PMB_PFN_MASK;398398+399399+ flags = data & (PMB_C | PMB_WT | PMB_UB);400400+ flags |= data & PMB_SZ_MASK;401401+402402+ addr = PMB_ADDR + (i << PMB_E_SHIFT);403403+ data = ctrl_inl(addr);404404+405405+ vpn = data & PMB_PFN_MASK;406406+407407+ pmbe = pmb_alloc(vpn, ppn, flags, i);408408+ WARN_ON(IS_ERR(pmbe));409409+ }410410+411411+ back_to_cached();412412+413413+ return 0;414414+}415415+#endif /* CONFIG_PMB */321416322417static int pmb_seq_show(struct seq_file *file, void *iter)323418{···431434static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)432435{433436 static pm_message_t prev_state;437437+ int i;434438435439 /* Restore the PMB after a resume from hibernation */436440 if (state.event == PM_EVENT_ON &&437441 prev_state.event == PM_EVENT_FREEZE) {438442 struct pmb_entry *pmbe;439439- spin_lock_irq(&pmb_list_lock);440440- for (pmbe = pmb_list; pmbe; pmbe = pmbe->next)441441- set_pmb_entry(pmbe);442442- spin_unlock_irq(&pmb_list_lock);443443+ for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {444444+ if (test_bit(i, &pmb_map)) {445445+ pmbe = &pmb_entry_list[i];446446+ set_pmb_entry(pmbe);447447+ }448448+ }443449 }444450 prev_state = state;445451 return 0;
···2020#include <asm/processor.h>2121#include "op_impl.h"22222323-extern struct op_sh_model op_model_sh7750_ops __weak;2424-extern struct op_sh_model op_model_sh4a_ops __weak;2525-2623static struct op_sh_model *model;27242825static struct op_counter_config ctr[20];···9194 */9295 ops->backtrace = sh_backtrace;93969494- switch (current_cpu_data.type) {9595- /* SH-4 types */9696- case CPU_SH7750:9797- case CPU_SH7750S:9898- lmodel = &op_model_sh7750_ops;9999- break;100100-101101- /* SH-4A types */102102- case CPU_SH7763:103103- case CPU_SH7770:104104- case CPU_SH7780:105105- case CPU_SH7781:106106- case CPU_SH7785:107107- case CPU_SH7786:108108- case CPU_SH7723:109109- case CPU_SH7724:110110- case CPU_SHX3:111111- lmodel = &op_model_sh4a_ops;112112- break;113113-114114- /* SH4AL-DSP types */115115- case CPU_SH7343:116116- case CPU_SH7722:117117- case CPU_SH7366:118118- lmodel = &op_model_sh4a_ops;119119- break;120120- }9797+ /*9898+ * XXX9999+ *100100+ * All of the SH7750/SH-4A counters have been converted to perf,101101+ * this infrastructure hook is left for other users until they've102102+ * had a chance to convert over, at which point all of this103103+ * will be deleted.104104+ */121105122106 if (!lmodel)123107 return -ENODEV;
+1-1
arch/sh/oprofile/op_impl.h
···66 unsigned long enabled;77 unsigned long event;8899- unsigned long long count;99+ unsigned long count;10101111 /* Dummy values for userspace tool compliance */1212 unsigned long kernel;
-255
arch/sh/oprofile/op_model_sh7750.c
···11-/*22- * arch/sh/oprofile/op_model_sh7750.c33- *44- * OProfile support for SH7750/SH7750S Performance Counters55- *66- * Copyright (C) 2003 - 2008 Paul Mundt77- *88- * This file is subject to the terms and conditions of the GNU General Public99- * License. See the file "COPYING" in the main directory of this archive1010- * for more details.1111- */1212-#include <linux/kernel.h>1313-#include <linux/oprofile.h>1414-#include <linux/profile.h>1515-#include <linux/init.h>1616-#include <linux/errno.h>1717-#include <linux/interrupt.h>1818-#include <linux/io.h>1919-#include <linux/fs.h>2020-#include "op_impl.h"2121-2222-#define PM_CR_BASE 0xff000084 /* 16-bit */2323-#define PM_CTR_BASE 0xff100004 /* 32-bit */2424-2525-#define PMCR(n) (PM_CR_BASE + ((n) * 0x04))2626-#define PMCTRH(n) (PM_CTR_BASE + 0x00 + ((n) * 0x08))2727-#define PMCTRL(n) (PM_CTR_BASE + 0x04 + ((n) * 0x08))2828-2929-#define PMCR_PMM_MASK 0x0000003f3030-3131-#define PMCR_CLKF 0x000001003232-#define PMCR_PMCLR 0x000020003333-#define PMCR_PMST 0x000040003434-#define PMCR_PMEN 0x000080003535-3636-struct op_sh_model op_model_sh7750_ops;3737-3838-#define NR_CNTRS 23939-4040-static struct sh7750_ppc_register_config {4141- unsigned int ctrl;4242- unsigned long cnt_hi;4343- unsigned long cnt_lo;4444-} regcache[NR_CNTRS];4545-4646-/*4747- * There are a number of events supported by each counter (33 in total).4848- * Since we have 2 counters, each counter will take the event code as it4949- * corresponds to the PMCR PMM setting. Each counter can be configured5050- * independently.5151- *5252- * Event Code Description5353- * ---------- -----------5454- *5555- * 0x01 Operand read access5656- * 0x02 Operand write access5757- * 0x03 UTLB miss5858- * 0x04 Operand cache read miss5959- * 0x05 Operand cache write miss6060- * 0x06 Instruction fetch (w/ cache)6161- * 0x07 Instruction TLB miss6262- * 0x08 Instruction cache miss6363- * 0x09 All operand accesses6464- * 0x0a All instruction accesses6565- * 0x0b OC RAM operand access6666- * 0x0d On-chip I/O space access6767- * 0x0e Operand access (r/w)6868- * 0x0f Operand cache miss (r/w)6969- * 0x10 Branch instruction7070- * 0x11 Branch taken7171- * 0x12 BSR/BSRF/JSR7272- * 0x13 Instruction execution7373- * 0x14 Instruction execution in parallel7474- * 0x15 FPU Instruction execution7575- * 0x16 Interrupt7676- * 0x17 NMI7777- * 0x18 trapa instruction execution7878- * 0x19 UBCA match7979- * 0x1a UBCB match8080- * 0x21 Instruction cache fill8181- * 0x22 Operand cache fill8282- * 0x23 Elapsed time8383- * 0x24 Pipeline freeze by I-cache miss8484- * 0x25 Pipeline freeze by D-cache miss8585- * 0x27 Pipeline freeze by branch instruction8686- * 0x28 Pipeline freeze by CPU register8787- * 0x29 Pipeline freeze by FPU8888- *8989- * Unfortunately we don't have a native exception or interrupt for counter9090- * overflow (although since these counters can run for 16.3 days without9191- * overflowing, it's not really necessary).9292- *9393- * OProfile on the other hand likes to have samples taken periodically, so9494- * for now we just piggyback the timer interrupt to get the expected9595- * behavior.9696- */9797-9898-static int sh7750_timer_notify(struct pt_regs *regs)9999-{100100- oprofile_add_sample(regs, 0);101101- return 0;102102-}103103-104104-static u64 sh7750_read_counter(int counter)105105-{106106- return (u64)((u64)(__raw_readl(PMCTRH(counter)) & 0xffff) << 32) |107107- __raw_readl(PMCTRL(counter));108108-}109109-110110-/*111111- * Files will be in a path like:112112- *113113- * /<oprofilefs mount point>/<counter number>/<file>114114- *115115- * So when dealing with <file>, we look to the parent dentry for the counter116116- * number.117117- */118118-static inline int to_counter(struct file *file)119119-{120120- const unsigned char *name = file->f_path.dentry->d_parent->d_name.name;121121-122122- return (int)simple_strtol(name, NULL, 10);123123-}124124-125125-/*126126- * XXX: We have 48-bit counters, so we're probably going to want something127127- * more along the lines of oprofilefs_ullong_to_user().. Truncating to128128- * unsigned long works fine for now though, as long as we don't attempt to129129- * profile for too horribly long.130130- */131131-static ssize_t sh7750_read_count(struct file *file, char __user *buf,132132- size_t count, loff_t *ppos)133133-{134134- int counter = to_counter(file);135135- u64 val = sh7750_read_counter(counter);136136-137137- return oprofilefs_ulong_to_user((unsigned long)val, buf, count, ppos);138138-}139139-140140-static ssize_t sh7750_write_count(struct file *file, const char __user *buf,141141- size_t count, loff_t *ppos)142142-{143143- int counter = to_counter(file);144144- unsigned long val;145145-146146- if (oprofilefs_ulong_from_user(&val, buf, count))147147- return -EFAULT;148148-149149- /*150150- * Any write will clear the counter, although only 0 should be151151- * written for this purpose, as we do not support setting the152152- * counter to an arbitrary value.153153- */154154- WARN_ON(val != 0);155155-156156- __raw_writew(__raw_readw(PMCR(counter)) | PMCR_PMCLR, PMCR(counter));157157-158158- return count;159159-}160160-161161-static const struct file_operations count_fops = {162162- .read = sh7750_read_count,163163- .write = sh7750_write_count,164164-};165165-166166-static int sh7750_ppc_create_files(struct super_block *sb, struct dentry *dir)167167-{168168- return oprofilefs_create_file(sb, dir, "count", &count_fops);169169-}170170-171171-static void sh7750_ppc_reg_setup(struct op_counter_config *ctr)172172-{173173- unsigned int counters = op_model_sh7750_ops.num_counters;174174- int i;175175-176176- for (i = 0; i < counters; i++) {177177- regcache[i].ctrl = 0;178178- regcache[i].cnt_hi = 0;179179- regcache[i].cnt_lo = 0;180180-181181- if (!ctr[i].enabled)182182- continue;183183-184184- regcache[i].ctrl |= ctr[i].event | PMCR_PMEN | PMCR_PMST;185185- regcache[i].cnt_hi = (unsigned long)((ctr->count >> 32) & 0xffff);186186- regcache[i].cnt_lo = (unsigned long)(ctr->count & 0xffffffff);187187- }188188-}189189-190190-static void sh7750_ppc_cpu_setup(void *args)191191-{192192- unsigned int counters = op_model_sh7750_ops.num_counters;193193- int i;194194-195195- for (i = 0; i < counters; i++) {196196- __raw_writew(0, PMCR(i));197197- __raw_writel(regcache[i].cnt_hi, PMCTRH(i));198198- __raw_writel(regcache[i].cnt_lo, PMCTRL(i));199199- }200200-}201201-202202-static void sh7750_ppc_cpu_start(void *args)203203-{204204- unsigned int counters = op_model_sh7750_ops.num_counters;205205- int i;206206-207207- for (i = 0; i < counters; i++)208208- __raw_writew(regcache[i].ctrl, PMCR(i));209209-}210210-211211-static void sh7750_ppc_cpu_stop(void *args)212212-{213213- unsigned int counters = op_model_sh7750_ops.num_counters;214214- int i;215215-216216- /* Disable the counters */217217- for (i = 0; i < counters; i++)218218- __raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i));219219-}220220-221221-static inline void sh7750_ppc_reset(void)222222-{223223- unsigned int counters = op_model_sh7750_ops.num_counters;224224- int i;225225-226226- /* Clear the counters */227227- for (i = 0; i < counters; i++)228228- __raw_writew(__raw_readw(PMCR(i)) | PMCR_PMCLR, PMCR(i));229229-}230230-231231-static int sh7750_ppc_init(void)232232-{233233- sh7750_ppc_reset();234234-235235- return register_timer_hook(sh7750_timer_notify);236236-}237237-238238-static void sh7750_ppc_exit(void)239239-{240240- unregister_timer_hook(sh7750_timer_notify);241241-242242- sh7750_ppc_reset();243243-}244244-245245-struct op_sh_model op_model_sh7750_ops = {246246- .cpu_type = "sh/sh7750",247247- .num_counters = NR_CNTRS,248248- .reg_setup = sh7750_ppc_reg_setup,249249- .cpu_setup = sh7750_ppc_cpu_setup,250250- .cpu_start = sh7750_ppc_cpu_start,251251- .cpu_stop = sh7750_ppc_cpu_stop,252252- .init = sh7750_ppc_init,253253- .exit = sh7750_ppc_exit,254254- .create_files = sh7750_ppc_create_files,255255-};
···3535 This driver supports the ASIC3 multifunction chip found on many3636 PDAs (mainly iPAQ and HTC based ones)37373838+config MFD_SH_MOBILE_SDHI3939+ bool "Support for SuperH Mobile SDHI"4040+ depends on SUPERH4141+ select MFD_CORE4242+ ---help---4343+ This driver supports the SDHI hardware block found in many4444+ SuperH Mobile SoCs.4545+3846config MFD_DM355EVM_MSP3947 bool "DaVinci DM355 EVM microcontroller"4048 depends on I2C && MACH_DAVINCI_DM355_EVM
···11+/*22+ * SuperH Mobile SDHI33+ *44+ * Copyright (C) 2009 Magnus Damm55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 as88+ * published by the Free Software Foundation.99+ *1010+ * Based on "Compaq ASIC3 support":1111+ *1212+ * Copyright 2001 Compaq Computer Corporation.1313+ * Copyright 2004-2005 Phil Blundell1414+ * Copyright 2007-2008 OpenedHand Ltd.1515+ *1616+ * Authors: Phil Blundell <pb@handhelds.org>,1717+ * Samuel Ortiz <sameo@openedhand.com>1818+ *1919+ */2020+2121+#include <linux/kernel.h>2222+#include <linux/clk.h>2323+#include <linux/platform_device.h>2424+2525+#include <linux/mfd/core.h>2626+#include <linux/mfd/tmio.h>2727+2828+struct sh_mobile_sdhi {2929+ struct clk *clk;3030+ struct tmio_mmc_data mmc_data;3131+ struct mfd_cell cell_mmc;3232+};3333+3434+static struct resource sh_mobile_sdhi_resources[] = {3535+ {3636+ .start = 0x000,3737+ .end = 0x1ff,3838+ .flags = IORESOURCE_MEM,3939+ },4040+ {4141+ .start = 0,4242+ .end = 0,4343+ .flags = IORESOURCE_IRQ,4444+ },4545+};4646+4747+static struct mfd_cell sh_mobile_sdhi_cell = {4848+ .name = "tmio-mmc",4949+ .num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),5050+ .resources = sh_mobile_sdhi_resources,5151+};5252+5353+static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)5454+{5555+ struct sh_mobile_sdhi *priv;5656+ struct resource *mem;5757+ char clk_name[8];5858+ int ret, irq;5959+6060+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);6161+ if (!mem)6262+ dev_err(&pdev->dev, "missing MEM resource\n");6363+6464+ irq = platform_get_irq(pdev, 0);6565+ if (irq < 0)6666+ dev_err(&pdev->dev, "missing IRQ resource\n");6767+6868+ if (!mem || (irq < 0))6969+ return -EINVAL;7070+7171+ priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);7272+ if (priv == NULL) {7373+ dev_err(&pdev->dev, "kzalloc failed\n");7474+ return -ENOMEM;7575+ }7676+7777+ snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);7878+ priv->clk = clk_get(&pdev->dev, clk_name);7979+ if (IS_ERR(priv->clk)) {8080+ dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);8181+ ret = PTR_ERR(priv->clk);8282+ kfree(priv);8383+ return ret;8484+ }8585+8686+ clk_enable(priv->clk);8787+8888+ /* FIXME: silly const unsigned int hclk */8989+ *(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);9090+9191+ memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));9292+ priv->cell_mmc.driver_data = &priv->mmc_data;9393+ priv->cell_mmc.platform_data = &priv->cell_mmc;9494+ priv->cell_mmc.data_size = sizeof(priv->cell_mmc);9595+9696+ platform_set_drvdata(pdev, priv);9797+9898+ ret = mfd_add_devices(&pdev->dev, pdev->id,9999+ &priv->cell_mmc, 1, mem, irq);100100+ if (ret) {101101+ clk_disable(priv->clk);102102+ clk_put(priv->clk);103103+ kfree(priv);104104+ }105105+106106+ return ret;107107+}108108+109109+static int sh_mobile_sdhi_remove(struct platform_device *pdev)110110+{111111+ struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev);112112+113113+ mfd_remove_devices(&pdev->dev);114114+ clk_disable(priv->clk);115115+ clk_put(priv->clk);116116+ kfree(priv);117117+118118+ return 0;119119+}120120+121121+static struct platform_driver sh_mobile_sdhi_driver = {122122+ .driver = {123123+ .name = "sh_mobile_sdhi",124124+ .owner = THIS_MODULE,125125+ },126126+ .probe = sh_mobile_sdhi_probe,127127+ .remove = __devexit_p(sh_mobile_sdhi_remove),128128+};129129+130130+static int __init sh_mobile_sdhi_init(void)131131+{132132+ return platform_driver_register(&sh_mobile_sdhi_driver);133133+}134134+135135+static void __exit sh_mobile_sdhi_exit(void)136136+{137137+ platform_driver_unregister(&sh_mobile_sdhi_driver);138138+}139139+140140+module_init(sh_mobile_sdhi_init);141141+module_exit(sh_mobile_sdhi_exit);142142+143143+MODULE_DESCRIPTION("SuperH Mobile SDHI driver");144144+MODULE_AUTHOR("Magnus Damm");145145+MODULE_LICENSE("GPL v2");
+1-1
drivers/mmc/host/Kconfig
···329329330330config MMC_TMIO331331 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"332332- depends on MFD_TMIO || MFD_ASIC3332332+ depends on MFD_TMIO || MFD_ASIC3 || SUPERH333333 help334334 This provides support for the SD/MMC cell found in TC6393XB,335335 T7L66XB and also HTC ASIC3
+109-14
drivers/sh/intc.c
···22 * Shared interrupt handling code for IPR and INTC2 types of IRQs.33 *44 * Copyright (C) 2007, 2008 Magnus Damm55+ * Copyright (C) 2009 Paul Mundt56 *67 * Based on intc2.c and ipr.c78 *···2524#include <linux/sysdev.h>2625#include <linux/list.h>2726#include <linux/topology.h>2727+#include <linux/bitmap.h>28282929#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \3030 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \···61596260static LIST_HEAD(intc_list);63616262+/*6363+ * The intc_irq_map provides a global map of bound IRQ vectors for a6464+ * given platform. Allocation of IRQs are either static through the CPU6565+ * vector map, or dynamic in the case of board mux vectors or MSI.6666+ *6767+ * As this is a central point for all IRQ controllers on the system,6868+ * each of the available sources are mapped out here. This combined with6969+ * sparseirq makes it quite trivial to keep the vector map tightly packed7070+ * when dynamically creating IRQs, as well as tying in to otherwise7171+ * unused irq_desc positions in the sparse array.7272+ */7373+static DECLARE_BITMAP(intc_irq_map, NR_IRQS);7474+static DEFINE_SPINLOCK(vector_lock);7575+6476#ifdef CONFIG_SMP6577#define IS_SMP(x) x.smp6678#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))···8670#endif87718872static unsigned int intc_prio_level[NR_IRQS]; /* for now */8989-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)9073static unsigned long ack_handle[NR_IRQS];9191-#endif92749375static inline struct intc_desc_int *get_intc_desc(unsigned int irq)9476{···264250 return 0; /* allow wakeup, but setup hardware in intc_suspend() */265251}266252267267-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)268253static void intc_mask_ack(unsigned int irq)269254{270255 struct intc_desc_int *d = get_intc_desc(irq);···295282 }296283 }297284}298298-#endif299285300286static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,301287 unsigned int nr_hp,···513501 return 0;514502}515503516516-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)517504static unsigned int __init intc_ack_data(struct intc_desc *desc,518505 struct intc_desc_int *d,519506 intc_enum enum_id)···544533545534 return 0;546535}547547-#endif548536549537static unsigned int __init intc_sense_data(struct intc_desc *desc,550538 struct intc_desc_int *d,···581571{582572 struct intc_handle_int *hp;583573 unsigned int data[2], primary;574574+575575+ /*576576+ * Register the IRQ position with the global IRQ map577577+ */578578+ set_bit(irq, intc_irq_map);584579585580 /* Prefer single interrupt source bitmap over other combinations:586581 * 1. bitmap, single interrupt source···656641 /* irq should be disabled by default */657642 d->chip.mask(irq);658643659659-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)660644 if (desc->ack_regs)661645 ack_handle[irq] = intc_ack_data(desc, d, enum_id);662662-#endif663646}664647665648static unsigned int __init save_reg(struct intc_desc_int *d,···694681 d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;695682 d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;696683 d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;697697-698698-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)699684 d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;700700-#endif685685+701686 d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT);702687#ifdef CONFIG_SMP703688 d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT);···738727 d->chip.set_type = intc_set_sense;739728 d->chip.set_wake = intc_set_wake;740729741741-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)742730 if (desc->ack_regs) {743731 for (i = 0; i < desc->nr_ack_regs; i++)744732 k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);745733746734 d->chip.mask_ack = intc_mask_ack;747735 }748748-#endif749736750737 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */751738···865856866857 return error;867858}868868-869859device_initcall(register_intc_sysdevs);860860+861861+/*862862+ * Dynamic IRQ allocation and deallocation863863+ */864864+static unsigned int create_irq_on_node(unsigned int irq_want, int node)865865+{866866+ unsigned int irq = 0, new;867867+ unsigned long flags;868868+ struct irq_desc *desc;869869+870870+ spin_lock_irqsave(&vector_lock, flags);871871+872872+ /*873873+ * First try the wanted IRQ, then scan.874874+ */875875+ if (test_and_set_bit(irq_want, intc_irq_map)) {876876+ new = find_first_zero_bit(intc_irq_map, nr_irqs);877877+ if (unlikely(new == nr_irqs))878878+ goto out_unlock;879879+880880+ desc = irq_to_desc_alloc_node(new, node);881881+ if (unlikely(!desc)) {882882+ pr_info("can't get irq_desc for %d\n", new);883883+ goto out_unlock;884884+ }885885+886886+ desc = move_irq_desc(desc, node);887887+ __set_bit(new, intc_irq_map);888888+ irq = new;889889+ }890890+891891+out_unlock:892892+ spin_unlock_irqrestore(&vector_lock, flags);893893+894894+ if (irq > 0)895895+ dynamic_irq_init(irq);896896+897897+ return irq;898898+}899899+900900+int create_irq(void)901901+{902902+ int nid = cpu_to_node(smp_processor_id());903903+ int irq;904904+905905+ irq = create_irq_on_node(NR_IRQS_LEGACY, nid);906906+ if (irq == 0)907907+ irq = -1;908908+909909+ return irq;910910+}911911+912912+void destroy_irq(unsigned int irq)913913+{914914+ unsigned long flags;915915+916916+ dynamic_irq_cleanup(irq);917917+918918+ spin_lock_irqsave(&vector_lock, flags);919919+ __clear_bit(irq, intc_irq_map);920920+ spin_unlock_irqrestore(&vector_lock, flags);921921+}922922+923923+int reserve_irq_vector(unsigned int irq)924924+{925925+ unsigned long flags;926926+ int ret = 0;927927+928928+ spin_lock_irqsave(&vector_lock, flags);929929+ if (test_and_set_bit(irq, intc_irq_map))930930+ ret = -EBUSY;931931+ spin_unlock_irqrestore(&vector_lock, flags);932932+933933+ return ret;934934+}935935+936936+void reserve_irq_legacy(void)937937+{938938+ unsigned long flags;939939+ int i, j;940940+941941+ spin_lock_irqsave(&vector_lock, flags);942942+ j = find_first_bit(intc_irq_map, nr_irqs);943943+ for (i = 0; i < j; i++)944944+ __set_bit(i, intc_irq_map);945945+ spin_unlock_irqrestore(&vector_lock, flags);946946+}
···281281 struct list_head *pagelist)282282{283283 struct sh_mobile_lcdc_chan *ch = info->par;284284- unsigned int nr_pages;285284286285 /* enable clocks before accessing hardware */287286 sh_mobile_lcdc_clk_on(ch->lcdc);288287289289- nr_pages = sh_mobile_lcdc_sginit(info, pagelist);290290- dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);288288+ /*289289+ * It's possible to get here without anything on the pagelist via290290+ * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync()291291+ * invocation. In the former case, the acceleration routines are292292+ * stepped in to when using the framebuffer console causing the293293+ * workqueue to be scheduled without any dirty pages on the list.294294+ *295295+ * Despite this, a panel update is still needed given that the296296+ * acceleration routines have their own methods for writing in297297+ * that still need to be updated.298298+ *299299+ * The fsync() and empty pagelist case could be optimized for,300300+ * but we don't bother, as any application exhibiting such301301+ * behaviour is fundamentally broken anyways.302302+ */303303+ if (!list_empty(pagelist)) {304304+ unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist);291305292292- /* trigger panel update */293293- lcdc_write_chan(ch, LDSM2R, 1);294294-295295- dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);306306+ /* trigger panel update */307307+ dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);308308+ lcdc_write_chan(ch, LDSM2R, 1);309309+ dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);310310+ } else311311+ lcdc_write_chan(ch, LDSM2R, 1);296312}297313298314static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
+3-4
include/linux/sh_intc.h
···5757 struct intc_sense_reg *sense_regs;5858 unsigned int nr_sense_regs;5959 char *name;6060-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)6160 struct intc_mask_reg *ack_regs;6261 unsigned int nr_ack_regs;6363-#endif6462};65636664#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)···7173 chipname, \7274}73757474-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)7576#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \7677 mask_regs, prio_regs, sense_regs, ack_regs) \7778struct intc_desc symbol __initdata = { \···8083 chipname, \8184 _INTC_ARRAY(ack_regs), \8285}8383-#endif84868587void __init register_intc_controller(struct intc_desc *desc);8688int intc_set_priority(unsigned int irq, unsigned int prio);8989+9090+int reserve_irq_vector(unsigned int irq);9191+void reserve_irq_legacy(void);87928893#endif /* __SH_INTC_H */