Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (137 commits)
sh: include empty zero page in romImage
sh: Make associative cache writes fatal on all SH-4A parts.
sh: Drop associative writes for SH-4 cache flushes.
sh: Partial revert of copy/clear_user_highpage() optimizations.
sh: Add default uImage rule for se7724, ap325rxa, and migor.
sh: allow runtime pm without suspend/resume callbacks
sh: mach-ecovec24: Remove un-defined settings for VPU
sh: mach-ecovec24: LCDC drive ability become high
sh: fix sh7724 VEU3F resource size
serial: sh-sci: Fix too early port disabling.
sh: pfc: pr_info() -> pr_debug() cleanups.
sh: pfc: Convert from ctrl_xxx() to __raw_xxx() I/O routines.
sh: Improve kfr2r09 serial port setup code
sh: Break out SuperH PFC code
sh: Move KEYSC header file
sh: convert /proc/cpu/aligmnent, /proc/cpu/kernel_alignment to seq_file
sh: Add CPG save/restore code for sh7724 R-standby
sh: Add SDHI power control support to Ecovec
mfd: Add power control platform data to SDHI driver
sh: mach-ecovec24: modify address map
...

+4773 -2437
+17 -12
arch/sh/Kconfig
··· 16 16 select HAVE_IOREMAP_PROT if MMU 17 17 select HAVE_ARCH_TRACEHOOK 18 18 select HAVE_DMA_API_DEBUG 19 + select HAVE_DMA_ATTRS 19 20 select HAVE_PERF_EVENTS 21 + select PERF_USE_VMALLOC 20 22 select HAVE_KERNEL_GZIP 21 23 select HAVE_KERNEL_BZIP2 22 24 select HAVE_KERNEL_LZMA ··· 39 37 select HAVE_FTRACE_MCOUNT_RECORD 40 38 select HAVE_DYNAMIC_FTRACE 41 39 select HAVE_FUNCTION_TRACE_MCOUNT_TEST 40 + select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE 42 41 select HAVE_FUNCTION_GRAPH_TRACER 43 42 select HAVE_ARCH_KGDB 44 43 select ARCH_HIBERNATION_POSSIBLE if MMU ··· 173 170 config IO_TRAPPED 174 171 bool 175 172 173 + config DMA_COHERENT 174 + bool 175 + 176 + config DMA_NONCOHERENT 177 + def_bool !DMA_COHERENT 178 + 176 179 source "init/Kconfig" 177 180 178 181 source "kernel/Kconfig.freezer" ··· 229 220 230 221 config CPU_SHX3 231 222 bool 223 + select DMA_COHERENT 232 224 233 225 config ARCH_SHMOBILE 234 226 bool ··· 771 761 default "0x00010000" if PAGE_SIZE_64KB 772 762 default "0x00000000" 773 763 774 - config UBC_WAKEUP 775 - bool "Wakeup UBC on startup" 776 - depends on CPU_SH4 && !CPU_SH4A 777 - help 778 - Selecting this option will wakeup the User Break Controller (UBC) on 779 - startup. Although the UBC is left in an awake state when the processor 780 - comes up, some boot loaders misbehave by putting the UBC to sleep in a 781 - power saving state, which causes issues with things like ptrace(). 782 - 783 - If unsure, say N. 784 - 785 764 choice 786 765 prompt "Kernel command line" 787 766 optional ··· 817 818 Dreamcast with a serial line terminal or a remote network 818 819 connection. 819 820 820 - source "arch/sh/drivers/pci/Kconfig" 821 + config PCI 822 + bool "PCI support" 823 + depends on SYS_SUPPORTS_PCI 824 + help 825 + Find out whether you have a PCI motherboard. PCI is the name of a 826 + bus system, i.e. the way the CPU talks to the other stuff inside 827 + your box. If you have PCI, say Y, otherwise N. 821 828 822 829 source "drivers/pci/pcie/Kconfig" 823 830
+4
arch/sh/Makefile
··· 78 78 defaultimage-$(CONFIG_SH_SH7785LCR) := uImage 79 79 defaultimage-$(CONFIG_SH_RSK) := uImage 80 80 defaultimage-$(CONFIG_SH_URQUELL) := uImage 81 + defaultimage-$(CONFIG_SH_MIGOR) := uImage 82 + defaultimage-$(CONFIG_SH_AP325RXA) := uImage 83 + defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE) := uImage 81 84 defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE) := vmlinux 82 85 defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE) := vmlinux 83 86 ··· 139 136 machdir-$(CONFIG_SH_EDOSK7705) += mach-edosk7705 140 137 machdir-$(CONFIG_SH_HIGHLANDER) += mach-highlander 141 138 machdir-$(CONFIG_SH_MIGOR) += mach-migor 139 + machdir-$(CONFIG_SH_AP325RXA) += mach-ap325rxa 142 140 machdir-$(CONFIG_SH_KFR2R09) += mach-kfr2r09 143 141 machdir-$(CONFIG_SH_ECOVEC) += mach-ecovec24 144 142 machdir-$(CONFIG_SH_SDK7780) += mach-sdk7780
-1
arch/sh/boards/Makefile
··· 1 1 # 2 2 # Specific board support, not covered by a mach group. 3 3 # 4 - obj-$(CONFIG_SH_AP325RXA) += board-ap325rxa.o 5 4 obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o 6 5 obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o 7 6 obj-$(CONFIG_SH_URQUELL) += board-urquell.o
+74 -23
arch/sh/boards/board-ap325rxa.c arch/sh/boards/mach-ap325rxa/setup.c
··· 20 20 #include <linux/i2c.h> 21 21 #include <linux/smsc911x.h> 22 22 #include <linux/gpio.h> 23 - #include <linux/spi/spi.h> 24 - #include <linux/spi/spi_gpio.h> 25 23 #include <media/ov772x.h> 26 24 #include <media/soc_camera.h> 27 25 #include <media/soc_camera_platform.h> ··· 27 29 #include <video/sh_mobile_lcdc.h> 28 30 #include <asm/io.h> 29 31 #include <asm/clock.h> 32 + #include <asm/suspend.h> 30 33 #include <cpu/sh7723.h> 31 34 32 35 static struct smsc911x_platform_config smsc911x_config = { ··· 408 409 }, 409 410 }; 410 411 411 - struct spi_gpio_platform_data sdcard_cn3_platform_data = { 412 - .sck = GPIO_PTD0, 413 - .mosi = GPIO_PTD1, 414 - .miso = GPIO_PTD2, 415 - .num_chipselect = 1, 412 + static struct resource sdhi0_cn3_resources[] = { 413 + [0] = { 414 + .name = "SDHI0", 415 + .start = 0x04ce0000, 416 + .end = 0x04ce01ff, 417 + .flags = IORESOURCE_MEM, 418 + }, 419 + [1] = { 420 + .start = 101, 421 + .flags = IORESOURCE_IRQ, 422 + }, 416 423 }; 417 424 418 - static struct platform_device sdcard_cn3_device = { 419 - .name = "spi_gpio", 420 - .dev = { 421 - .platform_data = &sdcard_cn3_platform_data, 425 + static struct platform_device sdhi0_cn3_device = { 426 + .name = "sh_mobile_sdhi", 427 + .id = 0, /* "sdhi0" clock */ 428 + .num_resources = ARRAY_SIZE(sdhi0_cn3_resources), 429 + .resource = sdhi0_cn3_resources, 430 + .archdata = { 431 + .hwblk_id = HWBLK_SDHI0, 432 + }, 433 + }; 434 + 435 + static struct resource sdhi1_cn7_resources[] = { 436 + [0] = { 437 + .name = "SDHI1", 438 + .start = 0x04cf0000, 439 + .end = 0x04cf01ff, 440 + .flags = IORESOURCE_MEM, 441 + }, 442 + [1] = { 443 + .start = 24, 444 + .flags = IORESOURCE_IRQ, 445 + }, 446 + }; 447 + 448 + static struct platform_device sdhi1_cn7_device = { 449 + .name = "sh_mobile_sdhi", 450 + .id = 1, /* "sdhi1" clock */ 451 + .num_resources = ARRAY_SIZE(sdhi1_cn7_resources), 452 + .resource = sdhi1_cn7_resources, 453 + .archdata = { 454 + .hwblk_id = HWBLK_SDHI1, 422 455 }, 423 456 }; 424 457 ··· 501 470 &lcdc_device, 502 471 &ceu_device, 503 472 &nand_flash_device, 504 - &sdcard_cn3_device, 473 + &sdhi0_cn3_device, 474 + &sdhi1_cn7_device, 505 475 &ap325rxa_camera[0], 506 476 &ap325rxa_camera[1], 507 477 }; 508 478 509 - static struct spi_board_info ap325rxa_spi_devices[] = { 510 - { 511 - .modalias = "mmc_spi", 512 - .max_speed_hz = 5000000, 513 - .chip_select = 0, 514 - .controller_data = (void *) GPIO_PTD5, 515 - }, 516 - }; 479 + extern char ap325rxa_sdram_enter_start; 480 + extern char ap325rxa_sdram_enter_end; 481 + extern char ap325rxa_sdram_leave_start; 482 + extern char ap325rxa_sdram_leave_end; 517 483 518 484 static int __init ap325rxa_devices_setup(void) 519 485 { 486 + /* register board specific self-refresh code */ 487 + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, 488 + &ap325rxa_sdram_enter_start, 489 + &ap325rxa_sdram_enter_end, 490 + &ap325rxa_sdram_leave_start, 491 + &ap325rxa_sdram_leave_end); 492 + 520 493 /* LD3 and LD4 LEDs */ 521 494 gpio_request(GPIO_PTX5, NULL); /* RUN */ 522 495 gpio_direction_output(GPIO_PTX5, 1); ··· 613 578 614 579 platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20); 615 580 581 + /* SDHI0 - CN3 - SD CARD */ 582 + gpio_request(GPIO_FN_SDHI0CD_PTD, NULL); 583 + gpio_request(GPIO_FN_SDHI0WP_PTD, NULL); 584 + gpio_request(GPIO_FN_SDHI0D3_PTD, NULL); 585 + gpio_request(GPIO_FN_SDHI0D2_PTD, NULL); 586 + gpio_request(GPIO_FN_SDHI0D1_PTD, NULL); 587 + gpio_request(GPIO_FN_SDHI0D0_PTD, NULL); 588 + gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL); 589 + gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL); 590 + 591 + /* SDHI1 - CN7 - MICRO SD CARD */ 592 + gpio_request(GPIO_FN_SDHI1CD, NULL); 593 + gpio_request(GPIO_FN_SDHI1D3, NULL); 594 + gpio_request(GPIO_FN_SDHI1D2, NULL); 595 + gpio_request(GPIO_FN_SDHI1D1, NULL); 596 + gpio_request(GPIO_FN_SDHI1D0, NULL); 597 + gpio_request(GPIO_FN_SDHI1CMD, NULL); 598 + gpio_request(GPIO_FN_SDHI1CLK, NULL); 599 + 616 600 i2c_register_board_info(0, ap325rxa_i2c_devices, 617 601 ARRAY_SIZE(ap325rxa_i2c_devices)); 618 - 619 - spi_register_board_info(ap325rxa_spi_devices, 620 - ARRAY_SIZE(ap325rxa_spi_devices)); 621 602 622 603 return platform_add_devices(ap325rxa_devices, 623 604 ARRAY_SIZE(ap325rxa_devices));
+2
arch/sh/boards/mach-ap325rxa/Makefile
··· 1 + obj-y := setup.o sdram.o 2 +
+69
arch/sh/boards/mach-ap325rxa/sdram.S
··· 1 + /* 2 + * AP325RXA sdram self/auto-refresh setup code 3 + * 4 + * Copyright (C) 2009 Magnus Damm 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + 11 + #include <linux/sys.h> 12 + #include <linux/errno.h> 13 + #include <linux/linkage.h> 14 + #include <asm/asm-offsets.h> 15 + #include <asm/suspend.h> 16 + #include <asm/romimage-macros.h> 17 + 18 + /* code to enter and leave self-refresh. must be self-contained. 19 + * this code will be copied to on-chip memory and executed from there. 20 + */ 21 + .balign 4 22 + ENTRY(ap325rxa_sdram_enter_start) 23 + 24 + /* SBSC: disable power down and put in self-refresh mode */ 25 + mov.l 1f, r4 26 + mov.l 2f, r1 27 + mov.l @r4, r2 28 + or r1, r2 29 + mov.l 3f, r3 30 + and r3, r2 31 + mov.l r2, @r4 32 + 33 + rts 34 + nop 35 + 36 + .balign 4 37 + 1: .long 0xfe400008 /* SDCR0 */ 38 + 2: .long 0x00000400 39 + 3: .long 0xffff7fff 40 + ENTRY(ap325rxa_sdram_enter_end) 41 + 42 + .balign 4 43 + ENTRY(ap325rxa_sdram_leave_start) 44 + 45 + /* SBSC: set auto-refresh mode */ 46 + mov.l 1f, r4 47 + mov.l @r4, r0 48 + mov.l 4f, r1 49 + and r1, r0 50 + mov.l r0, @r4 51 + mov.l 6f, r4 52 + mov.l 8f, r0 53 + mov.l @r4, r1 54 + mov #-1, r4 55 + add r4, r1 56 + or r1, r0 57 + mov.l 7f, r1 58 + mov.l r0, @r1 59 + 60 + rts 61 + nop 62 + 63 + .balign 4 64 + 1: .long 0xfe400008 /* SDCR0 */ 65 + 4: .long 0xfffffbff 66 + 6: .long 0xfe40001c /* RTCOR */ 67 + 7: .long 0xfe400018 /* RTCNT */ 68 + 8: .long 0xa55a0000 69 + ENTRY(ap325rxa_sdram_leave_end)
+1 -1
arch/sh/boards/mach-ecovec24/Makefile
··· 6 6 # for more details. 7 7 # 8 8 9 - obj-y := setup.o 9 + obj-y := setup.o sdram.o
+52
arch/sh/boards/mach-ecovec24/sdram.S
··· 1 + /* 2 + * Ecovec24 sdram self/auto-refresh setup code 3 + * 4 + * Copyright (C) 2009 Magnus Damm 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + 11 + #include <linux/sys.h> 12 + #include <linux/errno.h> 13 + #include <linux/linkage.h> 14 + #include <asm/asm-offsets.h> 15 + #include <asm/suspend.h> 16 + #include <asm/romimage-macros.h> 17 + 18 + /* code to enter and leave self-refresh. must be self-contained. 19 + * this code will be copied to on-chip memory and executed from there. 20 + */ 21 + .balign 4 22 + ENTRY(ecovec24_sdram_enter_start) 23 + 24 + /* DBSC: put memory in self-refresh mode */ 25 + 26 + ED 0xFD000010, 0x00000000 /* DBEN */ 27 + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ 28 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ 29 + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ 30 + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ 31 + 32 + rts 33 + nop 34 + 35 + ENTRY(ecovec24_sdram_enter_end) 36 + 37 + .balign 4 38 + ENTRY(ecovec24_sdram_leave_start) 39 + 40 + /* DBSC: put memory in auto-refresh mode */ 41 + 42 + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ 43 + WAIT 1 44 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ 45 + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ 46 + ED 0xFD000010, 0x00000001 /* DBEN */ 47 + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ 48 + 49 + rts 50 + nop 51 + 52 + ENTRY(ecovec24_sdram_leave_end)
+143 -54
arch/sh/boards/mach-ecovec24/setup.c
··· 20 20 #include <linux/i2c.h> 21 21 #include <linux/i2c/tsc2007.h> 22 22 #include <linux/input.h> 23 + #include <linux/input/sh_keysc.h> 24 + #include <linux/mfd/sh_mobile_sdhi.h> 23 25 #include <video/sh_mobile_lcdc.h> 24 26 #include <media/sh_mobile_ceu.h> 25 27 #include <asm/heartbeat.h> 26 28 #include <asm/sh_eth.h> 27 - #include <asm/sh_keysc.h> 28 29 #include <asm/clock.h> 30 + #include <asm/suspend.h> 29 31 #include <cpu/sh7724.h> 30 32 31 33 /* ··· 149 147 }, 150 148 .num_resources = ARRAY_SIZE(sh_eth_resources), 151 149 .resource = sh_eth_resources, 150 + .archdata = { 151 + .hwblk_id = HWBLK_ETHER, 152 + }, 152 153 }; 153 154 154 155 /* USB0 host */ ··· 190 185 .resource = usb0_host_resources, 191 186 }; 192 187 193 - /* 194 - * USB1 195 - * 196 - * CN5 can use both host/function, 197 - * and we can determine it by checking PTB[3] 198 - * 199 - * This time only USB1 host is supported. 200 - */ 188 + /* USB1 host/function */ 201 189 void usb1_port_power(int port, int power) 202 190 { 203 - if (!gpio_get_value(GPIO_PTB3)) { 204 - printk(KERN_ERR "USB1 function is not supported\n"); 205 - return; 206 - } 207 - 208 191 gpio_set_value(GPIO_PTB5, power); 209 192 } 210 193 211 - static struct r8a66597_platdata usb1_host_data = { 194 + static struct r8a66597_platdata usb1_common_data = { 212 195 .on_chip = 1, 213 196 .port_power = usb1_port_power, 214 197 }; 215 198 216 - static struct resource usb1_host_resources[] = { 199 + static struct resource usb1_common_resources[] = { 217 200 [0] = { 218 201 .start = 0xa4d90000, 219 202 .end = 0xa4d90124 - 1, ··· 214 221 }, 215 222 }; 216 223 217 - static struct platform_device usb1_host_device = { 218 - .name = "r8a66597_hcd", 224 + static struct platform_device usb1_common_device = { 225 + /* .name will be added in arch_setup */ 219 226 .id = 1, 220 227 .dev = { 221 228 .dma_mask = NULL, /* not use dma */ 222 229 .coherent_dma_mask = 0xffffffff, 223 - .platform_data = &usb1_host_data, 230 + .platform_data = &usb1_common_data, 224 231 }, 225 - .num_resources = ARRAY_SIZE(usb1_host_resources), 226 - .resource = usb1_host_resources, 232 + .num_resources = ARRAY_SIZE(usb1_common_resources), 233 + .resource = usb1_common_resources, 227 234 }; 228 235 229 236 /* LCDC */ ··· 421 428 .irq = IRQ0, 422 429 }; 423 430 431 + /* SHDI0 */ 432 + static void sdhi0_set_pwr(struct platform_device *pdev, int state) 433 + { 434 + gpio_set_value(GPIO_PTB6, state); 435 + } 436 + 437 + static struct sh_mobile_sdhi_info sdhi0_info = { 438 + .set_pwr = sdhi0_set_pwr, 439 + }; 440 + 441 + static struct resource sdhi0_resources[] = { 442 + [0] = { 443 + .name = "SDHI0", 444 + .start = 0x04ce0000, 445 + .end = 0x04ce01ff, 446 + .flags = IORESOURCE_MEM, 447 + }, 448 + [1] = { 449 + .start = 101, 450 + .flags = IORESOURCE_IRQ, 451 + }, 452 + }; 453 + 454 + static struct platform_device sdhi0_device = { 455 + .name = "sh_mobile_sdhi", 456 + .num_resources = ARRAY_SIZE(sdhi0_resources), 457 + .resource = sdhi0_resources, 458 + .id = 0, 459 + .dev = { 460 + .platform_data = &sdhi0_info, 461 + }, 462 + .archdata = { 463 + .hwblk_id = HWBLK_SDHI0, 464 + }, 465 + }; 466 + 467 + /* SHDI1 */ 468 + static void sdhi1_set_pwr(struct platform_device *pdev, int state) 469 + { 470 + gpio_set_value(GPIO_PTB7, state); 471 + } 472 + 473 + static struct sh_mobile_sdhi_info sdhi1_info = { 474 + .set_pwr = sdhi1_set_pwr, 475 + }; 476 + 477 + static struct resource sdhi1_resources[] = { 478 + [0] = { 479 + .name = "SDHI1", 480 + .start = 0x04cf0000, 481 + .end = 0x04cf01ff, 482 + .flags = IORESOURCE_MEM, 483 + }, 484 + [1] = { 485 + .start = 24, 486 + .flags = IORESOURCE_IRQ, 487 + }, 488 + }; 489 + 490 + static struct platform_device sdhi1_device = { 491 + .name = "sh_mobile_sdhi", 492 + .num_resources = ARRAY_SIZE(sdhi1_resources), 493 + .resource = sdhi1_resources, 494 + .id = 1, 495 + .dev = { 496 + .platform_data = &sdhi1_info, 497 + }, 498 + .archdata = { 499 + .hwblk_id = HWBLK_SDHI1, 500 + }, 501 + }; 502 + 424 503 static struct platform_device *ecovec_devices[] __initdata = { 425 504 &heartbeat_device, 426 505 &nor_flash_device, 427 506 &sh_eth_device, 428 507 &usb0_host_device, 429 - &usb1_host_device, /* USB1 host support */ 508 + &usb1_common_device, 430 509 &lcdc_device, 431 510 &ceu0_device, 432 511 &ceu1_device, 433 512 &keysc_device, 513 + &sdhi0_device, 514 + &sdhi1_device, 434 515 }; 435 516 436 517 #define EEPROM_ADDR 0x50 ··· 533 466 return buf; 534 467 } 535 468 536 - #define MAC_LEN 6 537 - static void __init sh_eth_init(void) 469 + static void __init sh_eth_init(struct sh_eth_plat_data *pd) 538 470 { 539 471 struct i2c_adapter *a = i2c_get_adapter(1); 540 - struct clk *eth_clk; 541 - u8 mac[MAC_LEN]; 542 472 int i; 543 473 544 474 if (!a) { ··· 543 479 return; 544 480 } 545 481 546 - eth_clk = clk_get(NULL, "eth0"); 547 - if (!eth_clk) { 548 - pr_err("can not get eth0 clk\n"); 549 - return; 550 - } 551 - 552 482 /* read MAC address frome EEPROM */ 553 - for (i = 0; i < MAC_LEN; i++) { 554 - mac[i] = mac_read(a, 0x10 + i); 483 + for (i = 0; i < sizeof(pd->mac_addr); i++) { 484 + pd->mac_addr[i] = mac_read(a, 0x10 + i); 555 485 msleep(10); 556 486 } 557 - 558 - /* clock enable */ 559 - clk_enable(eth_clk); 560 - 561 - /* reset sh-eth */ 562 - ctrl_outl(0x1, SH_ETH_ADDR + 0x0); 563 - 564 - /* set MAC addr */ 565 - ctrl_outl((mac[0] << 24) | 566 - (mac[1] << 16) | 567 - (mac[2] << 8) | 568 - (mac[3] << 0), SH_ETH_MAHR); 569 - ctrl_outl((mac[4] << 8) | 570 - (mac[5] << 0), SH_ETH_MALR); 571 - 572 - clk_put(eth_clk); 573 487 } 574 488 575 489 #define PORT_HIZA 0xA4050158 576 490 #define IODRIVEA 0xA405018A 491 + 492 + extern char ecovec24_sdram_enter_start; 493 + extern char ecovec24_sdram_enter_end; 494 + extern char ecovec24_sdram_leave_start; 495 + extern char ecovec24_sdram_leave_end; 496 + 577 497 static int __init arch_setup(void) 578 498 { 499 + /* register board specific self-refresh code */ 500 + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, 501 + &ecovec24_sdram_enter_start, 502 + &ecovec24_sdram_enter_end, 503 + &ecovec24_sdram_leave_start, 504 + &ecovec24_sdram_leave_end); 505 + 579 506 /* enable STATUS0, STATUS2 and PDSTATUS */ 580 507 gpio_request(GPIO_FN_STATUS0, NULL); 581 508 gpio_request(GPIO_FN_STATUS2, NULL); ··· 616 561 ctrl_outw(0x0600, 0xa40501d4); 617 562 ctrl_outw(0x0600, 0xa4050192); 618 563 564 + if (gpio_get_value(GPIO_PTB3)) { 565 + printk(KERN_INFO "USB1 function is selected\n"); 566 + usb1_common_device.name = "r8a66597_udc"; 567 + } else { 568 + printk(KERN_INFO "USB1 host is selected\n"); 569 + usb1_common_device.name = "r8a66597_hcd"; 570 + } 571 + 619 572 /* enable LCDC */ 620 573 gpio_request(GPIO_FN_LCDD23, NULL); 621 574 gpio_request(GPIO_FN_LCDD22, NULL); ··· 666 603 gpio_direction_output(GPIO_PTR1, 0); 667 604 gpio_direction_output(GPIO_PTA2, 0); 668 605 669 - /* I/O buffer drive ability is low */ 670 - ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0040 , IODRIVEA); 606 + /* I/O buffer drive ability is high */ 607 + ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA); 671 608 672 609 if (gpio_get_value(GPIO_PTE6)) { 673 610 /* DVI */ ··· 773 710 gpio_direction_input(GPIO_PTR5); 774 711 gpio_direction_input(GPIO_PTR6); 775 712 713 + /* enable SDHI0 (needs DS2.4 set to ON) */ 714 + gpio_request(GPIO_FN_SDHI0CD, NULL); 715 + gpio_request(GPIO_FN_SDHI0WP, NULL); 716 + gpio_request(GPIO_FN_SDHI0CMD, NULL); 717 + gpio_request(GPIO_FN_SDHI0CLK, NULL); 718 + gpio_request(GPIO_FN_SDHI0D3, NULL); 719 + gpio_request(GPIO_FN_SDHI0D2, NULL); 720 + gpio_request(GPIO_FN_SDHI0D1, NULL); 721 + gpio_request(GPIO_FN_SDHI0D0, NULL); 722 + gpio_request(GPIO_PTB6, NULL); 723 + gpio_direction_output(GPIO_PTB6, 0); 724 + 725 + /* enable SDHI1 (needs DS2.6,7 set to ON,OFF) */ 726 + gpio_request(GPIO_FN_SDHI1CD, NULL); 727 + gpio_request(GPIO_FN_SDHI1WP, NULL); 728 + gpio_request(GPIO_FN_SDHI1CMD, NULL); 729 + gpio_request(GPIO_FN_SDHI1CLK, NULL); 730 + gpio_request(GPIO_FN_SDHI1D3, NULL); 731 + gpio_request(GPIO_FN_SDHI1D2, NULL); 732 + gpio_request(GPIO_FN_SDHI1D1, NULL); 733 + gpio_request(GPIO_FN_SDHI1D0, NULL); 734 + gpio_request(GPIO_PTB7, NULL); 735 + gpio_direction_output(GPIO_PTB7, 0); 736 + 737 + /* I/O buffer drive ability is high for SDHI1 */ 738 + ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); 739 + 776 740 /* enable I2C device */ 777 741 i2c_register_board_info(1, i2c1_devices, 778 742 ARRAY_SIZE(i2c1_devices)); ··· 811 721 812 722 static int __init devices_setup(void) 813 723 { 814 - sh_eth_init(); 724 + sh_eth_init(&sh_eth_plat); 815 725 return 0; 816 726 } 817 727 device_initcall(devices_setup); 818 - 819 728 820 729 static struct sh_machine_vector mv_ecovec __initmv = { 821 730 .mv_name = "R0P7724 (EcoVec)",
+1 -1
arch/sh/boards/mach-highlander/setup.c
··· 384 384 385 385 static int highlander_irq_demux(int irq) 386 386 { 387 - if (irq >= HL_NR_IRL || !irl2irq[irq]) 387 + if (irq >= HL_NR_IRL || irq < 0 || !irl2irq[irq]) 388 388 return irq; 389 389 390 390 return irl2irq[irq];
+1 -1
arch/sh/boards/mach-kfr2r09/Makefile
··· 1 - obj-y := setup.o 1 + obj-y := setup.o sdram.o 2 2 obj-$(CONFIG_FB_SH_MOBILE_LCDC) += lcd_wqvga.o
+80
arch/sh/boards/mach-kfr2r09/sdram.S
··· 1 + /* 2 + * KFR2R09 sdram self/auto-refresh setup code 3 + * 4 + * Copyright (C) 2009 Magnus Damm 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + 11 + #include <linux/sys.h> 12 + #include <linux/errno.h> 13 + #include <linux/linkage.h> 14 + #include <asm/asm-offsets.h> 15 + #include <asm/suspend.h> 16 + #include <asm/romimage-macros.h> 17 + 18 + /* code to enter and leave self-refresh. must be self-contained. 19 + * this code will be copied to on-chip memory and executed from there. 20 + */ 21 + .balign 4 22 + ENTRY(kfr2r09_sdram_enter_start) 23 + 24 + /* DBSC: put memory in self-refresh mode */ 25 + 26 + ED 0xFD000010, 0x00000000 /* DBEN */ 27 + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ 28 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ 29 + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ 30 + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ 31 + 32 + rts 33 + nop 34 + 35 + ENTRY(kfr2r09_sdram_enter_end) 36 + 37 + .balign 4 38 + ENTRY(kfr2r09_sdram_leave_start) 39 + 40 + /* DBSC: put memory in auto-refresh mode */ 41 + 42 + mov.l @(SH_SLEEP_MODE, r5), r0 43 + tst #SUSP_SH_RSTANDBY, r0 44 + bf resume_rstandby 45 + 46 + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ 47 + WAIT 1 48 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ 49 + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ 50 + ED 0xFD000010, 0x00000001 /* DBEN */ 51 + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ 52 + 53 + rts 54 + nop 55 + 56 + resume_rstandby: 57 + 58 + /* DBSC: re-initialize and put in auto-refresh */ 59 + 60 + ED 0xFD000108, 0x40000301 /* DBPDCNT0 */ 61 + ED 0xFD000020, 0x011B0002 /* DBCONF */ 62 + ED 0xFD000030, 0x03060E02 /* DBTR0 */ 63 + ED 0xFD000034, 0x01020102 /* DBTR1 */ 64 + ED 0xFD000038, 0x01090406 /* DBTR2 */ 65 + ED 0xFD000008, 0x00000004 /* DBKIND */ 66 + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ 67 + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ 68 + ED 0xFD000018, 0x00000001 /* DBCKECNT */ 69 + WAIT 1 70 + ED 0xFD000010, 0x00000001 /* DBEN */ 71 + ED 0xFD000044, 0x000004AF /* DBRFPDN1 */ 72 + ED 0xFD000048, 0x20CF0037 /* DBRFPDN2 */ 73 + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ 74 + ED 0xFD000108, 0x40000300 /* DBPDCNT0 */ 75 + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ 76 + 77 + rts 78 + nop 79 + 80 + ENTRY(kfr2r09_sdram_leave_end)
+237 -1
arch/sh/boards/mach-kfr2r09/setup.c
··· 16 16 #include <linux/clk.h> 17 17 #include <linux/gpio.h> 18 18 #include <linux/input.h> 19 + #include <linux/input/sh_keysc.h> 19 20 #include <linux/i2c.h> 20 21 #include <linux/usb/r8a66597.h> 22 + #include <media/soc_camera.h> 23 + #include <media/sh_mobile_ceu.h> 21 24 #include <video/sh_mobile_lcdc.h> 25 + #include <asm/suspend.h> 22 26 #include <asm/clock.h> 23 27 #include <asm/machvec.h> 24 28 #include <asm/io.h> 25 - #include <asm/sh_keysc.h> 26 29 #include <cpu/sh7724.h> 27 30 #include <mach/kfr2r09.h> 28 31 ··· 215 212 .resource = kfr2r09_usb0_gadget_resources, 216 213 }; 217 214 215 + static struct sh_mobile_ceu_info sh_mobile_ceu_info = { 216 + .flags = SH_CEU_FLAG_USE_8BIT_BUS, 217 + }; 218 + 219 + static struct resource kfr2r09_ceu_resources[] = { 220 + [0] = { 221 + .name = "CEU", 222 + .start = 0xfe910000, 223 + .end = 0xfe91009f, 224 + .flags = IORESOURCE_MEM, 225 + }, 226 + [1] = { 227 + .start = 52, 228 + .end = 52, 229 + .flags = IORESOURCE_IRQ, 230 + }, 231 + [2] = { 232 + /* place holder for contiguous memory */ 233 + }, 234 + }; 235 + 236 + static struct platform_device kfr2r09_ceu_device = { 237 + .name = "sh_mobile_ceu", 238 + .id = 0, /* "ceu0" clock */ 239 + .num_resources = ARRAY_SIZE(kfr2r09_ceu_resources), 240 + .resource = kfr2r09_ceu_resources, 241 + .dev = { 242 + .platform_data = &sh_mobile_ceu_info, 243 + }, 244 + .archdata = { 245 + .hwblk_id = HWBLK_CEU0, 246 + }, 247 + }; 248 + 249 + static struct i2c_board_info kfr2r09_i2c_camera = { 250 + I2C_BOARD_INFO("rj54n1cb0c", 0x50), 251 + }; 252 + 253 + static struct clk *camera_clk; 254 + 255 + #define DRVCRB 0xA405018C 256 + static int camera_power(struct device *dev, int mode) 257 + { 258 + int ret; 259 + 260 + if (mode) { 261 + long rate; 262 + 263 + camera_clk = clk_get(NULL, "video_clk"); 264 + if (IS_ERR(camera_clk)) 265 + return PTR_ERR(camera_clk); 266 + 267 + /* set VIO_CKO clock to 25MHz */ 268 + rate = clk_round_rate(camera_clk, 25000000); 269 + ret = clk_set_rate(camera_clk, rate); 270 + if (ret < 0) 271 + goto eclkrate; 272 + 273 + /* set DRVCRB 274 + * 275 + * use 1.8 V for VccQ_VIO 276 + * use 2.85V for VccQ_SR 277 + */ 278 + ctrl_outw((ctrl_inw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB); 279 + 280 + /* reset clear */ 281 + ret = gpio_request(GPIO_PTB4, NULL); 282 + if (ret < 0) 283 + goto eptb4; 284 + ret = gpio_request(GPIO_PTB7, NULL); 285 + if (ret < 0) 286 + goto eptb7; 287 + 288 + ret = gpio_direction_output(GPIO_PTB4, 1); 289 + if (!ret) 290 + ret = gpio_direction_output(GPIO_PTB7, 1); 291 + if (ret < 0) 292 + goto egpioout; 293 + msleep(1); 294 + 295 + ret = clk_enable(camera_clk); /* start VIO_CKO */ 296 + if (ret < 0) 297 + goto eclkon; 298 + 299 + return 0; 300 + } 301 + 302 + ret = 0; 303 + 304 + clk_disable(camera_clk); 305 + eclkon: 306 + gpio_set_value(GPIO_PTB7, 0); 307 + egpioout: 308 + gpio_set_value(GPIO_PTB4, 0); 309 + gpio_free(GPIO_PTB7); 310 + eptb7: 311 + gpio_free(GPIO_PTB4); 312 + eptb4: 313 + eclkrate: 314 + clk_put(camera_clk); 315 + return ret; 316 + } 317 + 318 + static struct soc_camera_link rj54n1_link = { 319 + .power = camera_power, 320 + .board_info = &kfr2r09_i2c_camera, 321 + .i2c_adapter_id = 1, 322 + .module_name = "rj54n1cb0c", 323 + }; 324 + 325 + static struct platform_device kfr2r09_camera = { 326 + .name = "soc-camera-pdrv", 327 + .id = 0, 328 + .dev = { 329 + .platform_data = &rj54n1_link, 330 + }, 331 + }; 332 + 333 + static struct resource kfr2r09_sh_sdhi0_resources[] = { 334 + [0] = { 335 + .name = "SDHI0", 336 + .start = 0x04ce0000, 337 + .end = 0x04ce01ff, 338 + .flags = IORESOURCE_MEM, 339 + }, 340 + [1] = { 341 + .start = 101, 342 + .flags = IORESOURCE_IRQ, 343 + }, 344 + }; 345 + 346 + static struct platform_device kfr2r09_sh_sdhi0_device = { 347 + .name = "sh_mobile_sdhi", 348 + .num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources), 349 + .resource = kfr2r09_sh_sdhi0_resources, 350 + .archdata = { 351 + .hwblk_id = HWBLK_SDHI0, 352 + }, 353 + }; 354 + 218 355 static struct platform_device *kfr2r09_devices[] __initdata = { 219 356 &kfr2r09_nor_flash_device, 220 357 &kfr2r09_nand_flash_device, 221 358 &kfr2r09_sh_keysc_device, 222 359 &kfr2r09_sh_lcdc_device, 360 + &kfr2r09_ceu_device, 361 + &kfr2r09_camera, 362 + &kfr2r09_sh_sdhi0_device, 223 363 }; 224 364 225 365 #define BSC_CS0BCR 0xfec10004 ··· 414 268 415 269 return 0; 416 270 } 271 + 272 + static int kfr2r09_serial_i2c_setup(void) 273 + { 274 + struct i2c_adapter *a; 275 + struct i2c_msg msg; 276 + unsigned char buf[2]; 277 + int ret; 278 + 279 + a = i2c_get_adapter(0); 280 + if (!a) 281 + return -ENODEV; 282 + 283 + /* set bit 6 (the 7th bit) of chip at 0x09, register 0x13 */ 284 + buf[0] = 0x13; 285 + msg.addr = 0x09; 286 + msg.buf = buf; 287 + msg.len = 1; 288 + msg.flags = 0; 289 + ret = i2c_transfer(a, &msg, 1); 290 + if (ret != 1) 291 + return -ENODEV; 292 + 293 + buf[0] = 0; 294 + msg.addr = 0x09; 295 + msg.buf = buf; 296 + msg.len = 1; 297 + msg.flags = I2C_M_RD; 298 + ret = i2c_transfer(a, &msg, 1); 299 + if (ret != 1) 300 + return -ENODEV; 301 + 302 + buf[1] = buf[0] | (1 << 6); 303 + buf[0] = 0x13; 304 + msg.addr = 0x09; 305 + msg.buf = buf; 306 + msg.len = 2; 307 + msg.flags = 0; 308 + ret = i2c_transfer(a, &msg, 1); 309 + if (ret != 1) 310 + return -ENODEV; 311 + 312 + return 0; 313 + } 417 314 #else 418 315 static int kfr2r09_usb0_gadget_i2c_setup(void) 316 + { 317 + return -ENODEV; 318 + } 319 + 320 + static int kfr2r09_serial_i2c_setup(void) 419 321 { 420 322 return -ENODEV; 421 323 } ··· 493 299 return 0; 494 300 } 495 301 302 + extern char kfr2r09_sdram_enter_start; 303 + extern char kfr2r09_sdram_enter_end; 304 + extern char kfr2r09_sdram_leave_start; 305 + extern char kfr2r09_sdram_leave_end; 306 + 496 307 static int __init kfr2r09_devices_setup(void) 497 308 { 309 + /* register board specific self-refresh code */ 310 + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | 311 + SUSP_SH_RSTANDBY, 312 + &kfr2r09_sdram_enter_start, 313 + &kfr2r09_sdram_enter_end, 314 + &kfr2r09_sdram_leave_start, 315 + &kfr2r09_sdram_leave_end); 316 + 498 317 /* enable SCIF1 serial port for YC401 console support */ 499 318 gpio_request(GPIO_FN_SCIF1_RXD, NULL); 500 319 gpio_request(GPIO_FN_SCIF1_TXD, NULL); 320 + kfr2r09_serial_i2c_setup(); /* ECONTMSK(bit6=L10ONEN) set 1 */ 321 + gpio_request(GPIO_PTG3, NULL); /* HPON_ON */ 322 + gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */ 501 323 502 324 /* setup NOR flash at CS0 */ 503 325 ctrl_outl(0x36db0400, BSC_CS0BCR); ··· 570 360 /* setup USB function */ 571 361 if (kfr2r09_usb0_gadget_setup() == 0) 572 362 platform_device_register(&kfr2r09_usb0_gadget_device); 363 + 364 + /* CEU */ 365 + gpio_request(GPIO_FN_VIO_CKO, NULL); 366 + gpio_request(GPIO_FN_VIO0_CLK, NULL); 367 + gpio_request(GPIO_FN_VIO0_VD, NULL); 368 + gpio_request(GPIO_FN_VIO0_HD, NULL); 369 + gpio_request(GPIO_FN_VIO0_FLD, NULL); 370 + gpio_request(GPIO_FN_VIO0_D7, NULL); 371 + gpio_request(GPIO_FN_VIO0_D6, NULL); 372 + gpio_request(GPIO_FN_VIO0_D5, NULL); 373 + gpio_request(GPIO_FN_VIO0_D4, NULL); 374 + gpio_request(GPIO_FN_VIO0_D3, NULL); 375 + gpio_request(GPIO_FN_VIO0_D2, NULL); 376 + gpio_request(GPIO_FN_VIO0_D1, NULL); 377 + gpio_request(GPIO_FN_VIO0_D0, NULL); 378 + 379 + platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20); 380 + 381 + /* SDHI0 connected to yc304 */ 382 + gpio_request(GPIO_FN_SDHI0CD, NULL); 383 + gpio_request(GPIO_FN_SDHI0D3, NULL); 384 + gpio_request(GPIO_FN_SDHI0D2, NULL); 385 + gpio_request(GPIO_FN_SDHI0D1, NULL); 386 + gpio_request(GPIO_FN_SDHI0D0, NULL); 387 + gpio_request(GPIO_FN_SDHI0CMD, NULL); 388 + gpio_request(GPIO_FN_SDHI0CLK, NULL); 573 389 574 390 return platform_add_devices(kfr2r09_devices, 575 391 ARRAY_SIZE(kfr2r09_devices));
+1 -1
arch/sh/boards/mach-migor/Makefile
··· 1 - obj-y := setup.o 1 + obj-y := setup.o sdram.o 2 2 obj-$(CONFIG_SH_MIGOR_QVGA) += lcd_qvga.o
+69
arch/sh/boards/mach-migor/sdram.S
··· 1 + /* 2 + * Migo-R sdram self/auto-refresh setup code 3 + * 4 + * Copyright (C) 2009 Magnus Damm 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + 11 + #include <linux/sys.h> 12 + #include <linux/errno.h> 13 + #include <linux/linkage.h> 14 + #include <asm/asm-offsets.h> 15 + #include <asm/suspend.h> 16 + #include <asm/romimage-macros.h> 17 + 18 + /* code to enter and leave self-refresh. must be self-contained. 19 + * this code will be copied to on-chip memory and executed from there. 20 + */ 21 + .balign 4 22 + ENTRY(migor_sdram_enter_start) 23 + 24 + /* SBSC: disable power down and put in self-refresh mode */ 25 + mov.l 1f, r4 26 + mov.l 2f, r1 27 + mov.l @r4, r2 28 + or r1, r2 29 + mov.l 3f, r3 30 + and r3, r2 31 + mov.l r2, @r4 32 + 33 + rts 34 + nop 35 + 36 + .balign 4 37 + 1: .long 0xfe400008 /* SDCR0 */ 38 + 2: .long 0x00000400 39 + 3: .long 0xffff7fff 40 + ENTRY(migor_sdram_enter_end) 41 + 42 + .balign 4 43 + ENTRY(migor_sdram_leave_start) 44 + 45 + /* SBSC: set auto-refresh mode */ 46 + mov.l 1f, r4 47 + mov.l @r4, r0 48 + mov.l 4f, r1 49 + and r1, r0 50 + mov.l r0, @r4 51 + mov.l 6f, r4 52 + mov.l 8f, r0 53 + mov.l @r4, r1 54 + mov #-1, r4 55 + add r4, r1 56 + or r1, r0 57 + mov.l 7f, r1 58 + mov.l r0, @r1 59 + 60 + rts 61 + nop 62 + 63 + .balign 4 64 + 1: .long 0xfe400008 /* SDCR0 */ 65 + 4: .long 0xfffffbff 66 + 6: .long 0xfe40001c /* RTCOR */ 67 + 7: .long 0xfe400018 /* RTCNT */ 68 + 8: .long 0xa55a0000 69 + ENTRY(migor_sdram_leave_end)
+40 -25
arch/sh/boards/mach-migor/setup.c
··· 11 11 #include <linux/platform_device.h> 12 12 #include <linux/interrupt.h> 13 13 #include <linux/input.h> 14 + #include <linux/input/sh_keysc.h> 14 15 #include <linux/mtd/physmap.h> 15 16 #include <linux/mtd/nand.h> 16 17 #include <linux/i2c.h> ··· 19 18 #include <linux/delay.h> 20 19 #include <linux/clk.h> 21 20 #include <linux/gpio.h> 22 - #include <linux/spi/spi.h> 23 - #include <linux/spi/spi_gpio.h> 24 21 #include <video/sh_mobile_lcdc.h> 25 22 #include <media/sh_mobile_ceu.h> 26 23 #include <media/ov772x.h> ··· 26 27 #include <asm/clock.h> 27 28 #include <asm/machvec.h> 28 29 #include <asm/io.h> 29 - #include <asm/sh_keysc.h> 30 + #include <asm/suspend.h> 30 31 #include <mach/migor.h> 31 32 #include <cpu/sh7722.h> 32 33 ··· 389 390 }, 390 391 }; 391 392 392 - struct spi_gpio_platform_data sdcard_cn9_platform_data = { 393 - .sck = GPIO_PTD0, 394 - .mosi = GPIO_PTD1, 395 - .miso = GPIO_PTD2, 396 - .num_chipselect = 1, 393 + static struct resource sdhi_cn9_resources[] = { 394 + [0] = { 395 + .name = "SDHI", 396 + .start = 0x04ce0000, 397 + .end = 0x04ce01ff, 398 + .flags = IORESOURCE_MEM, 399 + }, 400 + [1] = { 401 + .start = 101, 402 + .flags = IORESOURCE_IRQ, 403 + }, 397 404 }; 398 405 399 - static struct platform_device sdcard_cn9_device = { 400 - .name = "spi_gpio", 401 - .dev = { 402 - .platform_data = &sdcard_cn9_platform_data, 406 + static struct platform_device sdhi_cn9_device = { 407 + .name = "sh_mobile_sdhi", 408 + .num_resources = ARRAY_SIZE(sdhi_cn9_resources), 409 + .resource = sdhi_cn9_resources, 410 + .archdata = { 411 + .hwblk_id = HWBLK_SDHI, 403 412 }, 404 413 }; 405 414 ··· 474 467 &migor_ceu_device, 475 468 &migor_nor_flash_device, 476 469 &migor_nand_flash_device, 477 - &sdcard_cn9_device, 470 + &sdhi_cn9_device, 478 471 &migor_camera[0], 479 472 &migor_camera[1], 480 473 }; 481 474 482 - static struct spi_board_info migor_spi_devices[] = { 483 - { 484 - .modalias = "mmc_spi", 485 - .max_speed_hz = 5000000, 486 - .chip_select = 0, 487 - .controller_data = (void *) GPIO_PTD5, 488 - }, 489 - }; 475 + extern char migor_sdram_enter_start; 476 + extern char migor_sdram_enter_end; 477 + extern char migor_sdram_leave_start; 478 + extern char migor_sdram_leave_end; 490 479 491 480 static int __init migor_devices_setup(void) 492 481 { 493 - 482 + /* register board specific self-refresh code */ 483 + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, 484 + &migor_sdram_enter_start, 485 + &migor_sdram_enter_end, 486 + &migor_sdram_leave_start, 487 + &migor_sdram_leave_end); 494 488 #ifdef CONFIG_PM 495 489 /* Let D11 LED show STATUS0 */ 496 490 gpio_request(GPIO_FN_STATUS0, NULL); ··· 532 524 ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR); 533 525 gpio_request(GPIO_PTA1, NULL); 534 526 gpio_direction_input(GPIO_PTA1); 527 + 528 + /* SDHI */ 529 + gpio_request(GPIO_FN_SDHICD, NULL); 530 + gpio_request(GPIO_FN_SDHIWP, NULL); 531 + gpio_request(GPIO_FN_SDHID3, NULL); 532 + gpio_request(GPIO_FN_SDHID2, NULL); 533 + gpio_request(GPIO_FN_SDHID1, NULL); 534 + gpio_request(GPIO_FN_SDHID0, NULL); 535 + gpio_request(GPIO_FN_SDHICMD, NULL); 536 + gpio_request(GPIO_FN_SDHICLK, NULL); 535 537 536 538 /* Touch Panel */ 537 539 gpio_request(GPIO_FN_IRQ6, NULL); ··· 629 611 630 612 i2c_register_board_info(0, migor_i2c_devices, 631 613 ARRAY_SIZE(migor_i2c_devices)); 632 - 633 - spi_register_board_info(migor_spi_devices, 634 - ARRAY_SIZE(migor_spi_devices)); 635 614 636 615 return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); 637 616 }
+1 -1
arch/sh/boards/mach-r2d/irq.c
··· 116 116 117 117 int rts7751r2d_irq_demux(int irq) 118 118 { 119 - if (irq >= R2D_NR_IRL || !irl2irq[irq]) 119 + if (irq >= R2D_NR_IRL || irq < 0 || !irl2irq[irq]) 120 120 return irq; 121 121 122 122 return irl2irq[irq];
+19 -13
arch/sh/boards/mach-se/7722/irq.c
··· 16 16 #include <asm/io.h> 17 17 #include <mach-se/mach/se7722.h> 18 18 19 + unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; 20 + 19 21 static void disable_se7722_irq(unsigned int irq) 20 22 { 21 - unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; 23 + unsigned int bit = (unsigned int)get_irq_chip_data(irq); 22 24 ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); 23 25 } 24 26 25 27 static void enable_se7722_irq(unsigned int irq) 26 28 { 27 - unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; 29 + unsigned int bit = (unsigned int)get_irq_chip_data(irq); 28 30 ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); 29 31 } 30 32 ··· 40 38 static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) 41 39 { 42 40 unsigned short intv = ctrl_inw(IRQ01_STS); 43 - struct irq_desc *ext_desc; 44 - unsigned int ext_irq = SE7722_FPGA_IRQ_BASE; 41 + unsigned int ext_irq = 0; 45 42 46 43 intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; 47 44 48 - while (intv) { 49 - if (intv & 1) { 50 - ext_desc = irq_desc + ext_irq; 51 - handle_level_irq(ext_irq, ext_desc); 52 - } 53 - intv >>= 1; 54 - ext_irq++; 45 + for (; intv; intv >>= 1, ext_irq++) { 46 + if (!(intv & 1)) 47 + continue; 48 + 49 + generic_handle_irq(se7722_fpga_irq[ext_irq]); 55 50 } 56 51 } 57 52 ··· 62 63 ctrl_outw(0, IRQ01_MASK); /* disable all irqs */ 63 64 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ 64 65 65 - for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) 66 - set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i, 66 + for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { 67 + se7722_fpga_irq[i] = create_irq(); 68 + if (se7722_fpga_irq[i] < 0) 69 + return; 70 + 71 + set_irq_chip_and_handler_name(se7722_fpga_irq[i], 67 72 &se7722_irq_chip, 68 73 handle_level_irq, "level"); 74 + 75 + set_irq_chip_data(se7722_fpga_irq[i], (void *)i); 76 + } 69 77 70 78 set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux); 71 79 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+11 -6
arch/sh/boards/mach-se/7722/setup.c
··· 14 14 #include <linux/platform_device.h> 15 15 #include <linux/ata_platform.h> 16 16 #include <linux/input.h> 17 + #include <linux/input/sh_keysc.h> 17 18 #include <linux/smc91x.h> 18 19 #include <mach-se/mach/se7722.h> 19 20 #include <mach-se/mach/mrshpc.h> ··· 22 21 #include <asm/clock.h> 23 22 #include <asm/io.h> 24 23 #include <asm/heartbeat.h> 25 - #include <asm/sh_keysc.h> 26 24 #include <cpu/sh7722.h> 27 25 28 26 /* Heartbeat */ ··· 60 60 .flags = IORESOURCE_MEM, 61 61 }, 62 62 [1] = { 63 - .start = SMC_IRQ, 64 - .end = SMC_IRQ, 63 + /* Filled in later */ 65 64 .flags = IORESOURCE_IRQ, 66 65 }, 67 66 }; ··· 89 90 .flags = IORESOURCE_IO, 90 91 }, 91 92 [2] = { 92 - .start = MRSHPC_IRQ0, 93 - .end = MRSHPC_IRQ0, 93 + /* Filled in later */ 94 94 .flags = IORESOURCE_IRQ, 95 95 }, 96 96 }; ··· 151 153 static int __init se7722_devices_setup(void) 152 154 { 153 155 mrshpc_setup_windows(); 156 + 157 + /* Wire-up dynamic vectors */ 158 + cf_ide_resources[2].start = cf_ide_resources[2].end = 159 + se7722_fpga_irq[SE7722_FPGA_IRQ_MRSHPC0]; 160 + 161 + smc91x_eth_resources[1].start = smc91x_eth_resources[1].end = 162 + se7722_fpga_irq[SE7722_FPGA_IRQ_SMC]; 163 + 154 164 return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices)); 155 165 } 156 166 device_initcall(se7722_devices_setup); ··· 199 193 static struct sh_machine_vector mv_se7722 __initmv = { 200 194 .mv_name = "Solution Engine 7722" , 201 195 .mv_setup = se7722_setup , 202 - .mv_nr_irqs = SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR, 203 196 .mv_init_irq = init_se7722_IRQ, 204 197 };
+1 -1
arch/sh/boards/mach-se/7724/Makefile
··· 7 7 # 8 8 # 9 9 10 - obj-y := setup.o irq.o 10 + obj-y := setup.o irq.o sdram.o
+52
arch/sh/boards/mach-se/7724/sdram.S
··· 1 + /* 2 + * MS7724SE sdram self/auto-refresh setup code 3 + * 4 + * Copyright (C) 2009 Magnus Damm 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + 11 + #include <linux/sys.h> 12 + #include <linux/errno.h> 13 + #include <linux/linkage.h> 14 + #include <asm/asm-offsets.h> 15 + #include <asm/suspend.h> 16 + #include <asm/romimage-macros.h> 17 + 18 + /* code to enter and leave self-refresh. must be self-contained. 19 + * this code will be copied to on-chip memory and executed from there. 20 + */ 21 + .balign 4 22 + ENTRY(ms7724se_sdram_enter_start) 23 + 24 + /* DBSC: put memory in self-refresh mode */ 25 + 26 + ED 0xFD000010, 0x00000000 /* DBEN */ 27 + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ 28 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ 29 + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ 30 + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ 31 + 32 + rts 33 + nop 34 + 35 + ENTRY(ms7724se_sdram_enter_end) 36 + 37 + .balign 4 38 + ENTRY(ms7724se_sdram_leave_start) 39 + 40 + /* DBSC: put memory in auto-refresh mode */ 41 + 42 + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ 43 + WAIT 1 44 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ 45 + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ 46 + ED 0xFD000010, 0x00000001 /* DBEN */ 47 + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ 48 + 49 + rts 50 + nop 51 + 52 + ENTRY(ms7724se_sdram_leave_end)
+85 -11
arch/sh/boards/mach-se/7724/setup.c
··· 19 19 #include <linux/smc91x.h> 20 20 #include <linux/gpio.h> 21 21 #include <linux/input.h> 22 + #include <linux/input/sh_keysc.h> 22 23 #include <linux/usb/r8a66597.h> 23 24 #include <video/sh_mobile_lcdc.h> 24 25 #include <media/sh_mobile_ceu.h> ··· 28 27 #include <asm/heartbeat.h> 29 28 #include <asm/sh_eth.h> 30 29 #include <asm/clock.h> 31 - #include <asm/sh_keysc.h> 30 + #include <asm/suspend.h> 32 31 #include <cpu/sh7724.h> 33 32 #include <mach-se/mach/se7724.h> 34 33 ··· 452 451 .resource = sh7724_usb1_gadget_resources, 453 452 }; 454 453 454 + static struct resource sdhi0_cn7_resources[] = { 455 + [0] = { 456 + .name = "SDHI0", 457 + .start = 0x04ce0000, 458 + .end = 0x04ce01ff, 459 + .flags = IORESOURCE_MEM, 460 + }, 461 + [1] = { 462 + .start = 101, 463 + .flags = IORESOURCE_IRQ, 464 + }, 465 + }; 466 + 467 + static struct platform_device sdhi0_cn7_device = { 468 + .name = "sh_mobile_sdhi", 469 + .id = 0, 470 + .num_resources = ARRAY_SIZE(sdhi0_cn7_resources), 471 + .resource = sdhi0_cn7_resources, 472 + .archdata = { 473 + .hwblk_id = HWBLK_SDHI0, 474 + }, 475 + }; 476 + 477 + static struct resource sdhi1_cn8_resources[] = { 478 + [0] = { 479 + .name = "SDHI1", 480 + .start = 0x04cf0000, 481 + .end = 0x04cf01ff, 482 + .flags = IORESOURCE_MEM, 483 + }, 484 + [1] = { 485 + .start = 24, 486 + .flags = IORESOURCE_IRQ, 487 + }, 488 + }; 489 + 490 + static struct platform_device sdhi1_cn8_device = { 491 + .name = "sh_mobile_sdhi", 492 + .id = 1, 493 + .num_resources = ARRAY_SIZE(sdhi1_cn8_resources), 494 + .resource = sdhi1_cn8_resources, 495 + .archdata = { 496 + .hwblk_id = HWBLK_SDHI1, 497 + }, 498 + }; 499 + 455 500 static struct platform_device *ms7724se_devices[] __initdata = { 456 501 &heartbeat_device, 457 502 &smc91x_eth_device, ··· 510 463 &sh7724_usb0_host_device, 511 464 &sh7724_usb1_gadget_device, 512 465 &fsi_device, 466 + &sdhi0_cn7_device, 467 + &sdhi1_cn8_device, 513 468 }; 514 469 515 470 #define EEPROM_OP 0xBA206000 ··· 536 487 static void __init sh_eth_init(void) 537 488 { 538 489 int i; 539 - u16 mac[3]; 490 + u16 mac; 540 491 541 492 /* check EEPROM status */ 542 493 if (!sh_eth_is_eeprom_ready()) ··· 550 501 if (!sh_eth_is_eeprom_ready()) 551 502 return; 552 503 553 - mac[i] = ctrl_inw(EEPROM_DATA); 554 - mac[i] = ((mac[i] & 0xFF) << 8) | (mac[i] >> 8); /* swap */ 504 + mac = ctrl_inw(EEPROM_DATA); 505 + sh_eth_plat.mac_addr[i << 1] = mac & 0xff; 506 + sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8; 555 507 } 556 - 557 - /* reset sh-eth */ 558 - ctrl_outl(0x1, SH_ETH_ADDR + 0x0); 559 - 560 - /* set MAC addr */ 561 - ctrl_outl(((mac[0] << 16) | (mac[1])), SH_ETH_MAHR); 562 - ctrl_outl((mac[2]), SH_ETH_MALR); 563 508 } 564 509 565 510 #define SW4140 0xBA201000 ··· 570 527 #define SW41_G 0x4000 571 528 #define SW41_H 0x8000 572 529 530 + extern char ms7724se_sdram_enter_start; 531 + extern char ms7724se_sdram_enter_end; 532 + extern char ms7724se_sdram_leave_start; 533 + extern char ms7724se_sdram_leave_end; 534 + 573 535 static int __init devices_setup(void) 574 536 { 575 537 u16 sw = ctrl_inw(SW4140); /* select camera, monitor */ 576 538 struct clk *fsia_clk; 577 539 540 + /* register board specific self-refresh code */ 541 + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, 542 + &ms7724se_sdram_enter_start, 543 + &ms7724se_sdram_enter_end, 544 + &ms7724se_sdram_leave_start, 545 + &ms7724se_sdram_leave_end); 578 546 /* Reset Release */ 579 547 ctrl_outw(ctrl_inw(FPGA_OUT) & 580 548 ~((1 << 1) | /* LAN */ ··· 754 700 clk_set_rate(fsia_clk, 11000); 755 701 clk_set_rate(&fsimcka_clk, 11000); 756 702 clk_put(fsia_clk); 703 + 704 + /* SDHI0 connected to cn7 */ 705 + gpio_request(GPIO_FN_SDHI0CD, NULL); 706 + gpio_request(GPIO_FN_SDHI0WP, NULL); 707 + gpio_request(GPIO_FN_SDHI0D3, NULL); 708 + gpio_request(GPIO_FN_SDHI0D2, NULL); 709 + gpio_request(GPIO_FN_SDHI0D1, NULL); 710 + gpio_request(GPIO_FN_SDHI0D0, NULL); 711 + gpio_request(GPIO_FN_SDHI0CMD, NULL); 712 + gpio_request(GPIO_FN_SDHI0CLK, NULL); 713 + 714 + /* SDHI1 connected to cn8 */ 715 + gpio_request(GPIO_FN_SDHI1CD, NULL); 716 + gpio_request(GPIO_FN_SDHI1WP, NULL); 717 + gpio_request(GPIO_FN_SDHI1D3, NULL); 718 + gpio_request(GPIO_FN_SDHI1D2, NULL); 719 + gpio_request(GPIO_FN_SDHI1D1, NULL); 720 + gpio_request(GPIO_FN_SDHI1D0, NULL); 721 + gpio_request(GPIO_FN_SDHI1CMD, NULL); 722 + gpio_request(GPIO_FN_SDHI1CLK, NULL); 757 723 758 724 /* 759 725 * enable SH-Eth
+1 -1
arch/sh/boot/compressed/misc.c
··· 131 131 #ifdef CONFIG_SUPERH64 132 132 output_addr = (CONFIG_MEMORY_START + 0x2000); 133 133 #else 134 - output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE); 134 + output_addr = __pa((unsigned long)&_text+PAGE_SIZE); 135 135 #ifdef CONFIG_29BIT 136 136 output_addr |= P2SEG; 137 137 #endif
+9 -3
arch/sh/boot/romimage/Makefile
··· 4 4 # create an image suitable for burning to flash from zImage 5 5 # 6 6 7 - targets := vmlinux head.o 7 + targets := vmlinux head.o zeropage.bin piggy.o 8 8 9 9 OBJECTS = $(obj)/head.o 10 - LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart 10 + LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart \ 11 + -T $(obj)/../../kernel/vmlinux.lds 11 12 12 13 $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE 13 14 $(call if_changed,ld) 14 15 @: 15 16 17 + OBJCOPYFLAGS += -j .empty_zero_page 18 + 19 + $(obj)/zeropage.bin: vmlinux FORCE 20 + $(call if_changed,objcopy) 21 + 16 22 LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T 17 23 18 - $(obj)/piggy.o: $(obj)/vmlinux.scr arch/sh/boot/zImage FORCE 24 + $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/zeropage.bin arch/sh/boot/zImage FORCE 19 25 $(call if_changed,ld)
+38
arch/sh/boot/romimage/head.S
··· 5 5 */ 6 6 7 7 .text 8 + #include <asm/page.h> 9 + 8 10 .global romstart 9 11 romstart: 12 + /* include board specific setup code */ 10 13 #include <mach/romimage.h> 14 + 15 + /* copy the empty_zero_page contents to where vmlinux expects it */ 16 + mova empty_zero_page_src, r0 17 + mov.l empty_zero_page_dst, r1 18 + mov #(PAGE_SHIFT - 4), r4 19 + mov #1, r3 20 + shld r4, r3 /* r3 = PAGE_SIZE / 16 */ 21 + 22 + 1: 23 + mov.l @r0, r4 24 + mov.l @(4, r0), r5 25 + mov.l @(8, r0), r6 26 + mov.l @(12, r0), r7 27 + add #16,r0 28 + mov.l r4, @r1 29 + mov.l r5, @(4, r1) 30 + mov.l r6, @(8, r1) 31 + mov.l r7, @(12, r1) 32 + dt r3 33 + add #16,r1 34 + bf 1b 35 + 36 + /* jump to the zImage entry point located after the zero page data */ 37 + mov #PAGE_SHIFT, r4 38 + mov #1, r1 39 + shld r4, r1 40 + mova empty_zero_page_src, r0 41 + add r1, r0 42 + jmp @r0 43 + nop 44 + 45 + .align 2 46 + empty_zero_page_dst: 47 + .long _text 48 + empty_zero_page_src:
-2
arch/sh/drivers/dma/dma-sysfs.c
··· 13 13 #include <linux/init.h> 14 14 #include <linux/sysdev.h> 15 15 #include <linux/platform_device.h> 16 - #include <linux/module.h> 17 16 #include <linux/err.h> 18 17 #include <linux/string.h> 19 18 #include <asm/dma.h> ··· 20 21 static struct sysdev_class dma_sysclass = { 21 22 .name = "dma", 22 23 }; 23 - EXPORT_SYMBOL(dma_sysclass); 24 24 25 25 static ssize_t dma_show_devices(struct sys_device *dev, 26 26 struct sysdev_attribute *attr, char *buf)
-19
arch/sh/drivers/pci/Kconfig
··· 1 - config PCI 2 - bool "PCI support" 3 - depends on SYS_SUPPORTS_PCI 4 - help 5 - Find out whether you have a PCI motherboard. PCI is the name of a 6 - bus system, i.e. the way the CPU talks to the other stuff inside 7 - your box. If you have PCI, say Y, otherwise N. 8 - 9 - config SH_PCIDMA_NONCOHERENT 10 - bool "Cache and PCI noncoherent" 11 - depends on PCI 12 - default y 13 - help 14 - Enable this option if your platform does not have a CPU cache which 15 - remains coherent with PCI DMA. It is safest to say 'Y', although you 16 - will see better performance if you can say 'N', because the PCI DMA 17 - code will not have to flush the CPU's caches. If you have a PCI host 18 - bridge integrated with your SH CPU, refer carefully to the chip specs 19 - to see if you can say 'N' here. Otherwise, leave it as 'Y'.
+6 -3
arch/sh/include/asm/addrspace.h
··· 28 28 /* Returns the privileged segment base of a given address */ 29 29 #define PXSEG(a) (((unsigned long)(a)) & 0xe0000000) 30 30 31 - /* Returns the physical address of a PnSEG (n=1,2) address */ 32 - #define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) 33 - 34 31 #if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED) 35 32 /* 36 33 * Map an address to a certain privileged segment ··· 56 59 #else 57 60 #define P3_ADDR_MAX P4SEG 58 61 #endif 62 + 63 + #ifndef __ASSEMBLY__ 64 + #ifdef CONFIG_PMB 65 + extern int __in_29bit_mode(void); 66 + #endif /* CONFIG_PMB */ 67 + #endif /* __ASSEMBLY__ */ 59 68 60 69 #endif /* __KERNEL__ */ 61 70 #endif /* __ASM_SH_ADDRSPACE_H */
+4 -5
arch/sh/include/asm/atomic.h
··· 78 78 #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) 79 79 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 80 80 81 - /* Atomic operations are already serializing on SH */ 82 - #define smp_mb__before_atomic_dec() barrier() 83 - #define smp_mb__after_atomic_dec() barrier() 84 - #define smp_mb__before_atomic_inc() barrier() 85 - #define smp_mb__after_atomic_inc() barrier() 81 + #define smp_mb__before_atomic_dec() smp_mb() 82 + #define smp_mb__after_atomic_dec() smp_mb() 83 + #define smp_mb__before_atomic_inc() smp_mb() 84 + #define smp_mb__after_atomic_inc() smp_mb() 86 85 87 86 #include <asm-generic/atomic-long.h> 88 87 #include <asm-generic/atomic64.h>
+2 -2
arch/sh/include/asm/bitops.h
··· 26 26 /* 27 27 * clear_bit() doesn't provide any barrier for the compiler. 28 28 */ 29 - #define smp_mb__before_clear_bit() barrier() 30 - #define smp_mb__after_clear_bit() barrier() 29 + #define smp_mb__before_clear_bit() smp_mb() 30 + #define smp_mb__after_clear_bit() smp_mb() 31 31 32 32 #ifdef CONFIG_SUPERH32 33 33 static inline unsigned long ffz(unsigned long word)
+4
arch/sh/include/asm/bugs.h
··· 14 14 15 15 #include <asm/processor.h> 16 16 17 + extern void select_idle_routine(void); 18 + 17 19 static void __init check_bugs(void) 18 20 { 19 21 extern unsigned long loops_per_jiffy; 20 22 char *p = &init_utsname()->machine[2]; /* "sh" */ 23 + 24 + select_idle_routine(); 21 25 22 26 current_cpu_data.loops_per_jiffy = loops_per_jiffy; 23 27
+64 -175
arch/sh/include/asm/dma-mapping.h
··· 1 1 #ifndef __ASM_SH_DMA_MAPPING_H 2 2 #define __ASM_SH_DMA_MAPPING_H 3 3 4 - #include <linux/mm.h> 5 - #include <linux/scatterlist.h> 6 - #include <linux/dma-debug.h> 7 - #include <asm/cacheflush.h> 8 - #include <asm/io.h> 4 + extern struct dma_map_ops *dma_ops; 5 + extern void no_iommu_init(void); 6 + 7 + static inline struct dma_map_ops *get_dma_ops(struct device *dev) 8 + { 9 + return dma_ops; 10 + } 11 + 9 12 #include <asm-generic/dma-coherent.h> 13 + #include <asm-generic/dma-mapping-common.h> 10 14 11 - extern struct bus_type pci_bus_type; 15 + static inline int dma_supported(struct device *dev, u64 mask) 16 + { 17 + struct dma_map_ops *ops = get_dma_ops(dev); 12 18 13 - #define dma_supported(dev, mask) (1) 19 + if (ops->dma_supported) 20 + return ops->dma_supported(dev, mask); 21 + 22 + return 1; 23 + } 14 24 15 25 static inline int dma_set_mask(struct device *dev, u64 mask) 16 26 { 27 + struct dma_map_ops *ops = get_dma_ops(dev); 28 + 17 29 if (!dev->dma_mask || !dma_supported(dev, mask)) 18 30 return -EIO; 31 + if (ops->set_dma_mask) 32 + return ops->set_dma_mask(dev, mask); 19 33 20 34 *dev->dma_mask = mask; 21 35 22 36 return 0; 23 37 } 24 38 25 - void *dma_alloc_coherent(struct device *dev, size_t size, 26 - dma_addr_t *dma_handle, gfp_t flag); 27 - 28 - void dma_free_coherent(struct device *dev, size_t size, 29 - void *vaddr, dma_addr_t dma_handle); 30 - 31 39 void dma_cache_sync(struct device *dev, void *vaddr, size_t size, 32 40 enum dma_data_direction dir); 33 41 34 42 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) 35 43 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) 44 + 45 + #ifdef CONFIG_DMA_COHERENT 36 46 #define dma_is_consistent(d, h) (1) 37 - 38 - static inline dma_addr_t dma_map_single(struct device *dev, 39 - void *ptr, size_t size, 40 - enum dma_data_direction dir) 41 - { 42 - dma_addr_t addr = virt_to_phys(ptr); 43 - 44 - #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) 45 - if (dev->bus == &pci_bus_type) 46 - return addr; 47 + #else 48 + #define dma_is_consistent(d, h) (0) 47 49 #endif 48 - dma_cache_sync(dev, ptr, size, dir); 49 - 50 - debug_dma_map_page(dev, virt_to_page(ptr), 51 - (unsigned long)ptr & ~PAGE_MASK, size, 52 - dir, addr, true); 53 - 54 - return addr; 55 - } 56 - 57 - static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, 58 - size_t size, enum dma_data_direction dir) 59 - { 60 - debug_dma_unmap_page(dev, addr, size, dir, true); 61 - } 62 - 63 - static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, 64 - int nents, enum dma_data_direction dir) 65 - { 66 - int i; 67 - 68 - for (i = 0; i < nents; i++) { 69 - #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT) 70 - dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir); 71 - #endif 72 - sg[i].dma_address = sg_phys(&sg[i]); 73 - sg[i].dma_length = sg[i].length; 74 - } 75 - 76 - debug_dma_map_sg(dev, sg, nents, i, dir); 77 - 78 - return nents; 79 - } 80 - 81 - static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, 82 - int nents, enum dma_data_direction dir) 83 - { 84 - debug_dma_unmap_sg(dev, sg, nents, dir); 85 - } 86 - 87 - static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, 88 - unsigned long offset, size_t size, 89 - enum dma_data_direction dir) 90 - { 91 - return dma_map_single(dev, page_address(page) + offset, size, dir); 92 - } 93 - 94 - static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, 95 - size_t size, enum dma_data_direction dir) 96 - { 97 - dma_unmap_single(dev, dma_address, size, dir); 98 - } 99 - 100 - static inline void __dma_sync_single(struct device *dev, dma_addr_t dma_handle, 101 - size_t size, enum dma_data_direction dir) 102 - { 103 - #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) 104 - if (dev->bus == &pci_bus_type) 105 - return; 106 - #endif 107 - dma_cache_sync(dev, phys_to_virt(dma_handle), size, dir); 108 - } 109 - 110 - static inline void dma_sync_single_range(struct device *dev, 111 - dma_addr_t dma_handle, 112 - unsigned long offset, size_t size, 113 - enum dma_data_direction dir) 114 - { 115 - #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) 116 - if (dev->bus == &pci_bus_type) 117 - return; 118 - #endif 119 - dma_cache_sync(dev, phys_to_virt(dma_handle) + offset, size, dir); 120 - } 121 - 122 - static inline void __dma_sync_sg(struct device *dev, struct scatterlist *sg, 123 - int nelems, enum dma_data_direction dir) 124 - { 125 - int i; 126 - 127 - for (i = 0; i < nelems; i++) { 128 - #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT) 129 - dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir); 130 - #endif 131 - sg[i].dma_address = sg_phys(&sg[i]); 132 - sg[i].dma_length = sg[i].length; 133 - } 134 - } 135 - 136 - static inline void dma_sync_single_for_cpu(struct device *dev, 137 - dma_addr_t dma_handle, size_t size, 138 - enum dma_data_direction dir) 139 - { 140 - __dma_sync_single(dev, dma_handle, size, dir); 141 - debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir); 142 - } 143 - 144 - static inline void dma_sync_single_for_device(struct device *dev, 145 - dma_addr_t dma_handle, 146 - size_t size, 147 - enum dma_data_direction dir) 148 - { 149 - __dma_sync_single(dev, dma_handle, size, dir); 150 - debug_dma_sync_single_for_device(dev, dma_handle, size, dir); 151 - } 152 - 153 - static inline void dma_sync_single_range_for_cpu(struct device *dev, 154 - dma_addr_t dma_handle, 155 - unsigned long offset, 156 - size_t size, 157 - enum dma_data_direction direction) 158 - { 159 - dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction); 160 - debug_dma_sync_single_range_for_cpu(dev, dma_handle, 161 - offset, size, direction); 162 - } 163 - 164 - static inline void dma_sync_single_range_for_device(struct device *dev, 165 - dma_addr_t dma_handle, 166 - unsigned long offset, 167 - size_t size, 168 - enum dma_data_direction direction) 169 - { 170 - dma_sync_single_for_device(dev, dma_handle+offset, size, direction); 171 - debug_dma_sync_single_range_for_device(dev, dma_handle, 172 - offset, size, direction); 173 - } 174 - 175 - 176 - static inline void dma_sync_sg_for_cpu(struct device *dev, 177 - struct scatterlist *sg, int nelems, 178 - enum dma_data_direction dir) 179 - { 180 - __dma_sync_sg(dev, sg, nelems, dir); 181 - debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir); 182 - } 183 - 184 - static inline void dma_sync_sg_for_device(struct device *dev, 185 - struct scatterlist *sg, int nelems, 186 - enum dma_data_direction dir) 187 - { 188 - __dma_sync_sg(dev, sg, nelems, dir); 189 - debug_dma_sync_sg_for_device(dev, sg, nelems, dir); 190 - } 191 50 192 51 static inline int dma_get_cache_alignment(void) 193 52 { ··· 59 200 60 201 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) 61 202 { 203 + struct dma_map_ops *ops = get_dma_ops(dev); 204 + 205 + if (ops->mapping_error) 206 + return ops->mapping_error(dev, dma_addr); 207 + 62 208 return dma_addr == 0; 63 209 } 64 210 65 - #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY 211 + static inline void *dma_alloc_coherent(struct device *dev, size_t size, 212 + dma_addr_t *dma_handle, gfp_t gfp) 213 + { 214 + struct dma_map_ops *ops = get_dma_ops(dev); 215 + void *memory; 66 216 67 - extern int 68 - dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, 69 - dma_addr_t device_addr, size_t size, int flags); 217 + if (dma_alloc_from_coherent(dev, size, dma_handle, &memory)) 218 + return memory; 219 + if (!ops->alloc_coherent) 220 + return NULL; 70 221 71 - extern void 72 - dma_release_declared_memory(struct device *dev); 222 + memory = ops->alloc_coherent(dev, size, dma_handle, gfp); 223 + debug_dma_alloc_coherent(dev, size, *dma_handle, memory); 73 224 74 - extern void * 75 - dma_mark_declared_memory_occupied(struct device *dev, 76 - dma_addr_t device_addr, size_t size); 225 + return memory; 226 + } 227 + 228 + static inline void dma_free_coherent(struct device *dev, size_t size, 229 + void *vaddr, dma_addr_t dma_handle) 230 + { 231 + struct dma_map_ops *ops = get_dma_ops(dev); 232 + 233 + WARN_ON(irqs_disabled()); /* for portability */ 234 + 235 + if (dma_release_from_coherent(dev, get_order(size), vaddr)) 236 + return; 237 + 238 + debug_dma_free_coherent(dev, size, vaddr, dma_handle); 239 + if (ops->free_coherent) 240 + ops->free_coherent(dev, size, vaddr, dma_handle); 241 + } 242 + 243 + /* arch/sh/mm/consistent.c */ 244 + extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, 245 + dma_addr_t *dma_addr, gfp_t flag); 246 + extern void dma_generic_free_coherent(struct device *dev, size_t size, 247 + void *vaddr, dma_addr_t dma_handle); 77 248 78 249 #endif /* __ASM_SH_DMA_MAPPING_H */
+28
arch/sh/include/asm/dwarf.h
··· 194 194 #define DWARF_ARCH_RA_REG 17 195 195 196 196 #ifndef __ASSEMBLY__ 197 + 198 + #include <linux/compiler.h> 199 + #include <linux/bug.h> 200 + #include <linux/list.h> 201 + #include <linux/module.h> 202 + 197 203 /* 198 204 * Read either the frame pointer (r14) or the stack pointer (r15). 199 205 * NOTE: this MUST be inlined. ··· 247 241 248 242 unsigned long flags; 249 243 #define DWARF_CIE_Z_AUGMENTATION (1 << 0) 244 + 245 + /* 246 + * 'mod' will be non-NULL if this CIE came from a module's 247 + * .eh_frame section. 248 + */ 249 + struct module *mod; 250 250 }; 251 251 252 252 /** ··· 267 255 unsigned char *instructions; 268 256 unsigned char *end; 269 257 struct list_head link; 258 + 259 + /* 260 + * 'mod' will be non-NULL if this FDE came from a module's 261 + * .eh_frame section. 262 + */ 263 + struct module *mod; 270 264 }; 271 265 272 266 /** ··· 382 364 383 365 extern struct dwarf_frame *dwarf_unwind_stack(unsigned long, 384 366 struct dwarf_frame *); 367 + extern void dwarf_free_frame(struct dwarf_frame *); 368 + 369 + extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *, 370 + struct module *); 371 + extern void module_dwarf_cleanup(struct module *); 372 + 385 373 #endif /* !__ASSEMBLY__ */ 386 374 387 375 #define CFI_STARTPROC .cfi_startproc ··· 415 391 static inline void dwarf_unwinder_init(void) 416 392 { 417 393 } 394 + 395 + #define module_dwarf_finalize(hdr, sechdrs, me) (0) 396 + #define module_dwarf_cleanup(mod) do { } while (0) 397 + 418 398 #endif 419 399 420 400 #endif /* CONFIG_DWARF_UNWINDER */
+9 -3
arch/sh/include/asm/fixmap.h
··· 14 14 #define _ASM_FIXMAP_H 15 15 16 16 #include <linux/kernel.h> 17 + #include <linux/threads.h> 17 18 #include <asm/page.h> 18 19 #ifdef CONFIG_HIGHMEM 19 - #include <linux/threads.h> 20 20 #include <asm/kmap_types.h> 21 21 #endif 22 22 ··· 46 46 * fix-mapped? 47 47 */ 48 48 enum fixed_addresses { 49 - #define FIX_N_COLOURS 16 49 + /* 50 + * The FIX_CMAP entries are used by kmap_coherent() to get virtual 51 + * addresses which are of a known color, and so their values are 52 + * important. __fix_to_virt(FIX_CMAP_END - n) must give an address 53 + * which is the same color as a page (n<<PAGE_SHIFT). 54 + */ 55 + #define FIX_N_COLOURS 8 50 56 FIX_CMAP_BEGIN, 51 - FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS, 57 + FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1, 52 58 FIX_UNCACHED, 53 59 #ifdef CONFIG_HIGHMEM 54 60 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+17 -9
arch/sh/include/asm/fpu.h
··· 18 18 19 19 struct task_struct; 20 20 21 - extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs); 21 + extern void save_fpu(struct task_struct *__tsk); 22 + void fpu_state_restore(struct pt_regs *regs); 22 23 #else 23 24 25 + #define save_fpu(tsk) do { } while (0) 24 26 #define release_fpu(regs) do { } while (0) 25 27 #define grab_fpu(regs) do { } while (0) 28 + #define fpu_state_restore(regs) do { } while (0) 26 29 27 - static inline void save_fpu(struct task_struct *tsk, struct pt_regs *regs) 28 - { 29 - clear_tsk_thread_flag(tsk, TIF_USEDFPU); 30 - } 31 30 #endif 32 31 33 32 struct user_regset; ··· 38 39 unsigned int pos, unsigned int count, 39 40 void *kbuf, void __user *ubuf); 40 41 42 + static inline void __unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs) 43 + { 44 + if (task_thread_info(tsk)->status & TS_USEDFPU) { 45 + task_thread_info(tsk)->status &= ~TS_USEDFPU; 46 + save_fpu(tsk); 47 + release_fpu(regs); 48 + } else 49 + tsk->fpu_counter = 0; 50 + } 51 + 41 52 static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs) 42 53 { 43 54 preempt_disable(); 44 - if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) 45 - save_fpu(tsk, regs); 55 + __unlazy_fpu(tsk, regs); 46 56 preempt_enable(); 47 57 } 48 58 49 59 static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs) 50 60 { 51 61 preempt_disable(); 52 - if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { 53 - clear_tsk_thread_flag(tsk, TIF_USEDFPU); 62 + if (task_thread_info(tsk)->status & TS_USEDFPU) { 63 + task_thread_info(tsk)->status &= ~TS_USEDFPU; 54 64 release_fpu(regs); 55 65 } 56 66 preempt_enable();
+17
arch/sh/include/asm/ftrace.h
··· 35 35 #endif /* __ASSEMBLY__ */ 36 36 #endif /* CONFIG_FUNCTION_TRACER */ 37 37 38 + #ifndef __ASSEMBLY__ 39 + 40 + /* arch/sh/kernel/return_address.c */ 41 + extern void *return_address(unsigned int); 42 + 43 + #define HAVE_ARCH_CALLER_ADDR 44 + 45 + #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) 46 + #define CALLER_ADDR1 ((unsigned long)return_address(1)) 47 + #define CALLER_ADDR2 ((unsigned long)return_address(2)) 48 + #define CALLER_ADDR3 ((unsigned long)return_address(3)) 49 + #define CALLER_ADDR4 ((unsigned long)return_address(4)) 50 + #define CALLER_ADDR5 ((unsigned long)return_address(5)) 51 + #define CALLER_ADDR6 ((unsigned long)return_address(6)) 52 + 53 + #endif /* __ASSEMBLY__ */ 54 + 38 55 #endif /* __ASM_SH_FTRACE_H */
+1 -81
arch/sh/include/asm/gpio.h
··· 20 20 #endif 21 21 22 22 #define ARCH_NR_GPIOS 512 23 - #include <asm-generic/gpio.h> 23 + #include <linux/sh_pfc.h> 24 24 25 25 #ifdef CONFIG_GPIOLIB 26 26 ··· 52 52 } 53 53 54 54 #endif /* CONFIG_GPIOLIB */ 55 - 56 - typedef unsigned short pinmux_enum_t; 57 - typedef unsigned short pinmux_flag_t; 58 - 59 - #define PINMUX_TYPE_NONE 0 60 - #define PINMUX_TYPE_FUNCTION 1 61 - #define PINMUX_TYPE_GPIO 2 62 - #define PINMUX_TYPE_OUTPUT 3 63 - #define PINMUX_TYPE_INPUT 4 64 - #define PINMUX_TYPE_INPUT_PULLUP 5 65 - #define PINMUX_TYPE_INPUT_PULLDOWN 6 66 - 67 - #define PINMUX_FLAG_TYPE (0x7) 68 - #define PINMUX_FLAG_WANT_PULLUP (1 << 3) 69 - #define PINMUX_FLAG_WANT_PULLDOWN (1 << 4) 70 - 71 - #define PINMUX_FLAG_DBIT_SHIFT 5 72 - #define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT) 73 - #define PINMUX_FLAG_DREG_SHIFT 10 74 - #define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT) 75 - 76 - struct pinmux_gpio { 77 - pinmux_enum_t enum_id; 78 - pinmux_flag_t flags; 79 - }; 80 - 81 - #define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark } 82 - #define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0 83 - 84 - struct pinmux_cfg_reg { 85 - unsigned long reg, reg_width, field_width; 86 - unsigned long *cnt; 87 - pinmux_enum_t *enum_ids; 88 - }; 89 - 90 - #define PINMUX_CFG_REG(name, r, r_width, f_width) \ 91 - .reg = r, .reg_width = r_width, .field_width = f_width, \ 92 - .cnt = (unsigned long [r_width / f_width]) {}, \ 93 - .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \ 94 - 95 - struct pinmux_data_reg { 96 - unsigned long reg, reg_width, reg_shadow; 97 - pinmux_enum_t *enum_ids; 98 - }; 99 - 100 - #define PINMUX_DATA_REG(name, r, r_width) \ 101 - .reg = r, .reg_width = r_width, \ 102 - .enum_ids = (pinmux_enum_t [r_width]) \ 103 - 104 - struct pinmux_range { 105 - pinmux_enum_t begin; 106 - pinmux_enum_t end; 107 - pinmux_enum_t force; 108 - }; 109 - 110 - struct pinmux_info { 111 - char *name; 112 - pinmux_enum_t reserved_id; 113 - struct pinmux_range data; 114 - struct pinmux_range input; 115 - struct pinmux_range input_pd; 116 - struct pinmux_range input_pu; 117 - struct pinmux_range output; 118 - struct pinmux_range mark; 119 - struct pinmux_range function; 120 - 121 - unsigned first_gpio, last_gpio; 122 - 123 - struct pinmux_gpio *gpios; 124 - struct pinmux_cfg_reg *cfg_regs; 125 - struct pinmux_data_reg *data_regs; 126 - 127 - pinmux_enum_t *gpio_data; 128 - unsigned int gpio_data_size; 129 - 130 - unsigned long *gpio_in_use; 131 - struct gpio_chip chip; 132 - }; 133 - 134 - int register_pinmux(struct pinmux_info *pip); 135 55 136 56 #endif /* __ASM_SH_GPIO_H */
+10 -3
arch/sh/include/asm/hardirq.h
··· 1 1 #ifndef __ASM_SH_HARDIRQ_H 2 2 #define __ASM_SH_HARDIRQ_H 3 3 4 - extern void ack_bad_irq(unsigned int irq); 5 - #define ack_bad_irq ack_bad_irq 4 + #include <linux/threads.h> 5 + #include <linux/irq.h> 6 6 7 - #include <asm-generic/hardirq.h> 7 + typedef struct { 8 + unsigned int __softirq_pending; 9 + unsigned int __nmi_count; /* arch dependent */ 10 + } ____cacheline_aligned irq_cpustat_t; 11 + 12 + #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 13 + 14 + extern void ack_bad_irq(unsigned int irq); 8 15 9 16 #endif /* __ASM_SH_HARDIRQ_H */
+5 -11
arch/sh/include/asm/io.h
··· 90 90 #define ctrl_outl __raw_writel 91 91 #define ctrl_outq __raw_writeq 92 92 93 + extern unsigned long generic_io_base; 94 + 93 95 static inline void ctrl_delay(void) 94 96 { 95 - #ifdef CONFIG_CPU_SH4 96 - __raw_readw(CCN_PVR); 97 - #elif defined(P2SEG) 98 - __raw_readw(P2SEG); 99 - #else 100 - #error "Need a dummy address for delay" 101 - #endif 97 + __raw_readw(generic_io_base); 102 98 } 103 99 104 100 #define __BUILD_MEMORY_STRING(bwlq, type) \ ··· 182 186 183 187 #define IO_SPACE_LIMIT 0xffffffff 184 188 185 - extern unsigned long generic_io_base; 186 - 187 189 /* 188 190 * This function provides a method for the generic case where a 189 191 * board-specific ioport_map simply needs to return the port + some ··· 240 246 static inline void __iomem * 241 247 __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) 242 248 { 243 - #if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) 249 + #if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB) 244 250 unsigned long last_addr = offset + size - 1; 245 251 #endif 246 252 void __iomem *ret; ··· 249 255 if (ret) 250 256 return ret; 251 257 252 - #if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) 258 + #if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB) 253 259 /* 254 260 * For P1 and P2 space this is trivial, as everything is already 255 261 * mapped. Uncached access for P1 addresses are done through P2.
+3 -28
arch/sh/include/asm/irqflags.h
··· 1 1 #ifndef __ASM_SH_IRQFLAGS_H 2 2 #define __ASM_SH_IRQFLAGS_H 3 3 4 - #ifdef CONFIG_SUPERH32 5 - #include "irqflags_32.h" 6 - #else 7 - #include "irqflags_64.h" 8 - #endif 4 + #define RAW_IRQ_DISABLED 0xf0 5 + #define RAW_IRQ_ENABLED 0x00 9 6 10 - #define raw_local_save_flags(flags) \ 11 - do { (flags) = __raw_local_save_flags(); } while (0) 12 - 13 - static inline int raw_irqs_disabled_flags(unsigned long flags) 14 - { 15 - return (flags != 0); 16 - } 17 - 18 - static inline int raw_irqs_disabled(void) 19 - { 20 - unsigned long flags = __raw_local_save_flags(); 21 - 22 - return raw_irqs_disabled_flags(flags); 23 - } 24 - 25 - #define raw_local_irq_save(flags) \ 26 - do { (flags) = __raw_local_irq_save(); } while (0) 27 - 28 - static inline void raw_local_irq_restore(unsigned long flags) 29 - { 30 - if ((flags & 0xf0) != 0xf0) 31 - raw_local_irq_enable(); 32 - } 7 + #include <asm-generic/irqflags.h> 33 8 34 9 #endif /* __ASM_SH_IRQFLAGS_H */
-99
arch/sh/include/asm/irqflags_32.h
··· 1 - #ifndef __ASM_SH_IRQFLAGS_32_H 2 - #define __ASM_SH_IRQFLAGS_32_H 3 - 4 - static inline void raw_local_irq_enable(void) 5 - { 6 - unsigned long __dummy0, __dummy1; 7 - 8 - __asm__ __volatile__ ( 9 - "stc sr, %0\n\t" 10 - "and %1, %0\n\t" 11 - #ifdef CONFIG_CPU_HAS_SR_RB 12 - "stc r6_bank, %1\n\t" 13 - "or %1, %0\n\t" 14 - #endif 15 - "ldc %0, sr\n\t" 16 - : "=&r" (__dummy0), "=r" (__dummy1) 17 - : "1" (~0x000000f0) 18 - : "memory" 19 - ); 20 - } 21 - 22 - static inline void raw_local_irq_disable(void) 23 - { 24 - unsigned long flags; 25 - 26 - __asm__ __volatile__ ( 27 - "stc sr, %0\n\t" 28 - "or #0xf0, %0\n\t" 29 - "ldc %0, sr\n\t" 30 - : "=&z" (flags) 31 - : /* no inputs */ 32 - : "memory" 33 - ); 34 - } 35 - 36 - static inline void set_bl_bit(void) 37 - { 38 - unsigned long __dummy0, __dummy1; 39 - 40 - __asm__ __volatile__ ( 41 - "stc sr, %0\n\t" 42 - "or %2, %0\n\t" 43 - "and %3, %0\n\t" 44 - "ldc %0, sr\n\t" 45 - : "=&r" (__dummy0), "=r" (__dummy1) 46 - : "r" (0x10000000), "r" (0xffffff0f) 47 - : "memory" 48 - ); 49 - } 50 - 51 - static inline void clear_bl_bit(void) 52 - { 53 - unsigned long __dummy0, __dummy1; 54 - 55 - __asm__ __volatile__ ( 56 - "stc sr, %0\n\t" 57 - "and %2, %0\n\t" 58 - "ldc %0, sr\n\t" 59 - : "=&r" (__dummy0), "=r" (__dummy1) 60 - : "1" (~0x10000000) 61 - : "memory" 62 - ); 63 - } 64 - 65 - static inline unsigned long __raw_local_save_flags(void) 66 - { 67 - unsigned long flags; 68 - 69 - __asm__ __volatile__ ( 70 - "stc sr, %0\n\t" 71 - "and #0xf0, %0\n\t" 72 - : "=&z" (flags) 73 - : /* no inputs */ 74 - : "memory" 75 - ); 76 - 77 - return flags; 78 - } 79 - 80 - static inline unsigned long __raw_local_irq_save(void) 81 - { 82 - unsigned long flags, __dummy; 83 - 84 - __asm__ __volatile__ ( 85 - "stc sr, %1\n\t" 86 - "mov %1, %0\n\t" 87 - "or #0xf0, %0\n\t" 88 - "ldc %0, sr\n\t" 89 - "mov %1, %0\n\t" 90 - "and #0xf0, %0\n\t" 91 - : "=&z" (flags), "=&r" (__dummy) 92 - : /* no inputs */ 93 - : "memory" 94 - ); 95 - 96 - return flags; 97 - } 98 - 99 - #endif /* __ASM_SH_IRQFLAGS_32_H */
-85
arch/sh/include/asm/irqflags_64.h
··· 1 - #ifndef __ASM_SH_IRQFLAGS_64_H 2 - #define __ASM_SH_IRQFLAGS_64_H 3 - 4 - #include <cpu/registers.h> 5 - 6 - #define SR_MASK_LL 0x00000000000000f0LL 7 - #define SR_BL_LL 0x0000000010000000LL 8 - 9 - static inline void raw_local_irq_enable(void) 10 - { 11 - unsigned long long __dummy0, __dummy1 = ~SR_MASK_LL; 12 - 13 - __asm__ __volatile__("getcon " __SR ", %0\n\t" 14 - "and %0, %1, %0\n\t" 15 - "putcon %0, " __SR "\n\t" 16 - : "=&r" (__dummy0) 17 - : "r" (__dummy1)); 18 - } 19 - 20 - static inline void raw_local_irq_disable(void) 21 - { 22 - unsigned long long __dummy0, __dummy1 = SR_MASK_LL; 23 - 24 - __asm__ __volatile__("getcon " __SR ", %0\n\t" 25 - "or %0, %1, %0\n\t" 26 - "putcon %0, " __SR "\n\t" 27 - : "=&r" (__dummy0) 28 - : "r" (__dummy1)); 29 - } 30 - 31 - static inline void set_bl_bit(void) 32 - { 33 - unsigned long long __dummy0, __dummy1 = SR_BL_LL; 34 - 35 - __asm__ __volatile__("getcon " __SR ", %0\n\t" 36 - "or %0, %1, %0\n\t" 37 - "putcon %0, " __SR "\n\t" 38 - : "=&r" (__dummy0) 39 - : "r" (__dummy1)); 40 - 41 - } 42 - 43 - static inline void clear_bl_bit(void) 44 - { 45 - unsigned long long __dummy0, __dummy1 = ~SR_BL_LL; 46 - 47 - __asm__ __volatile__("getcon " __SR ", %0\n\t" 48 - "and %0, %1, %0\n\t" 49 - "putcon %0, " __SR "\n\t" 50 - : "=&r" (__dummy0) 51 - : "r" (__dummy1)); 52 - } 53 - 54 - static inline unsigned long __raw_local_save_flags(void) 55 - { 56 - unsigned long long __dummy = SR_MASK_LL; 57 - unsigned long flags; 58 - 59 - __asm__ __volatile__ ( 60 - "getcon " __SR ", %0\n\t" 61 - "and %0, %1, %0" 62 - : "=&r" (flags) 63 - : "r" (__dummy)); 64 - 65 - return flags; 66 - } 67 - 68 - static inline unsigned long __raw_local_irq_save(void) 69 - { 70 - unsigned long long __dummy0, __dummy1 = SR_MASK_LL; 71 - unsigned long flags; 72 - 73 - __asm__ __volatile__ ( 74 - "getcon " __SR ", %1\n\t" 75 - "or %1, r63, %0\n\t" 76 - "or %1, %2, %1\n\t" 77 - "putcon %1, " __SR "\n\t" 78 - "and %0, %2, %0" 79 - : "=&r" (flags), "=&r" (__dummy0) 80 - : "r" (__dummy1)); 81 - 82 - return flags; 83 - } 84 - 85 - #endif /* __ASM_SH_IRQFLAGS_64_H */
+5 -8
arch/sh/include/asm/mmu.h
··· 7 7 #define PMB_PASCR 0xff000070 8 8 #define PMB_IRMCR 0xff000078 9 9 10 + #define PASCR_SE 0x80000000 11 + 10 12 #define PMB_ADDR 0xf6100000 11 13 #define PMB_DATA 0xf7100000 12 14 #define PMB_ENTRY_MAX 16 13 15 #define PMB_E_MASK 0x0000000f 14 16 #define PMB_E_SHIFT 8 17 + 18 + #define PMB_PFN_MASK 0xff000000 15 19 16 20 #define PMB_SZ_16M 0x00000000 17 21 #define PMB_SZ_64M 0x00000010 ··· 66 62 }; 67 63 68 64 /* arch/sh/mm/pmb.c */ 69 - int __set_pmb_entry(unsigned long vpn, unsigned long ppn, 70 - unsigned long flags, int *entry); 71 - int set_pmb_entry(struct pmb_entry *pmbe); 72 - void clear_pmb_entry(struct pmb_entry *pmbe); 73 - struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, 74 - unsigned long flags); 75 - void pmb_free(struct pmb_entry *pmbe); 76 65 long pmb_remap(unsigned long virt, unsigned long phys, 77 66 unsigned long size, unsigned long flags); 78 67 void pmb_unmap(unsigned long addr); 68 + int pmb_init(void); 79 69 #endif /* __ASSEMBLY__ */ 80 70 81 71 #endif /* __MMU_H */ 82 -
+8 -22
arch/sh/include/asm/pci.h
··· 3 3 4 4 #ifdef __KERNEL__ 5 5 6 - #include <linux/dma-mapping.h> 7 - 8 6 /* Can be used to override the logic in pci_scan_bus for skipping 9 7 already-configured bus numbers - to be used for buggy BIOSes 10 8 or architectures with incomplete PCI setup by the loader */ ··· 52 54 * address space. The networking and block device layers use 53 55 * this boolean for bounce buffer decisions. 54 56 */ 55 - #define PCI_DMA_BUS_IS_PHYS (1) 56 - 57 - #include <linux/types.h> 58 - #include <linux/slab.h> 59 - #include <asm/scatterlist.h> 60 - #include <linux/string.h> 61 - #include <asm/io.h> 57 + #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) 62 58 63 59 /* pci_unmap_{single,page} being a nop depends upon the 64 60 * configuration. 65 61 */ 66 - #ifdef CONFIG_SH_PCIDMA_NONCOHERENT 67 - #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ 68 - dma_addr_t ADDR_NAME; 69 - #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ 70 - __u32 LEN_NAME; 71 - #define pci_unmap_addr(PTR, ADDR_NAME) \ 72 - ((PTR)->ADDR_NAME) 73 - #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ 74 - (((PTR)->ADDR_NAME) = (VAL)) 75 - #define pci_unmap_len(PTR, LEN_NAME) \ 76 - ((PTR)->LEN_NAME) 77 - #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ 78 - (((PTR)->LEN_NAME) = (VAL)) 62 + #ifdef CONFIG_DMA_NONCOHERENT 63 + #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; 64 + #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME; 65 + #define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) 66 + #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) 67 + #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) 68 + #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) 79 69 #else 80 70 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) 81 71 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+29 -2
arch/sh/include/asm/perf_event.h
··· 1 1 #ifndef __ASM_SH_PERF_EVENT_H 2 2 #define __ASM_SH_PERF_EVENT_H 3 3 4 - /* SH only supports software events through this interface. */ 5 - static inline void set_perf_event_pending(void) {} 4 + struct hw_perf_event; 5 + 6 + #define MAX_HWEVENTS 2 7 + 8 + struct sh_pmu { 9 + const char *name; 10 + unsigned int num_events; 11 + void (*disable_all)(void); 12 + void (*enable_all)(void); 13 + void (*enable)(struct hw_perf_event *, int); 14 + void (*disable)(struct hw_perf_event *, int); 15 + u64 (*read)(int); 16 + int (*event_map)(int); 17 + unsigned int max_events; 18 + unsigned long raw_event_mask; 19 + const int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] 20 + [PERF_COUNT_HW_CACHE_OP_MAX] 21 + [PERF_COUNT_HW_CACHE_RESULT_MAX]; 22 + }; 23 + 24 + /* arch/sh/kernel/perf_event.c */ 25 + extern int register_sh_pmu(struct sh_pmu *); 26 + extern int reserve_pmc_hardware(void); 27 + extern void release_pmc_hardware(void); 28 + 29 + static inline void set_perf_event_pending(void) 30 + { 31 + /* Nothing to see here, move along. */ 32 + } 6 33 7 34 #define PERF_EVENT_INDEX_OFFSET 0 8 35
+22 -4
arch/sh/include/asm/pgtable.h
··· 75 75 #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) 76 76 #define FIRST_USER_ADDRESS 0 77 77 78 - #ifdef CONFIG_32BIT 79 - #define PHYS_ADDR_MASK 0xffffffff 78 + #define PHYS_ADDR_MASK29 0x1fffffff 79 + #define PHYS_ADDR_MASK32 0xffffffff 80 + 81 + #ifdef CONFIG_PMB 82 + static inline unsigned long phys_addr_mask(void) 83 + { 84 + /* Is the MMU in 29bit mode? */ 85 + if (__in_29bit_mode()) 86 + return PHYS_ADDR_MASK29; 87 + 88 + return PHYS_ADDR_MASK32; 89 + } 90 + #elif defined(CONFIG_32BIT) 91 + static inline unsigned long phys_addr_mask(void) 92 + { 93 + return PHYS_ADDR_MASK32; 94 + } 80 95 #else 81 - #define PHYS_ADDR_MASK 0x1fffffff 96 + static inline unsigned long phys_addr_mask(void) 97 + { 98 + return PHYS_ADDR_MASK29; 99 + } 82 100 #endif 83 101 84 - #define PTE_PHYS_MASK (PHYS_ADDR_MASK & PAGE_MASK) 102 + #define PTE_PHYS_MASK (phys_addr_mask() & PAGE_MASK) 85 103 #define PTE_FLAGS_MASK (~(PTE_PHYS_MASK) << PAGE_SHIFT) 86 104 87 105 #ifdef CONFIG_SUPERH32
+1 -1
arch/sh/include/asm/pgtable_32.h
··· 108 108 #define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED | _PAGE_FILE) 109 109 #endif 110 110 111 - #define _PAGE_FLAGS_HARDWARE_MASK (PHYS_ADDR_MASK & ~(_PAGE_CLEAR_FLAGS)) 111 + #define _PAGE_FLAGS_HARDWARE_MASK (phys_addr_mask() & ~(_PAGE_CLEAR_FLAGS)) 112 112 113 113 /* Hardware flags, page size encoding */ 114 114 #if !defined(CONFIG_MMU)
+2 -1
arch/sh/include/asm/processor_32.h
··· 56 56 #define SR_DSP 0x00001000 57 57 #define SR_IMASK 0x000000f0 58 58 #define SR_FD 0x00008000 59 + #define SR_MD 0x40000000 59 60 60 61 /* 61 62 * DSP structure and data ··· 137 136 extern void release_thread(struct task_struct *); 138 137 139 138 /* Prepare to copy thread state - unlazy all lazy status */ 140 - #define prepare_to_copy(tsk) do { } while (0) 139 + void prepare_to_copy(struct task_struct *tsk); 141 140 142 141 /* 143 142 * create a kernel thread without removing it from tasklists
+1 -1
arch/sh/include/asm/scatterlist.h
··· 1 1 #ifndef __ASM_SH_SCATTERLIST_H 2 2 #define __ASM_SH_SCATTERLIST_H 3 3 4 - #define ISA_DMA_THRESHOLD PHYS_ADDR_MASK 4 + #define ISA_DMA_THRESHOLD phys_addr_mask() 5 5 6 6 #include <asm-generic/scatterlist.h> 7 7
+3 -3
arch/sh/include/asm/sh_keysc.h include/linux/input/sh_keysc.h
··· 1 - #ifndef __ASM_KEYSC_H__ 2 - #define __ASM_KEYSC_H__ 1 + #ifndef __SH_KEYSC_H__ 2 + #define __SH_KEYSC_H__ 3 3 4 4 #define SH_KEYSC_MAXKEYS 30 5 5 ··· 11 11 int keycodes[SH_KEYSC_MAXKEYS]; 12 12 }; 13 13 14 - #endif /* __ASM_KEYSC_H__ */ 14 + #endif /* __SH_KEYSC_H__ */
+65
arch/sh/include/asm/suspend.h
··· 2 2 #define _ASM_SH_SUSPEND_H 3 3 4 4 #ifndef __ASSEMBLY__ 5 + #include <linux/notifier.h> 5 6 static inline int arch_prepare_suspend(void) { return 0; } 6 7 7 8 #include <asm/ptrace.h> ··· 20 19 static inline void sh_mobile_setup_cpuidle(void) {} 21 20 #endif 22 21 22 + /* notifier chains for pre/post sleep hooks */ 23 + extern struct atomic_notifier_head sh_mobile_pre_sleep_notifier_list; 24 + extern struct atomic_notifier_head sh_mobile_post_sleep_notifier_list; 25 + 26 + /* priority levels for notifiers */ 27 + #define SH_MOBILE_SLEEP_BOARD 0 28 + #define SH_MOBILE_SLEEP_CPU 1 29 + #define SH_MOBILE_PRE(x) (x) 30 + #define SH_MOBILE_POST(x) (-(x)) 31 + 32 + /* board code registration function for self-refresh assembly snippets */ 33 + void sh_mobile_register_self_refresh(unsigned long flags, 34 + void *pre_start, void *pre_end, 35 + void *post_start, void *post_end); 36 + 37 + /* register structure for address/data information */ 38 + struct sh_sleep_regs { 39 + unsigned long stbcr; 40 + unsigned long bar; 41 + 42 + /* MMU */ 43 + unsigned long pteh; 44 + unsigned long ptel; 45 + unsigned long ttb; 46 + unsigned long tea; 47 + unsigned long mmucr; 48 + unsigned long ptea; 49 + unsigned long pascr; 50 + unsigned long irmcr; 51 + 52 + /* Cache */ 53 + unsigned long ccr; 54 + unsigned long ramcr; 55 + }; 56 + 57 + /* data area for low-level sleep code */ 58 + struct sh_sleep_data { 59 + /* current sleep mode (SUSP_SH_...) */ 60 + unsigned long mode; 61 + 62 + /* addresses of board specific self-refresh snippets */ 63 + unsigned long sf_pre; 64 + unsigned long sf_post; 65 + 66 + /* address of resume code */ 67 + unsigned long resume; 68 + 69 + /* register state saved and restored by the assembly code */ 70 + unsigned long vbr; 71 + unsigned long spc; 72 + unsigned long sr; 73 + unsigned long sp; 74 + 75 + /* structure for keeping register addresses */ 76 + struct sh_sleep_regs addr; 77 + 78 + /* structure for saving/restoring register state */ 79 + struct sh_sleep_regs data; 80 + }; 81 + 82 + /* a bitmap of supported sleep modes (SUSP_SH..) */ 83 + extern unsigned long sh_mobile_sleep_supported; 84 + 23 85 #endif 24 86 25 87 /* flags passed to assembly suspend code */ ··· 91 27 #define SUSP_SH_RSTANDBY (1 << 2) /* SH-Mobile R-standby mode */ 92 28 #define SUSP_SH_USTANDBY (1 << 3) /* SH-Mobile U-standby mode */ 93 29 #define SUSP_SH_SF (1 << 4) /* Enable self-refresh */ 30 + #define SUSP_SH_MMU (1 << 5) /* Save/restore MMU and cache */ 94 31 95 32 #endif /* _ASM_SH_SUSPEND_H */
-4
arch/sh/include/asm/system.h
··· 171 171 BUILD_TRAP_HANDLER(fpu_state_restore); 172 172 BUILD_TRAP_HANDLER(nmi); 173 173 174 - #ifdef CONFIG_BUG 175 - extern void handle_BUG(struct pt_regs *); 176 - #endif 177 - 178 174 #define arch_align_stack(x) (x) 179 175 180 176 struct mem_access {
+29
arch/sh/include/asm/system_32.h
··· 232 232 unsigned long r6, unsigned long r7, 233 233 struct pt_regs __regs); 234 234 235 + static inline void set_bl_bit(void) 236 + { 237 + unsigned long __dummy0, __dummy1; 238 + 239 + __asm__ __volatile__ ( 240 + "stc sr, %0\n\t" 241 + "or %2, %0\n\t" 242 + "and %3, %0\n\t" 243 + "ldc %0, sr\n\t" 244 + : "=&r" (__dummy0), "=r" (__dummy1) 245 + : "r" (0x10000000), "r" (0xffffff0f) 246 + : "memory" 247 + ); 248 + } 249 + 250 + static inline void clear_bl_bit(void) 251 + { 252 + unsigned long __dummy0, __dummy1; 253 + 254 + __asm__ __volatile__ ( 255 + "stc sr, %0\n\t" 256 + "and %2, %0\n\t" 257 + "ldc %0, sr\n\t" 258 + : "=&r" (__dummy0), "=r" (__dummy1) 259 + : "1" (~0x10000000) 260 + : "memory" 261 + ); 262 + } 263 + 235 264 #endif /* __ASM_SH_SYSTEM_32_H */
+26
arch/sh/include/asm/system_64.h
··· 12 12 * License. See the file "COPYING" in the main directory of this archive 13 13 * for more details. 14 14 */ 15 + #include <cpu/registers.h> 15 16 #include <asm/processor.h> 16 17 17 18 /* ··· 46 45 static inline reg_size_t register_align(void *val) 47 46 { 48 47 return (unsigned long long)(signed long long)(signed long)val; 48 + } 49 + 50 + #define SR_BL_LL 0x0000000010000000LL 51 + 52 + static inline void set_bl_bit(void) 53 + { 54 + unsigned long long __dummy0, __dummy1 = SR_BL_LL; 55 + 56 + __asm__ __volatile__("getcon " __SR ", %0\n\t" 57 + "or %0, %1, %0\n\t" 58 + "putcon %0, " __SR "\n\t" 59 + : "=&r" (__dummy0) 60 + : "r" (__dummy1)); 61 + 62 + } 63 + 64 + static inline void clear_bl_bit(void) 65 + { 66 + unsigned long long __dummy0, __dummy1 = ~SR_BL_LL; 67 + 68 + __asm__ __volatile__("getcon " __SR ", %0\n\t" 69 + "and %0, %1, %0\n\t" 70 + "putcon %0, " __SR "\n\t" 71 + : "=&r" (__dummy0) 72 + : "r" (__dummy1)); 49 73 } 50 74 51 75 #endif /* __ASM_SH_SYSTEM_64_H */
+24 -6
arch/sh/include/asm/thread_info.h
··· 19 19 struct task_struct *task; /* main task structure */ 20 20 struct exec_domain *exec_domain; /* execution domain */ 21 21 unsigned long flags; /* low level flags */ 22 + __u32 status; /* thread synchronous flags */ 22 23 __u32 cpu; 23 24 int preempt_count; /* 0 => preemptable, <0 => BUG */ 24 25 mm_segment_t addr_limit; /* thread address space */ ··· 51 50 .task = &tsk, \ 52 51 .exec_domain = &default_exec_domain, \ 53 52 .flags = 0, \ 53 + .status = 0, \ 54 54 .cpu = 0, \ 55 55 .preempt_count = INIT_PREEMPT_COUNT, \ 56 56 .addr_limit = KERNEL_DS, \ ··· 113 111 #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 114 112 #define TIF_SIGPENDING 1 /* signal pending */ 115 113 #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ 116 - #define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */ 117 114 #define TIF_SINGLESTEP 4 /* singlestepping active */ 118 115 #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ 119 116 #define TIF_SECCOMP 6 /* secure computing */ 120 117 #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ 121 118 #define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */ 122 - #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ 123 119 #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ 124 120 #define TIF_MEMDIE 18 125 121 #define TIF_FREEZE 19 /* Freezing for suspend */ ··· 125 125 #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 126 126 #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 127 127 #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 128 - #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 129 128 #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) 130 129 #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) 131 130 #define _TIF_SECCOMP (1 << TIF_SECCOMP) 132 131 #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 133 132 #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) 134 - #define _TIF_USEDFPU (1 << TIF_USEDFPU) 135 133 #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 136 134 #define _TIF_FREEZE (1 << TIF_FREEZE) 137 135 ··· 147 149 /* work to do on any return to u-space */ 148 150 #define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \ 149 151 _TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \ 150 - _TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK | \ 151 - _TIF_NOTIFY_RESUME | _TIF_SYSCALL_TRACEPOINT) 152 + _TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \ 153 + _TIF_SYSCALL_TRACEPOINT) 152 154 153 155 /* work to do on interrupt/exception return */ 154 156 #define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \ 155 157 _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP)) 158 + 159 + /* 160 + * Thread-synchronous status. 161 + * 162 + * This is different from the flags in that nobody else 163 + * ever touches our thread-synchronous status, so we don't 164 + * have to worry about atomic accesses. 165 + */ 166 + #define TS_RESTORE_SIGMASK 0x0001 /* restore signal mask in do_signal() */ 167 + #define TS_USEDFPU 0x0002 /* FPU used by this task this quantum */ 168 + 169 + #ifndef __ASSEMBLY__ 170 + #define HAVE_SET_RESTORE_SIGMASK 1 171 + static inline void set_restore_sigmask(void) 172 + { 173 + struct thread_info *ti = current_thread_info(); 174 + ti->status |= TS_RESTORE_SIGMASK; 175 + set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags); 176 + } 177 + #endif /* !__ASSEMBLY__ */ 156 178 157 179 #endif /* __KERNEL__ */ 158 180
+8
arch/sh/include/asm/topology.h
··· 40 40 41 41 #endif 42 42 43 + #define mc_capable() (1) 44 + 45 + const struct cpumask *cpu_coregroup_mask(unsigned int cpu); 46 + 47 + extern cpumask_t cpu_core_map[NR_CPUS]; 48 + 49 + #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) 50 + 43 51 #include <asm-generic/topology.h> 44 52 45 53 #endif /* _ASM_SH_TOPOLOGY_H */
-11
arch/sh/include/asm/ubc.h
··· 60 60 #define BRCR_UBDE (1 << 0) 61 61 #endif 62 62 63 - #ifndef __ASSEMBLY__ 64 - /* arch/sh/kernel/cpu/ubc.S */ 65 - extern void ubc_sleep(void); 66 - 67 - #ifdef CONFIG_UBC_WAKEUP 68 - extern void ubc_wakeup(void); 69 - #else 70 - #define ubc_wakeup() do { } while (0) 71 - #endif 72 - #endif 73 - 74 63 #endif /* __KERNEL__ */ 75 64 #endif /* __ASM_SH_UBC_H */
+58 -1
arch/sh/include/asm/watchdog.h
··· 2 2 * include/asm-sh/watchdog.h 3 3 * 4 4 * Copyright (C) 2002, 2003 Paul Mundt 5 + * Copyright (C) 2009 Siemens AG 6 + * Copyright (C) 2009 Valentin Sitdikov 5 7 * 6 8 * This program is free software; you can redistribute it and/or modify it 7 9 * under the terms of the GNU General Public License as published by the ··· 63 61 #define WTCSR_CKS_2048 0x06 64 62 #define WTCSR_CKS_4096 0x07 65 63 64 + #if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780) 65 + /** 66 + * sh_wdt_read_cnt - Read from Counter 67 + * Reads back the WTCNT value. 68 + */ 69 + static inline __u32 sh_wdt_read_cnt(void) 70 + { 71 + return ctrl_inl(WTCNT_R); 72 + } 73 + 74 + /** 75 + * sh_wdt_write_cnt - Write to Counter 76 + * @val: Value to write 77 + * 78 + * Writes the given value @val to the lower byte of the timer counter. 79 + * The upper byte is set manually on each write. 80 + */ 81 + static inline void sh_wdt_write_cnt(__u32 val) 82 + { 83 + ctrl_outl((WTCNT_HIGH << 24) | (__u32)val, WTCNT); 84 + } 85 + 86 + /** 87 + * sh_wdt_write_bst - Write to Counter 88 + * @val: Value to write 89 + * 90 + * Writes the given value @val to the lower byte of the timer counter. 91 + * The upper byte is set manually on each write. 92 + */ 93 + static inline void sh_wdt_write_bst(__u32 val) 94 + { 95 + ctrl_outl((WTBST_HIGH << 24) | (__u32)val, WTBST); 96 + } 97 + /** 98 + * sh_wdt_read_csr - Read from Control/Status Register 99 + * 100 + * Reads back the WTCSR value. 101 + */ 102 + static inline __u32 sh_wdt_read_csr(void) 103 + { 104 + return ctrl_inl(WTCSR_R); 105 + } 106 + 107 + /** 108 + * sh_wdt_write_csr - Write to Control/Status Register 109 + * @val: Value to write 110 + * 111 + * Writes the given value @val to the lower byte of the control/status 112 + * register. The upper byte is set manually on each write. 113 + */ 114 + static inline void sh_wdt_write_csr(__u32 val) 115 + { 116 + ctrl_outl((WTCSR_HIGH << 24) | (__u32)val, WTCSR); 117 + } 118 + #else 66 119 /** 67 120 * sh_wdt_read_cnt - Read from Counter 68 121 * Reads back the WTCNT value. ··· 160 103 { 161 104 ctrl_outw((WTCSR_HIGH << 8) | (__u16)val, WTCSR); 162 105 } 163 - 106 + #endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */ 164 107 #endif /* __KERNEL__ */ 165 108 #endif /* __ASM_SH_WATCHDOG_H */
+13
arch/sh/include/cpu-sh4/cpu/watchdog.h
··· 2 2 * include/asm-sh/cpu-sh4/watchdog.h 3 3 * 4 4 * Copyright (C) 2002, 2003 Paul Mundt 5 + * Copyright (C) 2009 Siemens AG 6 + * Copyright (C) 2009 Sitdikov Valentin 5 7 * 6 8 * This file is subject to the terms and conditions of the GNU General Public 7 9 * License. See the file "COPYING" in the main directory of this archive ··· 12 10 #ifndef __ASM_CPU_SH4_WATCHDOG_H 13 11 #define __ASM_CPU_SH4_WATCHDOG_H 14 12 13 + #if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780) 14 + /* Prefix definition */ 15 + #define WTBST_HIGH 0x55 16 + /* Register definitions */ 17 + #define WTCNT_R 0xffcc0010 /*WDTCNT*/ 18 + #define WTCSR 0xffcc0004 /*WDTCSR*/ 19 + #define WTCNT 0xffcc0000 /*WDTST*/ 20 + #define WTST WTCNT 21 + #define WTBST 0xffcc0008 /*WDTBST*/ 22 + #else 15 23 /* Register definitions */ 16 24 #define WTCNT 0xffc00008 17 25 #define WTCSR 0xffc0000c 26 + #endif 18 27 19 28 /* Bit definitions */ 20 29 #define WTCSR_TME 0x80
+1 -2
arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
··· 22 22 LIST "setup clocks" 23 23 ED 0xa4150024, 0x00004000 24 24 ED 0xa4150000, 0x8E003508 25 - ED 0xa4150004, 0x00000000 26 25 27 26 WAIT 1 28 27 29 28 LIST "BSC" 30 29 ED 0xff800020, 0xa5a50000 31 - ED 0xfec10000, 0x00000013 30 + ED 0xfec10000, 0x00001013 32 31 ED 0xfec10004, 0x11110400 33 32 ED 0xfec10024, 0x00000440 34 33
+2 -9
arch/sh/include/mach-se/mach/se7722.h
··· 92 92 #define SE7722_FPGA_IRQ_MRSHPC1 3 /* IRQ1 */ 93 93 #define SE7722_FPGA_IRQ_MRSHPC2 4 /* IRQ1 */ 94 94 #define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */ 95 - 96 95 #define SE7722_FPGA_IRQ_NR 6 97 - #define SE7722_FPGA_IRQ_BASE 110 98 - 99 - #define MRSHPC_IRQ3 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC3) 100 - #define MRSHPC_IRQ2 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC2) 101 - #define MRSHPC_IRQ1 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC1) 102 - #define MRSHPC_IRQ0 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC0) 103 - #define SMC_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_SMC) 104 - #define USB_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_USB) 105 96 106 97 /* arch/sh/boards/se/7722/irq.c */ 98 + extern unsigned int se7722_fpga_irq[]; 99 + 107 100 void init_se7722_IRQ(void); 108 101 109 102 #define __IO_PREFIX se7722
+7 -3
arch/sh/kernel/Makefile
··· 9 9 CFLAGS_REMOVE_ftrace.o = -pg 10 10 endif 11 11 12 - obj-y := debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o \ 13 - machvec.o nmi_debug.o process_$(BITS).o ptrace_$(BITS).o \ 12 + CFLAGS_REMOVE_return_address.o = -pg 13 + 14 + obj-y := debugtraps.o dma-nommu.o dumpstack.o \ 15 + idle.o io.o io_generic.o irq.o \ 16 + irq_$(BITS).o machvec.o nmi_debug.o process_$(BITS).o \ 17 + ptrace_$(BITS).o return_address.o \ 14 18 setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \ 15 19 syscalls_$(BITS).o time.o topology.o traps.o \ 16 20 traps_$(BITS).o unwinder.o ··· 32 28 obj-$(CONFIG_STACKTRACE) += stacktrace.o 33 29 obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 34 30 obj-$(CONFIG_KPROBES) += kprobes.o 35 - obj-$(CONFIG_GENERIC_GPIO) += gpio.o 36 31 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 37 32 obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o 38 33 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 39 34 obj-$(CONFIG_DUMP_CODE) += disassemble.o 40 35 obj-$(CONFIG_HIBERNATION) += swsusp.o 41 36 obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o 37 + obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o 42 38 43 39 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o 44 40
+23
arch/sh/kernel/asm-offsets.c
··· 34 34 DEFINE(PBE_NEXT, offsetof(struct pbe, next)); 35 35 DEFINE(SWSUSP_ARCH_REGS_SIZE, sizeof(struct swsusp_arch_regs)); 36 36 #endif 37 + 38 + DEFINE(SH_SLEEP_MODE, offsetof(struct sh_sleep_data, mode)); 39 + DEFINE(SH_SLEEP_SF_PRE, offsetof(struct sh_sleep_data, sf_pre)); 40 + DEFINE(SH_SLEEP_SF_POST, offsetof(struct sh_sleep_data, sf_post)); 41 + DEFINE(SH_SLEEP_RESUME, offsetof(struct sh_sleep_data, resume)); 42 + DEFINE(SH_SLEEP_VBR, offsetof(struct sh_sleep_data, vbr)); 43 + DEFINE(SH_SLEEP_SPC, offsetof(struct sh_sleep_data, spc)); 44 + DEFINE(SH_SLEEP_SR, offsetof(struct sh_sleep_data, sr)); 45 + DEFINE(SH_SLEEP_SP, offsetof(struct sh_sleep_data, sp)); 46 + DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr)); 47 + DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data)); 48 + DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr)); 49 + DEFINE(SH_SLEEP_REG_BAR, offsetof(struct sh_sleep_regs, bar)); 50 + DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh)); 51 + DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel)); 52 + DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb)); 53 + DEFINE(SH_SLEEP_REG_TEA, offsetof(struct sh_sleep_regs, tea)); 54 + DEFINE(SH_SLEEP_REG_MMUCR, offsetof(struct sh_sleep_regs, mmucr)); 55 + DEFINE(SH_SLEEP_REG_PTEA, offsetof(struct sh_sleep_regs, ptea)); 56 + DEFINE(SH_SLEEP_REG_PASCR, offsetof(struct sh_sleep_regs, pascr)); 57 + DEFINE(SH_SLEEP_REG_IRMCR, offsetof(struct sh_sleep_regs, irmcr)); 58 + DEFINE(SH_SLEEP_REG_CCR, offsetof(struct sh_sleep_regs, ccr)); 59 + DEFINE(SH_SLEEP_REG_RAMCR, offsetof(struct sh_sleep_regs, ramcr)); 37 60 return 0; 38 61 }
-1
arch/sh/kernel/cpu/Makefile
··· 15 15 16 16 # Common interfaces. 17 17 18 - obj-$(CONFIG_UBC_WAKEUP) += ubc.o 19 18 obj-$(CONFIG_SH_ADC) += adc.o 20 19 obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o 21 20
+6 -22
arch/sh/kernel/cpu/init.c
··· 75 75 /* 76 76 * Future proofing. 77 77 * 78 - * Disable support for slottable sleep instruction 79 - * and non-nop instructions in the rte delay slot. 78 + * Disable support for slottable sleep instruction, non-nop 79 + * instructions in the rte delay slot, and associative writes to 80 + * the memory-mapped cache array. 80 81 */ 81 - expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP); 82 - 83 - /* 84 - * Enable associative writes to the memory-mapped cache array 85 - * until the cache flush ops have been rewritten. 86 - */ 87 - expmask |= EXPMASK_MMCAW; 82 + expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP | EXPMASK_MMCAW); 88 83 89 84 __raw_writel(expmask, EXPMASK); 90 85 ctrl_barrier(); ··· 306 311 if (fpu_disabled) { 307 312 printk("FPU Disabled\n"); 308 313 current_cpu_data.flags &= ~CPU_HAS_FPU; 309 - disable_fpu(); 310 314 } 311 315 312 316 /* FPU initialization */ 317 + disable_fpu(); 313 318 if ((current_cpu_data.flags & CPU_HAS_FPU)) { 314 - clear_thread_flag(TIF_USEDFPU); 319 + current_thread_info()->status &= ~TS_USEDFPU; 315 320 clear_used_math(); 316 321 } 317 322 ··· 331 336 current_cpu_data.flags &= ~CPU_HAS_DSP; 332 337 release_dsp(); 333 338 } 334 - #endif 335 - 336 - /* 337 - * Some brain-damaged loaders decided it would be a good idea to put 338 - * the UBC to sleep. This causes some issues when it comes to things 339 - * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. 340 - * we wake it up and hope that all is well. 341 - */ 342 - #ifdef CONFIG_SUPERH32 343 - if (raw_smp_processor_id() == 0) 344 - ubc_wakeup(); 345 339 #endif 346 340 347 341 speculative_execution_init();
+16 -11
arch/sh/kernel/cpu/sh2a/fpu.c
··· 25 25 26 26 /* 27 27 * Save FPU registers onto task structure. 28 - * Assume called with FPU enabled (SR.FD=0). 29 28 */ 30 29 void 31 - save_fpu(struct task_struct *tsk, struct pt_regs *regs) 30 + save_fpu(struct task_struct *tsk) 32 31 { 33 32 unsigned long dummy; 34 33 35 - clear_tsk_thread_flag(tsk, TIF_USEDFPU); 36 34 enable_fpu(); 37 35 asm volatile("sts.l fpul, @-%0\n\t" 38 36 "sts.l fpscr, @-%0\n\t" ··· 58 60 : "memory"); 59 61 60 62 disable_fpu(); 61 - release_fpu(regs); 62 63 } 63 64 64 65 static void ··· 595 598 struct task_struct *tsk = current; 596 599 TRAP_HANDLER_DECL; 597 600 598 - save_fpu(tsk, regs); 601 + __unlazy_fpu(tsk, regs); 599 602 if (ieee_fpe_handler(regs)) { 600 603 tsk->thread.fpu.hard.fpscr &= 601 604 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); 602 605 grab_fpu(regs); 603 606 restore_fpu(tsk); 604 - set_tsk_thread_flag(tsk, TIF_USEDFPU); 607 + task_thread_info(tsk)->status |= TS_USEDFPU; 605 608 return; 606 609 } 607 610 608 611 force_sig(SIGFPE, tsk); 609 612 } 610 613 611 - BUILD_TRAP_HANDLER(fpu_state_restore) 614 + void fpu_state_restore(struct pt_regs *regs) 612 615 { 613 616 struct task_struct *tsk = current; 614 - TRAP_HANDLER_DECL; 615 617 616 618 grab_fpu(regs); 617 - if (!user_mode(regs)) { 619 + if (unlikely(!user_mode(regs))) { 618 620 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); 621 + BUG(); 619 622 return; 620 623 } 621 624 622 - if (used_math()) { 625 + if (likely(used_math())) { 623 626 /* Using the FPU again. */ 624 627 restore_fpu(tsk); 625 628 } else { ··· 627 630 fpu_init(); 628 631 set_used_math(); 629 632 } 630 - set_tsk_thread_flag(tsk, TIF_USEDFPU); 633 + task_thread_info(tsk)->status |= TS_USEDFPU; 634 + tsk->fpu_counter++; 635 + } 636 + 637 + BUILD_TRAP_HANDLER(fpu_state_restore) 638 + { 639 + TRAP_HANDLER_DECL; 640 + 641 + fpu_state_restore(regs); 631 642 }
-33
arch/sh/kernel/cpu/sh3/entry.S
··· 297 297 ! 298 298 .balign 256,0,256 299 299 general_exception: 300 - #ifndef CONFIG_CPU_SUBTYPE_SHX3 301 300 bra handle_exception 302 301 sts pr, k3 ! save original pr value in k3 303 - #else 304 - mov.l 1f, k4 305 - mov.l @k4, k4 306 - 307 - ! Is EXPEVT larger than 0x800? 308 - mov #0x8, k0 309 - shll8 k0 310 - cmp/hs k0, k4 311 - bf 0f 312 - 313 - ! then add 0x580 (k2 is 0xd80 or 0xda0) 314 - mov #0x58, k0 315 - shll2 k0 316 - shll2 k0 317 - add k0, k4 318 - 0: 319 - ! Setup stack and save DSP context (k0 contains original r15 on return) 320 - bsr prepare_stack 321 - nop 322 - 323 - ! Save registers / Switch to bank 0 324 - mov k4, k2 ! keep vector in k2 325 - mov.l 1f, k4 ! SR bits to clear in k4 326 - bsr save_regs ! needs original pr value in k3 327 - nop 328 - 329 - bra handle_exception_special 330 - nop 331 - 332 - .align 2 333 - 1: .long EXPEVT 334 - #endif 335 302 336 303 ! prepare_stack() 337 304 ! - roll back gRB
+7 -1
arch/sh/kernel/cpu/sh4/Makefile
··· 9 9 obj-$(CONFIG_SH_FPU) += fpu.o softfloat.o 10 10 obj-$(CONFIG_SH_STORE_QUEUES) += sq.o 11 11 12 + # Perf events 13 + perf-$(CONFIG_CPU_SUBTYPE_SH7750) := perf_event.o 14 + perf-$(CONFIG_CPU_SUBTYPE_SH7750S) := perf_event.o 15 + perf-$(CONFIG_CPU_SUBTYPE_SH7091) := perf_event.o 16 + 12 17 # CPU subtype setup 13 18 obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o 14 19 obj-$(CONFIG_CPU_SUBTYPE_SH7750R) += setup-sh7750.o ··· 32 27 # Additional clocks by subtype 33 28 clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o 34 29 35 - obj-y += $(clock-y) 30 + obj-y += $(clock-y) 31 + obj-$(CONFIG_PERF_EVENTS) += $(perf-y)
+16 -12
arch/sh/kernel/cpu/sh4/fpu.c
··· 41 41 42 42 /* 43 43 * Save FPU registers onto task structure. 44 - * Assume called with FPU enabled (SR.FD=0). 45 44 */ 46 - void save_fpu(struct task_struct *tsk, struct pt_regs *regs) 45 + void save_fpu(struct task_struct *tsk) 47 46 { 48 47 unsigned long dummy; 49 48 50 - clear_tsk_thread_flag(tsk, TIF_USEDFPU); 51 49 enable_fpu(); 52 50 asm volatile ("sts.l fpul, @-%0\n\t" 53 51 "sts.l fpscr, @-%0\n\t" ··· 90 92 :"memory"); 91 93 92 94 disable_fpu(); 93 - release_fpu(regs); 94 95 } 95 96 96 97 static void restore_fpu(struct task_struct *tsk) ··· 282 285 /* fcnvsd */ 283 286 struct task_struct *tsk = current; 284 287 285 - save_fpu(tsk, regs); 286 288 if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)) 287 289 /* FPU error */ 288 290 denormal_to_double(&tsk->thread.fpu.hard, ··· 458 462 struct task_struct *tsk = current; 459 463 TRAP_HANDLER_DECL; 460 464 461 - save_fpu(tsk, regs); 465 + __unlazy_fpu(tsk, regs); 462 466 fpu_exception_flags = 0; 463 467 if (ieee_fpe_handler(regs)) { 464 468 tsk->thread.fpu.hard.fpscr &= ··· 469 473 tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10); 470 474 grab_fpu(regs); 471 475 restore_fpu(tsk); 472 - set_tsk_thread_flag(tsk, TIF_USEDFPU); 476 + task_thread_info(tsk)->status |= TS_USEDFPU; 473 477 if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) & 474 478 (fpu_exception_flags >> 2)) == 0) { 475 479 return; ··· 479 483 force_sig(SIGFPE, tsk); 480 484 } 481 485 482 - BUILD_TRAP_HANDLER(fpu_state_restore) 486 + void fpu_state_restore(struct pt_regs *regs) 483 487 { 484 488 struct task_struct *tsk = current; 485 - TRAP_HANDLER_DECL; 486 489 487 490 grab_fpu(regs); 488 - if (!user_mode(regs)) { 491 + if (unlikely(!user_mode(regs))) { 489 492 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); 493 + BUG(); 490 494 return; 491 495 } 492 496 493 - if (used_math()) { 497 + if (likely(used_math())) { 494 498 /* Using the FPU again. */ 495 499 restore_fpu(tsk); 496 500 } else { ··· 498 502 fpu_init(); 499 503 set_used_math(); 500 504 } 501 - set_tsk_thread_flag(tsk, TIF_USEDFPU); 505 + task_thread_info(tsk)->status |= TS_USEDFPU; 506 + tsk->fpu_counter++; 507 + } 508 + 509 + BUILD_TRAP_HANDLER(fpu_state_restore) 510 + { 511 + TRAP_HANDLER_DECL; 512 + 513 + fpu_state_restore(regs); 502 514 }
+253
arch/sh/kernel/cpu/sh4/perf_event.c
··· 1 + /* 2 + * Performance events support for SH7750-style performance counters 3 + * 4 + * Copyright (C) 2009 Paul Mundt 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + #include <linux/kernel.h> 11 + #include <linux/init.h> 12 + #include <linux/io.h> 13 + #include <linux/irq.h> 14 + #include <linux/perf_event.h> 15 + #include <asm/processor.h> 16 + 17 + #define PM_CR_BASE 0xff000084 /* 16-bit */ 18 + #define PM_CTR_BASE 0xff100004 /* 32-bit */ 19 + 20 + #define PMCR(n) (PM_CR_BASE + ((n) * 0x04)) 21 + #define PMCTRH(n) (PM_CTR_BASE + 0x00 + ((n) * 0x08)) 22 + #define PMCTRL(n) (PM_CTR_BASE + 0x04 + ((n) * 0x08)) 23 + 24 + #define PMCR_PMM_MASK 0x0000003f 25 + 26 + #define PMCR_CLKF 0x00000100 27 + #define PMCR_PMCLR 0x00002000 28 + #define PMCR_PMST 0x00004000 29 + #define PMCR_PMEN 0x00008000 30 + 31 + static struct sh_pmu sh7750_pmu; 32 + 33 + /* 34 + * There are a number of events supported by each counter (33 in total). 35 + * Since we have 2 counters, each counter will take the event code as it 36 + * corresponds to the PMCR PMM setting. Each counter can be configured 37 + * independently. 38 + * 39 + * Event Code Description 40 + * ---------- ----------- 41 + * 42 + * 0x01 Operand read access 43 + * 0x02 Operand write access 44 + * 0x03 UTLB miss 45 + * 0x04 Operand cache read miss 46 + * 0x05 Operand cache write miss 47 + * 0x06 Instruction fetch (w/ cache) 48 + * 0x07 Instruction TLB miss 49 + * 0x08 Instruction cache miss 50 + * 0x09 All operand accesses 51 + * 0x0a All instruction accesses 52 + * 0x0b OC RAM operand access 53 + * 0x0d On-chip I/O space access 54 + * 0x0e Operand access (r/w) 55 + * 0x0f Operand cache miss (r/w) 56 + * 0x10 Branch instruction 57 + * 0x11 Branch taken 58 + * 0x12 BSR/BSRF/JSR 59 + * 0x13 Instruction execution 60 + * 0x14 Instruction execution in parallel 61 + * 0x15 FPU Instruction execution 62 + * 0x16 Interrupt 63 + * 0x17 NMI 64 + * 0x18 trapa instruction execution 65 + * 0x19 UBCA match 66 + * 0x1a UBCB match 67 + * 0x21 Instruction cache fill 68 + * 0x22 Operand cache fill 69 + * 0x23 Elapsed time 70 + * 0x24 Pipeline freeze by I-cache miss 71 + * 0x25 Pipeline freeze by D-cache miss 72 + * 0x27 Pipeline freeze by branch instruction 73 + * 0x28 Pipeline freeze by CPU register 74 + * 0x29 Pipeline freeze by FPU 75 + */ 76 + 77 + static const int sh7750_general_events[] = { 78 + [PERF_COUNT_HW_CPU_CYCLES] = 0x0023, 79 + [PERF_COUNT_HW_INSTRUCTIONS] = 0x000a, 80 + [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0006, /* I-cache */ 81 + [PERF_COUNT_HW_CACHE_MISSES] = 0x0008, /* I-cache */ 82 + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0010, 83 + [PERF_COUNT_HW_BRANCH_MISSES] = -1, 84 + [PERF_COUNT_HW_BUS_CYCLES] = -1, 85 + }; 86 + 87 + #define C(x) PERF_COUNT_HW_CACHE_##x 88 + 89 + static const int sh7750_cache_events 90 + [PERF_COUNT_HW_CACHE_MAX] 91 + [PERF_COUNT_HW_CACHE_OP_MAX] 92 + [PERF_COUNT_HW_CACHE_RESULT_MAX] = 93 + { 94 + [ C(L1D) ] = { 95 + [ C(OP_READ) ] = { 96 + [ C(RESULT_ACCESS) ] = 0x0001, 97 + [ C(RESULT_MISS) ] = 0x0004, 98 + }, 99 + [ C(OP_WRITE) ] = { 100 + [ C(RESULT_ACCESS) ] = 0x0002, 101 + [ C(RESULT_MISS) ] = 0x0005, 102 + }, 103 + [ C(OP_PREFETCH) ] = { 104 + [ C(RESULT_ACCESS) ] = 0, 105 + [ C(RESULT_MISS) ] = 0, 106 + }, 107 + }, 108 + 109 + [ C(L1I) ] = { 110 + [ C(OP_READ) ] = { 111 + [ C(RESULT_ACCESS) ] = 0x0006, 112 + [ C(RESULT_MISS) ] = 0x0008, 113 + }, 114 + [ C(OP_WRITE) ] = { 115 + [ C(RESULT_ACCESS) ] = -1, 116 + [ C(RESULT_MISS) ] = -1, 117 + }, 118 + [ C(OP_PREFETCH) ] = { 119 + [ C(RESULT_ACCESS) ] = 0, 120 + [ C(RESULT_MISS) ] = 0, 121 + }, 122 + }, 123 + 124 + [ C(LL) ] = { 125 + [ C(OP_READ) ] = { 126 + [ C(RESULT_ACCESS) ] = 0, 127 + [ C(RESULT_MISS) ] = 0, 128 + }, 129 + [ C(OP_WRITE) ] = { 130 + [ C(RESULT_ACCESS) ] = 0, 131 + [ C(RESULT_MISS) ] = 0, 132 + }, 133 + [ C(OP_PREFETCH) ] = { 134 + [ C(RESULT_ACCESS) ] = 0, 135 + [ C(RESULT_MISS) ] = 0, 136 + }, 137 + }, 138 + 139 + [ C(DTLB) ] = { 140 + [ C(OP_READ) ] = { 141 + [ C(RESULT_ACCESS) ] = 0, 142 + [ C(RESULT_MISS) ] = 0x0003, 143 + }, 144 + [ C(OP_WRITE) ] = { 145 + [ C(RESULT_ACCESS) ] = 0, 146 + [ C(RESULT_MISS) ] = 0, 147 + }, 148 + [ C(OP_PREFETCH) ] = { 149 + [ C(RESULT_ACCESS) ] = 0, 150 + [ C(RESULT_MISS) ] = 0, 151 + }, 152 + }, 153 + 154 + [ C(ITLB) ] = { 155 + [ C(OP_READ) ] = { 156 + [ C(RESULT_ACCESS) ] = 0, 157 + [ C(RESULT_MISS) ] = 0x0007, 158 + }, 159 + [ C(OP_WRITE) ] = { 160 + [ C(RESULT_ACCESS) ] = -1, 161 + [ C(RESULT_MISS) ] = -1, 162 + }, 163 + [ C(OP_PREFETCH) ] = { 164 + [ C(RESULT_ACCESS) ] = -1, 165 + [ C(RESULT_MISS) ] = -1, 166 + }, 167 + }, 168 + 169 + [ C(BPU) ] = { 170 + [ C(OP_READ) ] = { 171 + [ C(RESULT_ACCESS) ] = -1, 172 + [ C(RESULT_MISS) ] = -1, 173 + }, 174 + [ C(OP_WRITE) ] = { 175 + [ C(RESULT_ACCESS) ] = -1, 176 + [ C(RESULT_MISS) ] = -1, 177 + }, 178 + [ C(OP_PREFETCH) ] = { 179 + [ C(RESULT_ACCESS) ] = -1, 180 + [ C(RESULT_MISS) ] = -1, 181 + }, 182 + }, 183 + }; 184 + 185 + static int sh7750_event_map(int event) 186 + { 187 + return sh7750_general_events[event]; 188 + } 189 + 190 + static u64 sh7750_pmu_read(int idx) 191 + { 192 + return (u64)((u64)(__raw_readl(PMCTRH(idx)) & 0xffff) << 32) | 193 + __raw_readl(PMCTRL(idx)); 194 + } 195 + 196 + static void sh7750_pmu_disable(struct hw_perf_event *hwc, int idx) 197 + { 198 + unsigned int tmp; 199 + 200 + tmp = __raw_readw(PMCR(idx)); 201 + tmp &= ~(PMCR_PMM_MASK | PMCR_PMEN); 202 + __raw_writew(tmp, PMCR(idx)); 203 + } 204 + 205 + static void sh7750_pmu_enable(struct hw_perf_event *hwc, int idx) 206 + { 207 + __raw_writew(__raw_readw(PMCR(idx)) | PMCR_PMCLR, PMCR(idx)); 208 + __raw_writew(hwc->config | PMCR_PMEN | PMCR_PMST, PMCR(idx)); 209 + } 210 + 211 + static void sh7750_pmu_disable_all(void) 212 + { 213 + int i; 214 + 215 + for (i = 0; i < sh7750_pmu.num_events; i++) 216 + __raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i)); 217 + } 218 + 219 + static void sh7750_pmu_enable_all(void) 220 + { 221 + int i; 222 + 223 + for (i = 0; i < sh7750_pmu.num_events; i++) 224 + __raw_writew(__raw_readw(PMCR(i)) | PMCR_PMEN, PMCR(i)); 225 + } 226 + 227 + static struct sh_pmu sh7750_pmu = { 228 + .name = "SH7750", 229 + .num_events = 2, 230 + .event_map = sh7750_event_map, 231 + .max_events = ARRAY_SIZE(sh7750_general_events), 232 + .raw_event_mask = PMCR_PMM_MASK, 233 + .cache_events = &sh7750_cache_events, 234 + .read = sh7750_pmu_read, 235 + .disable = sh7750_pmu_disable, 236 + .enable = sh7750_pmu_enable, 237 + .disable_all = sh7750_pmu_disable_all, 238 + .enable_all = sh7750_pmu_enable_all, 239 + }; 240 + 241 + static int __init sh7750_pmu_init(void) 242 + { 243 + /* 244 + * Make sure this CPU actually has perf counters. 245 + */ 246 + if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) { 247 + pr_notice("HW perf events unsupported, software events only.\n"); 248 + return -ENODEV; 249 + } 250 + 251 + return register_sh_pmu(&sh7750_pmu); 252 + } 253 + arch_initcall(sh7750_pmu_init);
+1
arch/sh/kernel/cpu/sh4a/Makefile
··· 44 44 obj-y += $(clock-y) 45 45 obj-$(CONFIG_SMP) += $(smp-y) 46 46 obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y) 47 + obj-$(CONFIG_PERF_EVENTS) += perf_event.o
+1 -1
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
··· 152 152 SH_CLK_DIV6("fsia_clk", &div3_clk, FCLKACR, 0), 153 153 SH_CLK_DIV6("fsib_clk", &div3_clk, FCLKBCR, 0), 154 154 SH_CLK_DIV6("irda_clk", &div3_clk, IRDACLKCR, 0), 155 - SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, 0), 155 + SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT), 156 156 }; 157 157 158 158 #define R_CLK (&r_clk)
+269
arch/sh/kernel/cpu/sh4a/perf_event.c
··· 1 + /* 2 + * Performance events support for SH-4A performance counters 3 + * 4 + * Copyright (C) 2009 Paul Mundt 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + #include <linux/kernel.h> 11 + #include <linux/init.h> 12 + #include <linux/io.h> 13 + #include <linux/irq.h> 14 + #include <linux/perf_event.h> 15 + #include <asm/processor.h> 16 + 17 + #define PPC_CCBR(idx) (0xff200800 + (sizeof(u32) * idx)) 18 + #define PPC_PMCTR(idx) (0xfc100000 + (sizeof(u32) * idx)) 19 + 20 + #define CCBR_CIT_MASK (0x7ff << 6) 21 + #define CCBR_DUC (1 << 3) 22 + #define CCBR_CMDS (1 << 1) 23 + #define CCBR_PPCE (1 << 0) 24 + 25 + #define PPC_PMCAT 0xfc100080 26 + 27 + #define PMCAT_OVF3 (1 << 27) 28 + #define PMCAT_CNN3 (1 << 26) 29 + #define PMCAT_CLR3 (1 << 25) 30 + #define PMCAT_OVF2 (1 << 19) 31 + #define PMCAT_CLR2 (1 << 17) 32 + #define PMCAT_OVF1 (1 << 11) 33 + #define PMCAT_CNN1 (1 << 10) 34 + #define PMCAT_CLR1 (1 << 9) 35 + #define PMCAT_OVF0 (1 << 3) 36 + #define PMCAT_CLR0 (1 << 1) 37 + 38 + static struct sh_pmu sh4a_pmu; 39 + 40 + /* 41 + * Supported raw event codes: 42 + * 43 + * Event Code Description 44 + * ---------- ----------- 45 + * 46 + * 0x0000 number of elapsed cycles 47 + * 0x0200 number of elapsed cycles in privileged mode 48 + * 0x0280 number of elapsed cycles while SR.BL is asserted 49 + * 0x0202 instruction execution 50 + * 0x0203 instruction execution in parallel 51 + * 0x0204 number of unconditional branches 52 + * 0x0208 number of exceptions 53 + * 0x0209 number of interrupts 54 + * 0x0220 UTLB miss caused by instruction fetch 55 + * 0x0222 UTLB miss caused by operand access 56 + * 0x02a0 number of ITLB misses 57 + * 0x0028 number of accesses to instruction memories 58 + * 0x0029 number of accesses to instruction cache 59 + * 0x002a instruction cache miss 60 + * 0x022e number of access to instruction X/Y memory 61 + * 0x0030 number of reads to operand memories 62 + * 0x0038 number of writes to operand memories 63 + * 0x0031 number of operand cache read accesses 64 + * 0x0039 number of operand cache write accesses 65 + * 0x0032 operand cache read miss 66 + * 0x003a operand cache write miss 67 + * 0x0236 number of reads to operand X/Y memory 68 + * 0x023e number of writes to operand X/Y memory 69 + * 0x0237 number of reads to operand U memory 70 + * 0x023f number of writes to operand U memory 71 + * 0x0337 number of U memory read buffer misses 72 + * 0x02b4 number of wait cycles due to operand read access 73 + * 0x02bc number of wait cycles due to operand write access 74 + * 0x0033 number of wait cycles due to operand cache read miss 75 + * 0x003b number of wait cycles due to operand cache write miss 76 + */ 77 + 78 + /* 79 + * Special reserved bits used by hardware emulators, read values will 80 + * vary, but writes must always be 0. 81 + */ 82 + #define PMCAT_EMU_CLR_MASK ((1 << 24) | (1 << 16) | (1 << 8) | (1 << 0)) 83 + 84 + static const int sh4a_general_events[] = { 85 + [PERF_COUNT_HW_CPU_CYCLES] = 0x0000, 86 + [PERF_COUNT_HW_INSTRUCTIONS] = 0x0202, 87 + [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0029, /* I-cache */ 88 + [PERF_COUNT_HW_CACHE_MISSES] = 0x002a, /* I-cache */ 89 + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0204, 90 + [PERF_COUNT_HW_BRANCH_MISSES] = -1, 91 + [PERF_COUNT_HW_BUS_CYCLES] = -1, 92 + }; 93 + 94 + #define C(x) PERF_COUNT_HW_CACHE_##x 95 + 96 + static const int sh4a_cache_events 97 + [PERF_COUNT_HW_CACHE_MAX] 98 + [PERF_COUNT_HW_CACHE_OP_MAX] 99 + [PERF_COUNT_HW_CACHE_RESULT_MAX] = 100 + { 101 + [ C(L1D) ] = { 102 + [ C(OP_READ) ] = { 103 + [ C(RESULT_ACCESS) ] = 0x0031, 104 + [ C(RESULT_MISS) ] = 0x0032, 105 + }, 106 + [ C(OP_WRITE) ] = { 107 + [ C(RESULT_ACCESS) ] = 0x0039, 108 + [ C(RESULT_MISS) ] = 0x003a, 109 + }, 110 + [ C(OP_PREFETCH) ] = { 111 + [ C(RESULT_ACCESS) ] = 0, 112 + [ C(RESULT_MISS) ] = 0, 113 + }, 114 + }, 115 + 116 + [ C(L1I) ] = { 117 + [ C(OP_READ) ] = { 118 + [ C(RESULT_ACCESS) ] = 0x0029, 119 + [ C(RESULT_MISS) ] = 0x002a, 120 + }, 121 + [ C(OP_WRITE) ] = { 122 + [ C(RESULT_ACCESS) ] = -1, 123 + [ C(RESULT_MISS) ] = -1, 124 + }, 125 + [ C(OP_PREFETCH) ] = { 126 + [ C(RESULT_ACCESS) ] = 0, 127 + [ C(RESULT_MISS) ] = 0, 128 + }, 129 + }, 130 + 131 + [ C(LL) ] = { 132 + [ C(OP_READ) ] = { 133 + [ C(RESULT_ACCESS) ] = 0x0030, 134 + [ C(RESULT_MISS) ] = 0, 135 + }, 136 + [ C(OP_WRITE) ] = { 137 + [ C(RESULT_ACCESS) ] = 0x0038, 138 + [ C(RESULT_MISS) ] = 0, 139 + }, 140 + [ C(OP_PREFETCH) ] = { 141 + [ C(RESULT_ACCESS) ] = 0, 142 + [ C(RESULT_MISS) ] = 0, 143 + }, 144 + }, 145 + 146 + [ C(DTLB) ] = { 147 + [ C(OP_READ) ] = { 148 + [ C(RESULT_ACCESS) ] = 0x0222, 149 + [ C(RESULT_MISS) ] = 0x0220, 150 + }, 151 + [ C(OP_WRITE) ] = { 152 + [ C(RESULT_ACCESS) ] = 0, 153 + [ C(RESULT_MISS) ] = 0, 154 + }, 155 + [ C(OP_PREFETCH) ] = { 156 + [ C(RESULT_ACCESS) ] = 0, 157 + [ C(RESULT_MISS) ] = 0, 158 + }, 159 + }, 160 + 161 + [ C(ITLB) ] = { 162 + [ C(OP_READ) ] = { 163 + [ C(RESULT_ACCESS) ] = 0, 164 + [ C(RESULT_MISS) ] = 0x02a0, 165 + }, 166 + [ C(OP_WRITE) ] = { 167 + [ C(RESULT_ACCESS) ] = -1, 168 + [ C(RESULT_MISS) ] = -1, 169 + }, 170 + [ C(OP_PREFETCH) ] = { 171 + [ C(RESULT_ACCESS) ] = -1, 172 + [ C(RESULT_MISS) ] = -1, 173 + }, 174 + }, 175 + 176 + [ C(BPU) ] = { 177 + [ C(OP_READ) ] = { 178 + [ C(RESULT_ACCESS) ] = -1, 179 + [ C(RESULT_MISS) ] = -1, 180 + }, 181 + [ C(OP_WRITE) ] = { 182 + [ C(RESULT_ACCESS) ] = -1, 183 + [ C(RESULT_MISS) ] = -1, 184 + }, 185 + [ C(OP_PREFETCH) ] = { 186 + [ C(RESULT_ACCESS) ] = -1, 187 + [ C(RESULT_MISS) ] = -1, 188 + }, 189 + }, 190 + }; 191 + 192 + static int sh4a_event_map(int event) 193 + { 194 + return sh4a_general_events[event]; 195 + } 196 + 197 + static u64 sh4a_pmu_read(int idx) 198 + { 199 + return __raw_readl(PPC_PMCTR(idx)); 200 + } 201 + 202 + static void sh4a_pmu_disable(struct hw_perf_event *hwc, int idx) 203 + { 204 + unsigned int tmp; 205 + 206 + tmp = __raw_readl(PPC_CCBR(idx)); 207 + tmp &= ~(CCBR_CIT_MASK | CCBR_DUC); 208 + __raw_writel(tmp, PPC_CCBR(idx)); 209 + } 210 + 211 + static void sh4a_pmu_enable(struct hw_perf_event *hwc, int idx) 212 + { 213 + unsigned int tmp; 214 + 215 + tmp = __raw_readl(PPC_PMCAT); 216 + tmp &= ~PMCAT_EMU_CLR_MASK; 217 + tmp |= idx ? PMCAT_CLR1 : PMCAT_CLR0; 218 + __raw_writel(tmp, PPC_PMCAT); 219 + 220 + tmp = __raw_readl(PPC_CCBR(idx)); 221 + tmp |= (hwc->config << 6) | CCBR_CMDS | CCBR_PPCE; 222 + __raw_writel(tmp, PPC_CCBR(idx)); 223 + 224 + __raw_writel(__raw_readl(PPC_CCBR(idx)) | CCBR_DUC, PPC_CCBR(idx)); 225 + } 226 + 227 + static void sh4a_pmu_disable_all(void) 228 + { 229 + int i; 230 + 231 + for (i = 0; i < sh4a_pmu.num_events; i++) 232 + __raw_writel(__raw_readl(PPC_CCBR(i)) & ~CCBR_DUC, PPC_CCBR(i)); 233 + } 234 + 235 + static void sh4a_pmu_enable_all(void) 236 + { 237 + int i; 238 + 239 + for (i = 0; i < sh4a_pmu.num_events; i++) 240 + __raw_writel(__raw_readl(PPC_CCBR(i)) | CCBR_DUC, PPC_CCBR(i)); 241 + } 242 + 243 + static struct sh_pmu sh4a_pmu = { 244 + .name = "SH-4A", 245 + .num_events = 2, 246 + .event_map = sh4a_event_map, 247 + .max_events = ARRAY_SIZE(sh4a_general_events), 248 + .raw_event_mask = 0x3ff, 249 + .cache_events = &sh4a_cache_events, 250 + .read = sh4a_pmu_read, 251 + .disable = sh4a_pmu_disable, 252 + .enable = sh4a_pmu_enable, 253 + .disable_all = sh4a_pmu_disable_all, 254 + .enable_all = sh4a_pmu_enable_all, 255 + }; 256 + 257 + static int __init sh4a_pmu_init(void) 258 + { 259 + /* 260 + * Make sure this CPU actually has perf counters. 261 + */ 262 + if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) { 263 + pr_notice("HW perf events unsupported, software events only.\n"); 264 + return -ENODEV; 265 + } 266 + 267 + return register_sh_pmu(&sh4a_pmu); 268 + } 269 + arch_initcall(sh4a_pmu_init);
+262 -2
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
··· 20 20 #include <linux/uio_driver.h> 21 21 #include <linux/sh_timer.h> 22 22 #include <linux/io.h> 23 + #include <linux/notifier.h> 24 + #include <asm/suspend.h> 23 25 #include <asm/clock.h> 24 26 #include <asm/mmzone.h> 25 27 #include <cpu/sh7724.h> ··· 204 202 [0] = { 205 203 .name = "VEU3F0", 206 204 .start = 0xfe920000, 207 - .end = 0xfe9200cb - 1, 205 + .end = 0xfe9200cb, 208 206 .flags = IORESOURCE_MEM, 209 207 }, 210 208 [1] = { ··· 236 234 [0] = { 237 235 .name = "VEU3F1", 238 236 .start = 0xfe924000, 239 - .end = 0xfe9240cb - 1, 237 + .end = 0xfe9240cb, 240 238 .flags = IORESOURCE_MEM, 241 239 }, 242 240 [1] = { ··· 525 523 }, 526 524 }; 527 525 526 + /* SPU2DSP0 */ 527 + static struct uio_info spu0_platform_data = { 528 + .name = "SPU2DSP0", 529 + .version = "0", 530 + .irq = 86, 531 + }; 532 + 533 + static struct resource spu0_resources[] = { 534 + [0] = { 535 + .name = "SPU2DSP0", 536 + .start = 0xFE200000, 537 + .end = 0xFE2FFFFF, 538 + .flags = IORESOURCE_MEM, 539 + }, 540 + [1] = { 541 + /* place holder for contiguous memory */ 542 + }, 543 + }; 544 + 545 + static struct platform_device spu0_device = { 546 + .name = "uio_pdrv_genirq", 547 + .id = 4, 548 + .dev = { 549 + .platform_data = &spu0_platform_data, 550 + }, 551 + .resource = spu0_resources, 552 + .num_resources = ARRAY_SIZE(spu0_resources), 553 + .archdata = { 554 + .hwblk_id = HWBLK_SPU, 555 + }, 556 + }; 557 + 558 + /* SPU2DSP1 */ 559 + static struct uio_info spu1_platform_data = { 560 + .name = "SPU2DSP1", 561 + .version = "0", 562 + .irq = 87, 563 + }; 564 + 565 + static struct resource spu1_resources[] = { 566 + [0] = { 567 + .name = "SPU2DSP1", 568 + .start = 0xFE300000, 569 + .end = 0xFE3FFFFF, 570 + .flags = IORESOURCE_MEM, 571 + }, 572 + [1] = { 573 + /* place holder for contiguous memory */ 574 + }, 575 + }; 576 + 577 + static struct platform_device spu1_device = { 578 + .name = "uio_pdrv_genirq", 579 + .id = 5, 580 + .dev = { 581 + .platform_data = &spu1_platform_data, 582 + }, 583 + .resource = spu1_resources, 584 + .num_resources = ARRAY_SIZE(spu1_resources), 585 + .archdata = { 586 + .hwblk_id = HWBLK_SPU, 587 + }, 588 + }; 589 + 528 590 static struct platform_device *sh7724_devices[] __initdata = { 529 591 &cmt_device, 530 592 &tmu0_device, ··· 605 539 &veu0_device, 606 540 &veu1_device, 607 541 &jpu_device, 542 + &spu0_device, 543 + &spu1_device, 608 544 }; 609 545 610 546 static int __init sh7724_devices_setup(void) ··· 615 547 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20); 616 548 platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20); 617 549 platform_resource_setup_memory(&jpu_device, "jpu", 2 << 20); 550 + platform_resource_setup_memory(&spu0_device, "spu0", 2 << 20); 551 + platform_resource_setup_memory(&spu1_device, "spu1", 2 << 20); 618 552 619 553 return platform_add_devices(sh7724_devices, 620 554 ARRAY_SIZE(sh7724_devices)); ··· 897 827 { 898 828 register_intc_controller(&intc_desc); 899 829 } 830 + 831 + static struct { 832 + /* BSC */ 833 + unsigned long mmselr; 834 + unsigned long cs0bcr; 835 + unsigned long cs4bcr; 836 + unsigned long cs5abcr; 837 + unsigned long cs5bbcr; 838 + unsigned long cs6abcr; 839 + unsigned long cs6bbcr; 840 + unsigned long cs4wcr; 841 + unsigned long cs5awcr; 842 + unsigned long cs5bwcr; 843 + unsigned long cs6awcr; 844 + unsigned long cs6bwcr; 845 + /* INTC */ 846 + unsigned short ipra; 847 + unsigned short iprb; 848 + unsigned short iprc; 849 + unsigned short iprd; 850 + unsigned short ipre; 851 + unsigned short iprf; 852 + unsigned short iprg; 853 + unsigned short iprh; 854 + unsigned short ipri; 855 + unsigned short iprj; 856 + unsigned short iprk; 857 + unsigned short iprl; 858 + unsigned char imr0; 859 + unsigned char imr1; 860 + unsigned char imr2; 861 + unsigned char imr3; 862 + unsigned char imr4; 863 + unsigned char imr5; 864 + unsigned char imr6; 865 + unsigned char imr7; 866 + unsigned char imr8; 867 + unsigned char imr9; 868 + unsigned char imr10; 869 + unsigned char imr11; 870 + unsigned char imr12; 871 + /* RWDT */ 872 + unsigned short rwtcnt; 873 + unsigned short rwtcsr; 874 + /* CPG */ 875 + unsigned long irdaclk; 876 + unsigned long spuclk; 877 + } sh7724_rstandby_state; 878 + 879 + static int sh7724_pre_sleep_notifier_call(struct notifier_block *nb, 880 + unsigned long flags, void *unused) 881 + { 882 + if (!(flags & SUSP_SH_RSTANDBY)) 883 + return NOTIFY_DONE; 884 + 885 + /* BCR */ 886 + sh7724_rstandby_state.mmselr = __raw_readl(0xff800020); /* MMSELR */ 887 + sh7724_rstandby_state.mmselr |= 0xa5a50000; 888 + sh7724_rstandby_state.cs0bcr = __raw_readl(0xfec10004); /* CS0BCR */ 889 + sh7724_rstandby_state.cs4bcr = __raw_readl(0xfec10010); /* CS4BCR */ 890 + sh7724_rstandby_state.cs5abcr = __raw_readl(0xfec10014); /* CS5ABCR */ 891 + sh7724_rstandby_state.cs5bbcr = __raw_readl(0xfec10018); /* CS5BBCR */ 892 + sh7724_rstandby_state.cs6abcr = __raw_readl(0xfec1001c); /* CS6ABCR */ 893 + sh7724_rstandby_state.cs6bbcr = __raw_readl(0xfec10020); /* CS6BBCR */ 894 + sh7724_rstandby_state.cs4wcr = __raw_readl(0xfec10030); /* CS4WCR */ 895 + sh7724_rstandby_state.cs5awcr = __raw_readl(0xfec10034); /* CS5AWCR */ 896 + sh7724_rstandby_state.cs5bwcr = __raw_readl(0xfec10038); /* CS5BWCR */ 897 + sh7724_rstandby_state.cs6awcr = __raw_readl(0xfec1003c); /* CS6AWCR */ 898 + sh7724_rstandby_state.cs6bwcr = __raw_readl(0xfec10040); /* CS6BWCR */ 899 + 900 + /* INTC */ 901 + sh7724_rstandby_state.ipra = __raw_readw(0xa4080000); /* IPRA */ 902 + sh7724_rstandby_state.iprb = __raw_readw(0xa4080004); /* IPRB */ 903 + sh7724_rstandby_state.iprc = __raw_readw(0xa4080008); /* IPRC */ 904 + sh7724_rstandby_state.iprd = __raw_readw(0xa408000c); /* IPRD */ 905 + sh7724_rstandby_state.ipre = __raw_readw(0xa4080010); /* IPRE */ 906 + sh7724_rstandby_state.iprf = __raw_readw(0xa4080014); /* IPRF */ 907 + sh7724_rstandby_state.iprg = __raw_readw(0xa4080018); /* IPRG */ 908 + sh7724_rstandby_state.iprh = __raw_readw(0xa408001c); /* IPRH */ 909 + sh7724_rstandby_state.ipri = __raw_readw(0xa4080020); /* IPRI */ 910 + sh7724_rstandby_state.iprj = __raw_readw(0xa4080024); /* IPRJ */ 911 + sh7724_rstandby_state.iprk = __raw_readw(0xa4080028); /* IPRK */ 912 + sh7724_rstandby_state.iprl = __raw_readw(0xa408002c); /* IPRL */ 913 + sh7724_rstandby_state.imr0 = __raw_readb(0xa4080080); /* IMR0 */ 914 + sh7724_rstandby_state.imr1 = __raw_readb(0xa4080084); /* IMR1 */ 915 + sh7724_rstandby_state.imr2 = __raw_readb(0xa4080088); /* IMR2 */ 916 + sh7724_rstandby_state.imr3 = __raw_readb(0xa408008c); /* IMR3 */ 917 + sh7724_rstandby_state.imr4 = __raw_readb(0xa4080090); /* IMR4 */ 918 + sh7724_rstandby_state.imr5 = __raw_readb(0xa4080094); /* IMR5 */ 919 + sh7724_rstandby_state.imr6 = __raw_readb(0xa4080098); /* IMR6 */ 920 + sh7724_rstandby_state.imr7 = __raw_readb(0xa408009c); /* IMR7 */ 921 + sh7724_rstandby_state.imr8 = __raw_readb(0xa40800a0); /* IMR8 */ 922 + sh7724_rstandby_state.imr9 = __raw_readb(0xa40800a4); /* IMR9 */ 923 + sh7724_rstandby_state.imr10 = __raw_readb(0xa40800a8); /* IMR10 */ 924 + sh7724_rstandby_state.imr11 = __raw_readb(0xa40800ac); /* IMR11 */ 925 + sh7724_rstandby_state.imr12 = __raw_readb(0xa40800b0); /* IMR12 */ 926 + 927 + /* RWDT */ 928 + sh7724_rstandby_state.rwtcnt = __raw_readb(0xa4520000); /* RWTCNT */ 929 + sh7724_rstandby_state.rwtcnt |= 0x5a00; 930 + sh7724_rstandby_state.rwtcsr = __raw_readb(0xa4520004); /* RWTCSR */ 931 + sh7724_rstandby_state.rwtcsr |= 0xa500; 932 + __raw_writew(sh7724_rstandby_state.rwtcsr & 0x07, 0xa4520004); 933 + 934 + /* CPG */ 935 + sh7724_rstandby_state.irdaclk = __raw_readl(0xa4150018); /* IRDACLKCR */ 936 + sh7724_rstandby_state.spuclk = __raw_readl(0xa415003c); /* SPUCLKCR */ 937 + 938 + return NOTIFY_DONE; 939 + } 940 + 941 + static int sh7724_post_sleep_notifier_call(struct notifier_block *nb, 942 + unsigned long flags, void *unused) 943 + { 944 + if (!(flags & SUSP_SH_RSTANDBY)) 945 + return NOTIFY_DONE; 946 + 947 + /* BCR */ 948 + __raw_writel(sh7724_rstandby_state.mmselr, 0xff800020); /* MMSELR */ 949 + __raw_writel(sh7724_rstandby_state.cs0bcr, 0xfec10004); /* CS0BCR */ 950 + __raw_writel(sh7724_rstandby_state.cs4bcr, 0xfec10010); /* CS4BCR */ 951 + __raw_writel(sh7724_rstandby_state.cs5abcr, 0xfec10014); /* CS5ABCR */ 952 + __raw_writel(sh7724_rstandby_state.cs5bbcr, 0xfec10018); /* CS5BBCR */ 953 + __raw_writel(sh7724_rstandby_state.cs6abcr, 0xfec1001c); /* CS6ABCR */ 954 + __raw_writel(sh7724_rstandby_state.cs6bbcr, 0xfec10020); /* CS6BBCR */ 955 + __raw_writel(sh7724_rstandby_state.cs4wcr, 0xfec10030); /* CS4WCR */ 956 + __raw_writel(sh7724_rstandby_state.cs5awcr, 0xfec10034); /* CS5AWCR */ 957 + __raw_writel(sh7724_rstandby_state.cs5bwcr, 0xfec10038); /* CS5BWCR */ 958 + __raw_writel(sh7724_rstandby_state.cs6awcr, 0xfec1003c); /* CS6AWCR */ 959 + __raw_writel(sh7724_rstandby_state.cs6bwcr, 0xfec10040); /* CS6BWCR */ 960 + 961 + /* INTC */ 962 + __raw_writew(sh7724_rstandby_state.ipra, 0xa4080000); /* IPRA */ 963 + __raw_writew(sh7724_rstandby_state.iprb, 0xa4080004); /* IPRB */ 964 + __raw_writew(sh7724_rstandby_state.iprc, 0xa4080008); /* IPRC */ 965 + __raw_writew(sh7724_rstandby_state.iprd, 0xa408000c); /* IPRD */ 966 + __raw_writew(sh7724_rstandby_state.ipre, 0xa4080010); /* IPRE */ 967 + __raw_writew(sh7724_rstandby_state.iprf, 0xa4080014); /* IPRF */ 968 + __raw_writew(sh7724_rstandby_state.iprg, 0xa4080018); /* IPRG */ 969 + __raw_writew(sh7724_rstandby_state.iprh, 0xa408001c); /* IPRH */ 970 + __raw_writew(sh7724_rstandby_state.ipri, 0xa4080020); /* IPRI */ 971 + __raw_writew(sh7724_rstandby_state.iprj, 0xa4080024); /* IPRJ */ 972 + __raw_writew(sh7724_rstandby_state.iprk, 0xa4080028); /* IPRK */ 973 + __raw_writew(sh7724_rstandby_state.iprl, 0xa408002c); /* IPRL */ 974 + __raw_writeb(sh7724_rstandby_state.imr0, 0xa4080080); /* IMR0 */ 975 + __raw_writeb(sh7724_rstandby_state.imr1, 0xa4080084); /* IMR1 */ 976 + __raw_writeb(sh7724_rstandby_state.imr2, 0xa4080088); /* IMR2 */ 977 + __raw_writeb(sh7724_rstandby_state.imr3, 0xa408008c); /* IMR3 */ 978 + __raw_writeb(sh7724_rstandby_state.imr4, 0xa4080090); /* IMR4 */ 979 + __raw_writeb(sh7724_rstandby_state.imr5, 0xa4080094); /* IMR5 */ 980 + __raw_writeb(sh7724_rstandby_state.imr6, 0xa4080098); /* IMR6 */ 981 + __raw_writeb(sh7724_rstandby_state.imr7, 0xa408009c); /* IMR7 */ 982 + __raw_writeb(sh7724_rstandby_state.imr8, 0xa40800a0); /* IMR8 */ 983 + __raw_writeb(sh7724_rstandby_state.imr9, 0xa40800a4); /* IMR9 */ 984 + __raw_writeb(sh7724_rstandby_state.imr10, 0xa40800a8); /* IMR10 */ 985 + __raw_writeb(sh7724_rstandby_state.imr11, 0xa40800ac); /* IMR11 */ 986 + __raw_writeb(sh7724_rstandby_state.imr12, 0xa40800b0); /* IMR12 */ 987 + 988 + /* RWDT */ 989 + __raw_writew(sh7724_rstandby_state.rwtcnt, 0xa4520000); /* RWTCNT */ 990 + __raw_writew(sh7724_rstandby_state.rwtcsr, 0xa4520004); /* RWTCSR */ 991 + 992 + /* CPG */ 993 + __raw_writel(sh7724_rstandby_state.irdaclk, 0xa4150018); /* IRDACLKCR */ 994 + __raw_writel(sh7724_rstandby_state.spuclk, 0xa415003c); /* SPUCLKCR */ 995 + 996 + return NOTIFY_DONE; 997 + } 998 + 999 + static struct notifier_block sh7724_pre_sleep_notifier = { 1000 + .notifier_call = sh7724_pre_sleep_notifier_call, 1001 + .priority = SH_MOBILE_PRE(SH_MOBILE_SLEEP_CPU), 1002 + }; 1003 + 1004 + static struct notifier_block sh7724_post_sleep_notifier = { 1005 + .notifier_call = sh7724_post_sleep_notifier_call, 1006 + .priority = SH_MOBILE_POST(SH_MOBILE_SLEEP_CPU), 1007 + }; 1008 + 1009 + static int __init sh7724_sleep_setup(void) 1010 + { 1011 + atomic_notifier_chain_register(&sh_mobile_pre_sleep_notifier_list, 1012 + &sh7724_pre_sleep_notifier); 1013 + 1014 + atomic_notifier_chain_register(&sh_mobile_post_sleep_notifier_list, 1015 + &sh7724_post_sleep_notifier); 1016 + return 0; 1017 + } 1018 + arch_initcall(sh7724_sleep_setup); 1019 +
+27 -18
arch/sh/kernel/cpu/sh4a/setup-shx3.c
··· 15 15 #include <linux/sh_timer.h> 16 16 #include <asm/mmzone.h> 17 17 18 + /* 19 + * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2 20 + * INTEVT values overlap with the FPU EXPEVT ones, requiring special 21 + * demuxing in the exception dispatch path. 22 + * 23 + * As this overlap is something that never should have made it in to 24 + * silicon in the first place, we just refuse to deal with the port at 25 + * all rather than adding infrastructure to hack around it. 26 + */ 18 27 static struct plat_sci_port sci_platform_data[] = { 19 28 { 20 29 .mapbase = 0xffc30000, ··· 35 26 .flags = UPF_BOOT_AUTOCONF, 36 27 .type = PORT_SCIF, 37 28 .irqs = { 44, 45, 47, 46 }, 38 - }, { 39 - .mapbase = 0xffc50000, 40 - .flags = UPF_BOOT_AUTOCONF, 41 - .type = PORT_SCIF, 42 - .irqs = { 48, 49, 51, 50 }, 43 29 }, { 44 30 .mapbase = 0xffc60000, 45 31 .flags = UPF_BOOT_AUTOCONF, ··· 272 268 UNUSED = 0, 273 269 274 270 /* interrupt sources */ 275 - IRL, IRQ0, IRQ1, IRQ2, IRQ3, 271 + IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 272 + IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 273 + IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 274 + IRL_HHLL, IRL_HHLH, IRL_HHHL, 275 + IRQ0, IRQ1, IRQ2, IRQ3, 276 276 HUDII, 277 277 TMU0, TMU1, TMU2, TMU3, TMU4, TMU5, 278 278 PCII0, PCII1, PCII2, PCII3, PCII4, ··· 299 291 INTICI4, INTICI5, INTICI6, INTICI7, 300 292 301 293 /* interrupt groups */ 302 - PCII56789, SCIF0, SCIF1, SCIF2, SCIF3, 294 + IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3, 303 295 DMAC0, DMAC1, 304 296 }; 305 297 ··· 317 309 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), 318 310 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0), 319 311 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0), 320 - INTC_VECT(SCIF2_ERI, 0x800), INTC_VECT(SCIF2_RXI, 0x820), 321 - INTC_VECT(SCIF2_BRI, 0x840), INTC_VECT(SCIF2_TXI, 0x860), 322 312 INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0), 323 313 INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0), 324 314 INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920), ··· 350 344 }; 351 345 352 346 static struct intc_group groups[] __initdata = { 347 + INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 348 + IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 349 + IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 350 + IRL_HHLL, IRL_HHLH, IRL_HHHL), 353 351 INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9), 354 352 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), 355 353 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), 356 - INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI), 357 354 INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI), 358 355 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, 359 356 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), ··· 428 419 429 420 /* External interrupt pins in IRL mode */ 430 421 static struct intc_vect vectors_irl[] __initdata = { 431 - INTC_VECT(IRL, 0x200), INTC_VECT(IRL, 0x220), 432 - INTC_VECT(IRL, 0x240), INTC_VECT(IRL, 0x260), 433 - INTC_VECT(IRL, 0x280), INTC_VECT(IRL, 0x2a0), 434 - INTC_VECT(IRL, 0x2c0), INTC_VECT(IRL, 0x2e0), 435 - INTC_VECT(IRL, 0x300), INTC_VECT(IRL, 0x320), 436 - INTC_VECT(IRL, 0x340), INTC_VECT(IRL, 0x360), 437 - INTC_VECT(IRL, 0x380), INTC_VECT(IRL, 0x3a0), 438 - INTC_VECT(IRL, 0x3c0), 422 + INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), 423 + INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), 424 + INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), 425 + INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0), 426 + INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320), 427 + INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360), 428 + INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0), 429 + INTC_VECT(IRL_HHHL, 0x3c0), 439 430 }; 440 431 441 432 static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
+19 -18
arch/sh/kernel/cpu/sh4a/smp-shx3.c
··· 14 14 #include <linux/interrupt.h> 15 15 #include <linux/io.h> 16 16 17 + #define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12)) 18 + #define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12)) 19 + 20 + #define STBCR_MSTP 0x00000001 21 + #define STBCR_RESET 0x00000002 22 + #define STBCR_LTSLP 0x80000000 23 + 17 24 static irqreturn_t ipi_interrupt_handler(int irq, void *arg) 18 25 { 19 26 unsigned int message = (unsigned int)(long)arg; ··· 28 21 unsigned int offs = 4 * cpu; 29 22 unsigned int x; 30 23 31 - x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */ 24 + x = __raw_readl(0xfe410070 + offs); /* C0INITICI..CnINTICI */ 32 25 x &= (1 << (message << 2)); 33 - ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */ 26 + __raw_writel(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */ 34 27 35 28 smp_message_recv(message); 36 29 ··· 43 36 int i, num; 44 37 45 38 init_cpu_possible(cpumask_of(cpu)); 39 + 40 + /* Enable light sleep for the boot CPU */ 41 + __raw_writel(__raw_readl(STBCR_REG(cpu)) | STBCR_LTSLP, STBCR_REG(cpu)); 46 42 47 43 __cpu_number_map[0] = 0; 48 44 __cpu_logical_map[0] = 0; ··· 76 66 "IPI", (void *)(long)i); 77 67 } 78 68 79 - #define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12)) 80 - #define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12)) 81 - 82 - #define STBCR_MSTP 0x00000001 83 - #define STBCR_RESET 0x00000002 84 - #define STBCR_LTSLP 0x80000000 85 - 86 - #define STBCR_AP_VAL (STBCR_RESET | STBCR_LTSLP) 87 - 88 69 void plat_start_cpu(unsigned int cpu, unsigned long entry_point) 89 70 { 90 - ctrl_outl(entry_point, RESET_REG(cpu)); 71 + __raw_writel(entry_point, RESET_REG(cpu)); 91 72 92 - if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) 93 - ctrl_outl(STBCR_MSTP, STBCR_REG(cpu)); 73 + if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP)) 74 + __raw_writel(STBCR_MSTP, STBCR_REG(cpu)); 94 75 95 - while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) 76 + while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP)) 96 77 cpu_relax(); 97 78 98 79 /* Start up secondary processor by sending a reset */ 99 - ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu)); 80 + __raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu)); 100 81 } 101 82 102 83 int plat_smp_processor_id(void) 103 84 { 104 - return ctrl_inl(0xff000048); /* CPIDR */ 85 + return __raw_readl(0xff000048); /* CPIDR */ 105 86 } 106 87 107 88 void plat_send_ipi(unsigned int cpu, unsigned int message) ··· 101 100 102 101 BUG_ON(cpu >= 4); 103 102 104 - ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ 103 + __raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ 105 104 }
+1 -1
arch/sh/kernel/cpu/sh5/entry.S
··· 933 933 934 934 pta restore_all, tr1 935 935 936 - movi (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8 936 + movi _TIF_SIGPENDING, r8 937 937 and r8, r7, r8 938 938 pta work_notifysig, tr0 939 939 bne r8, ZERO, tr0
+24 -18
arch/sh/kernel/cpu/shmobile/cpuidle.c
··· 87 87 88 88 dev->safe_state = state; 89 89 90 - state = &dev->states[i++]; 91 - snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); 92 - strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN); 93 - state->exit_latency = 100; 94 - state->target_residency = 1 * 2; 95 - state->power_usage = 1; 96 - state->flags = 0; 97 - state->flags |= CPUIDLE_FLAG_TIME_VALID; 98 - state->enter = cpuidle_sleep_enter; 90 + if (sh_mobile_sleep_supported & SUSP_SH_SF) { 91 + state = &dev->states[i++]; 92 + snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); 93 + strncpy(state->desc, "SuperH Sleep Mode [SF]", 94 + CPUIDLE_DESC_LEN); 95 + state->exit_latency = 100; 96 + state->target_residency = 1 * 2; 97 + state->power_usage = 1; 98 + state->flags = 0; 99 + state->flags |= CPUIDLE_FLAG_TIME_VALID; 100 + state->enter = cpuidle_sleep_enter; 101 + } 99 102 100 - state = &dev->states[i++]; 101 - snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); 102 - strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN); 103 - state->exit_latency = 2300; 104 - state->target_residency = 1 * 2; 105 - state->power_usage = 1; 106 - state->flags = 0; 107 - state->flags |= CPUIDLE_FLAG_TIME_VALID; 108 - state->enter = cpuidle_sleep_enter; 103 + if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) { 104 + state = &dev->states[i++]; 105 + snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); 106 + strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", 107 + CPUIDLE_DESC_LEN); 108 + state->exit_latency = 2300; 109 + state->target_residency = 1 * 2; 110 + state->power_usage = 1; 111 + state->flags = 0; 112 + state->flags |= CPUIDLE_FLAG_TIME_VALID; 113 + state->enter = cpuidle_sleep_enter; 114 + } 109 115 110 116 dev->state_count = i; 111 117
+96 -21
arch/sh/kernel/cpu/shmobile/pm.c
··· 15 15 #include <linux/suspend.h> 16 16 #include <asm/suspend.h> 17 17 #include <asm/uaccess.h> 18 + #include <asm/cacheflush.h> 19 + 20 + /* 21 + * Notifier lists for pre/post sleep notification 22 + */ 23 + ATOMIC_NOTIFIER_HEAD(sh_mobile_pre_sleep_notifier_list); 24 + ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list); 18 25 19 26 /* 20 27 * Sleep modes available on SuperH Mobile: ··· 33 26 #define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) 34 27 #define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) 35 28 #define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) 29 + #define SUSP_MODE_RSTANDBY (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF) 30 + /* 31 + * U-standby mode is unsupported since it needs bootloader hacks 32 + */ 36 33 37 - /* 38 - * The following modes are not there yet: 39 - * 40 - * R-standby mode is unsupported, but will be added in the future 41 - * U-standby mode is low priority since it needs bootloader hacks 42 - */ 43 - 44 - #define ILRAM_BASE 0xe5200000 45 - 46 - extern const unsigned char sh_mobile_standby[]; 47 - extern const unsigned int sh_mobile_standby_size; 34 + #ifdef CONFIG_CPU_SUBTYPE_SH7724 35 + #define RAM_BASE 0xfd800000 /* RSMEM */ 36 + #else 37 + #define RAM_BASE 0xe5200000 /* ILRAM */ 38 + #endif 48 39 49 40 void sh_mobile_call_standby(unsigned long mode) 50 41 { 51 - void *onchip_mem = (void *)ILRAM_BASE; 52 - void (*standby_onchip_mem)(unsigned long, unsigned long) = onchip_mem; 42 + void *onchip_mem = (void *)RAM_BASE; 43 + struct sh_sleep_data *sdp = onchip_mem; 44 + void (*standby_onchip_mem)(unsigned long, unsigned long); 45 + 46 + /* code located directly after data structure */ 47 + standby_onchip_mem = (void *)(sdp + 1); 48 + 49 + atomic_notifier_call_chain(&sh_mobile_pre_sleep_notifier_list, 50 + mode, NULL); 51 + 52 + /* flush the caches if MMU flag is set */ 53 + if (mode & SUSP_SH_MMU) 54 + flush_cache_all(); 53 55 54 56 /* Let assembly snippet in on-chip memory handle the rest */ 55 - standby_onchip_mem(mode, ILRAM_BASE); 57 + standby_onchip_mem(mode, RAM_BASE); 58 + 59 + atomic_notifier_call_chain(&sh_mobile_post_sleep_notifier_list, 60 + mode, NULL); 61 + } 62 + 63 + extern char sh_mobile_sleep_enter_start; 64 + extern char sh_mobile_sleep_enter_end; 65 + 66 + extern char sh_mobile_sleep_resume_start; 67 + extern char sh_mobile_sleep_resume_end; 68 + 69 + unsigned long sh_mobile_sleep_supported = SUSP_SH_SLEEP; 70 + 71 + void sh_mobile_register_self_refresh(unsigned long flags, 72 + void *pre_start, void *pre_end, 73 + void *post_start, void *post_end) 74 + { 75 + void *onchip_mem = (void *)RAM_BASE; 76 + void *vp; 77 + struct sh_sleep_data *sdp; 78 + int n; 79 + 80 + /* part 0: data area */ 81 + sdp = onchip_mem; 82 + sdp->addr.stbcr = 0xa4150020; /* STBCR */ 83 + sdp->addr.bar = 0xa4150040; /* BAR */ 84 + sdp->addr.pteh = 0xff000000; /* PTEH */ 85 + sdp->addr.ptel = 0xff000004; /* PTEL */ 86 + sdp->addr.ttb = 0xff000008; /* TTB */ 87 + sdp->addr.tea = 0xff00000c; /* TEA */ 88 + sdp->addr.mmucr = 0xff000010; /* MMUCR */ 89 + sdp->addr.ptea = 0xff000034; /* PTEA */ 90 + sdp->addr.pascr = 0xff000070; /* PASCR */ 91 + sdp->addr.irmcr = 0xff000078; /* IRMCR */ 92 + sdp->addr.ccr = 0xff00001c; /* CCR */ 93 + sdp->addr.ramcr = 0xff000074; /* RAMCR */ 94 + vp = sdp + 1; 95 + 96 + /* part 1: common code to enter sleep mode */ 97 + n = &sh_mobile_sleep_enter_end - &sh_mobile_sleep_enter_start; 98 + memcpy(vp, &sh_mobile_sleep_enter_start, n); 99 + vp += roundup(n, 4); 100 + 101 + /* part 2: board specific code to enter self-refresh mode */ 102 + n = pre_end - pre_start; 103 + memcpy(vp, pre_start, n); 104 + sdp->sf_pre = (unsigned long)vp; 105 + vp += roundup(n, 4); 106 + 107 + /* part 3: board specific code to resume from self-refresh mode */ 108 + n = post_end - post_start; 109 + memcpy(vp, post_start, n); 110 + sdp->sf_post = (unsigned long)vp; 111 + vp += roundup(n, 4); 112 + 113 + /* part 4: common code to resume from sleep mode */ 114 + WARN_ON(vp > (onchip_mem + 0x600)); 115 + vp = onchip_mem + 0x600; /* located at interrupt vector */ 116 + n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start; 117 + memcpy(vp, &sh_mobile_sleep_resume_start, n); 118 + sdp->resume = (unsigned long)vp; 119 + 120 + sh_mobile_sleep_supported |= flags; 56 121 } 57 122 58 123 static int sh_pm_enter(suspend_state_t state) 59 124 { 125 + if (!(sh_mobile_sleep_supported & SUSP_MODE_STANDBY_SF)) 126 + return -ENXIO; 127 + 60 128 local_irq_disable(); 61 129 set_bl_bit(); 62 130 sh_mobile_call_standby(SUSP_MODE_STANDBY_SF); ··· 147 65 148 66 static int __init sh_pm_init(void) 149 67 { 150 - void *onchip_mem = (void *)ILRAM_BASE; 151 - 152 - /* Copy the assembly snippet to the otherwise ununsed ILRAM */ 153 - memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size); 154 - wmb(); 155 - ctrl_barrier(); 156 - 157 68 suspend_set_ops(&sh_pm_ops); 158 69 sh_mobile_setup_cpuidle(); 159 70 return 0;
+11 -6
arch/sh/kernel/cpu/shmobile/pm_runtime.c
··· 45 45 46 46 dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk); 47 47 48 - if (d->driver && d->driver->pm && d->driver->pm->runtime_resume) { 48 + if (d->driver) { 49 49 hwblk_enable(hwblk_info, hwblk); 50 50 ret = 0; 51 51 52 52 if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) { 53 - ret = d->driver->pm->runtime_resume(d); 53 + if (d->driver->pm && d->driver->pm->runtime_resume) 54 + ret = d->driver->pm->runtime_resume(d); 55 + 54 56 if (!ret) 55 57 clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags); 56 58 else ··· 75 73 76 74 dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk); 77 75 78 - if (d->driver && d->driver->pm && d->driver->pm->runtime_suspend) { 76 + if (d->driver) { 79 77 BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags)); 78 + ret = 0; 80 79 81 - hwblk_enable(hwblk_info, hwblk); 82 - ret = d->driver->pm->runtime_suspend(d); 83 - hwblk_disable(hwblk_info, hwblk); 80 + if (d->driver->pm && d->driver->pm->runtime_suspend) { 81 + hwblk_enable(hwblk_info, hwblk); 82 + ret = d->driver->pm->runtime_suspend(d); 83 + hwblk_disable(hwblk_info, hwblk); 84 + } 84 85 85 86 if (!ret) { 86 87 set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
+192 -150
arch/sh/kernel/cpu/shmobile/sleep.S
··· 20 20 * Kernel mode register usage, see entry.S: 21 21 * k0 scratch 22 22 * k1 scratch 23 - * k4 scratch 24 23 */ 25 24 #define k0 r0 26 25 #define k1 r1 27 - #define k4 r4 28 26 29 - /* manage self-refresh and enter standby mode. 27 + /* manage self-refresh and enter standby mode. must be self-contained. 30 28 * this code will be copied to on-chip memory and executed from there. 31 29 */ 30 + .balign 4 31 + ENTRY(sh_mobile_sleep_enter_start) 32 32 33 - .balign 4096,0,4096 34 - ENTRY(sh_mobile_standby) 33 + /* save mode flags */ 34 + mov.l r4, @(SH_SLEEP_MODE, r5) 35 35 36 36 /* save original vbr */ 37 - stc vbr, r1 38 - mova saved_vbr, r0 39 - mov.l r1, @r0 37 + stc vbr, r0 38 + mov.l r0, @(SH_SLEEP_VBR, r5) 40 39 41 40 /* point vbr to our on-chip memory page */ 42 41 ldc r5, vbr 43 42 44 43 /* save return address */ 45 - mova saved_spc, r0 46 - sts pr, r5 47 - mov.l r5, @r0 44 + sts pr, r0 45 + mov.l r0, @(SH_SLEEP_SPC, r5) 48 46 49 47 /* save sr */ 50 - mova saved_sr, r0 51 - stc sr, r5 52 - mov.l r5, @r0 48 + stc sr, r0 49 + mov.l r0, @(SH_SLEEP_SR, r5) 53 50 54 - /* save mode flags */ 55 - mova saved_mode, r0 56 - mov.l r4, @r0 51 + /* save sp */ 52 + mov.l r15, @(SH_SLEEP_SP, r5) 57 53 58 - /* put mode flags in r0 */ 59 - mov r4, r0 54 + /* save stbcr */ 55 + bsr save_register 56 + mov #SH_SLEEP_REG_STBCR, r0 60 57 58 + /* save mmu and cache context if needed */ 59 + mov.l @(SH_SLEEP_MODE, r5), r0 60 + tst #SUSP_SH_MMU, r0 61 + bt skip_mmu_save_disable 62 + 63 + /* save mmu state */ 64 + bsr save_register 65 + mov #SH_SLEEP_REG_PTEH, r0 66 + 67 + bsr save_register 68 + mov #SH_SLEEP_REG_PTEL, r0 69 + 70 + bsr save_register 71 + mov #SH_SLEEP_REG_TTB, r0 72 + 73 + bsr save_register 74 + mov #SH_SLEEP_REG_TEA, r0 75 + 76 + bsr save_register 77 + mov #SH_SLEEP_REG_MMUCR, r0 78 + 79 + bsr save_register 80 + mov #SH_SLEEP_REG_PTEA, r0 81 + 82 + bsr save_register 83 + mov #SH_SLEEP_REG_PASCR, r0 84 + 85 + bsr save_register 86 + mov #SH_SLEEP_REG_IRMCR, r0 87 + 88 + /* invalidate TLBs and disable the MMU */ 89 + bsr get_register 90 + mov #SH_SLEEP_REG_MMUCR, r0 91 + mov #4, r1 92 + mov.l r1, @r0 93 + icbi @r0 94 + 95 + /* save cache registers and disable caches */ 96 + bsr save_register 97 + mov #SH_SLEEP_REG_CCR, r0 98 + 99 + bsr save_register 100 + mov #SH_SLEEP_REG_RAMCR, r0 101 + 102 + bsr get_register 103 + mov #SH_SLEEP_REG_CCR, r0 104 + mov #0, r1 105 + mov.l r1, @r0 106 + icbi @r0 107 + 108 + skip_mmu_save_disable: 109 + /* call self-refresh entering code if needed */ 110 + mov.l @(SH_SLEEP_MODE, r5), r0 61 111 tst #SUSP_SH_SF, r0 62 112 bt skip_set_sf 63 - #ifdef CONFIG_CPU_SUBTYPE_SH7724 64 - /* DBSC: put memory in self-refresh mode */ 65 - mov.l dben_reg, r4 66 - mov.l dben_data0, r1 67 - mov.l r1, @r4 68 113 69 - mov.l dbrfpdn0_reg, r4 70 - mov.l dbrfpdn0_data0, r1 71 - mov.l r1, @r4 72 - 73 - mov.l dbcmdcnt_reg, r4 74 - mov.l dbcmdcnt_data0, r1 75 - mov.l r1, @r4 76 - 77 - mov.l dbcmdcnt_reg, r4 78 - mov.l dbcmdcnt_data1, r1 79 - mov.l r1, @r4 80 - 81 - mov.l dbrfpdn0_reg, r4 82 - mov.l dbrfpdn0_data1, r1 83 - mov.l r1, @r4 84 - #else 85 - /* SBSC: disable power down and put in self-refresh mode */ 86 - mov.l 1f, r4 87 - mov.l 2f, r1 88 - mov.l @r4, r2 89 - or r1, r2 90 - mov.l 3f, r3 91 - and r3, r2 92 - mov.l r2, @r4 93 - #endif 114 + mov.l @(SH_SLEEP_SF_PRE, r5), r0 115 + jsr @r0 116 + nop 94 117 95 118 skip_set_sf: 119 + mov.l @(SH_SLEEP_MODE, r5), r0 96 120 tst #SUSP_SH_STANDBY, r0 97 121 bt test_rstandby 98 122 ··· 127 103 test_rstandby: 128 104 tst #SUSP_SH_RSTANDBY, r0 129 105 bt test_ustandby 106 + 107 + /* setup BAR register */ 108 + bsr get_register 109 + mov #SH_SLEEP_REG_BAR, r0 110 + mov.l @(SH_SLEEP_RESUME, r5), r1 111 + mov.l r1, @r0 130 112 131 113 /* set mode to "r-standby mode" */ 132 114 bra do_sleep ··· 153 123 154 124 do_sleep: 155 125 /* setup and enter selected standby mode */ 156 - mov.l 5f, r4 157 - mov.l r1, @r4 126 + bsr get_register 127 + mov #SH_SLEEP_REG_STBCR, r0 128 + mov.l r1, @r0 158 129 again: 159 130 sleep 160 131 bra again 161 132 nop 162 133 163 - restore_jump_vbr: 134 + save_register: 135 + add #SH_SLEEP_BASE_ADDR, r0 136 + mov.l @(r0, r5), r1 137 + add #-SH_SLEEP_BASE_ADDR, r0 138 + mov.l @r1, r1 139 + add #SH_SLEEP_BASE_DATA, r0 140 + mov.l r1, @(r0, r5) 141 + add #-SH_SLEEP_BASE_DATA, r0 142 + rts 143 + nop 144 + 145 + get_register: 146 + add #SH_SLEEP_BASE_ADDR, r0 147 + mov.l @(r0, r5), r0 148 + rts 149 + nop 150 + ENTRY(sh_mobile_sleep_enter_end) 151 + 152 + .balign 4 153 + ENTRY(sh_mobile_sleep_resume_start) 154 + 155 + /* figure out start address */ 156 + bsr 0f 157 + nop 158 + 0: 159 + sts pr, k1 160 + mov.l 1f, k0 161 + and k0, k1 162 + 163 + /* store pointer to data area in VBR */ 164 + ldc k1, vbr 165 + 166 + /* setup sr with saved sr */ 167 + mov.l @(SH_SLEEP_SR, k1), k0 168 + ldc k0, sr 169 + 170 + /* now: user register set! */ 171 + stc vbr, r5 172 + 164 173 /* setup spc with return address to c code */ 165 - mov.l saved_spc, k0 166 - ldc k0, spc 174 + mov.l @(SH_SLEEP_SPC, r5), r0 175 + ldc r0, spc 167 176 168 177 /* restore vbr */ 169 - mov.l saved_vbr, k0 170 - ldc k0, vbr 178 + mov.l @(SH_SLEEP_VBR, r5), r0 179 + ldc r0, vbr 171 180 172 181 /* setup ssr with saved sr */ 173 - mov.l saved_sr, k0 174 - ldc k0, ssr 182 + mov.l @(SH_SLEEP_SR, r5), r0 183 + ldc r0, ssr 175 184 176 - /* get mode flags */ 177 - mov.l saved_mode, k0 185 + /* restore sp */ 186 + mov.l @(SH_SLEEP_SP, r5), r15 178 187 179 - done_sleep: 180 - /* reset standby mode to sleep mode */ 181 - mov.l 5f, k4 182 - mov #0x00, k1 183 - mov.l k1, @k4 188 + /* restore sleep mode register */ 189 + bsr restore_register 190 + mov #SH_SLEEP_REG_STBCR, r0 184 191 185 - tst #SUSP_SH_SF, k0 192 + /* call self-refresh resume code if needed */ 193 + mov.l @(SH_SLEEP_MODE, r5), r0 194 + tst #SUSP_SH_SF, r0 186 195 bt skip_restore_sf 187 196 188 - #ifdef CONFIG_CPU_SUBTYPE_SH7724 189 - /* DBSC: put memory in auto-refresh mode */ 190 - mov.l dbrfpdn0_reg, k4 191 - mov.l dbrfpdn0_data0, k1 192 - mov.l k1, @k4 197 + mov.l @(SH_SLEEP_SF_POST, r5), r0 198 + jsr @r0 199 + nop 193 200 194 - nop /* sleep 140 ns */ 195 - nop 196 - nop 197 - nop 198 - 199 - mov.l dbcmdcnt_reg, k4 200 - mov.l dbcmdcnt_data0, k1 201 - mov.l k1, @k4 202 - 203 - mov.l dbcmdcnt_reg, k4 204 - mov.l dbcmdcnt_data1, k1 205 - mov.l k1, @k4 206 - 207 - mov.l dben_reg, k4 208 - mov.l dben_data1, k1 209 - mov.l k1, @k4 210 - 211 - mov.l dbrfpdn0_reg, k4 212 - mov.l dbrfpdn0_data2, k1 213 - mov.l k1, @k4 214 - #else 215 - /* SBSC: set auto-refresh mode */ 216 - mov.l 1f, k4 217 - mov.l @k4, k0 218 - mov.l 4f, k1 219 - and k1, k0 220 - mov.l k0, @k4 221 - mov.l 6f, k4 222 - mov.l 8f, k0 223 - mov.l @k4, k1 224 - mov #-1, k4 225 - add k4, k1 226 - or k1, k0 227 - mov.l 7f, k1 228 - mov.l k0, @k1 229 - #endif 230 201 skip_restore_sf: 231 - /* jump to vbr vector */ 232 - mov.l saved_vbr, k0 233 - mov.l offset_vbr, k4 234 - add k4, k0 235 - jmp @k0 202 + /* restore mmu and cache state if needed */ 203 + mov.l @(SH_SLEEP_MODE, r5), r0 204 + tst #SUSP_SH_MMU, r0 205 + bt skip_restore_mmu 206 + 207 + /* restore mmu state */ 208 + bsr restore_register 209 + mov #SH_SLEEP_REG_PTEH, r0 210 + 211 + bsr restore_register 212 + mov #SH_SLEEP_REG_PTEL, r0 213 + 214 + bsr restore_register 215 + mov #SH_SLEEP_REG_TTB, r0 216 + 217 + bsr restore_register 218 + mov #SH_SLEEP_REG_TEA, r0 219 + 220 + bsr restore_register 221 + mov #SH_SLEEP_REG_PTEA, r0 222 + 223 + bsr restore_register 224 + mov #SH_SLEEP_REG_PASCR, r0 225 + 226 + bsr restore_register 227 + mov #SH_SLEEP_REG_IRMCR, r0 228 + 229 + bsr restore_register 230 + mov #SH_SLEEP_REG_MMUCR, r0 231 + icbi @r0 232 + 233 + /* restore cache settings */ 234 + bsr restore_register 235 + mov #SH_SLEEP_REG_RAMCR, r0 236 + icbi @r0 237 + 238 + bsr restore_register 239 + mov #SH_SLEEP_REG_CCR, r0 240 + icbi @r0 241 + 242 + skip_restore_mmu: 243 + rte 244 + nop 245 + 246 + restore_register: 247 + add #SH_SLEEP_BASE_DATA, r0 248 + mov.l @(r0, r5), r1 249 + add #-SH_SLEEP_BASE_DATA, r0 250 + add #SH_SLEEP_BASE_ADDR, r0 251 + mov.l @(r0, r5), r0 252 + mov.l r1, @r0 253 + rts 236 254 nop 237 255 238 256 .balign 4 239 - saved_mode: .long 0 240 - saved_spc: .long 0 241 - saved_sr: .long 0 242 - saved_vbr: .long 0 243 - offset_vbr: .long 0x600 244 - #ifdef CONFIG_CPU_SUBTYPE_SH7724 245 - dben_reg: .long 0xfd000010 /* DBEN */ 246 - dben_data0: .long 0 247 - dben_data1: .long 1 248 - dbrfpdn0_reg: .long 0xfd000040 /* DBRFPDN0 */ 249 - dbrfpdn0_data0: .long 0 250 - dbrfpdn0_data1: .long 1 251 - dbrfpdn0_data2: .long 0x00010000 252 - dbcmdcnt_reg: .long 0xfd000014 /* DBCMDCNT */ 253 - dbcmdcnt_data0: .long 2 254 - dbcmdcnt_data1: .long 4 255 - #else 256 - 1: .long 0xfe400008 /* SDCR0 */ 257 - 2: .long 0x00000400 258 - 3: .long 0xffff7fff 259 - 4: .long 0xfffffbff 260 - #endif 261 - 5: .long 0xa4150020 /* STBCR */ 262 - 6: .long 0xfe40001c /* RTCOR */ 263 - 7: .long 0xfe400018 /* RTCNT */ 264 - 8: .long 0xa55a0000 265 - 266 - 267 - /* interrupt vector @ 0x600 */ 268 - .balign 0x400,0,0x400 269 - .long 0xdeadbeef 270 - .balign 0x200,0,0x200 271 - bra restore_jump_vbr 272 - nop 273 - sh_mobile_standby_end: 274 - 275 - ENTRY(sh_mobile_standby_size) 276 - .long sh_mobile_standby_end - sh_mobile_standby 257 + 1: .long ~0x7ff 258 + ENTRY(sh_mobile_sleep_resume_end)
-59
arch/sh/kernel/cpu/ubc.S
··· 1 - /* 2 - * arch/sh/kernel/cpu/ubc.S 3 - * 4 - * Set of management routines for the User Break Controller (UBC) 5 - * 6 - * Copyright (C) 2002 Paul Mundt 7 - * 8 - * This program is free software; you can redistribute it and/or modify it 9 - * under the terms of the GNU General Public License as published by the 10 - * Free Software Foundation; either version 2 of the License, or (at your 11 - * option) any later version. 12 - */ 13 - #include <linux/linkage.h> 14 - #include <asm/ubc.h> 15 - 16 - #define STBCR2 0xffc00010 17 - 18 - ENTRY(ubc_sleep) 19 - mov #0, r0 20 - 21 - mov.l 1f, r1 ! Zero out UBC_BBRA .. 22 - mov.w r0, @r1 23 - 24 - mov.l 2f, r1 ! .. same for BBRB .. 25 - mov.w r0, @r1 26 - 27 - mov.l 3f, r1 ! .. and again for BRCR. 28 - mov.w r0, @r1 29 - 30 - mov.w @r1, r0 ! Dummy read BRCR 31 - 32 - mov.l 4f, r1 ! Set MSTP5 in STBCR2 33 - mov.b @r1, r0 34 - or #0x01, r0 35 - mov.b r0, @r1 36 - 37 - mov.b @r1, r0 ! Two dummy reads .. 38 - mov.b @r1, r0 39 - 40 - rts 41 - nop 42 - 43 - ENTRY(ubc_wakeup) 44 - mov.l 4f, r1 ! Clear MSTP5 45 - mov.b @r1, r0 46 - and #0xfe, r0 47 - mov.b r0, @r1 48 - 49 - mov.b @r1, r0 ! Two more dummy reads .. 50 - mov.b @r1, r0 51 - 52 - rts 53 - nop 54 - 55 - 1: .long UBC_BBRA 56 - 2: .long UBC_BBRB 57 - 3: .long UBC_BRCR 58 - 4: .long STBCR2 59 -
+82
arch/sh/kernel/dma-nommu.c
··· 1 + /* 2 + * DMA mapping support for platforms lacking IOMMUs. 3 + * 4 + * Copyright (C) 2009 Paul Mundt 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + #include <linux/dma-mapping.h> 11 + #include <linux/io.h> 12 + 13 + static dma_addr_t nommu_map_page(struct device *dev, struct page *page, 14 + unsigned long offset, size_t size, 15 + enum dma_data_direction dir, 16 + struct dma_attrs *attrs) 17 + { 18 + dma_addr_t addr = page_to_phys(page) + offset; 19 + 20 + WARN_ON(size == 0); 21 + dma_cache_sync(dev, page_address(page) + offset, size, dir); 22 + 23 + return addr; 24 + } 25 + 26 + static int nommu_map_sg(struct device *dev, struct scatterlist *sg, 27 + int nents, enum dma_data_direction dir, 28 + struct dma_attrs *attrs) 29 + { 30 + struct scatterlist *s; 31 + int i; 32 + 33 + WARN_ON(nents == 0 || sg[0].length == 0); 34 + 35 + for_each_sg(sg, s, nents, i) { 36 + BUG_ON(!sg_page(s)); 37 + 38 + dma_cache_sync(dev, sg_virt(s), s->length, dir); 39 + 40 + s->dma_address = sg_phys(s); 41 + s->dma_length = s->length; 42 + } 43 + 44 + return nents; 45 + } 46 + 47 + #ifdef CONFIG_DMA_NONCOHERENT 48 + static void nommu_sync_single(struct device *dev, dma_addr_t addr, 49 + size_t size, enum dma_data_direction dir) 50 + { 51 + dma_cache_sync(dev, phys_to_virt(addr), size, dir); 52 + } 53 + 54 + static void nommu_sync_sg(struct device *dev, struct scatterlist *sg, 55 + int nelems, enum dma_data_direction dir) 56 + { 57 + struct scatterlist *s; 58 + int i; 59 + 60 + for_each_sg(sg, s, nelems, i) 61 + dma_cache_sync(dev, sg_virt(s), s->length, dir); 62 + } 63 + #endif 64 + 65 + struct dma_map_ops nommu_dma_ops = { 66 + .alloc_coherent = dma_generic_alloc_coherent, 67 + .free_coherent = dma_generic_free_coherent, 68 + .map_page = nommu_map_page, 69 + .map_sg = nommu_map_sg, 70 + #ifdef CONFIG_DMA_NONCOHERENT 71 + .sync_single_for_device = nommu_sync_single, 72 + .sync_sg_for_device = nommu_sync_sg, 73 + #endif 74 + .is_phys = 1, 75 + }; 76 + 77 + void __init no_iommu_init(void) 78 + { 79 + if (dma_ops) 80 + return; 81 + dma_ops = &nommu_dma_ops; 82 + }
+190 -70
arch/sh/kernel/dwarf.c
··· 20 20 #include <linux/list.h> 21 21 #include <linux/mempool.h> 22 22 #include <linux/mm.h> 23 + #include <linux/elf.h> 23 24 #include <linux/ftrace.h> 24 25 #include <asm/dwarf.h> 25 26 #include <asm/unwinder.h> ··· 531 530 } 532 531 533 532 /** 534 - * dwarf_unwind_stack - recursively unwind the stack 533 + * dwarf_free_frame - free the memory allocated for @frame 534 + * @frame: the frame to free 535 + */ 536 + void dwarf_free_frame(struct dwarf_frame *frame) 537 + { 538 + dwarf_frame_free_regs(frame); 539 + mempool_free(frame, dwarf_frame_pool); 540 + } 541 + 542 + /** 543 + * dwarf_unwind_stack - unwind the stack 544 + * 535 545 * @pc: address of the function to unwind 536 546 * @prev: struct dwarf_frame of the previous stackframe on the callstack 537 547 * ··· 560 548 unsigned long addr; 561 549 562 550 /* 563 - * If this is the first invocation of this recursive function we 564 - * need get the contents of a physical register to get the CFA 565 - * in order to begin the virtual unwinding of the stack. 551 + * If we're starting at the top of the stack we need get the 552 + * contents of a physical register to get the CFA in order to 553 + * begin the virtual unwinding of the stack. 566 554 * 567 555 * NOTE: the return address is guaranteed to be setup by the 568 556 * time this function makes its first function call. ··· 605 593 fde = dwarf_lookup_fde(pc); 606 594 if (!fde) { 607 595 /* 608 - * This is our normal exit path - the one that stops the 609 - * recursion. There's two reasons why we might exit 610 - * here, 596 + * This is our normal exit path. There are two reasons 597 + * why we might exit here, 611 598 * 612 599 * a) pc has no asscociated DWARF frame info and so 613 600 * we don't know how to unwind this frame. This is ··· 648 637 649 638 } else { 650 639 /* 651 - * Again, this is the first invocation of this 652 - * recurisve function. We need to physically 653 - * read the contents of a register in order to 654 - * get the Canonical Frame Address for this 640 + * Again, we're starting from the top of the 641 + * stack. We need to physically read 642 + * the contents of a register in order to get 643 + * the Canonical Frame Address for this 655 644 * function. 656 645 */ 657 646 frame->cfa = dwarf_read_arch_reg(frame->cfa_register); ··· 681 670 return frame; 682 671 683 672 bail: 684 - dwarf_frame_free_regs(frame); 685 - mempool_free(frame, dwarf_frame_pool); 673 + dwarf_free_frame(frame); 686 674 return NULL; 687 675 } 688 676 689 677 static int dwarf_parse_cie(void *entry, void *p, unsigned long len, 690 - unsigned char *end) 678 + unsigned char *end, struct module *mod) 691 679 { 692 680 struct dwarf_cie *cie; 693 681 unsigned long flags; ··· 782 772 cie->initial_instructions = p; 783 773 cie->instructions_end = end; 784 774 775 + cie->mod = mod; 776 + 785 777 /* Add to list */ 786 778 spin_lock_irqsave(&dwarf_cie_lock, flags); 787 779 list_add_tail(&cie->link, &dwarf_cie_list); ··· 794 782 795 783 static int dwarf_parse_fde(void *entry, u32 entry_type, 796 784 void *start, unsigned long len, 797 - unsigned char *end) 785 + unsigned char *end, struct module *mod) 798 786 { 799 787 struct dwarf_fde *fde; 800 788 struct dwarf_cie *cie; ··· 843 831 fde->instructions = p; 844 832 fde->end = end; 845 833 834 + fde->mod = mod; 835 + 846 836 /* Add to list. */ 847 837 spin_lock_irqsave(&dwarf_fde_lock, flags); 848 838 list_add_tail(&fde->link, &dwarf_fde_list); ··· 868 854 while (1) { 869 855 frame = dwarf_unwind_stack(return_addr, _frame); 870 856 871 - if (_frame) { 872 - dwarf_frame_free_regs(_frame); 873 - mempool_free(_frame, dwarf_frame_pool); 874 - } 857 + if (_frame) 858 + dwarf_free_frame(_frame); 875 859 876 860 _frame = frame; 877 861 ··· 879 867 return_addr = frame->return_addr; 880 868 ops->address(data, return_addr, 1); 881 869 } 870 + 871 + if (frame) 872 + dwarf_free_frame(frame); 882 873 } 883 874 884 875 static struct unwinder dwarf_unwinder = { ··· 911 896 } 912 897 913 898 /** 899 + * dwarf_parse_section - parse DWARF section 900 + * @eh_frame_start: start address of the .eh_frame section 901 + * @eh_frame_end: end address of the .eh_frame section 902 + * @mod: the kernel module containing the .eh_frame section 903 + * 904 + * Parse the information in a .eh_frame section. 905 + */ 906 + static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end, 907 + struct module *mod) 908 + { 909 + u32 entry_type; 910 + void *p, *entry; 911 + int count, err = 0; 912 + unsigned long len = 0; 913 + unsigned int c_entries, f_entries; 914 + unsigned char *end; 915 + 916 + c_entries = 0; 917 + f_entries = 0; 918 + entry = eh_frame_start; 919 + 920 + while ((char *)entry < eh_frame_end) { 921 + p = entry; 922 + 923 + count = dwarf_entry_len(p, &len); 924 + if (count == 0) { 925 + /* 926 + * We read a bogus length field value. There is 927 + * nothing we can do here apart from disabling 928 + * the DWARF unwinder. We can't even skip this 929 + * entry and move to the next one because 'len' 930 + * tells us where our next entry is. 931 + */ 932 + err = -EINVAL; 933 + goto out; 934 + } else 935 + p += count; 936 + 937 + /* initial length does not include itself */ 938 + end = p + len; 939 + 940 + entry_type = get_unaligned((u32 *)p); 941 + p += 4; 942 + 943 + if (entry_type == DW_EH_FRAME_CIE) { 944 + err = dwarf_parse_cie(entry, p, len, end, mod); 945 + if (err < 0) 946 + goto out; 947 + else 948 + c_entries++; 949 + } else { 950 + err = dwarf_parse_fde(entry, entry_type, p, len, 951 + end, mod); 952 + if (err < 0) 953 + goto out; 954 + else 955 + f_entries++; 956 + } 957 + 958 + entry = (char *)entry + len + 4; 959 + } 960 + 961 + printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n", 962 + c_entries, f_entries); 963 + 964 + return 0; 965 + 966 + out: 967 + return err; 968 + } 969 + 970 + #ifdef CONFIG_MODULES 971 + int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, 972 + struct module *me) 973 + { 974 + unsigned int i, err; 975 + unsigned long start, end; 976 + char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; 977 + 978 + start = end = 0; 979 + 980 + for (i = 1; i < hdr->e_shnum; i++) { 981 + /* Alloc bit cleared means "ignore it." */ 982 + if ((sechdrs[i].sh_flags & SHF_ALLOC) 983 + && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) { 984 + start = sechdrs[i].sh_addr; 985 + end = start + sechdrs[i].sh_size; 986 + break; 987 + } 988 + } 989 + 990 + /* Did we find the .eh_frame section? */ 991 + if (i != hdr->e_shnum) { 992 + err = dwarf_parse_section((char *)start, (char *)end, me); 993 + if (err) { 994 + printk(KERN_WARNING "%s: failed to parse DWARF info\n", 995 + me->name); 996 + return err; 997 + } 998 + } 999 + 1000 + return 0; 1001 + } 1002 + 1003 + /** 1004 + * module_dwarf_cleanup - remove FDE/CIEs associated with @mod 1005 + * @mod: the module that is being unloaded 1006 + * 1007 + * Remove any FDEs and CIEs from the global lists that came from 1008 + * @mod's .eh_frame section because @mod is being unloaded. 1009 + */ 1010 + void module_dwarf_cleanup(struct module *mod) 1011 + { 1012 + struct dwarf_fde *fde; 1013 + struct dwarf_cie *cie; 1014 + unsigned long flags; 1015 + 1016 + spin_lock_irqsave(&dwarf_cie_lock, flags); 1017 + 1018 + again_cie: 1019 + list_for_each_entry(cie, &dwarf_cie_list, link) { 1020 + if (cie->mod == mod) 1021 + break; 1022 + } 1023 + 1024 + if (&cie->link != &dwarf_cie_list) { 1025 + list_del(&cie->link); 1026 + kfree(cie); 1027 + goto again_cie; 1028 + } 1029 + 1030 + spin_unlock_irqrestore(&dwarf_cie_lock, flags); 1031 + 1032 + spin_lock_irqsave(&dwarf_fde_lock, flags); 1033 + 1034 + again_fde: 1035 + list_for_each_entry(fde, &dwarf_fde_list, link) { 1036 + if (fde->mod == mod) 1037 + break; 1038 + } 1039 + 1040 + if (&fde->link != &dwarf_fde_list) { 1041 + list_del(&fde->link); 1042 + kfree(fde); 1043 + goto again_fde; 1044 + } 1045 + 1046 + spin_unlock_irqrestore(&dwarf_fde_lock, flags); 1047 + } 1048 + #endif /* CONFIG_MODULES */ 1049 + 1050 + /** 914 1051 * dwarf_unwinder_init - initialise the dwarf unwinder 915 1052 * 916 1053 * Build the data structures describing the .dwarf_frame section to ··· 1073 906 */ 1074 907 static int __init dwarf_unwinder_init(void) 1075 908 { 1076 - u32 entry_type; 1077 - void *p, *entry; 1078 - int count, err = 0; 1079 - unsigned long len; 1080 - unsigned int c_entries, f_entries; 1081 - unsigned char *end; 909 + int err; 1082 910 INIT_LIST_HEAD(&dwarf_cie_list); 1083 911 INIT_LIST_HEAD(&dwarf_fde_list); 1084 - 1085 - c_entries = 0; 1086 - f_entries = 0; 1087 - entry = &__start_eh_frame; 1088 912 1089 913 dwarf_frame_cachep = kmem_cache_create("dwarf_frames", 1090 914 sizeof(struct dwarf_frame), 0, ··· 1095 937 mempool_free_slab, 1096 938 dwarf_reg_cachep); 1097 939 1098 - while ((char *)entry < __stop_eh_frame) { 1099 - p = entry; 1100 - 1101 - count = dwarf_entry_len(p, &len); 1102 - if (count == 0) { 1103 - /* 1104 - * We read a bogus length field value. There is 1105 - * nothing we can do here apart from disabling 1106 - * the DWARF unwinder. We can't even skip this 1107 - * entry and move to the next one because 'len' 1108 - * tells us where our next entry is. 1109 - */ 1110 - goto out; 1111 - } else 1112 - p += count; 1113 - 1114 - /* initial length does not include itself */ 1115 - end = p + len; 1116 - 1117 - entry_type = get_unaligned((u32 *)p); 1118 - p += 4; 1119 - 1120 - if (entry_type == DW_EH_FRAME_CIE) { 1121 - err = dwarf_parse_cie(entry, p, len, end); 1122 - if (err < 0) 1123 - goto out; 1124 - else 1125 - c_entries++; 1126 - } else { 1127 - err = dwarf_parse_fde(entry, entry_type, p, len, end); 1128 - if (err < 0) 1129 - goto out; 1130 - else 1131 - f_entries++; 1132 - } 1133 - 1134 - entry = (char *)entry + len + 4; 1135 - } 1136 - 1137 - printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n", 1138 - c_entries, f_entries); 940 + err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL); 941 + if (err) 942 + goto out; 1139 943 1140 944 err = unwinder_register(&dwarf_unwinder); 1141 945 if (err)
+1 -1
arch/sh/kernel/entry-common.S
··· 133 133 ! r8: current_thread_info 134 134 ! t: result of "tst #_TIF_NEED_RESCHED, r0" 135 135 bf/s work_resched 136 - tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 136 + tst #_TIF_SIGPENDING, r0 137 137 work_notifysig: 138 138 bt/s __restore_all 139 139 mov r15, r4
+145 -1
arch/sh/kernel/ftrace.c
··· 62 62 return ftrace_replaced_code; 63 63 } 64 64 65 + /* 66 + * Modifying code must take extra care. On an SMP machine, if 67 + * the code being modified is also being executed on another CPU 68 + * that CPU will have undefined results and possibly take a GPF. 69 + * We use kstop_machine to stop other CPUS from exectuing code. 70 + * But this does not stop NMIs from happening. We still need 71 + * to protect against that. We separate out the modification of 72 + * the code to take care of this. 73 + * 74 + * Two buffers are added: An IP buffer and a "code" buffer. 75 + * 76 + * 1) Put the instruction pointer into the IP buffer 77 + * and the new code into the "code" buffer. 78 + * 2) Wait for any running NMIs to finish and set a flag that says 79 + * we are modifying code, it is done in an atomic operation. 80 + * 3) Write the code 81 + * 4) clear the flag. 82 + * 5) Wait for any running NMIs to finish. 83 + * 84 + * If an NMI is executed, the first thing it does is to call 85 + * "ftrace_nmi_enter". This will check if the flag is set to write 86 + * and if it is, it will write what is in the IP and "code" buffers. 87 + * 88 + * The trick is, it does not matter if everyone is writing the same 89 + * content to the code location. Also, if a CPU is executing code 90 + * it is OK to write to that code location if the contents being written 91 + * are the same as what exists. 92 + */ 93 + #define MOD_CODE_WRITE_FLAG (1 << 31) /* set when NMI should do the write */ 94 + static atomic_t nmi_running = ATOMIC_INIT(0); 95 + static int mod_code_status; /* holds return value of text write */ 96 + static void *mod_code_ip; /* holds the IP to write to */ 97 + static void *mod_code_newcode; /* holds the text to write to the IP */ 98 + 99 + static unsigned nmi_wait_count; 100 + static atomic_t nmi_update_count = ATOMIC_INIT(0); 101 + 102 + int ftrace_arch_read_dyn_info(char *buf, int size) 103 + { 104 + int r; 105 + 106 + r = snprintf(buf, size, "%u %u", 107 + nmi_wait_count, 108 + atomic_read(&nmi_update_count)); 109 + return r; 110 + } 111 + 112 + static void clear_mod_flag(void) 113 + { 114 + int old = atomic_read(&nmi_running); 115 + 116 + for (;;) { 117 + int new = old & ~MOD_CODE_WRITE_FLAG; 118 + 119 + if (old == new) 120 + break; 121 + 122 + old = atomic_cmpxchg(&nmi_running, old, new); 123 + } 124 + } 125 + 126 + static void ftrace_mod_code(void) 127 + { 128 + /* 129 + * Yes, more than one CPU process can be writing to mod_code_status. 130 + * (and the code itself) 131 + * But if one were to fail, then they all should, and if one were 132 + * to succeed, then they all should. 133 + */ 134 + mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode, 135 + MCOUNT_INSN_SIZE); 136 + 137 + /* if we fail, then kill any new writers */ 138 + if (mod_code_status) 139 + clear_mod_flag(); 140 + } 141 + 142 + void ftrace_nmi_enter(void) 143 + { 144 + if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) { 145 + smp_rmb(); 146 + ftrace_mod_code(); 147 + atomic_inc(&nmi_update_count); 148 + } 149 + /* Must have previous changes seen before executions */ 150 + smp_mb(); 151 + } 152 + 153 + void ftrace_nmi_exit(void) 154 + { 155 + /* Finish all executions before clearing nmi_running */ 156 + smp_mb(); 157 + atomic_dec(&nmi_running); 158 + } 159 + 160 + static void wait_for_nmi_and_set_mod_flag(void) 161 + { 162 + if (!atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG)) 163 + return; 164 + 165 + do { 166 + cpu_relax(); 167 + } while (atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG)); 168 + 169 + nmi_wait_count++; 170 + } 171 + 172 + static void wait_for_nmi(void) 173 + { 174 + if (!atomic_read(&nmi_running)) 175 + return; 176 + 177 + do { 178 + cpu_relax(); 179 + } while (atomic_read(&nmi_running)); 180 + 181 + nmi_wait_count++; 182 + } 183 + 184 + static int 185 + do_ftrace_mod_code(unsigned long ip, void *new_code) 186 + { 187 + mod_code_ip = (void *)ip; 188 + mod_code_newcode = new_code; 189 + 190 + /* The buffers need to be visible before we let NMIs write them */ 191 + smp_mb(); 192 + 193 + wait_for_nmi_and_set_mod_flag(); 194 + 195 + /* Make sure all running NMIs have finished before we write the code */ 196 + smp_mb(); 197 + 198 + ftrace_mod_code(); 199 + 200 + /* Make sure the write happens before clearing the bit */ 201 + smp_mb(); 202 + 203 + clear_mod_flag(); 204 + wait_for_nmi(); 205 + 206 + return mod_code_status; 207 + } 208 + 65 209 static int ftrace_modify_code(unsigned long ip, unsigned char *old_code, 66 210 unsigned char *new_code) 67 211 { ··· 230 86 return -EINVAL; 231 87 232 88 /* replace the text with the new text */ 233 - if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE)) 89 + if (do_ftrace_mod_code(ip, new_code)) 234 90 return -EPERM; 235 91 236 92 flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
+18 -25
arch/sh/kernel/gpio.c drivers/sh/pfc.c
··· 7 7 * License. See the file "COPYING" in the main directory of this archive 8 8 * for more details. 9 9 */ 10 - 11 10 #include <linux/errno.h> 12 11 #include <linux/kernel.h> 13 12 #include <linux/list.h> ··· 34 35 { 35 36 switch (reg_width) { 36 37 case 8: 37 - return ctrl_inb(reg); 38 + return __raw_readb(reg); 38 39 case 16: 39 - return ctrl_inw(reg); 40 + return __raw_readw(reg); 40 41 case 32: 41 - return ctrl_inl(reg); 42 + return __raw_readl(reg); 42 43 } 43 44 44 45 BUG(); ··· 51 52 { 52 53 switch (reg_width) { 53 54 case 8: 54 - ctrl_outb(data, reg); 55 + __raw_writeb(data, reg); 55 56 return; 56 57 case 16: 57 - ctrl_outw(data, reg); 58 + __raw_writew(data, reg); 58 59 return; 59 60 case 32: 60 - ctrl_outl(data, reg); 61 + __raw_writel(data, reg); 61 62 return; 62 63 } 63 64 ··· 71 72 72 73 pos = dr->reg_width - (in_pos + 1); 73 74 74 - #ifdef DEBUG 75 - pr_info("write_bit addr = %lx, value = %ld, pos = %ld, " 76 - "r_width = %ld\n", 77 - dr->reg, !!value, pos, dr->reg_width); 78 - #endif 75 + pr_debug("write_bit addr = %lx, value = %ld, pos = %ld, " 76 + "r_width = %ld\n", 77 + dr->reg, !!value, pos, dr->reg_width); 79 78 80 79 if (value) 81 80 set_bit(pos, &dr->reg_shadow); ··· 92 95 mask = (1 << field_width) - 1; 93 96 pos = reg_width - ((in_pos + 1) * field_width); 94 97 95 - #ifdef DEBUG 96 - pr_info("read_reg: addr = %lx, pos = %ld, " 97 - "r_width = %ld, f_width = %ld\n", 98 - reg, pos, reg_width, field_width); 99 - #endif 98 + pr_debug("read_reg: addr = %lx, pos = %ld, " 99 + "r_width = %ld, f_width = %ld\n", 100 + reg, pos, reg_width, field_width); 100 101 101 102 data = gpio_read_raw_reg(reg, reg_width); 102 103 return (data >> pos) & mask; ··· 109 114 mask = (1 << field_width) - 1; 110 115 pos = reg_width - ((in_pos + 1) * field_width); 111 116 112 - #ifdef DEBUG 113 - pr_info("write_reg addr = %lx, value = %ld, pos = %ld, " 114 - "r_width = %ld, f_width = %ld\n", 115 - reg, value, pos, reg_width, field_width); 116 - #endif 117 + pr_debug("write_reg addr = %lx, value = %ld, pos = %ld, " 118 + "r_width = %ld, f_width = %ld\n", 119 + reg, value, pos, reg_width, field_width); 117 120 118 121 mask = ~(mask << pos); 119 122 value = value << pos; 120 123 121 124 switch (reg_width) { 122 125 case 8: 123 - ctrl_outb((ctrl_inb(reg) & mask) | value, reg); 126 + __raw_writeb((__raw_readb(reg) & mask) | value, reg); 124 127 break; 125 128 case 16: 126 - ctrl_outw((ctrl_inw(reg) & mask) | value, reg); 129 + __raw_writew((__raw_readw(reg) & mask) | value, reg); 127 130 break; 128 131 case 32: 129 - ctrl_outl((ctrl_inl(reg) & mask) | value, reg); 132 + __raw_writel((__raw_readl(reg) & mask) | value, reg); 130 133 break; 131 134 } 132 135 }
+1 -1
arch/sh/kernel/head_32.S
··· 33 33 .long 1 /* LOADER_TYPE */ 34 34 .long 0x00000000 /* INITRD_START */ 35 35 .long 0x00000000 /* INITRD_SIZE */ 36 - #ifdef CONFIG_32BIT 36 + #if defined(CONFIG_32BIT) && defined(CONFIG_PMB_FIXED) 37 37 .long 0x53453f00 + 32 /* "SE?" = 32 bit */ 38 38 #else 39 39 .long 0x53453f00 + 29 /* "SE?" = 29 bit */
+70 -26
arch/sh/kernel/idle.c
··· 21 21 #include <asm/atomic.h> 22 22 23 23 static int hlt_counter; 24 - void (*pm_idle)(void); 24 + void (*pm_idle)(void) = NULL; 25 25 void (*pm_power_off)(void); 26 26 EXPORT_SYMBOL(pm_power_off); 27 27 ··· 39 39 } 40 40 __setup("hlt", hlt_setup); 41 41 42 - void default_idle(void) 42 + static inline int hlt_works(void) 43 43 { 44 - if (!hlt_counter) { 45 - clear_thread_flag(TIF_POLLING_NRFLAG); 46 - smp_mb__after_clear_bit(); 47 - set_bl_bit(); 48 - stop_critical_timings(); 49 - 50 - while (!need_resched()) 51 - cpu_sleep(); 52 - 53 - start_critical_timings(); 54 - clear_bl_bit(); 55 - set_thread_flag(TIF_POLLING_NRFLAG); 56 - } else 57 - while (!need_resched()) 58 - cpu_relax(); 44 + return !hlt_counter; 59 45 } 60 46 47 + /* 48 + * On SMP it's slightly faster (but much more power-consuming!) 49 + * to poll the ->work.need_resched flag instead of waiting for the 50 + * cross-CPU IPI to arrive. Use this option with caution. 51 + */ 52 + static void poll_idle(void) 53 + { 54 + local_irq_enable(); 55 + while (!need_resched()) 56 + cpu_relax(); 57 + } 58 + 59 + void default_idle(void) 60 + { 61 + if (hlt_works()) { 62 + clear_thread_flag(TIF_POLLING_NRFLAG); 63 + smp_mb__after_clear_bit(); 64 + 65 + if (!need_resched()) { 66 + local_irq_enable(); 67 + cpu_sleep(); 68 + } else 69 + local_irq_enable(); 70 + 71 + set_thread_flag(TIF_POLLING_NRFLAG); 72 + } else 73 + poll_idle(); 74 + } 75 + 76 + /* 77 + * The idle thread. There's no useful work to be done, so just try to conserve 78 + * power and have a low exit latency (ie sit in a loop waiting for somebody to 79 + * say that they'd like to reschedule) 80 + */ 61 81 void cpu_idle(void) 62 82 { 83 + unsigned int cpu = smp_processor_id(); 84 + 63 85 set_thread_flag(TIF_POLLING_NRFLAG); 64 86 65 87 /* endless idle loop with no priority at all */ 66 88 while (1) { 67 - void (*idle)(void) = pm_idle; 68 - 69 - if (!idle) 70 - idle = default_idle; 71 - 72 89 tick_nohz_stop_sched_tick(1); 73 - while (!need_resched()) 74 - idle(); 75 - tick_nohz_restart_sched_tick(); 76 90 91 + while (!need_resched() && cpu_online(cpu)) { 92 + check_pgt_cache(); 93 + rmb(); 94 + 95 + local_irq_disable(); 96 + /* Don't trace irqs off for idle */ 97 + stop_critical_timings(); 98 + pm_idle(); 99 + /* 100 + * Sanity check to ensure that pm_idle() returns 101 + * with IRQs enabled 102 + */ 103 + WARN_ON(irqs_disabled()); 104 + start_critical_timings(); 105 + } 106 + 107 + tick_nohz_restart_sched_tick(); 77 108 preempt_enable_no_resched(); 78 109 schedule(); 79 110 preempt_disable(); 80 - check_pgt_cache(); 81 111 } 112 + } 113 + 114 + void __cpuinit select_idle_routine(void) 115 + { 116 + /* 117 + * If a platform has set its own idle routine, leave it alone. 118 + */ 119 + if (pm_idle) 120 + return; 121 + 122 + if (hlt_works()) 123 + pm_idle = default_idle; 124 + else 125 + pm_idle = poll_idle; 82 126 } 83 127 84 128 static void do_nothing(void *unused)
+3 -1
arch/sh/kernel/io_generic.c
··· 24 24 #define dummy_read() 25 25 #endif 26 26 27 - unsigned long generic_io_base; 27 + unsigned long generic_io_base = 0; 28 28 29 29 u8 generic_inb(unsigned long port) 30 30 { ··· 147 147 148 148 void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) 149 149 { 150 + #ifdef P1SEG 150 151 if (PXSEG(addr) >= P1SEG) 151 152 return (void __iomem *)addr; 153 + #endif 152 154 153 155 return (void __iomem *)(addr + generic_io_base); 154 156 }
+14
arch/sh/kernel/irq.c
··· 37 37 */ 38 38 static int show_other_interrupts(struct seq_file *p, int prec) 39 39 { 40 + int j; 41 + 42 + seq_printf(p, "%*s: ", prec, "NMI"); 43 + for_each_online_cpu(j) 44 + seq_printf(p, "%10u ", irq_stat[j].__nmi_count); 45 + seq_printf(p, " Non-maskable interrupts\n"); 46 + 40 47 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); 48 + 41 49 return 0; 42 50 } 43 51 ··· 262 254 void __init init_IRQ(void) 263 255 { 264 256 plat_irq_setup(); 257 + 258 + /* 259 + * Pin any of the legacy IRQ vectors that haven't already been 260 + * grabbed by the platform 261 + */ 262 + reserve_irq_legacy(); 265 263 266 264 /* Perform the machine specific initialisation */ 267 265 if (sh_mv.mv_init_irq)
+57
arch/sh/kernel/irq_32.c
··· 1 + /* 2 + * SHcompact irqflags support 3 + * 4 + * Copyright (C) 2006 - 2009 Paul Mundt 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + #include <linux/irqflags.h> 11 + #include <linux/module.h> 12 + 13 + void notrace raw_local_irq_restore(unsigned long flags) 14 + { 15 + unsigned long __dummy0, __dummy1; 16 + 17 + if (flags == RAW_IRQ_DISABLED) { 18 + __asm__ __volatile__ ( 19 + "stc sr, %0\n\t" 20 + "or #0xf0, %0\n\t" 21 + "ldc %0, sr\n\t" 22 + : "=&z" (__dummy0) 23 + : /* no inputs */ 24 + : "memory" 25 + ); 26 + } else { 27 + __asm__ __volatile__ ( 28 + "stc sr, %0\n\t" 29 + "and %1, %0\n\t" 30 + #ifdef CONFIG_CPU_HAS_SR_RB 31 + "stc r6_bank, %1\n\t" 32 + "or %1, %0\n\t" 33 + #endif 34 + "ldc %0, sr\n\t" 35 + : "=&r" (__dummy0), "=r" (__dummy1) 36 + : "1" (~RAW_IRQ_DISABLED) 37 + : "memory" 38 + ); 39 + } 40 + } 41 + EXPORT_SYMBOL(raw_local_irq_restore); 42 + 43 + unsigned long notrace __raw_local_save_flags(void) 44 + { 45 + unsigned long flags; 46 + 47 + __asm__ __volatile__ ( 48 + "stc sr, %0\n\t" 49 + "and #0xf0, %0\n\t" 50 + : "=&z" (flags) 51 + : /* no inputs */ 52 + : "memory" 53 + ); 54 + 55 + return flags; 56 + } 57 + EXPORT_SYMBOL(__raw_local_save_flags);
+51
arch/sh/kernel/irq_64.c
··· 1 + /* 2 + * SHmedia irqflags support 3 + * 4 + * Copyright (C) 2006 - 2009 Paul Mundt 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + #include <linux/irqflags.h> 11 + #include <linux/module.h> 12 + #include <cpu/registers.h> 13 + 14 + void notrace raw_local_irq_restore(unsigned long flags) 15 + { 16 + unsigned long long __dummy; 17 + 18 + if (flags == RAW_IRQ_DISABLED) { 19 + __asm__ __volatile__ ( 20 + "getcon " __SR ", %0\n\t" 21 + "or %0, %1, %0\n\t" 22 + "putcon %0, " __SR "\n\t" 23 + : "=&r" (__dummy) 24 + : "r" (RAW_IRQ_DISABLED) 25 + ); 26 + } else { 27 + __asm__ __volatile__ ( 28 + "getcon " __SR ", %0\n\t" 29 + "and %0, %1, %0\n\t" 30 + "putcon %0, " __SR "\n\t" 31 + : "=&r" (__dummy) 32 + : "r" (~RAW_IRQ_DISABLED) 33 + ); 34 + } 35 + } 36 + EXPORT_SYMBOL(raw_local_irq_restore); 37 + 38 + unsigned long notrace __raw_local_save_flags(void) 39 + { 40 + unsigned long flags; 41 + 42 + __asm__ __volatile__ ( 43 + "getcon " __SR ", %0\n\t" 44 + "and %0, %1, %0" 45 + : "=&r" (flags) 46 + : "r" (RAW_IRQ_DISABLED) 47 + ); 48 + 49 + return flags; 50 + } 51 + EXPORT_SYMBOL(__raw_local_save_flags);
-6
arch/sh/kernel/machine_kexec.c
··· 46 46 */ 47 47 int machine_kexec_prepare(struct kimage *image) 48 48 { 49 - /* older versions of kexec-tools are passing 50 - * the zImage entry point as a virtual address. 51 - */ 52 - if (image->start != PHYSADDR(image->start)) 53 - return -EINVAL; /* upgrade your kexec-tools */ 54 - 55 49 return 0; 56 50 } 57 51
+4
arch/sh/kernel/machvec.c
··· 135 135 if (!sh_mv.mv_nr_irqs) 136 136 sh_mv.mv_nr_irqs = NR_IRQS; 137 137 138 + #ifdef P2SEG 138 139 __set_io_port_base(P2SEG); 140 + #else 141 + __set_io_port_base(0); 142 + #endif 139 143 }
+8 -1
arch/sh/kernel/module.c
··· 32 32 #include <linux/string.h> 33 33 #include <linux/kernel.h> 34 34 #include <asm/unaligned.h> 35 + #include <asm/dwarf.h> 35 36 36 37 void *module_alloc(unsigned long size) 37 38 { ··· 146 145 const Elf_Shdr *sechdrs, 147 146 struct module *me) 148 147 { 149 - return module_bug_finalize(hdr, sechdrs, me); 148 + int ret = 0; 149 + 150 + ret |= module_dwarf_finalize(hdr, sechdrs, me); 151 + ret |= module_bug_finalize(hdr, sechdrs, me); 152 + 153 + return ret; 150 154 } 151 155 152 156 void module_arch_cleanup(struct module *mod) 153 157 { 154 158 module_bug_cleanup(mod); 159 + module_dwarf_cleanup(mod); 155 160 }
+98
arch/sh/kernel/perf_callchain.c
··· 1 + /* 2 + * Performance event callchain support - SuperH architecture code 3 + * 4 + * Copyright (C) 2009 Paul Mundt 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + #include <linux/kernel.h> 11 + #include <linux/sched.h> 12 + #include <linux/perf_event.h> 13 + #include <linux/percpu.h> 14 + #include <asm/unwinder.h> 15 + #include <asm/ptrace.h> 16 + 17 + static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip) 18 + { 19 + if (entry->nr < PERF_MAX_STACK_DEPTH) 20 + entry->ip[entry->nr++] = ip; 21 + } 22 + 23 + static void callchain_warning(void *data, char *msg) 24 + { 25 + } 26 + 27 + static void 28 + callchain_warning_symbol(void *data, char *msg, unsigned long symbol) 29 + { 30 + } 31 + 32 + static int callchain_stack(void *data, char *name) 33 + { 34 + return 0; 35 + } 36 + 37 + static void callchain_address(void *data, unsigned long addr, int reliable) 38 + { 39 + struct perf_callchain_entry *entry = data; 40 + 41 + if (reliable) 42 + callchain_store(entry, addr); 43 + } 44 + 45 + static const struct stacktrace_ops callchain_ops = { 46 + .warning = callchain_warning, 47 + .warning_symbol = callchain_warning_symbol, 48 + .stack = callchain_stack, 49 + .address = callchain_address, 50 + }; 51 + 52 + static void 53 + perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) 54 + { 55 + callchain_store(entry, PERF_CONTEXT_KERNEL); 56 + callchain_store(entry, regs->pc); 57 + 58 + unwind_stack(NULL, regs, NULL, &callchain_ops, entry); 59 + } 60 + 61 + static void 62 + perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry) 63 + { 64 + int is_user; 65 + 66 + if (!regs) 67 + return; 68 + 69 + is_user = user_mode(regs); 70 + 71 + if (!current || current->pid == 0) 72 + return; 73 + 74 + if (is_user && current->state != TASK_RUNNING) 75 + return; 76 + 77 + /* 78 + * Only the kernel side is implemented for now. 79 + */ 80 + if (!is_user) 81 + perf_callchain_kernel(regs, entry); 82 + } 83 + 84 + /* 85 + * No need for separate IRQ and NMI entries. 86 + */ 87 + static DEFINE_PER_CPU(struct perf_callchain_entry, callchain); 88 + 89 + struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) 90 + { 91 + struct perf_callchain_entry *entry = &__get_cpu_var(callchain); 92 + 93 + entry->nr = 0; 94 + 95 + perf_do_callchain(regs, entry); 96 + 97 + return entry; 98 + }
+312
arch/sh/kernel/perf_event.c
··· 1 + /* 2 + * Performance event support framework for SuperH hardware counters. 3 + * 4 + * Copyright (C) 2009 Paul Mundt 5 + * 6 + * Heavily based on the x86 and PowerPC implementations. 7 + * 8 + * x86: 9 + * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de> 10 + * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar 11 + * Copyright (C) 2009 Jaswinder Singh Rajput 12 + * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter 13 + * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> 14 + * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com> 15 + * 16 + * ppc: 17 + * Copyright 2008-2009 Paul Mackerras, IBM Corporation. 18 + * 19 + * This file is subject to the terms and conditions of the GNU General Public 20 + * License. See the file "COPYING" in the main directory of this archive 21 + * for more details. 22 + */ 23 + #include <linux/kernel.h> 24 + #include <linux/init.h> 25 + #include <linux/io.h> 26 + #include <linux/irq.h> 27 + #include <linux/perf_event.h> 28 + #include <asm/processor.h> 29 + 30 + struct cpu_hw_events { 31 + struct perf_event *events[MAX_HWEVENTS]; 32 + unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; 33 + unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; 34 + }; 35 + 36 + DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); 37 + 38 + static struct sh_pmu *sh_pmu __read_mostly; 39 + 40 + /* Number of perf_events counting hardware events */ 41 + static atomic_t num_events; 42 + /* Used to avoid races in calling reserve/release_pmc_hardware */ 43 + static DEFINE_MUTEX(pmc_reserve_mutex); 44 + 45 + /* 46 + * Stub these out for now, do something more profound later. 47 + */ 48 + int reserve_pmc_hardware(void) 49 + { 50 + return 0; 51 + } 52 + 53 + void release_pmc_hardware(void) 54 + { 55 + } 56 + 57 + static inline int sh_pmu_initialized(void) 58 + { 59 + return !!sh_pmu; 60 + } 61 + 62 + /* 63 + * Release the PMU if this is the last perf_event. 64 + */ 65 + static void hw_perf_event_destroy(struct perf_event *event) 66 + { 67 + if (!atomic_add_unless(&num_events, -1, 1)) { 68 + mutex_lock(&pmc_reserve_mutex); 69 + if (atomic_dec_return(&num_events) == 0) 70 + release_pmc_hardware(); 71 + mutex_unlock(&pmc_reserve_mutex); 72 + } 73 + } 74 + 75 + static int hw_perf_cache_event(int config, int *evp) 76 + { 77 + unsigned long type, op, result; 78 + int ev; 79 + 80 + if (!sh_pmu->cache_events) 81 + return -EINVAL; 82 + 83 + /* unpack config */ 84 + type = config & 0xff; 85 + op = (config >> 8) & 0xff; 86 + result = (config >> 16) & 0xff; 87 + 88 + if (type >= PERF_COUNT_HW_CACHE_MAX || 89 + op >= PERF_COUNT_HW_CACHE_OP_MAX || 90 + result >= PERF_COUNT_HW_CACHE_RESULT_MAX) 91 + return -EINVAL; 92 + 93 + ev = (*sh_pmu->cache_events)[type][op][result]; 94 + if (ev == 0) 95 + return -EOPNOTSUPP; 96 + if (ev == -1) 97 + return -EINVAL; 98 + *evp = ev; 99 + return 0; 100 + } 101 + 102 + static int __hw_perf_event_init(struct perf_event *event) 103 + { 104 + struct perf_event_attr *attr = &event->attr; 105 + struct hw_perf_event *hwc = &event->hw; 106 + int config = -1; 107 + int err; 108 + 109 + if (!sh_pmu_initialized()) 110 + return -ENODEV; 111 + 112 + /* 113 + * All of the on-chip counters are "limited", in that they have 114 + * no interrupts, and are therefore unable to do sampling without 115 + * further work and timer assistance. 116 + */ 117 + if (hwc->sample_period) 118 + return -EINVAL; 119 + 120 + /* 121 + * See if we need to reserve the counter. 122 + * 123 + * If no events are currently in use, then we have to take a 124 + * mutex to ensure that we don't race with another task doing 125 + * reserve_pmc_hardware or release_pmc_hardware. 126 + */ 127 + err = 0; 128 + if (!atomic_inc_not_zero(&num_events)) { 129 + mutex_lock(&pmc_reserve_mutex); 130 + if (atomic_read(&num_events) == 0 && 131 + reserve_pmc_hardware()) 132 + err = -EBUSY; 133 + else 134 + atomic_inc(&num_events); 135 + mutex_unlock(&pmc_reserve_mutex); 136 + } 137 + 138 + if (err) 139 + return err; 140 + 141 + event->destroy = hw_perf_event_destroy; 142 + 143 + switch (attr->type) { 144 + case PERF_TYPE_RAW: 145 + config = attr->config & sh_pmu->raw_event_mask; 146 + break; 147 + case PERF_TYPE_HW_CACHE: 148 + err = hw_perf_cache_event(attr->config, &config); 149 + if (err) 150 + return err; 151 + break; 152 + case PERF_TYPE_HARDWARE: 153 + if (attr->config >= sh_pmu->max_events) 154 + return -EINVAL; 155 + 156 + config = sh_pmu->event_map(attr->config); 157 + break; 158 + } 159 + 160 + if (config == -1) 161 + return -EINVAL; 162 + 163 + hwc->config |= config; 164 + 165 + return 0; 166 + } 167 + 168 + static void sh_perf_event_update(struct perf_event *event, 169 + struct hw_perf_event *hwc, int idx) 170 + { 171 + u64 prev_raw_count, new_raw_count; 172 + s64 delta; 173 + int shift = 0; 174 + 175 + /* 176 + * Depending on the counter configuration, they may or may not 177 + * be chained, in which case the previous counter value can be 178 + * updated underneath us if the lower-half overflows. 179 + * 180 + * Our tactic to handle this is to first atomically read and 181 + * exchange a new raw count - then add that new-prev delta 182 + * count to the generic counter atomically. 183 + * 184 + * As there is no interrupt associated with the overflow events, 185 + * this is the simplest approach for maintaining consistency. 186 + */ 187 + again: 188 + prev_raw_count = atomic64_read(&hwc->prev_count); 189 + new_raw_count = sh_pmu->read(idx); 190 + 191 + if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count, 192 + new_raw_count) != prev_raw_count) 193 + goto again; 194 + 195 + /* 196 + * Now we have the new raw value and have updated the prev 197 + * timestamp already. We can now calculate the elapsed delta 198 + * (counter-)time and add that to the generic counter. 199 + * 200 + * Careful, not all hw sign-extends above the physical width 201 + * of the count. 202 + */ 203 + delta = (new_raw_count << shift) - (prev_raw_count << shift); 204 + delta >>= shift; 205 + 206 + atomic64_add(delta, &event->count); 207 + } 208 + 209 + static void sh_pmu_disable(struct perf_event *event) 210 + { 211 + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 212 + struct hw_perf_event *hwc = &event->hw; 213 + int idx = hwc->idx; 214 + 215 + clear_bit(idx, cpuc->active_mask); 216 + sh_pmu->disable(hwc, idx); 217 + 218 + barrier(); 219 + 220 + sh_perf_event_update(event, &event->hw, idx); 221 + 222 + cpuc->events[idx] = NULL; 223 + clear_bit(idx, cpuc->used_mask); 224 + 225 + perf_event_update_userpage(event); 226 + } 227 + 228 + static int sh_pmu_enable(struct perf_event *event) 229 + { 230 + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 231 + struct hw_perf_event *hwc = &event->hw; 232 + int idx = hwc->idx; 233 + 234 + if (test_and_set_bit(idx, cpuc->used_mask)) { 235 + idx = find_first_zero_bit(cpuc->used_mask, sh_pmu->num_events); 236 + if (idx == sh_pmu->num_events) 237 + return -EAGAIN; 238 + 239 + set_bit(idx, cpuc->used_mask); 240 + hwc->idx = idx; 241 + } 242 + 243 + sh_pmu->disable(hwc, idx); 244 + 245 + cpuc->events[idx] = event; 246 + set_bit(idx, cpuc->active_mask); 247 + 248 + sh_pmu->enable(hwc, idx); 249 + 250 + perf_event_update_userpage(event); 251 + 252 + return 0; 253 + } 254 + 255 + static void sh_pmu_read(struct perf_event *event) 256 + { 257 + sh_perf_event_update(event, &event->hw, event->hw.idx); 258 + } 259 + 260 + static const struct pmu pmu = { 261 + .enable = sh_pmu_enable, 262 + .disable = sh_pmu_disable, 263 + .read = sh_pmu_read, 264 + }; 265 + 266 + const struct pmu *hw_perf_event_init(struct perf_event *event) 267 + { 268 + int err = __hw_perf_event_init(event); 269 + if (unlikely(err)) { 270 + if (event->destroy) 271 + event->destroy(event); 272 + return ERR_PTR(err); 273 + } 274 + 275 + return &pmu; 276 + } 277 + 278 + void hw_perf_event_setup(int cpu) 279 + { 280 + struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); 281 + 282 + memset(cpuhw, 0, sizeof(struct cpu_hw_events)); 283 + } 284 + 285 + void hw_perf_enable(void) 286 + { 287 + if (!sh_pmu_initialized()) 288 + return; 289 + 290 + sh_pmu->enable_all(); 291 + } 292 + 293 + void hw_perf_disable(void) 294 + { 295 + if (!sh_pmu_initialized()) 296 + return; 297 + 298 + sh_pmu->disable_all(); 299 + } 300 + 301 + int register_sh_pmu(struct sh_pmu *pmu) 302 + { 303 + if (sh_pmu) 304 + return -EBUSY; 305 + sh_pmu = pmu; 306 + 307 + pr_info("Performance Events: %s support registered\n", pmu->name); 308 + 309 + WARN_ON(pmu->num_events > MAX_HWEVENTS); 310 + 311 + return 0; 312 + }
+32 -10
arch/sh/kernel/process_32.c
··· 134 134 regs.regs[5] = (unsigned long)fn; 135 135 136 136 regs.pc = (unsigned long)kernel_thread_helper; 137 - regs.sr = (1 << 30); 137 + regs.sr = SR_MD; 138 + #if defined(CONFIG_SH_FPU) 139 + regs.sr |= SR_FD; 140 + #endif 138 141 139 142 /* Ok, create the new process.. */ 140 143 pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ··· 145 142 146 143 return pid; 147 144 } 145 + EXPORT_SYMBOL(kernel_thread); 148 146 149 147 /* 150 148 * Free current thread data structures etc.. ··· 190 186 191 187 return fpvalid; 192 188 } 189 + EXPORT_SYMBOL(dump_fpu); 190 + 191 + /* 192 + * This gets called before we allocate a new thread and copy 193 + * the current task into it. 194 + */ 195 + void prepare_to_copy(struct task_struct *tsk) 196 + { 197 + unlazy_fpu(tsk, task_pt_regs(tsk)); 198 + } 193 199 194 200 asmlinkage void ret_from_fork(void); 195 201 ··· 209 195 { 210 196 struct thread_info *ti = task_thread_info(p); 211 197 struct pt_regs *childregs; 212 - #if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP) 198 + #if defined(CONFIG_SH_DSP) 213 199 struct task_struct *tsk = current; 214 - #endif 215 - 216 - #if defined(CONFIG_SH_FPU) 217 - unlazy_fpu(tsk, regs); 218 - p->thread.fpu = tsk->thread.fpu; 219 - copy_to_stopped_child_used_math(p); 220 200 #endif 221 201 222 202 #if defined(CONFIG_SH_DSP) ··· 232 224 } else { 233 225 childregs->regs[15] = (unsigned long)childregs; 234 226 ti->addr_limit = KERNEL_DS; 227 + ti->status &= ~TS_USEDFPU; 228 + p->fpu_counter = 0; 235 229 } 236 230 237 231 if (clone_flags & CLONE_SETTLS) ··· 298 288 __notrace_funcgraph struct task_struct * 299 289 __switch_to(struct task_struct *prev, struct task_struct *next) 300 290 { 301 - #if defined(CONFIG_SH_FPU) 291 + struct thread_struct *next_t = &next->thread; 292 + 302 293 unlazy_fpu(prev, task_pt_regs(prev)); 303 - #endif 294 + 295 + /* we're going to use this soon, after a few expensive things */ 296 + if (next->fpu_counter > 5) 297 + prefetch(&next_t->fpu.hard); 304 298 305 299 #ifdef CONFIG_MMU 306 300 /* ··· 334 320 ctrl_outw(0, UBC_BBRB); 335 321 #endif 336 322 } 323 + 324 + /* 325 + * If the task has used fpu the last 5 timeslices, just do a full 326 + * restore of the math state immediately to avoid the trap; the 327 + * chances of needing FPU soon are obviously high now 328 + */ 329 + if (next->fpu_counter > 5) 330 + fpu_state_restore(task_pt_regs(next)); 337 331 338 332 return prev; 339 333 }
+2
arch/sh/kernel/process_64.c
··· 335 335 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, 336 336 &regs, 0, NULL, NULL); 337 337 } 338 + EXPORT_SYMBOL(kernel_thread); 338 339 339 340 /* 340 341 * Free current thread data structures etc.. ··· 418 417 return 0; /* Task didn't use the fpu at all. */ 419 418 #endif 420 419 } 420 + EXPORT_SYMBOL(dump_fpu); 421 421 422 422 asmlinkage void ret_from_fork(void); 423 423
+54
arch/sh/kernel/return_address.c
··· 1 + /* 2 + * arch/sh/kernel/return_address.c 3 + * 4 + * Copyright (C) 2009 Matt Fleming 5 + * Copyright (C) 2009 Paul Mundt 6 + * 7 + * This file is subject to the terms and conditions of the GNU General Public 8 + * License. See the file "COPYING" in the main directory of this archive 9 + * for more details. 10 + */ 11 + #include <linux/kernel.h> 12 + #include <asm/dwarf.h> 13 + 14 + #ifdef CONFIG_DWARF_UNWINDER 15 + 16 + void *return_address(unsigned int depth) 17 + { 18 + struct dwarf_frame *frame; 19 + unsigned long ra; 20 + int i; 21 + 22 + for (i = 0, frame = NULL, ra = 0; i <= depth; i++) { 23 + struct dwarf_frame *tmp; 24 + 25 + tmp = dwarf_unwind_stack(ra, frame); 26 + 27 + if (frame) 28 + dwarf_free_frame(frame); 29 + 30 + frame = tmp; 31 + 32 + if (!frame || !frame->return_addr) 33 + break; 34 + 35 + ra = frame->return_addr; 36 + } 37 + 38 + /* Failed to unwind the stack to the specified depth. */ 39 + WARN_ON(i != depth + 1); 40 + 41 + if (frame) 42 + dwarf_free_frame(frame); 43 + 44 + return (void *)ra; 45 + } 46 + 47 + #else 48 + 49 + void *return_address(unsigned int depth) 50 + { 51 + return NULL; 52 + } 53 + 54 + #endif
+4
arch/sh/kernel/setup.c
··· 453 453 454 454 paging_init(); 455 455 456 + #ifdef CONFIG_PMB_ENABLE 457 + pmb_init(); 458 + #endif 459 + 456 460 #ifdef CONFIG_SMP 457 461 plat_smp_setup(); 458 462 #endif
+12 -55
arch/sh/kernel/sh_ksyms_32.c
··· 1 1 #include <linux/module.h> 2 - #include <linux/smp.h> 3 - #include <linux/user.h> 4 - #include <linux/elfcore.h> 5 - #include <linux/sched.h> 6 - #include <linux/in6.h> 7 - #include <linux/interrupt.h> 8 - #include <linux/vmalloc.h> 9 - #include <linux/pci.h> 10 - #include <linux/irq.h> 11 - #include <asm/sections.h> 12 - #include <asm/processor.h> 13 - #include <asm/uaccess.h> 2 + #include <linux/string.h> 3 + #include <linux/uaccess.h> 4 + #include <linux/delay.h> 5 + #include <linux/mm.h> 14 6 #include <asm/checksum.h> 15 - #include <asm/io.h> 16 - #include <asm/delay.h> 17 - #include <asm/tlbflush.h> 18 - #include <asm/cacheflush.h> 19 - #include <asm/ftrace.h> 7 + #include <asm/sections.h> 20 8 21 - extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); 22 - 23 - /* platform dependent support */ 24 - EXPORT_SYMBOL(dump_fpu); 25 - EXPORT_SYMBOL(kernel_thread); 26 - EXPORT_SYMBOL(strlen); 27 - 28 - /* PCI exports */ 29 - #ifdef CONFIG_PCI 30 - EXPORT_SYMBOL(pci_alloc_consistent); 31 - EXPORT_SYMBOL(pci_free_consistent); 32 - #endif 33 - 34 - /* mem exports */ 35 9 EXPORT_SYMBOL(memchr); 36 10 EXPORT_SYMBOL(memcpy); 37 11 EXPORT_SYMBOL(memset); ··· 14 40 EXPORT_SYMBOL(__udelay); 15 41 EXPORT_SYMBOL(__ndelay); 16 42 EXPORT_SYMBOL(__const_udelay); 43 + EXPORT_SYMBOL(strlen); 44 + EXPORT_SYMBOL(csum_partial); 45 + EXPORT_SYMBOL(csum_partial_copy_generic); 46 + EXPORT_SYMBOL(copy_page); 47 + EXPORT_SYMBOL(__clear_user); 48 + EXPORT_SYMBOL(_ebss); 49 + EXPORT_SYMBOL(empty_zero_page); 17 50 18 51 #define DECLARE_EXPORT(name) \ 19 52 extern void name(void);EXPORT_SYMBOL(name) ··· 88 107 DECLARE_EXPORT(__udivsi3_i4); 89 108 DECLARE_EXPORT(__sdivsi3_i4i); 90 109 DECLARE_EXPORT(__udivsi3_i4i); 91 - 92 - #if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ 93 - defined(CONFIG_SH7705_CACHE_32KB)) 94 - /* needed by some modules */ 95 - EXPORT_SYMBOL(flush_cache_all); 96 - EXPORT_SYMBOL(flush_cache_range); 97 - EXPORT_SYMBOL(flush_dcache_page); 98 - #endif 99 - 100 110 #ifdef CONFIG_MCOUNT 101 111 DECLARE_EXPORT(mcount); 102 - #endif 103 - EXPORT_SYMBOL(csum_partial); 104 - EXPORT_SYMBOL(csum_partial_copy_generic); 105 - #ifdef CONFIG_IPV6 106 - EXPORT_SYMBOL(csum_ipv6_magic); 107 - #endif 108 - EXPORT_SYMBOL(copy_page); 109 - EXPORT_SYMBOL(__clear_user); 110 - EXPORT_SYMBOL(_ebss); 111 - EXPORT_SYMBOL(empty_zero_page); 112 - 113 - #ifndef CONFIG_CACHE_OFF 114 - EXPORT_SYMBOL(__flush_purge_region); 115 - EXPORT_SYMBOL(__flush_wback_region); 116 - EXPORT_SYMBOL(__flush_invalidate_region); 117 112 #endif
-10
arch/sh/kernel/sh_ksyms_64.c
··· 24 24 #include <asm/delay.h> 25 25 #include <asm/irq.h> 26 26 27 - extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); 28 - 29 - /* platform dependent support */ 30 - EXPORT_SYMBOL(dump_fpu); 31 - EXPORT_SYMBOL(kernel_thread); 32 - 33 - #ifdef CONFIG_VT 34 - EXPORT_SYMBOL(screen_info); 35 - #endif 36 - 37 27 EXPORT_SYMBOL(__put_user_asm_b); 38 28 EXPORT_SYMBOL(__put_user_asm_w); 39 29 EXPORT_SYMBOL(__put_user_asm_l);
+14 -10
arch/sh/kernel/signal_32.c
··· 67 67 68 68 current->state = TASK_INTERRUPTIBLE; 69 69 schedule(); 70 - set_thread_flag(TIF_RESTORE_SIGMASK); 70 + set_restore_sigmask(); 71 + 71 72 return -ERESTARTNOHAND; 72 73 } 73 74 ··· 591 590 if (try_to_freeze()) 592 591 goto no_signal; 593 592 594 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 593 + if (current_thread_info()->status & TS_RESTORE_SIGMASK) 595 594 oldset = &current->saved_sigmask; 596 595 else 597 596 oldset = &current->blocked; ··· 603 602 /* Whee! Actually deliver the signal. */ 604 603 if (handle_signal(signr, &ka, &info, oldset, 605 604 regs, save_r0) == 0) { 606 - /* a signal was successfully delivered; the saved 605 + /* 606 + * A signal was successfully delivered; the saved 607 607 * sigmask will have been stored in the signal frame, 608 608 * and will be restored by sigreturn, so we can simply 609 - * clear the TIF_RESTORE_SIGMASK flag */ 610 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 611 - clear_thread_flag(TIF_RESTORE_SIGMASK); 609 + * clear the TS_RESTORE_SIGMASK flag 610 + */ 611 + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 612 612 613 613 tracehook_signal_handler(signr, &info, &ka, regs, 614 614 test_thread_flag(TIF_SINGLESTEP)); ··· 633 631 } 634 632 } 635 633 636 - /* if there's no signal to deliver, we just put the saved sigmask 637 - * back */ 638 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 639 - clear_thread_flag(TIF_RESTORE_SIGMASK); 634 + /* 635 + * If there's no signal to deliver, we just put the saved sigmask 636 + * back. 637 + */ 638 + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 639 + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 640 640 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 641 641 } 642 642 }
+6 -7
arch/sh/kernel/signal_64.c
··· 101 101 if (try_to_freeze()) 102 102 goto no_signal; 103 103 104 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 104 + if (current_thread_info()->status & TS_RESTORE_SIGMASK) 105 105 oldset = &current->saved_sigmask; 106 106 else if (!oldset) 107 107 oldset = &current->blocked; ··· 115 115 /* 116 116 * If a signal was successfully delivered, the 117 117 * saved sigmask is in its frame, and we can 118 - * clear the TIF_RESTORE_SIGMASK flag. 118 + * clear the TS_RESTORE_SIGMASK flag. 119 119 */ 120 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 121 - clear_thread_flag(TIF_RESTORE_SIGMASK); 122 - 120 + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 123 121 tracehook_signal_handler(signr, &info, &ka, regs, 0); 124 122 return 1; 125 123 } ··· 144 146 } 145 147 146 148 /* No signal to deliver -- put the saved sigmask back */ 147 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 148 - clear_thread_flag(TIF_RESTORE_SIGMASK); 149 + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 150 + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 149 151 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 150 152 } 151 153 ··· 174 176 while (1) { 175 177 current->state = TASK_INTERRUPTIBLE; 176 178 schedule(); 179 + set_restore_sigmask(); 177 180 regs->pc += 4; /* because sys_sigreturn decrements the pc */ 178 181 if (do_signal(regs, &saveset)) { 179 182 /* pc now points at signal handler. Need to decrement
+3 -1
arch/sh/kernel/smp.c
··· 122 122 stack_start.bss_start = 0; /* don't clear bss for secondary cpus */ 123 123 stack_start.start_kernel_fn = start_secondary; 124 124 125 - flush_cache_all(); 125 + flush_icache_range((unsigned long)&stack_start, 126 + (unsigned long)&stack_start + sizeof(stack_start)); 127 + wmb(); 126 128 127 129 plat_start_cpu(cpu, (unsigned long)_stext); 128 130
+26
arch/sh/kernel/topology.c
··· 16 16 17 17 static DEFINE_PER_CPU(struct cpu, cpu_devices); 18 18 19 + cpumask_t cpu_core_map[NR_CPUS]; 20 + 21 + static cpumask_t cpu_coregroup_map(unsigned int cpu) 22 + { 23 + /* 24 + * Presently all SH-X3 SMP cores are multi-cores, so just keep it 25 + * simple until we have a method for determining topology.. 26 + */ 27 + return cpu_possible_map; 28 + } 29 + 30 + const struct cpumask *cpu_coregroup_mask(unsigned int cpu) 31 + { 32 + return &cpu_core_map[cpu]; 33 + } 34 + 35 + int arch_update_cpu_topology(void) 36 + { 37 + unsigned int cpu; 38 + 39 + for_each_possible_cpu(cpu) 40 + cpu_core_map[cpu] = cpu_coregroup_map(cpu); 41 + 42 + return 0; 43 + } 44 + 19 45 static int __init topology_init(void) 20 46 { 21 47 int i, ret;
+5 -3
arch/sh/kernel/traps.c
··· 9 9 #include <asm/unwinder.h> 10 10 #include <asm/system.h> 11 11 12 - #ifdef CONFIG_BUG 13 - void handle_BUG(struct pt_regs *regs) 12 + #ifdef CONFIG_GENERIC_BUG 13 + static void handle_BUG(struct pt_regs *regs) 14 14 { 15 15 const struct bug_entry *bug; 16 16 unsigned long bugaddr = regs->pc; ··· 81 81 SIGTRAP) == NOTIFY_STOP) 82 82 return; 83 83 84 - #ifdef CONFIG_BUG 84 + #ifdef CONFIG_GENERIC_BUG 85 85 if (__kernel_text_address(instruction_pointer(regs))) { 86 86 insn_size_t insn = *(insn_size_t *)instruction_pointer(regs); 87 87 if (insn == TRAPA_BUG_OPCODE) ··· 95 95 96 96 BUILD_TRAP_HANDLER(nmi) 97 97 { 98 + unsigned int cpu = smp_processor_id(); 98 99 TRAP_HANDLER_DECL; 99 100 100 101 nmi_enter(); 102 + nmi_count(cpu)++; 101 103 102 104 switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) { 103 105 case NOTIFY_OK:
+32 -52
arch/sh/kernel/traps_32.c
··· 25 25 #include <linux/kexec.h> 26 26 #include <linux/limits.h> 27 27 #include <linux/proc_fs.h> 28 + #include <linux/seq_file.h> 28 29 #include <linux/sysfs.h> 29 30 #include <asm/system.h> 30 31 #include <asm/uaccess.h> ··· 69 68 "signal+warn" 70 69 }; 71 70 72 - static int 73 - proc_alignment_read(char *page, char **start, off_t off, int count, int *eof, 74 - void *data) 71 + static int alignment_proc_show(struct seq_file *m, void *v) 75 72 { 76 - char *p = page; 77 - int len; 78 - 79 - p += sprintf(p, "User:\t\t%lu\n", se_user); 80 - p += sprintf(p, "System:\t\t%lu\n", se_sys); 81 - p += sprintf(p, "Half:\t\t%lu\n", se_half); 82 - p += sprintf(p, "Word:\t\t%lu\n", se_word); 83 - p += sprintf(p, "DWord:\t\t%lu\n", se_dword); 84 - p += sprintf(p, "Multi:\t\t%lu\n", se_multi); 85 - p += sprintf(p, "User faults:\t%i (%s)\n", se_usermode, 73 + seq_printf(m, "User:\t\t%lu\n", se_user); 74 + seq_printf(m, "System:\t\t%lu\n", se_sys); 75 + seq_printf(m, "Half:\t\t%lu\n", se_half); 76 + seq_printf(m, "Word:\t\t%lu\n", se_word); 77 + seq_printf(m, "DWord:\t\t%lu\n", se_dword); 78 + seq_printf(m, "Multi:\t\t%lu\n", se_multi); 79 + seq_printf(m, "User faults:\t%i (%s)\n", se_usermode, 86 80 se_usermode_action[se_usermode]); 87 - p += sprintf(p, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn, 81 + seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn, 88 82 se_kernmode_warn ? "+warn" : ""); 89 - 90 - len = (p - page) - off; 91 - if (len < 0) 92 - len = 0; 93 - 94 - *eof = (len <= count) ? 1 : 0; 95 - *start = page + off; 96 - 97 - return len; 83 + return 0; 98 84 } 99 85 100 - static int proc_alignment_write(struct file *file, const char __user *buffer, 101 - unsigned long count, void *data) 86 + static int alignment_proc_open(struct inode *inode, struct file *file) 102 87 { 88 + return single_open(file, alignment_proc_show, NULL); 89 + } 90 + 91 + static ssize_t alignment_proc_write(struct file *file, 92 + const char __user *buffer, size_t count, loff_t *pos) 93 + { 94 + int *data = PDE(file->f_path.dentry->d_inode)->data; 103 95 char mode; 104 96 105 97 if (count > 0) { 106 98 if (get_user(mode, buffer)) 107 99 return -EFAULT; 108 100 if (mode >= '0' && mode <= '5') 109 - se_usermode = mode - '0'; 101 + *data = mode - '0'; 110 102 } 111 103 return count; 112 104 } 113 105 114 - static int proc_alignment_kern_write(struct file *file, const char __user *buffer, 115 - unsigned long count, void *data) 116 - { 117 - char mode; 118 - 119 - if (count > 0) { 120 - if (get_user(mode, buffer)) 121 - return -EFAULT; 122 - if (mode >= '0' && mode <= '1') 123 - se_kernmode_warn = mode - '0'; 124 - } 125 - return count; 126 - } 106 + static const struct file_operations alignment_proc_fops = { 107 + .owner = THIS_MODULE, 108 + .open = alignment_proc_open, 109 + .read = seq_read, 110 + .llseek = seq_lseek, 111 + .release = single_release, 112 + .write = alignment_proc_write, 113 + }; 127 114 #endif 128 115 129 116 static void dump_mem(const char *str, unsigned long bottom, unsigned long top) ··· 934 945 set_exception_table_evt(0x800, do_reserved_inst); 935 946 set_exception_table_evt(0x820, do_illegal_slot_inst); 936 947 #elif defined(CONFIG_SH_FPU) 937 - #ifdef CONFIG_CPU_SUBTYPE_SHX3 938 - set_exception_table_evt(0xd80, fpu_state_restore_trap_handler); 939 - set_exception_table_evt(0xda0, fpu_state_restore_trap_handler); 940 - #else 941 948 set_exception_table_evt(0x800, fpu_state_restore_trap_handler); 942 949 set_exception_table_evt(0x820, fpu_state_restore_trap_handler); 943 - #endif 944 950 #endif 945 951 946 952 #ifdef CONFIG_CPU_SH2 ··· 995 1011 if (!dir) 996 1012 return -ENOMEM; 997 1013 998 - res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, dir); 1014 + res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir, 1015 + &alignment_proc_fops, &se_usermode); 999 1016 if (!res) 1000 1017 return -ENOMEM; 1001 1018 1002 - res->read_proc = proc_alignment_read; 1003 - res->write_proc = proc_alignment_write; 1004 - 1005 - res = create_proc_entry("kernel_alignment", S_IWUSR | S_IRUGO, dir); 1019 + res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir, 1020 + &alignment_proc_fops, &se_kernmode_warn); 1006 1021 if (!res) 1007 1022 return -ENOMEM; 1008 - 1009 - res->read_proc = proc_alignment_read; 1010 - res->write_proc = proc_alignment_kern_write; 1011 1023 1012 1024 return 0; 1013 1025 }
+5 -2
arch/sh/lib/Makefile
··· 2 2 # Makefile for SuperH-specific library files.. 3 3 # 4 4 5 - lib-y = delay.o memset.o memmove.o memchr.o \ 5 + lib-y = delay.o memmove.o memchr.o \ 6 6 checksum.o strlen.o div64.o div64-generic.o 7 7 8 8 # Extracted from libgcc ··· 23 23 memcpy-y := memcpy.o 24 24 memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o 25 25 26 + memset-y := memset.o 27 + memset-$(CONFIG_CPU_SH4) := memset-sh4.o 28 + 26 29 lib-$(CONFIG_MMU) += copy_page.o __clear_user.o 27 30 lib-$(CONFIG_MCOUNT) += mcount.o 28 - lib-y += $(memcpy-y) $(udivsi3-y) 31 + lib-y += $(memcpy-y) $(memset-y) $(udivsi3-y) 29 32 30 33 EXTRA_CFLAGS += -Werror
+107
arch/sh/lib/memset-sh4.S
··· 1 + /* 2 + * "memset" implementation for SH4 3 + * 4 + * Copyright (C) 1999 Niibe Yutaka 5 + * Copyright (c) 2009 STMicroelectronics Limited 6 + * Author: Stuart Menefy <stuart.menefy:st.com> 7 + */ 8 + 9 + /* 10 + * void *memset(void *s, int c, size_t n); 11 + */ 12 + 13 + #include <linux/linkage.h> 14 + 15 + ENTRY(memset) 16 + mov #12,r0 17 + add r6,r4 18 + cmp/gt r6,r0 19 + bt/s 40f ! if it's too small, set a byte at once 20 + mov r4,r0 21 + and #3,r0 22 + cmp/eq #0,r0 23 + bt/s 2f ! It's aligned 24 + sub r0,r6 25 + 1: 26 + dt r0 27 + bf/s 1b 28 + mov.b r5,@-r4 29 + 2: ! make VVVV 30 + extu.b r5,r5 31 + swap.b r5,r0 ! V0 32 + or r0,r5 ! VV 33 + swap.w r5,r0 ! VV00 34 + or r0,r5 ! VVVV 35 + 36 + ! Check if enough bytes need to be copied to be worth the big loop 37 + mov #0x40, r0 ! (MT) 38 + cmp/gt r6,r0 ! (MT) 64 > len => slow loop 39 + 40 + bt/s 22f 41 + mov r6,r0 42 + 43 + ! align the dst to the cache block size if necessary 44 + mov r4, r3 45 + mov #~(0x1f), r1 46 + 47 + and r3, r1 48 + cmp/eq r3, r1 49 + 50 + bt/s 11f ! dst is already aligned 51 + sub r1, r3 ! r3-r1 -> r3 52 + shlr2 r3 ! number of loops 53 + 54 + 10: mov.l r5,@-r4 55 + dt r3 56 + bf/s 10b 57 + add #-4, r6 58 + 59 + 11: ! dst is 32byte aligned 60 + mov r6,r2 61 + mov #-5,r0 62 + shld r0,r2 ! number of loops 63 + 64 + add #-32, r4 65 + mov r5, r0 66 + 12: 67 + movca.l r0,@r4 68 + mov.l r5,@(4, r4) 69 + mov.l r5,@(8, r4) 70 + mov.l r5,@(12,r4) 71 + mov.l r5,@(16,r4) 72 + mov.l r5,@(20,r4) 73 + add #-0x20, r6 74 + mov.l r5,@(24,r4) 75 + dt r2 76 + mov.l r5,@(28,r4) 77 + bf/s 12b 78 + add #-32, r4 79 + 80 + add #32, r4 81 + mov #8, r0 82 + cmp/ge r0, r6 83 + bf 40f 84 + 85 + mov r6,r0 86 + 22: 87 + shlr2 r0 88 + shlr r0 ! r0 = r6 >> 3 89 + 3: 90 + dt r0 91 + mov.l r5,@-r4 ! set 8-byte at once 92 + bf/s 3b 93 + mov.l r5,@-r4 94 + ! 95 + mov #7,r0 96 + and r0,r6 97 + 98 + ! fill bytes (length may be zero) 99 + 40: tst r6,r6 100 + bt 5f 101 + 4: 102 + dt r6 103 + bf/s 4b 104 + mov.b r5,@-r4 105 + 5: 106 + rts 107 + mov r4,r0
+3 -3
arch/sh/math-emu/math.c
··· 558 558 (finsn >> 8) & 0xf); 559 559 tsk->thread.fpu.hard.fpscr &= 560 560 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); 561 - set_tsk_thread_flag(tsk, TIF_USEDFPU); 561 + task_thread_info(tsk)->status |= TS_USEDFPU; 562 562 } else { 563 563 info.si_signo = SIGFPE; 564 564 info.si_errno = 0; ··· 619 619 struct task_struct *tsk = current; 620 620 struct sh_fpu_soft_struct *fpu = &(tsk->thread.fpu.soft); 621 621 622 - if (!test_tsk_thread_flag(tsk, TIF_USEDFPU)) { 622 + if (!(task_thread_info(tsk)->status & TS_USEDFPU)) { 623 623 /* initialize once. */ 624 624 fpu_init(fpu); 625 - set_tsk_thread_flag(tsk, TIF_USEDFPU); 625 + task_thread_info(tsk)->status |= TS_USEDFPU; 626 626 } 627 627 628 628 return fpu_emulate(inst, fpu, regs);
+12 -7
arch/sh/mm/Kconfig
··· 82 82 83 83 config PMB_ENABLE 84 84 bool "Support 32-bit physical addressing through PMB" 85 - depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785) 86 - select 32BIT 85 + depends on MMU && EXPERIMENTAL && CPU_SH4A 87 86 default y 88 87 help 89 88 If you say Y here, physical addressing will be extended to ··· 96 97 97 98 config PMB 98 99 bool "PMB" 99 - depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785) 100 - select 32BIT 100 + depends on MMU && EXPERIMENTAL && CPU_SH4A 101 101 help 102 102 If you say Y here, physical addressing will be extended to 103 103 32-bits through the SH-4A PMB. If this is not set, legacy ··· 104 106 105 107 config PMB_FIXED 106 108 bool "fixed PMB" 107 - depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || \ 108 - CPU_SUBTYPE_SH7780 || \ 109 - CPU_SUBTYPE_SH7785) 109 + depends on MMU && EXPERIMENTAL && CPU_SH4A 110 110 select 32BIT 111 111 help 112 112 If this option is enabled, fixed PMB mappings are inherited ··· 253 257 endchoice 254 258 255 259 source "mm/Kconfig" 260 + 261 + config SCHED_MC 262 + bool "Multi-core scheduler support" 263 + depends on SMP 264 + default y 265 + help 266 + Multi-core scheduler support improves the CPU scheduler's decision 267 + making when dealing with multi-core CPU chips at a cost of slightly 268 + increased overhead in some places. If unsure say N here. 256 269 257 270 endmenu 258 271
+1 -2
arch/sh/mm/Makefile
··· 33 33 endif 34 34 35 35 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 36 - obj-$(CONFIG_PMB) += pmb.o 37 - obj-$(CONFIG_PMB_FIXED) += pmb-fixed.o 36 + obj-$(CONFIG_PMB_ENABLE) += pmb.o 38 37 obj-$(CONFIG_NUMA) += numa.o 39 38 40 39 # Special flags for fault_64.o. This puts restrictions on the number of
+77 -424
arch/sh/mm/cache-sh4.c
··· 2 2 * arch/sh/mm/cache-sh4.c 3 3 * 4 4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 5 - * Copyright (C) 2001 - 2007 Paul Mundt 5 + * Copyright (C) 2001 - 2009 Paul Mundt 6 6 * Copyright (C) 2003 Richard Curnow 7 7 * Copyright (c) 2007 STMicroelectronics (R&D) Ltd. 8 8 * ··· 15 15 #include <linux/io.h> 16 16 #include <linux/mutex.h> 17 17 #include <linux/fs.h> 18 + #include <linux/highmem.h> 19 + #include <asm/pgtable.h> 18 20 #include <asm/mmu_context.h> 19 21 #include <asm/cacheflush.h> 20 22 ··· 25 23 * flushing. Anything exceeding this will simply flush the dcache in its 26 24 * entirety. 27 25 */ 28 - #define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */ 29 26 #define MAX_ICACHE_PAGES 32 30 27 31 28 static void __flush_cache_one(unsigned long addr, unsigned long phys, 32 29 unsigned long exec_offset); 33 - 34 - /* 35 - * This is initialised here to ensure that it is not placed in the BSS. If 36 - * that were to happen, note that cache_init gets called before the BSS is 37 - * cleared, so this would get nulled out which would be hopeless. 38 - */ 39 - static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) = 40 - (void (*)(unsigned long, unsigned long))0xdeadbeef; 41 30 42 31 /* 43 32 * Write back the range of D-cache, and purge the I-cache. ··· 90 97 unsigned long flags, exec_offset = 0; 91 98 92 99 /* 93 - * All types of SH-4 require PC to be in P2 to operate on the I-cache. 94 - * Some types of SH-4 require PC to be in P2 to operate on the D-cache. 100 + * All types of SH-4 require PC to be uncached to operate on the I-cache. 101 + * Some types of SH-4 require PC to be uncached to operate on the D-cache. 95 102 */ 96 103 if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) || 97 104 (start < CACHE_OC_ADDRESS_ARRAY)) 98 - exec_offset = 0x20000000; 105 + exec_offset = cached_to_uncached; 99 106 100 107 local_irq_save(flags); 101 - __flush_cache_one(start | SH_CACHE_ASSOC, P1SEGADDR(phys), exec_offset); 108 + __flush_cache_one(start, phys, exec_offset); 102 109 local_irq_restore(flags); 103 110 } 104 111 ··· 117 124 else 118 125 #endif 119 126 { 120 - unsigned long phys = PHYSADDR(page_address(page)); 127 + unsigned long phys = page_to_phys(page); 121 128 unsigned long addr = CACHE_OC_ADDRESS_ARRAY; 122 129 int i, n; 123 130 ··· 152 159 local_irq_restore(flags); 153 160 } 154 161 155 - static inline void flush_dcache_all(void) 162 + static void flush_dcache_all(void) 156 163 { 157 - (*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size); 158 - wmb(); 164 + unsigned long addr, end_addr, entry_offset; 165 + 166 + end_addr = CACHE_OC_ADDRESS_ARRAY + 167 + (current_cpu_data.dcache.sets << 168 + current_cpu_data.dcache.entry_shift) * 169 + current_cpu_data.dcache.ways; 170 + 171 + entry_offset = 1 << current_cpu_data.dcache.entry_shift; 172 + 173 + for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; ) { 174 + __raw_writel(0, addr); addr += entry_offset; 175 + __raw_writel(0, addr); addr += entry_offset; 176 + __raw_writel(0, addr); addr += entry_offset; 177 + __raw_writel(0, addr); addr += entry_offset; 178 + __raw_writel(0, addr); addr += entry_offset; 179 + __raw_writel(0, addr); addr += entry_offset; 180 + __raw_writel(0, addr); addr += entry_offset; 181 + __raw_writel(0, addr); addr += entry_offset; 182 + } 159 183 } 160 184 161 185 static void sh4_flush_cache_all(void *unused) ··· 181 171 flush_icache_all(); 182 172 } 183 173 184 - static void __flush_cache_mm(struct mm_struct *mm, unsigned long start, 185 - unsigned long end) 186 - { 187 - unsigned long d = 0, p = start & PAGE_MASK; 188 - unsigned long alias_mask = boot_cpu_data.dcache.alias_mask; 189 - unsigned long n_aliases = boot_cpu_data.dcache.n_aliases; 190 - unsigned long select_bit; 191 - unsigned long all_aliases_mask; 192 - unsigned long addr_offset; 193 - pgd_t *dir; 194 - pmd_t *pmd; 195 - pud_t *pud; 196 - pte_t *pte; 197 - int i; 198 - 199 - dir = pgd_offset(mm, p); 200 - pud = pud_offset(dir, p); 201 - pmd = pmd_offset(pud, p); 202 - end = PAGE_ALIGN(end); 203 - 204 - all_aliases_mask = (1 << n_aliases) - 1; 205 - 206 - do { 207 - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) { 208 - p &= PMD_MASK; 209 - p += PMD_SIZE; 210 - pmd++; 211 - 212 - continue; 213 - } 214 - 215 - pte = pte_offset_kernel(pmd, p); 216 - 217 - do { 218 - unsigned long phys; 219 - pte_t entry = *pte; 220 - 221 - if (!(pte_val(entry) & _PAGE_PRESENT)) { 222 - pte++; 223 - p += PAGE_SIZE; 224 - continue; 225 - } 226 - 227 - phys = pte_val(entry) & PTE_PHYS_MASK; 228 - 229 - if ((p ^ phys) & alias_mask) { 230 - d |= 1 << ((p & alias_mask) >> PAGE_SHIFT); 231 - d |= 1 << ((phys & alias_mask) >> PAGE_SHIFT); 232 - 233 - if (d == all_aliases_mask) 234 - goto loop_exit; 235 - } 236 - 237 - pte++; 238 - p += PAGE_SIZE; 239 - } while (p < end && ((unsigned long)pte & ~PAGE_MASK)); 240 - pmd++; 241 - } while (p < end); 242 - 243 - loop_exit: 244 - addr_offset = 0; 245 - select_bit = 1; 246 - 247 - for (i = 0; i < n_aliases; i++) { 248 - if (d & select_bit) { 249 - (*__flush_dcache_segment_fn)(addr_offset, PAGE_SIZE); 250 - wmb(); 251 - } 252 - 253 - select_bit <<= 1; 254 - addr_offset += PAGE_SIZE; 255 - } 256 - } 257 - 258 174 /* 259 175 * Note : (RPC) since the caches are physically tagged, the only point 260 176 * of flush_cache_mm for SH-4 is to get rid of aliases from the 261 177 * D-cache. The assumption elsewhere, e.g. flush_cache_range, is that 262 178 * lines can stay resident so long as the virtual address they were 263 179 * accessed with (hence cache set) is in accord with the physical 264 - * address (i.e. tag). It's no different here. So I reckon we don't 265 - * need to flush the I-cache, since aliases don't matter for that. We 266 - * should try that. 180 + * address (i.e. tag). It's no different here. 267 181 * 268 182 * Caller takes mm->mmap_sem. 269 183 */ ··· 198 264 if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT) 199 265 return; 200 266 201 - /* 202 - * If cache is only 4k-per-way, there are never any 'aliases'. Since 203 - * the cache is physically tagged, the data can just be left in there. 204 - */ 205 - if (boot_cpu_data.dcache.n_aliases == 0) 206 - return; 207 - 208 - /* 209 - * Don't bother groveling around the dcache for the VMA ranges 210 - * if there are too many PTEs to make it worthwhile. 211 - */ 212 - if (mm->nr_ptes >= MAX_DCACHE_PAGES) 213 - flush_dcache_all(); 214 - else { 215 - struct vm_area_struct *vma; 216 - 217 - /* 218 - * In this case there are reasonably sized ranges to flush, 219 - * iterate through the VMA list and take care of any aliases. 220 - */ 221 - for (vma = mm->mmap; vma; vma = vma->vm_next) 222 - __flush_cache_mm(mm, vma->vm_start, vma->vm_end); 223 - } 224 - 225 - /* Only touch the icache if one of the VMAs has VM_EXEC set. */ 226 - if (mm->exec_vm) 227 - flush_icache_all(); 267 + flush_dcache_all(); 228 268 } 229 269 230 270 /* ··· 211 303 { 212 304 struct flusher_data *data = args; 213 305 struct vm_area_struct *vma; 306 + struct page *page; 214 307 unsigned long address, pfn, phys; 215 - unsigned int alias_mask; 308 + int map_coherent = 0; 309 + pgd_t *pgd; 310 + pud_t *pud; 311 + pmd_t *pmd; 312 + pte_t *pte; 313 + void *vaddr; 216 314 217 315 vma = data->vma; 218 - address = data->addr1; 316 + address = data->addr1 & PAGE_MASK; 219 317 pfn = data->addr2; 220 318 phys = pfn << PAGE_SHIFT; 319 + page = pfn_to_page(pfn); 221 320 222 321 if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT) 223 322 return; 224 323 225 - alias_mask = boot_cpu_data.dcache.alias_mask; 324 + pgd = pgd_offset(vma->vm_mm, address); 325 + pud = pud_offset(pgd, address); 326 + pmd = pmd_offset(pud, address); 327 + pte = pte_offset_kernel(pmd, address); 226 328 227 - /* We only need to flush D-cache when we have alias */ 228 - if ((address^phys) & alias_mask) { 229 - /* Loop 4K of the D-cache */ 230 - flush_cache_one( 231 - CACHE_OC_ADDRESS_ARRAY | (address & alias_mask), 232 - phys); 233 - /* Loop another 4K of the D-cache */ 234 - flush_cache_one( 235 - CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask), 236 - phys); 329 + /* If the page isn't present, there is nothing to do here. */ 330 + if (!(pte_val(*pte) & _PAGE_PRESENT)) 331 + return; 332 + 333 + if ((vma->vm_mm == current->active_mm)) 334 + vaddr = NULL; 335 + else { 336 + /* 337 + * Use kmap_coherent or kmap_atomic to do flushes for 338 + * another ASID than the current one. 339 + */ 340 + map_coherent = (current_cpu_data.dcache.n_aliases && 341 + !test_bit(PG_dcache_dirty, &page->flags) && 342 + page_mapped(page)); 343 + if (map_coherent) 344 + vaddr = kmap_coherent(page, address); 345 + else 346 + vaddr = kmap_atomic(page, KM_USER0); 347 + 348 + address = (unsigned long)vaddr; 237 349 } 238 350 239 - alias_mask = boot_cpu_data.icache.alias_mask; 240 - if (vma->vm_flags & VM_EXEC) { 241 - /* 242 - * Evict entries from the portion of the cache from which code 243 - * may have been executed at this address (virtual). There's 244 - * no need to evict from the portion corresponding to the 245 - * physical address as for the D-cache, because we know the 246 - * kernel has never executed the code through its identity 247 - * translation. 248 - */ 249 - flush_cache_one( 250 - CACHE_IC_ADDRESS_ARRAY | (address & alias_mask), 251 - phys); 351 + if (pages_do_alias(address, phys)) 352 + flush_cache_one(CACHE_OC_ADDRESS_ARRAY | 353 + (address & shm_align_mask), phys); 354 + 355 + if (vma->vm_flags & VM_EXEC) 356 + flush_icache_all(); 357 + 358 + if (vaddr) { 359 + if (map_coherent) 360 + kunmap_coherent(vaddr); 361 + else 362 + kunmap_atomic(vaddr, KM_USER0); 252 363 } 253 364 } 254 365 ··· 300 373 if (boot_cpu_data.dcache.n_aliases == 0) 301 374 return; 302 375 303 - /* 304 - * Don't bother with the lookup and alias check if we have a 305 - * wide range to cover, just blow away the dcache in its 306 - * entirety instead. -- PFM. 307 - */ 308 - if (((end - start) >> PAGE_SHIFT) >= MAX_DCACHE_PAGES) 309 - flush_dcache_all(); 310 - else 311 - __flush_cache_mm(vma->vm_mm, start, end); 376 + flush_dcache_all(); 312 377 313 - if (vma->vm_flags & VM_EXEC) { 314 - /* 315 - * TODO: Is this required??? Need to look at how I-cache 316 - * coherency is assured when new programs are loaded to see if 317 - * this matters. 318 - */ 378 + if (vma->vm_flags & VM_EXEC) 319 379 flush_icache_all(); 320 - } 321 380 } 322 381 323 382 /** ··· 377 464 } while (--way_count != 0); 378 465 } 379 466 380 - /* 381 - * Break the 1, 2 and 4 way variants of this out into separate functions to 382 - * avoid nearly all the overhead of having the conditional stuff in the function 383 - * bodies (+ the 1 and 2 way cases avoid saving any registers too). 384 - * 385 - * We want to eliminate unnecessary bus transactions, so this code uses 386 - * a non-obvious technique. 387 - * 388 - * Loop over a cache way sized block of, one cache line at a time. For each 389 - * line, use movca.a to cause the current cache line contents to be written 390 - * back, but without reading anything from main memory. However this has the 391 - * side effect that the cache is now caching that memory location. So follow 392 - * this with a cache invalidate to mark the cache line invalid. And do all 393 - * this with interrupts disabled, to avoid the cache line being accidently 394 - * evicted while it is holding garbage. 395 - * 396 - * This also breaks in a number of circumstances: 397 - * - if there are modifications to the region of memory just above 398 - * empty_zero_page (for example because a breakpoint has been placed 399 - * there), then these can be lost. 400 - * 401 - * This is because the the memory address which the cache temporarily 402 - * caches in the above description is empty_zero_page. So the 403 - * movca.l hits the cache (it is assumed that it misses, or at least 404 - * isn't dirty), modifies the line and then invalidates it, losing the 405 - * required change. 406 - * 407 - * - If caches are disabled or configured in write-through mode, then 408 - * the movca.l writes garbage directly into memory. 409 - */ 410 - static void __flush_dcache_segment_writethrough(unsigned long start, 411 - unsigned long extent_per_way) 412 - { 413 - unsigned long addr; 414 - int i; 415 - 416 - addr = CACHE_OC_ADDRESS_ARRAY | (start & cpu_data->dcache.entry_mask); 417 - 418 - while (extent_per_way) { 419 - for (i = 0; i < cpu_data->dcache.ways; i++) 420 - __raw_writel(0, addr + cpu_data->dcache.way_incr * i); 421 - 422 - addr += cpu_data->dcache.linesz; 423 - extent_per_way -= cpu_data->dcache.linesz; 424 - } 425 - } 426 - 427 - static void __flush_dcache_segment_1way(unsigned long start, 428 - unsigned long extent_per_way) 429 - { 430 - unsigned long orig_sr, sr_with_bl; 431 - unsigned long base_addr; 432 - unsigned long way_incr, linesz, way_size; 433 - struct cache_info *dcache; 434 - register unsigned long a0, a0e; 435 - 436 - asm volatile("stc sr, %0" : "=r" (orig_sr)); 437 - sr_with_bl = orig_sr | (1<<28); 438 - base_addr = ((unsigned long)&empty_zero_page[0]); 439 - 440 - /* 441 - * The previous code aligned base_addr to 16k, i.e. the way_size of all 442 - * existing SH-4 D-caches. Whilst I don't see a need to have this 443 - * aligned to any better than the cache line size (which it will be 444 - * anyway by construction), let's align it to at least the way_size of 445 - * any existing or conceivable SH-4 D-cache. -- RPC 446 - */ 447 - base_addr = ((base_addr >> 16) << 16); 448 - base_addr |= start; 449 - 450 - dcache = &boot_cpu_data.dcache; 451 - linesz = dcache->linesz; 452 - way_incr = dcache->way_incr; 453 - way_size = dcache->way_size; 454 - 455 - a0 = base_addr; 456 - a0e = base_addr + extent_per_way; 457 - do { 458 - asm volatile("ldc %0, sr" : : "r" (sr_with_bl)); 459 - asm volatile("movca.l r0, @%0\n\t" 460 - "ocbi @%0" : : "r" (a0)); 461 - a0 += linesz; 462 - asm volatile("movca.l r0, @%0\n\t" 463 - "ocbi @%0" : : "r" (a0)); 464 - a0 += linesz; 465 - asm volatile("movca.l r0, @%0\n\t" 466 - "ocbi @%0" : : "r" (a0)); 467 - a0 += linesz; 468 - asm volatile("movca.l r0, @%0\n\t" 469 - "ocbi @%0" : : "r" (a0)); 470 - asm volatile("ldc %0, sr" : : "r" (orig_sr)); 471 - a0 += linesz; 472 - } while (a0 < a0e); 473 - } 474 - 475 - static void __flush_dcache_segment_2way(unsigned long start, 476 - unsigned long extent_per_way) 477 - { 478 - unsigned long orig_sr, sr_with_bl; 479 - unsigned long base_addr; 480 - unsigned long way_incr, linesz, way_size; 481 - struct cache_info *dcache; 482 - register unsigned long a0, a1, a0e; 483 - 484 - asm volatile("stc sr, %0" : "=r" (orig_sr)); 485 - sr_with_bl = orig_sr | (1<<28); 486 - base_addr = ((unsigned long)&empty_zero_page[0]); 487 - 488 - /* See comment under 1-way above */ 489 - base_addr = ((base_addr >> 16) << 16); 490 - base_addr |= start; 491 - 492 - dcache = &boot_cpu_data.dcache; 493 - linesz = dcache->linesz; 494 - way_incr = dcache->way_incr; 495 - way_size = dcache->way_size; 496 - 497 - a0 = base_addr; 498 - a1 = a0 + way_incr; 499 - a0e = base_addr + extent_per_way; 500 - do { 501 - asm volatile("ldc %0, sr" : : "r" (sr_with_bl)); 502 - asm volatile("movca.l r0, @%0\n\t" 503 - "movca.l r0, @%1\n\t" 504 - "ocbi @%0\n\t" 505 - "ocbi @%1" : : 506 - "r" (a0), "r" (a1)); 507 - a0 += linesz; 508 - a1 += linesz; 509 - asm volatile("movca.l r0, @%0\n\t" 510 - "movca.l r0, @%1\n\t" 511 - "ocbi @%0\n\t" 512 - "ocbi @%1" : : 513 - "r" (a0), "r" (a1)); 514 - a0 += linesz; 515 - a1 += linesz; 516 - asm volatile("movca.l r0, @%0\n\t" 517 - "movca.l r0, @%1\n\t" 518 - "ocbi @%0\n\t" 519 - "ocbi @%1" : : 520 - "r" (a0), "r" (a1)); 521 - a0 += linesz; 522 - a1 += linesz; 523 - asm volatile("movca.l r0, @%0\n\t" 524 - "movca.l r0, @%1\n\t" 525 - "ocbi @%0\n\t" 526 - "ocbi @%1" : : 527 - "r" (a0), "r" (a1)); 528 - asm volatile("ldc %0, sr" : : "r" (orig_sr)); 529 - a0 += linesz; 530 - a1 += linesz; 531 - } while (a0 < a0e); 532 - } 533 - 534 - static void __flush_dcache_segment_4way(unsigned long start, 535 - unsigned long extent_per_way) 536 - { 537 - unsigned long orig_sr, sr_with_bl; 538 - unsigned long base_addr; 539 - unsigned long way_incr, linesz, way_size; 540 - struct cache_info *dcache; 541 - register unsigned long a0, a1, a2, a3, a0e; 542 - 543 - asm volatile("stc sr, %0" : "=r" (orig_sr)); 544 - sr_with_bl = orig_sr | (1<<28); 545 - base_addr = ((unsigned long)&empty_zero_page[0]); 546 - 547 - /* See comment under 1-way above */ 548 - base_addr = ((base_addr >> 16) << 16); 549 - base_addr |= start; 550 - 551 - dcache = &boot_cpu_data.dcache; 552 - linesz = dcache->linesz; 553 - way_incr = dcache->way_incr; 554 - way_size = dcache->way_size; 555 - 556 - a0 = base_addr; 557 - a1 = a0 + way_incr; 558 - a2 = a1 + way_incr; 559 - a3 = a2 + way_incr; 560 - a0e = base_addr + extent_per_way; 561 - do { 562 - asm volatile("ldc %0, sr" : : "r" (sr_with_bl)); 563 - asm volatile("movca.l r0, @%0\n\t" 564 - "movca.l r0, @%1\n\t" 565 - "movca.l r0, @%2\n\t" 566 - "movca.l r0, @%3\n\t" 567 - "ocbi @%0\n\t" 568 - "ocbi @%1\n\t" 569 - "ocbi @%2\n\t" 570 - "ocbi @%3\n\t" : : 571 - "r" (a0), "r" (a1), "r" (a2), "r" (a3)); 572 - a0 += linesz; 573 - a1 += linesz; 574 - a2 += linesz; 575 - a3 += linesz; 576 - asm volatile("movca.l r0, @%0\n\t" 577 - "movca.l r0, @%1\n\t" 578 - "movca.l r0, @%2\n\t" 579 - "movca.l r0, @%3\n\t" 580 - "ocbi @%0\n\t" 581 - "ocbi @%1\n\t" 582 - "ocbi @%2\n\t" 583 - "ocbi @%3\n\t" : : 584 - "r" (a0), "r" (a1), "r" (a2), "r" (a3)); 585 - a0 += linesz; 586 - a1 += linesz; 587 - a2 += linesz; 588 - a3 += linesz; 589 - asm volatile("movca.l r0, @%0\n\t" 590 - "movca.l r0, @%1\n\t" 591 - "movca.l r0, @%2\n\t" 592 - "movca.l r0, @%3\n\t" 593 - "ocbi @%0\n\t" 594 - "ocbi @%1\n\t" 595 - "ocbi @%2\n\t" 596 - "ocbi @%3\n\t" : : 597 - "r" (a0), "r" (a1), "r" (a2), "r" (a3)); 598 - a0 += linesz; 599 - a1 += linesz; 600 - a2 += linesz; 601 - a3 += linesz; 602 - asm volatile("movca.l r0, @%0\n\t" 603 - "movca.l r0, @%1\n\t" 604 - "movca.l r0, @%2\n\t" 605 - "movca.l r0, @%3\n\t" 606 - "ocbi @%0\n\t" 607 - "ocbi @%1\n\t" 608 - "ocbi @%2\n\t" 609 - "ocbi @%3\n\t" : : 610 - "r" (a0), "r" (a1), "r" (a2), "r" (a3)); 611 - asm volatile("ldc %0, sr" : : "r" (orig_sr)); 612 - a0 += linesz; 613 - a1 += linesz; 614 - a2 += linesz; 615 - a3 += linesz; 616 - } while (a0 < a0e); 617 - } 618 - 619 467 extern void __weak sh4__flush_region_init(void); 620 468 621 469 /* ··· 384 710 */ 385 711 void __init sh4_cache_init(void) 386 712 { 387 - unsigned int wt_enabled = !!(__raw_readl(CCR) & CCR_CACHE_WT); 388 - 389 713 printk("PVR=%08x CVR=%08x PRR=%08x\n", 390 714 ctrl_inl(CCN_PVR), 391 715 ctrl_inl(CCN_CVR), 392 716 ctrl_inl(CCN_PRR)); 393 - 394 - if (wt_enabled) 395 - __flush_dcache_segment_fn = __flush_dcache_segment_writethrough; 396 - else { 397 - switch (boot_cpu_data.dcache.ways) { 398 - case 1: 399 - __flush_dcache_segment_fn = __flush_dcache_segment_1way; 400 - break; 401 - case 2: 402 - __flush_dcache_segment_fn = __flush_dcache_segment_2way; 403 - break; 404 - case 4: 405 - __flush_dcache_segment_fn = __flush_dcache_segment_4way; 406 - break; 407 - default: 408 - panic("unknown number of cache ways\n"); 409 - break; 410 - } 411 - } 412 717 413 718 local_flush_icache_range = sh4_flush_icache_range; 414 719 local_flush_dcache_page = sh4_flush_dcache_page;
+1 -1
arch/sh/mm/cache-sh5.c
··· 563 563 564 564 static void sh5_flush_dcache_page(void *page) 565 565 { 566 - sh64_dcache_purge_phy_page(page_to_phys(page)); 566 + sh64_dcache_purge_phy_page(page_to_phys((struct page *)page)); 567 567 wmb(); 568 568 } 569 569
+1 -1
arch/sh/mm/cache-sh7705.c
··· 141 141 if (mapping && !mapping_mapped(mapping)) 142 142 set_bit(PG_dcache_dirty, &page->flags); 143 143 else 144 - __flush_dcache_page(PHYSADDR(page_address(page))); 144 + __flush_dcache_page(__pa(page_address(page))); 145 145 } 146 146 147 147 static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
+17 -1
arch/sh/mm/cache.c
··· 27 27 void (*local_flush_cache_sigtramp)(void *args) = cache_noop; 28 28 29 29 void (*__flush_wback_region)(void *start, int size); 30 + EXPORT_SYMBOL(__flush_wback_region); 30 31 void (*__flush_purge_region)(void *start, int size); 32 + EXPORT_SYMBOL(__flush_purge_region); 31 33 void (*__flush_invalidate_region)(void *start, int size); 34 + EXPORT_SYMBOL(__flush_invalidate_region); 32 35 33 36 static inline void noop__flush_region(void *start, int size) 34 37 { ··· 164 161 { 165 162 cacheop_on_each_cpu(local_flush_cache_all, NULL, 1); 166 163 } 164 + EXPORT_SYMBOL(flush_cache_all); 167 165 168 166 void flush_cache_mm(struct mm_struct *mm) 169 167 { 168 + if (boot_cpu_data.dcache.n_aliases == 0) 169 + return; 170 + 170 171 cacheop_on_each_cpu(local_flush_cache_mm, mm, 1); 171 172 } 172 173 173 174 void flush_cache_dup_mm(struct mm_struct *mm) 174 175 { 176 + if (boot_cpu_data.dcache.n_aliases == 0) 177 + return; 178 + 175 179 cacheop_on_each_cpu(local_flush_cache_dup_mm, mm, 1); 176 180 } 177 181 ··· 205 195 206 196 cacheop_on_each_cpu(local_flush_cache_range, (void *)&data, 1); 207 197 } 198 + EXPORT_SYMBOL(flush_cache_range); 208 199 209 200 void flush_dcache_page(struct page *page) 210 201 { 211 202 cacheop_on_each_cpu(local_flush_dcache_page, page, 1); 212 203 } 204 + EXPORT_SYMBOL(flush_dcache_page); 213 205 214 206 void flush_icache_range(unsigned long start, unsigned long end) 215 207 { ··· 277 265 278 266 void __init cpu_cache_init(void) 279 267 { 280 - unsigned int cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE); 268 + unsigned int cache_disabled = 0; 269 + 270 + #ifdef CCR 271 + cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE); 272 + #endif 281 273 282 274 compute_alias(&boot_cpu_data.icache); 283 275 compute_alias(&boot_cpu_data.dcache);
+10 -18
arch/sh/mm/consistent.c
··· 15 15 #include <linux/dma-mapping.h> 16 16 #include <linux/dma-debug.h> 17 17 #include <linux/io.h> 18 + #include <linux/module.h> 18 19 #include <asm/cacheflush.h> 19 20 #include <asm/addrspace.h> 20 21 21 22 #define PREALLOC_DMA_DEBUG_ENTRIES 4096 23 + 24 + struct dma_map_ops *dma_ops; 25 + EXPORT_SYMBOL(dma_ops); 22 26 23 27 static int __init dma_init(void) 24 28 { ··· 31 27 } 32 28 fs_initcall(dma_init); 33 29 34 - void *dma_alloc_coherent(struct device *dev, size_t size, 35 - dma_addr_t *dma_handle, gfp_t gfp) 30 + void *dma_generic_alloc_coherent(struct device *dev, size_t size, 31 + dma_addr_t *dma_handle, gfp_t gfp) 36 32 { 37 33 void *ret, *ret_nocache; 38 34 int order = get_order(size); 39 - 40 - if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) 41 - return ret; 42 35 43 36 ret = (void *)__get_free_pages(gfp, order); 44 37 if (!ret) ··· 58 57 59 58 *dma_handle = virt_to_phys(ret); 60 59 61 - debug_dma_alloc_coherent(dev, size, *dma_handle, ret_nocache); 62 - 63 60 return ret_nocache; 64 61 } 65 - EXPORT_SYMBOL(dma_alloc_coherent); 66 62 67 - void dma_free_coherent(struct device *dev, size_t size, 68 - void *vaddr, dma_addr_t dma_handle) 63 + void dma_generic_free_coherent(struct device *dev, size_t size, 64 + void *vaddr, dma_addr_t dma_handle) 69 65 { 70 66 int order = get_order(size); 71 67 unsigned long pfn = dma_handle >> PAGE_SHIFT; 72 68 int k; 73 69 74 - WARN_ON(irqs_disabled()); /* for portability */ 75 - 76 - if (dma_release_from_coherent(dev, order, vaddr)) 77 - return; 78 - 79 - debug_dma_free_coherent(dev, size, vaddr, dma_handle); 80 70 for (k = 0; k < (1 << order); k++) 81 71 __free_pages(pfn_to_page(pfn + k), 0); 72 + 82 73 iounmap(vaddr); 83 74 } 84 - EXPORT_SYMBOL(dma_free_coherent); 85 75 86 76 void dma_cache_sync(struct device *dev, void *vaddr, size_t size, 87 77 enum dma_data_direction direction) 88 78 { 89 - #ifdef CONFIG_CPU_SH5 79 + #if defined(CONFIG_CPU_SH5) || defined(CONFIG_PMB) 90 80 void *p1addr = vaddr; 91 81 #else 92 82 void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
+19
arch/sh/mm/init.c
··· 15 15 #include <linux/pagemap.h> 16 16 #include <linux/percpu.h> 17 17 #include <linux/io.h> 18 + #include <linux/dma-mapping.h> 18 19 #include <asm/mmu_context.h> 19 20 #include <asm/tlb.h> 20 21 #include <asm/cacheflush.h> ··· 187 186 set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start)); 188 187 } 189 188 189 + /* 190 + * Early initialization for any I/O MMUs we might have. 191 + */ 192 + static void __init iommu_init(void) 193 + { 194 + no_iommu_init(); 195 + } 196 + 190 197 void __init mem_init(void) 191 198 { 192 199 int codesize, datasize, initsize; 193 200 int nid; 201 + 202 + iommu_init(); 194 203 195 204 num_physpages = 0; 196 205 high_memory = NULL; ··· 334 323 } 335 324 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); 336 325 #endif 326 + 337 327 #endif /* CONFIG_MEMORY_HOTPLUG */ 328 + 329 + #ifdef CONFIG_PMB 330 + int __in_29bit_mode(void) 331 + { 332 + return !(ctrl_inl(PMB_PASCR) & PASCR_SE); 333 + } 334 + #endif /* CONFIG_PMB */
+3 -1
arch/sh/mm/kmap.c
··· 39 39 pagefault_disable(); 40 40 41 41 idx = FIX_CMAP_END - 42 - ((addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT); 42 + (((addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1)) + 43 + (FIX_N_COLOURS * smp_processor_id())); 44 + 43 45 vaddr = __fix_to_virt(idx); 44 46 45 47 BUG_ON(!pte_none(*(kmap_coherent_pte - idx)));
+1 -1
arch/sh/mm/numa.c
··· 60 60 unsigned long bootmem_paddr; 61 61 62 62 /* Don't allow bogus node assignment */ 63 - BUG_ON(nid > MAX_NUMNODES || nid == 0); 63 + BUG_ON(nid > MAX_NUMNODES || nid <= 0); 64 64 65 65 start_pfn = start >> PAGE_SHIFT; 66 66 end_pfn = end >> PAGE_SHIFT;
-45
arch/sh/mm/pmb-fixed.c
··· 1 - /* 2 - * arch/sh/mm/fixed_pmb.c 3 - * 4 - * Copyright (C) 2009 Renesas Solutions Corp. 5 - * 6 - * This file is subject to the terms and conditions of the GNU General Public 7 - * License. See the file "COPYING" in the main directory of this archive 8 - * for more details. 9 - */ 10 - #include <linux/init.h> 11 - #include <linux/mm.h> 12 - #include <linux/io.h> 13 - #include <asm/mmu.h> 14 - #include <asm/mmu_context.h> 15 - 16 - static int __uses_jump_to_uncached fixed_pmb_init(void) 17 - { 18 - int i; 19 - unsigned long addr, data; 20 - 21 - jump_to_uncached(); 22 - 23 - for (i = 0; i < PMB_ENTRY_MAX; i++) { 24 - addr = PMB_DATA + (i << PMB_E_SHIFT); 25 - data = ctrl_inl(addr); 26 - if (!(data & PMB_V)) 27 - continue; 28 - 29 - if (data & PMB_C) { 30 - #if defined(CONFIG_CACHE_WRITETHROUGH) 31 - data |= PMB_WT; 32 - #elif defined(CONFIG_CACHE_WRITEBACK) 33 - data &= ~PMB_WT; 34 - #else 35 - data &= ~(PMB_C | PMB_WT); 36 - #endif 37 - } 38 - ctrl_outl(data, addr); 39 - } 40 - 41 - back_to_cached(); 42 - 43 - return 0; 44 - } 45 - arch_initcall(fixed_pmb_init);
+136 -136
arch/sh/mm/pmb.c
··· 35 35 36 36 static void __pmb_unmap(struct pmb_entry *); 37 37 38 - static struct kmem_cache *pmb_cache; 38 + static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES]; 39 39 static unsigned long pmb_map; 40 - 41 - static struct pmb_entry pmb_init_map[] = { 42 - /* vpn ppn flags (ub/sz/c/wt) */ 43 - 44 - /* P1 Section Mappings */ 45 - { 0x80000000, 0x00000000, PMB_SZ_64M | PMB_C, }, 46 - { 0x84000000, 0x04000000, PMB_SZ_64M | PMB_C, }, 47 - { 0x88000000, 0x08000000, PMB_SZ_128M | PMB_C, }, 48 - { 0x90000000, 0x10000000, PMB_SZ_64M | PMB_C, }, 49 - { 0x94000000, 0x14000000, PMB_SZ_64M | PMB_C, }, 50 - { 0x98000000, 0x18000000, PMB_SZ_64M | PMB_C, }, 51 - 52 - /* P2 Section Mappings */ 53 - { 0xa0000000, 0x00000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, 54 - { 0xa4000000, 0x04000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, 55 - { 0xa8000000, 0x08000000, PMB_UB | PMB_SZ_128M | PMB_WT, }, 56 - { 0xb0000000, 0x10000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, 57 - { 0xb4000000, 0x14000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, 58 - { 0xb8000000, 0x18000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, 59 - }; 60 40 61 41 static inline unsigned long mk_pmb_entry(unsigned int entry) 62 42 { ··· 53 73 return mk_pmb_entry(entry) | PMB_DATA; 54 74 } 55 75 56 - static DEFINE_SPINLOCK(pmb_list_lock); 57 - static struct pmb_entry *pmb_list; 58 - 59 - static inline void pmb_list_add(struct pmb_entry *pmbe) 76 + static int pmb_alloc_entry(void) 60 77 { 61 - struct pmb_entry **p, *tmp; 78 + unsigned int pos; 62 79 63 - p = &pmb_list; 64 - while ((tmp = *p) != NULL) 65 - p = &tmp->next; 80 + repeat: 81 + pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES); 66 82 67 - pmbe->next = tmp; 68 - *p = pmbe; 83 + if (unlikely(pos > NR_PMB_ENTRIES)) 84 + return -ENOSPC; 85 + 86 + if (test_and_set_bit(pos, &pmb_map)) 87 + goto repeat; 88 + 89 + return pos; 69 90 } 70 91 71 - static inline void pmb_list_del(struct pmb_entry *pmbe) 72 - { 73 - struct pmb_entry **p, *tmp; 74 - 75 - for (p = &pmb_list; (tmp = *p); p = &tmp->next) 76 - if (tmp == pmbe) { 77 - *p = tmp->next; 78 - return; 79 - } 80 - } 81 - 82 - struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, 83 - unsigned long flags) 92 + static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, 93 + unsigned long flags, int entry) 84 94 { 85 95 struct pmb_entry *pmbe; 96 + int pos; 86 97 87 - pmbe = kmem_cache_alloc(pmb_cache, GFP_KERNEL); 98 + if (entry == PMB_NO_ENTRY) { 99 + pos = pmb_alloc_entry(); 100 + if (pos < 0) 101 + return ERR_PTR(pos); 102 + } else { 103 + if (test_bit(entry, &pmb_map)) 104 + return ERR_PTR(-ENOSPC); 105 + pos = entry; 106 + } 107 + 108 + pmbe = &pmb_entry_list[pos]; 88 109 if (!pmbe) 89 110 return ERR_PTR(-ENOMEM); 90 111 91 112 pmbe->vpn = vpn; 92 113 pmbe->ppn = ppn; 93 114 pmbe->flags = flags; 94 - 95 - spin_lock_irq(&pmb_list_lock); 96 - pmb_list_add(pmbe); 97 - spin_unlock_irq(&pmb_list_lock); 115 + pmbe->entry = pos; 98 116 99 117 return pmbe; 100 118 } 101 119 102 - void pmb_free(struct pmb_entry *pmbe) 120 + static void pmb_free(struct pmb_entry *pmbe) 103 121 { 104 - spin_lock_irq(&pmb_list_lock); 105 - pmb_list_del(pmbe); 106 - spin_unlock_irq(&pmb_list_lock); 122 + int pos = pmbe->entry; 107 123 108 - kmem_cache_free(pmb_cache, pmbe); 124 + pmbe->vpn = 0; 125 + pmbe->ppn = 0; 126 + pmbe->flags = 0; 127 + pmbe->entry = 0; 128 + 129 + clear_bit(pos, &pmb_map); 109 130 } 110 131 111 132 /* 112 133 * Must be in P2 for __set_pmb_entry() 113 134 */ 114 - int __set_pmb_entry(unsigned long vpn, unsigned long ppn, 115 - unsigned long flags, int *entry) 135 + static void __set_pmb_entry(unsigned long vpn, unsigned long ppn, 136 + unsigned long flags, int pos) 116 137 { 117 - unsigned int pos = *entry; 118 - 119 - if (unlikely(pos == PMB_NO_ENTRY)) 120 - pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES); 121 - 122 - repeat: 123 - if (unlikely(pos > NR_PMB_ENTRIES)) 124 - return -ENOSPC; 125 - 126 - if (test_and_set_bit(pos, &pmb_map)) { 127 - pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES); 128 - goto repeat; 129 - } 130 - 131 138 ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos)); 132 139 133 140 #ifdef CONFIG_CACHE_WRITETHROUGH ··· 128 161 #endif 129 162 130 163 ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos)); 131 - 132 - *entry = pos; 133 - 134 - return 0; 135 164 } 136 165 137 - int __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe) 166 + static void __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe) 138 167 { 139 - int ret; 140 - 141 168 jump_to_uncached(); 142 - ret = __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &pmbe->entry); 169 + __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, pmbe->entry); 143 170 back_to_cached(); 144 - 145 - return ret; 146 171 } 147 172 148 - void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe) 173 + static void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe) 149 174 { 150 175 unsigned int entry = pmbe->entry; 151 176 unsigned long addr; 152 177 153 - /* 154 - * Don't allow clearing of wired init entries, P1 or P2 access 155 - * without a corresponding mapping in the PMB will lead to reset 156 - * by the TLB. 157 - */ 158 - if (unlikely(entry < ARRAY_SIZE(pmb_init_map) || 159 - entry >= NR_PMB_ENTRIES)) 178 + if (unlikely(entry >= NR_PMB_ENTRIES)) 160 179 return; 161 180 162 181 jump_to_uncached(); ··· 155 202 ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr); 156 203 157 204 back_to_cached(); 158 - 159 - clear_bit(entry, &pmb_map); 160 205 } 161 206 162 207 ··· 190 239 191 240 again: 192 241 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { 193 - int ret; 194 - 195 242 if (size < pmb_sizes[i].size) 196 243 continue; 197 244 198 - pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag); 245 + pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag, 246 + PMB_NO_ENTRY); 199 247 if (IS_ERR(pmbe)) { 200 248 err = PTR_ERR(pmbe); 201 249 goto out; 202 250 } 203 251 204 - ret = set_pmb_entry(pmbe); 205 - if (ret != 0) { 206 - pmb_free(pmbe); 207 - err = -EBUSY; 208 - goto out; 209 - } 252 + set_pmb_entry(pmbe); 210 253 211 254 phys += pmb_sizes[i].size; 212 255 vaddr += pmb_sizes[i].size; ··· 237 292 238 293 void pmb_unmap(unsigned long addr) 239 294 { 240 - struct pmb_entry **p, *pmbe; 295 + struct pmb_entry *pmbe = NULL; 296 + int i; 241 297 242 - for (p = &pmb_list; (pmbe = *p); p = &pmbe->next) 243 - if (pmbe->vpn == addr) 244 - break; 298 + for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { 299 + if (test_bit(i, &pmb_map)) { 300 + pmbe = &pmb_entry_list[i]; 301 + if (pmbe->vpn == addr) 302 + break; 303 + } 304 + } 245 305 246 306 if (unlikely(!pmbe)) 247 307 return; ··· 256 306 257 307 static void __pmb_unmap(struct pmb_entry *pmbe) 258 308 { 259 - WARN_ON(!test_bit(pmbe->entry, &pmb_map)); 309 + BUG_ON(!test_bit(pmbe->entry, &pmb_map)); 260 310 261 311 do { 262 312 struct pmb_entry *pmblink = pmbe; 263 313 264 - if (pmbe->entry != PMB_NO_ENTRY) 265 - clear_pmb_entry(pmbe); 314 + /* 315 + * We may be called before this pmb_entry has been 316 + * entered into the PMB table via set_pmb_entry(), but 317 + * that's OK because we've allocated a unique slot for 318 + * this entry in pmb_alloc() (even if we haven't filled 319 + * it yet). 320 + * 321 + * Therefore, calling clear_pmb_entry() is safe as no 322 + * other mapping can be using that slot. 323 + */ 324 + clear_pmb_entry(pmbe); 266 325 267 326 pmbe = pmblink->link; 268 327 ··· 279 320 } while (pmbe); 280 321 } 281 322 282 - static void pmb_cache_ctor(void *pmb) 323 + #ifdef CONFIG_PMB 324 + int __uses_jump_to_uncached pmb_init(void) 283 325 { 284 - struct pmb_entry *pmbe = pmb; 285 - 286 - memset(pmb, 0, sizeof(struct pmb_entry)); 287 - 288 - pmbe->entry = PMB_NO_ENTRY; 289 - } 290 - 291 - static int __uses_jump_to_uncached pmb_init(void) 292 - { 293 - unsigned int nr_entries = ARRAY_SIZE(pmb_init_map); 294 - unsigned int entry, i; 295 - 296 - BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES)); 297 - 298 - pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0, 299 - SLAB_PANIC, pmb_cache_ctor); 326 + unsigned int i; 327 + long size, ret; 300 328 301 329 jump_to_uncached(); 302 330 303 331 /* 304 - * Ordering is important, P2 must be mapped in the PMB before we 305 - * can set PMB.SE, and P1 must be mapped before we jump back to 306 - * P1 space. 332 + * Insert PMB entries for the P1 and P2 areas so that, after 333 + * we've switched the MMU to 32-bit mode, the semantics of P1 334 + * and P2 are the same as in 29-bit mode, e.g. 335 + * 336 + * P1 - provides a cached window onto physical memory 337 + * P2 - provides an uncached window onto physical memory 307 338 */ 308 - for (entry = 0; entry < nr_entries; entry++) { 309 - struct pmb_entry *pmbe = pmb_init_map + entry; 339 + size = __MEMORY_START + __MEMORY_SIZE; 310 340 311 - __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &entry); 312 - } 341 + ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C); 342 + BUG_ON(ret != size); 343 + 344 + ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB); 345 + BUG_ON(ret != size); 313 346 314 347 ctrl_outl(0, PMB_IRMCR); 315 348 316 349 /* PMB.SE and UB[7] */ 317 - ctrl_outl((1 << 31) | (1 << 7), PMB_PASCR); 350 + ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR); 318 351 319 352 /* Flush out the TLB */ 320 353 i = ctrl_inl(MMUCR); ··· 317 366 318 367 return 0; 319 368 } 320 - arch_initcall(pmb_init); 369 + #else 370 + int __uses_jump_to_uncached pmb_init(void) 371 + { 372 + int i; 373 + unsigned long addr, data; 374 + 375 + jump_to_uncached(); 376 + 377 + for (i = 0; i < PMB_ENTRY_MAX; i++) { 378 + struct pmb_entry *pmbe; 379 + unsigned long vpn, ppn, flags; 380 + 381 + addr = PMB_DATA + (i << PMB_E_SHIFT); 382 + data = ctrl_inl(addr); 383 + if (!(data & PMB_V)) 384 + continue; 385 + 386 + if (data & PMB_C) { 387 + #if defined(CONFIG_CACHE_WRITETHROUGH) 388 + data |= PMB_WT; 389 + #elif defined(CONFIG_CACHE_WRITEBACK) 390 + data &= ~PMB_WT; 391 + #else 392 + data &= ~(PMB_C | PMB_WT); 393 + #endif 394 + } 395 + ctrl_outl(data, addr); 396 + 397 + ppn = data & PMB_PFN_MASK; 398 + 399 + flags = data & (PMB_C | PMB_WT | PMB_UB); 400 + flags |= data & PMB_SZ_MASK; 401 + 402 + addr = PMB_ADDR + (i << PMB_E_SHIFT); 403 + data = ctrl_inl(addr); 404 + 405 + vpn = data & PMB_PFN_MASK; 406 + 407 + pmbe = pmb_alloc(vpn, ppn, flags, i); 408 + WARN_ON(IS_ERR(pmbe)); 409 + } 410 + 411 + back_to_cached(); 412 + 413 + return 0; 414 + } 415 + #endif /* CONFIG_PMB */ 321 416 322 417 static int pmb_seq_show(struct seq_file *file, void *iter) 323 418 { ··· 431 434 static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state) 432 435 { 433 436 static pm_message_t prev_state; 437 + int i; 434 438 435 439 /* Restore the PMB after a resume from hibernation */ 436 440 if (state.event == PM_EVENT_ON && 437 441 prev_state.event == PM_EVENT_FREEZE) { 438 442 struct pmb_entry *pmbe; 439 - spin_lock_irq(&pmb_list_lock); 440 - for (pmbe = pmb_list; pmbe; pmbe = pmbe->next) 441 - set_pmb_entry(pmbe); 442 - spin_unlock_irq(&pmb_list_lock); 443 + for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { 444 + if (test_bit(i, &pmb_map)) { 445 + pmbe = &pmb_entry_list[i]; 446 + set_pmb_entry(pmbe); 447 + } 448 + } 443 449 } 444 450 prev_state = state; 445 451 return 0;
-4
arch/sh/oprofile/Makefile
··· 7 7 timer_int.o ) 8 8 9 9 oprofile-y := $(DRIVER_OBJS) common.o backtrace.o 10 - 11 - oprofile-$(CONFIG_CPU_SUBTYPE_SH7750S) += op_model_sh7750.o 12 - oprofile-$(CONFIG_CPU_SUBTYPE_SH7750) += op_model_sh7750.o 13 - oprofile-$(CONFIG_CPU_SUBTYPE_SH7091) += op_model_sh7750.o
+8 -30
arch/sh/oprofile/common.c
··· 20 20 #include <asm/processor.h> 21 21 #include "op_impl.h" 22 22 23 - extern struct op_sh_model op_model_sh7750_ops __weak; 24 - extern struct op_sh_model op_model_sh4a_ops __weak; 25 - 26 23 static struct op_sh_model *model; 27 24 28 25 static struct op_counter_config ctr[20]; ··· 91 94 */ 92 95 ops->backtrace = sh_backtrace; 93 96 94 - switch (current_cpu_data.type) { 95 - /* SH-4 types */ 96 - case CPU_SH7750: 97 - case CPU_SH7750S: 98 - lmodel = &op_model_sh7750_ops; 99 - break; 100 - 101 - /* SH-4A types */ 102 - case CPU_SH7763: 103 - case CPU_SH7770: 104 - case CPU_SH7780: 105 - case CPU_SH7781: 106 - case CPU_SH7785: 107 - case CPU_SH7786: 108 - case CPU_SH7723: 109 - case CPU_SH7724: 110 - case CPU_SHX3: 111 - lmodel = &op_model_sh4a_ops; 112 - break; 113 - 114 - /* SH4AL-DSP types */ 115 - case CPU_SH7343: 116 - case CPU_SH7722: 117 - case CPU_SH7366: 118 - lmodel = &op_model_sh4a_ops; 119 - break; 120 - } 97 + /* 98 + * XXX 99 + * 100 + * All of the SH7750/SH-4A counters have been converted to perf, 101 + * this infrastructure hook is left for other users until they've 102 + * had a chance to convert over, at which point all of this 103 + * will be deleted. 104 + */ 121 105 122 106 if (!lmodel) 123 107 return -ENODEV;
+1 -1
arch/sh/oprofile/op_impl.h
··· 6 6 unsigned long enabled; 7 7 unsigned long event; 8 8 9 - unsigned long long count; 9 + unsigned long count; 10 10 11 11 /* Dummy values for userspace tool compliance */ 12 12 unsigned long kernel;
-255
arch/sh/oprofile/op_model_sh7750.c
··· 1 - /* 2 - * arch/sh/oprofile/op_model_sh7750.c 3 - * 4 - * OProfile support for SH7750/SH7750S Performance Counters 5 - * 6 - * Copyright (C) 2003 - 2008 Paul Mundt 7 - * 8 - * This file is subject to the terms and conditions of the GNU General Public 9 - * License. See the file "COPYING" in the main directory of this archive 10 - * for more details. 11 - */ 12 - #include <linux/kernel.h> 13 - #include <linux/oprofile.h> 14 - #include <linux/profile.h> 15 - #include <linux/init.h> 16 - #include <linux/errno.h> 17 - #include <linux/interrupt.h> 18 - #include <linux/io.h> 19 - #include <linux/fs.h> 20 - #include "op_impl.h" 21 - 22 - #define PM_CR_BASE 0xff000084 /* 16-bit */ 23 - #define PM_CTR_BASE 0xff100004 /* 32-bit */ 24 - 25 - #define PMCR(n) (PM_CR_BASE + ((n) * 0x04)) 26 - #define PMCTRH(n) (PM_CTR_BASE + 0x00 + ((n) * 0x08)) 27 - #define PMCTRL(n) (PM_CTR_BASE + 0x04 + ((n) * 0x08)) 28 - 29 - #define PMCR_PMM_MASK 0x0000003f 30 - 31 - #define PMCR_CLKF 0x00000100 32 - #define PMCR_PMCLR 0x00002000 33 - #define PMCR_PMST 0x00004000 34 - #define PMCR_PMEN 0x00008000 35 - 36 - struct op_sh_model op_model_sh7750_ops; 37 - 38 - #define NR_CNTRS 2 39 - 40 - static struct sh7750_ppc_register_config { 41 - unsigned int ctrl; 42 - unsigned long cnt_hi; 43 - unsigned long cnt_lo; 44 - } regcache[NR_CNTRS]; 45 - 46 - /* 47 - * There are a number of events supported by each counter (33 in total). 48 - * Since we have 2 counters, each counter will take the event code as it 49 - * corresponds to the PMCR PMM setting. Each counter can be configured 50 - * independently. 51 - * 52 - * Event Code Description 53 - * ---------- ----------- 54 - * 55 - * 0x01 Operand read access 56 - * 0x02 Operand write access 57 - * 0x03 UTLB miss 58 - * 0x04 Operand cache read miss 59 - * 0x05 Operand cache write miss 60 - * 0x06 Instruction fetch (w/ cache) 61 - * 0x07 Instruction TLB miss 62 - * 0x08 Instruction cache miss 63 - * 0x09 All operand accesses 64 - * 0x0a All instruction accesses 65 - * 0x0b OC RAM operand access 66 - * 0x0d On-chip I/O space access 67 - * 0x0e Operand access (r/w) 68 - * 0x0f Operand cache miss (r/w) 69 - * 0x10 Branch instruction 70 - * 0x11 Branch taken 71 - * 0x12 BSR/BSRF/JSR 72 - * 0x13 Instruction execution 73 - * 0x14 Instruction execution in parallel 74 - * 0x15 FPU Instruction execution 75 - * 0x16 Interrupt 76 - * 0x17 NMI 77 - * 0x18 trapa instruction execution 78 - * 0x19 UBCA match 79 - * 0x1a UBCB match 80 - * 0x21 Instruction cache fill 81 - * 0x22 Operand cache fill 82 - * 0x23 Elapsed time 83 - * 0x24 Pipeline freeze by I-cache miss 84 - * 0x25 Pipeline freeze by D-cache miss 85 - * 0x27 Pipeline freeze by branch instruction 86 - * 0x28 Pipeline freeze by CPU register 87 - * 0x29 Pipeline freeze by FPU 88 - * 89 - * Unfortunately we don't have a native exception or interrupt for counter 90 - * overflow (although since these counters can run for 16.3 days without 91 - * overflowing, it's not really necessary). 92 - * 93 - * OProfile on the other hand likes to have samples taken periodically, so 94 - * for now we just piggyback the timer interrupt to get the expected 95 - * behavior. 96 - */ 97 - 98 - static int sh7750_timer_notify(struct pt_regs *regs) 99 - { 100 - oprofile_add_sample(regs, 0); 101 - return 0; 102 - } 103 - 104 - static u64 sh7750_read_counter(int counter) 105 - { 106 - return (u64)((u64)(__raw_readl(PMCTRH(counter)) & 0xffff) << 32) | 107 - __raw_readl(PMCTRL(counter)); 108 - } 109 - 110 - /* 111 - * Files will be in a path like: 112 - * 113 - * /<oprofilefs mount point>/<counter number>/<file> 114 - * 115 - * So when dealing with <file>, we look to the parent dentry for the counter 116 - * number. 117 - */ 118 - static inline int to_counter(struct file *file) 119 - { 120 - const unsigned char *name = file->f_path.dentry->d_parent->d_name.name; 121 - 122 - return (int)simple_strtol(name, NULL, 10); 123 - } 124 - 125 - /* 126 - * XXX: We have 48-bit counters, so we're probably going to want something 127 - * more along the lines of oprofilefs_ullong_to_user().. Truncating to 128 - * unsigned long works fine for now though, as long as we don't attempt to 129 - * profile for too horribly long. 130 - */ 131 - static ssize_t sh7750_read_count(struct file *file, char __user *buf, 132 - size_t count, loff_t *ppos) 133 - { 134 - int counter = to_counter(file); 135 - u64 val = sh7750_read_counter(counter); 136 - 137 - return oprofilefs_ulong_to_user((unsigned long)val, buf, count, ppos); 138 - } 139 - 140 - static ssize_t sh7750_write_count(struct file *file, const char __user *buf, 141 - size_t count, loff_t *ppos) 142 - { 143 - int counter = to_counter(file); 144 - unsigned long val; 145 - 146 - if (oprofilefs_ulong_from_user(&val, buf, count)) 147 - return -EFAULT; 148 - 149 - /* 150 - * Any write will clear the counter, although only 0 should be 151 - * written for this purpose, as we do not support setting the 152 - * counter to an arbitrary value. 153 - */ 154 - WARN_ON(val != 0); 155 - 156 - __raw_writew(__raw_readw(PMCR(counter)) | PMCR_PMCLR, PMCR(counter)); 157 - 158 - return count; 159 - } 160 - 161 - static const struct file_operations count_fops = { 162 - .read = sh7750_read_count, 163 - .write = sh7750_write_count, 164 - }; 165 - 166 - static int sh7750_ppc_create_files(struct super_block *sb, struct dentry *dir) 167 - { 168 - return oprofilefs_create_file(sb, dir, "count", &count_fops); 169 - } 170 - 171 - static void sh7750_ppc_reg_setup(struct op_counter_config *ctr) 172 - { 173 - unsigned int counters = op_model_sh7750_ops.num_counters; 174 - int i; 175 - 176 - for (i = 0; i < counters; i++) { 177 - regcache[i].ctrl = 0; 178 - regcache[i].cnt_hi = 0; 179 - regcache[i].cnt_lo = 0; 180 - 181 - if (!ctr[i].enabled) 182 - continue; 183 - 184 - regcache[i].ctrl |= ctr[i].event | PMCR_PMEN | PMCR_PMST; 185 - regcache[i].cnt_hi = (unsigned long)((ctr->count >> 32) & 0xffff); 186 - regcache[i].cnt_lo = (unsigned long)(ctr->count & 0xffffffff); 187 - } 188 - } 189 - 190 - static void sh7750_ppc_cpu_setup(void *args) 191 - { 192 - unsigned int counters = op_model_sh7750_ops.num_counters; 193 - int i; 194 - 195 - for (i = 0; i < counters; i++) { 196 - __raw_writew(0, PMCR(i)); 197 - __raw_writel(regcache[i].cnt_hi, PMCTRH(i)); 198 - __raw_writel(regcache[i].cnt_lo, PMCTRL(i)); 199 - } 200 - } 201 - 202 - static void sh7750_ppc_cpu_start(void *args) 203 - { 204 - unsigned int counters = op_model_sh7750_ops.num_counters; 205 - int i; 206 - 207 - for (i = 0; i < counters; i++) 208 - __raw_writew(regcache[i].ctrl, PMCR(i)); 209 - } 210 - 211 - static void sh7750_ppc_cpu_stop(void *args) 212 - { 213 - unsigned int counters = op_model_sh7750_ops.num_counters; 214 - int i; 215 - 216 - /* Disable the counters */ 217 - for (i = 0; i < counters; i++) 218 - __raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i)); 219 - } 220 - 221 - static inline void sh7750_ppc_reset(void) 222 - { 223 - unsigned int counters = op_model_sh7750_ops.num_counters; 224 - int i; 225 - 226 - /* Clear the counters */ 227 - for (i = 0; i < counters; i++) 228 - __raw_writew(__raw_readw(PMCR(i)) | PMCR_PMCLR, PMCR(i)); 229 - } 230 - 231 - static int sh7750_ppc_init(void) 232 - { 233 - sh7750_ppc_reset(); 234 - 235 - return register_timer_hook(sh7750_timer_notify); 236 - } 237 - 238 - static void sh7750_ppc_exit(void) 239 - { 240 - unregister_timer_hook(sh7750_timer_notify); 241 - 242 - sh7750_ppc_reset(); 243 - } 244 - 245 - struct op_sh_model op_model_sh7750_ops = { 246 - .cpu_type = "sh/sh7750", 247 - .num_counters = NR_CNTRS, 248 - .reg_setup = sh7750_ppc_reg_setup, 249 - .cpu_setup = sh7750_ppc_cpu_setup, 250 - .cpu_start = sh7750_ppc_cpu_start, 251 - .cpu_stop = sh7750_ppc_cpu_stop, 252 - .init = sh7750_ppc_init, 253 - .exit = sh7750_ppc_exit, 254 - .create_files = sh7750_ppc_create_files, 255 - };
+5 -5
drivers/cdrom/gdrom.c
··· 214 214 gdrom_getsense(NULL); 215 215 return; 216 216 } 217 - outsw(PHYSADDR(GDROM_DATA_REG), cmd, 6); 217 + outsw(GDROM_DATA_REG, cmd, 6); 218 218 } 219 219 220 220 ··· 298 298 err = -EINVAL; 299 299 goto cleanup_readtoc; 300 300 } 301 - insw(PHYSADDR(GDROM_DATA_REG), toc, tocsize/2); 301 + insw(GDROM_DATA_REG, toc, tocsize/2); 302 302 if (gd.status & 0x01) 303 303 err = -EINVAL; 304 304 ··· 449 449 GDROM_DEFAULT_TIMEOUT); 450 450 if (gd.pending) 451 451 goto cleanup_sense; 452 - insw(PHYSADDR(GDROM_DATA_REG), &sense, sense_command->buflen/2); 452 + insw(GDROM_DATA_REG, &sense, sense_command->buflen/2); 453 453 if (sense[1] & 40) { 454 454 printk(KERN_INFO "GDROM: Drive not ready - command aborted\n"); 455 455 goto cleanup_sense; ··· 586 586 spin_unlock(&gdrom_lock); 587 587 block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET; 588 588 block_cnt = blk_rq_sectors(req)/GD_TO_BLK; 589 - ctrl_outl(PHYSADDR(req->buffer), GDROM_DMA_STARTADDR_REG); 589 + ctrl_outl(virt_to_phys(req->buffer), GDROM_DMA_STARTADDR_REG); 590 590 ctrl_outl(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG); 591 591 ctrl_outl(1, GDROM_DMA_DIRECTION_REG); 592 592 ctrl_outl(1, GDROM_DMA_ENABLE_REG); ··· 615 615 cpu_relax(); 616 616 gd.pending = 1; 617 617 gd.transfer = 1; 618 - outsw(PHYSADDR(GDROM_DATA_REG), &read_command->cmd, 6); 618 + outsw(GDROM_DATA_REG, &read_command->cmd, 6); 619 619 timeout = jiffies + HZ / 2; 620 620 /* Wait for any pending DMA to finish */ 621 621 while (ctrl_inb(GDROM_DMA_STATUS_REG) &&
+1 -1
drivers/input/keyboard/sh_keysc.c
··· 18 18 #include <linux/delay.h> 19 19 #include <linux/platform_device.h> 20 20 #include <linux/input.h> 21 + #include <linux/input/sh_keysc.h> 21 22 #include <linux/clk.h> 22 23 #include <linux/io.h> 23 - #include <asm/sh_keysc.h> 24 24 25 25 #define KYCR1_OFFS 0x00 26 26 #define KYCR2_OFFS 0x04
+8
drivers/mfd/Kconfig
··· 35 35 This driver supports the ASIC3 multifunction chip found on many 36 36 PDAs (mainly iPAQ and HTC based ones) 37 37 38 + config MFD_SH_MOBILE_SDHI 39 + bool "Support for SuperH Mobile SDHI" 40 + depends on SUPERH 41 + select MFD_CORE 42 + ---help--- 43 + This driver supports the SDHI hardware block found in many 44 + SuperH Mobile SoCs. 45 + 38 46 config MFD_DM355EVM_MSP 39 47 bool "DaVinci DM355 EVM microcontroller" 40 48 depends on I2C && MACH_DAVINCI_DM355_EVM
+1
drivers/mfd/Makefile
··· 4 4 5 5 obj-$(CONFIG_MFD_SM501) += sm501.o 6 6 obj-$(CONFIG_MFD_ASIC3) += asic3.o 7 + obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o 7 8 8 9 obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o 9 10 obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
+156
drivers/mfd/sh_mobile_sdhi.c
··· 1 + /* 2 + * SuperH Mobile SDHI 3 + * 4 + * Copyright (C) 2009 Magnus Damm 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * Based on "Compaq ASIC3 support": 11 + * 12 + * Copyright 2001 Compaq Computer Corporation. 13 + * Copyright 2004-2005 Phil Blundell 14 + * Copyright 2007-2008 OpenedHand Ltd. 15 + * 16 + * Authors: Phil Blundell <pb@handhelds.org>, 17 + * Samuel Ortiz <sameo@openedhand.com> 18 + * 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/clk.h> 23 + #include <linux/platform_device.h> 24 + 25 + #include <linux/mfd/core.h> 26 + #include <linux/mfd/tmio.h> 27 + #include <linux/mfd/sh_mobile_sdhi.h> 28 + 29 + struct sh_mobile_sdhi { 30 + struct clk *clk; 31 + struct tmio_mmc_data mmc_data; 32 + struct mfd_cell cell_mmc; 33 + }; 34 + 35 + static struct resource sh_mobile_sdhi_resources[] = { 36 + { 37 + .start = 0x000, 38 + .end = 0x1ff, 39 + .flags = IORESOURCE_MEM, 40 + }, 41 + { 42 + .start = 0, 43 + .end = 0, 44 + .flags = IORESOURCE_IRQ, 45 + }, 46 + }; 47 + 48 + static struct mfd_cell sh_mobile_sdhi_cell = { 49 + .name = "tmio-mmc", 50 + .num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources), 51 + .resources = sh_mobile_sdhi_resources, 52 + }; 53 + 54 + static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state) 55 + { 56 + struct platform_device *pdev = to_platform_device(tmio->dev.parent); 57 + struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; 58 + 59 + if (p && p->set_pwr) 60 + p->set_pwr(pdev, state); 61 + } 62 + 63 + static int __init sh_mobile_sdhi_probe(struct platform_device *pdev) 64 + { 65 + struct sh_mobile_sdhi *priv; 66 + struct resource *mem; 67 + char clk_name[8]; 68 + int ret, irq; 69 + 70 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 71 + if (!mem) 72 + dev_err(&pdev->dev, "missing MEM resource\n"); 73 + 74 + irq = platform_get_irq(pdev, 0); 75 + if (irq < 0) 76 + dev_err(&pdev->dev, "missing IRQ resource\n"); 77 + 78 + if (!mem || (irq < 0)) 79 + return -EINVAL; 80 + 81 + priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL); 82 + if (priv == NULL) { 83 + dev_err(&pdev->dev, "kzalloc failed\n"); 84 + return -ENOMEM; 85 + } 86 + 87 + snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id); 88 + priv->clk = clk_get(&pdev->dev, clk_name); 89 + if (IS_ERR(priv->clk)) { 90 + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); 91 + ret = PTR_ERR(priv->clk); 92 + kfree(priv); 93 + return ret; 94 + } 95 + 96 + clk_enable(priv->clk); 97 + 98 + /* FIXME: silly const unsigned int hclk */ 99 + *(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk); 100 + priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr; 101 + 102 + memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); 103 + priv->cell_mmc.driver_data = &priv->mmc_data; 104 + priv->cell_mmc.platform_data = &priv->cell_mmc; 105 + priv->cell_mmc.data_size = sizeof(priv->cell_mmc); 106 + 107 + platform_set_drvdata(pdev, priv); 108 + 109 + ret = mfd_add_devices(&pdev->dev, pdev->id, 110 + &priv->cell_mmc, 1, mem, irq); 111 + if (ret) { 112 + clk_disable(priv->clk); 113 + clk_put(priv->clk); 114 + kfree(priv); 115 + } 116 + 117 + return ret; 118 + } 119 + 120 + static int sh_mobile_sdhi_remove(struct platform_device *pdev) 121 + { 122 + struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev); 123 + 124 + mfd_remove_devices(&pdev->dev); 125 + clk_disable(priv->clk); 126 + clk_put(priv->clk); 127 + kfree(priv); 128 + 129 + return 0; 130 + } 131 + 132 + static struct platform_driver sh_mobile_sdhi_driver = { 133 + .driver = { 134 + .name = "sh_mobile_sdhi", 135 + .owner = THIS_MODULE, 136 + }, 137 + .probe = sh_mobile_sdhi_probe, 138 + .remove = __devexit_p(sh_mobile_sdhi_remove), 139 + }; 140 + 141 + static int __init sh_mobile_sdhi_init(void) 142 + { 143 + return platform_driver_register(&sh_mobile_sdhi_driver); 144 + } 145 + 146 + static void __exit sh_mobile_sdhi_exit(void) 147 + { 148 + platform_driver_unregister(&sh_mobile_sdhi_driver); 149 + } 150 + 151 + module_init(sh_mobile_sdhi_init); 152 + module_exit(sh_mobile_sdhi_exit); 153 + 154 + MODULE_DESCRIPTION("SuperH Mobile SDHI driver"); 155 + MODULE_AUTHOR("Magnus Damm"); 156 + MODULE_LICENSE("GPL v2");
+1 -1
drivers/mmc/host/Kconfig
··· 329 329 330 330 config MMC_TMIO 331 331 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" 332 - depends on MFD_TMIO || MFD_ASIC3 332 + depends on MFD_TMIO || MFD_ASIC3 || SUPERH 333 333 help 334 334 This provides support for the SD/MMC cell found in TC6393XB, 335 335 T7L66XB and also HTC ASIC3
+1 -1
drivers/rtc/rtc-ds1302.c
··· 201 201 .name = DRV_NAME, 202 202 .owner = THIS_MODULE, 203 203 }, 204 - .remove = __exit_p(ds1302_rtc_remove), 204 + .remove = __devexit_p(ds1302_rtc_remove), 205 205 }; 206 206 207 207 static int __init ds1302_rtc_init(void)
+1 -1
drivers/serial/Kconfig
··· 996 996 997 997 config SERIAL_SH_SCI 998 998 tristate "SuperH SCI(F) serial port support" 999 - depends on SUPERH || H8300 999 + depends on HAVE_CLK && (SUPERH || H8300) 1000 1000 select SERIAL_CORE 1001 1001 1002 1002 config SERIAL_SH_SCI_NR_UARTS
+4 -55
drivers/serial/sh-sci.c
··· 50 50 #include <linux/list.h> 51 51 52 52 #ifdef CONFIG_SUPERH 53 - #include <asm/clock.h> 54 53 #include <asm/sh_bios.h> 55 54 #endif 56 55 ··· 78 79 struct timer_list break_timer; 79 80 int break_flag; 80 81 81 - #ifdef CONFIG_HAVE_CLK 82 82 /* Interface clock */ 83 83 struct clk *iclk; 84 84 /* Data clock */ 85 85 struct clk *dclk; 86 - #endif 86 + 87 87 struct list_head node; 88 88 }; 89 89 90 90 struct sh_sci_priv { 91 91 spinlock_t lock; 92 92 struct list_head ports; 93 - 94 - #ifdef CONFIG_HAVE_CLK 95 93 struct notifier_block clk_nb; 96 - #endif 97 94 }; 98 95 99 96 /* Function prototypes */ ··· 150 155 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port)); 151 156 } 152 157 #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ 153 - 154 - #if defined(__H8300S__) 155 - enum { sci_disable, sci_enable }; 156 - 157 - static void h8300_sci_config(struct uart_port *port, unsigned int ctrl) 158 - { 159 - volatile unsigned char *mstpcrl = (volatile unsigned char *)MSTPCRL; 160 - int ch = (port->mapbase - SMR0) >> 3; 161 - unsigned char mask = 1 << (ch+1); 162 - 163 - if (ctrl == sci_disable) 164 - *mstpcrl |= mask; 165 - else 166 - *mstpcrl &= ~mask; 167 - } 168 - 169 - static void h8300_sci_enable(struct uart_port *port) 170 - { 171 - h8300_sci_config(port, sci_enable); 172 - } 173 - 174 - static void h8300_sci_disable(struct uart_port *port) 175 - { 176 - h8300_sci_config(port, sci_disable); 177 - } 178 - #endif 179 158 180 159 #if defined(__H8300H__) || defined(__H8300S__) 181 160 static void sci_init_pins(struct uart_port *port, unsigned int cflag) ··· 702 733 return ret; 703 734 } 704 735 705 - #ifdef CONFIG_HAVE_CLK 706 736 /* 707 737 * Here we define a transistion notifier so that we can update all of our 708 738 * ports' baud rate when the peripheral clock changes. ··· 719 751 spin_lock_irqsave(&priv->lock, flags); 720 752 list_for_each_entry(sci_port, &priv->ports, node) 721 753 sci_port->port.uartclk = clk_get_rate(sci_port->dclk); 722 - 723 754 spin_unlock_irqrestore(&priv->lock, flags); 724 755 } 725 756 ··· 745 778 746 779 clk_disable(sci_port->dclk); 747 780 } 748 - #endif 749 781 750 782 static int sci_request_irq(struct sci_port *port) 751 783 { ··· 799 833 800 834 static unsigned int sci_tx_empty(struct uart_port *port) 801 835 { 802 - /* Can't detect */ 803 - return TIOCSER_TEMT; 836 + unsigned short status = sci_in(port, SCxSR); 837 + return status & SCxSR_TEND(port) ? TIOCSER_TEMT : 0; 804 838 } 805 839 806 840 static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) ··· 1043 1077 sci_port->port.iotype = UPIO_MEM; 1044 1078 sci_port->port.line = index; 1045 1079 sci_port->port.fifosize = 1; 1046 - 1047 - #if defined(__H8300H__) || defined(__H8300S__) 1048 - #ifdef __H8300S__ 1049 - sci_port->enable = h8300_sci_enable; 1050 - sci_port->disable = h8300_sci_disable; 1051 - #endif 1052 - sci_port->port.uartclk = CONFIG_CPU_CLOCK; 1053 - #elif defined(CONFIG_HAVE_CLK) 1054 1080 sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; 1055 1081 sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); 1056 1082 sci_port->enable = sci_clk_enable; 1057 1083 sci_port->disable = sci_clk_disable; 1058 - #else 1059 - #error "Need a valid uartclk" 1060 - #endif 1061 1084 1062 1085 sci_port->break_timer.data = (unsigned long)sci_port; 1063 1086 sci_port->break_timer.function = sci_break_timer; ··· 1061 1106 sci_port->type = sci_port->port.type = p->type; 1062 1107 1063 1108 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); 1064 - 1065 1109 } 1066 1110 1067 1111 #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE ··· 1193 1239 struct sci_port *p; 1194 1240 unsigned long flags; 1195 1241 1196 - #ifdef CONFIG_HAVE_CLK 1197 1242 cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); 1198 - #endif 1199 1243 1200 1244 spin_lock_irqsave(&priv->lock, flags); 1201 1245 list_for_each_entry(p, &priv->ports, node) 1202 1246 uart_remove_one_port(&sci_uart_driver, &p->port); 1203 - 1204 1247 spin_unlock_irqrestore(&priv->lock, flags); 1205 1248 1206 1249 kfree(priv); ··· 1258 1307 spin_lock_init(&priv->lock); 1259 1308 platform_set_drvdata(dev, priv); 1260 1309 1261 - #ifdef CONFIG_HAVE_CLK 1262 1310 priv->clk_nb.notifier_call = sci_notifier; 1263 1311 cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); 1264 - #endif 1265 1312 1266 1313 if (dev->id != -1) { 1267 1314 ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]); ··· 1319 1370 1320 1371 static struct platform_driver sci_driver = { 1321 1372 .probe = sci_probe, 1322 - .remove = __devexit_p(sci_remove), 1373 + .remove = sci_remove, 1323 1374 .driver = { 1324 1375 .name = "sh-sci", 1325 1376 .owner = THIS_MODULE,
+1 -1
drivers/serial/sh-sci.h
··· 1 1 #include <linux/serial_core.h> 2 - #include <asm/io.h> 2 + #include <linux/io.h> 3 3 #include <linux/gpio.h> 4 4 5 5 #if defined(CONFIG_H83007) || defined(CONFIG_H83068)
+1
drivers/sh/Makefile
··· 3 3 # 4 4 obj-$(CONFIG_SUPERHYWAY) += superhyway/ 5 5 obj-$(CONFIG_MAPLE) += maple/ 6 + obj-$(CONFIG_GENERIC_GPIO) += pfc.o 6 7 obj-y += intc.o
+109 -14
drivers/sh/intc.c
··· 2 2 * Shared interrupt handling code for IPR and INTC2 types of IRQs. 3 3 * 4 4 * Copyright (C) 2007, 2008 Magnus Damm 5 + * Copyright (C) 2009 Paul Mundt 5 6 * 6 7 * Based on intc2.c and ipr.c 7 8 * ··· 25 24 #include <linux/sysdev.h> 26 25 #include <linux/list.h> 27 26 #include <linux/topology.h> 27 + #include <linux/bitmap.h> 28 28 29 29 #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ 30 30 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ ··· 61 59 62 60 static LIST_HEAD(intc_list); 63 61 62 + /* 63 + * The intc_irq_map provides a global map of bound IRQ vectors for a 64 + * given platform. Allocation of IRQs are either static through the CPU 65 + * vector map, or dynamic in the case of board mux vectors or MSI. 66 + * 67 + * As this is a central point for all IRQ controllers on the system, 68 + * each of the available sources are mapped out here. This combined with 69 + * sparseirq makes it quite trivial to keep the vector map tightly packed 70 + * when dynamically creating IRQs, as well as tying in to otherwise 71 + * unused irq_desc positions in the sparse array. 72 + */ 73 + static DECLARE_BITMAP(intc_irq_map, NR_IRQS); 74 + static DEFINE_SPINLOCK(vector_lock); 75 + 64 76 #ifdef CONFIG_SMP 65 77 #define IS_SMP(x) x.smp 66 78 #define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) ··· 86 70 #endif 87 71 88 72 static unsigned int intc_prio_level[NR_IRQS]; /* for now */ 89 - #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 90 73 static unsigned long ack_handle[NR_IRQS]; 91 - #endif 92 74 93 75 static inline struct intc_desc_int *get_intc_desc(unsigned int irq) 94 76 { ··· 264 250 return 0; /* allow wakeup, but setup hardware in intc_suspend() */ 265 251 } 266 252 267 - #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 268 253 static void intc_mask_ack(unsigned int irq) 269 254 { 270 255 struct intc_desc_int *d = get_intc_desc(irq); ··· 295 282 } 296 283 } 297 284 } 298 - #endif 299 285 300 286 static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, 301 287 unsigned int nr_hp, ··· 513 501 return 0; 514 502 } 515 503 516 - #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 517 504 static unsigned int __init intc_ack_data(struct intc_desc *desc, 518 505 struct intc_desc_int *d, 519 506 intc_enum enum_id) ··· 544 533 545 534 return 0; 546 535 } 547 - #endif 548 536 549 537 static unsigned int __init intc_sense_data(struct intc_desc *desc, 550 538 struct intc_desc_int *d, ··· 581 571 { 582 572 struct intc_handle_int *hp; 583 573 unsigned int data[2], primary; 574 + 575 + /* 576 + * Register the IRQ position with the global IRQ map 577 + */ 578 + set_bit(irq, intc_irq_map); 584 579 585 580 /* Prefer single interrupt source bitmap over other combinations: 586 581 * 1. bitmap, single interrupt source ··· 656 641 /* irq should be disabled by default */ 657 642 d->chip.mask(irq); 658 643 659 - #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 660 644 if (desc->ack_regs) 661 645 ack_handle[irq] = intc_ack_data(desc, d, enum_id); 662 - #endif 663 646 } 664 647 665 648 static unsigned int __init save_reg(struct intc_desc_int *d, ··· 694 681 d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0; 695 682 d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; 696 683 d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; 697 - 698 - #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 699 684 d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; 700 - #endif 685 + 701 686 d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT); 702 687 #ifdef CONFIG_SMP 703 688 d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT); ··· 738 727 d->chip.set_type = intc_set_sense; 739 728 d->chip.set_wake = intc_set_wake; 740 729 741 - #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 742 730 if (desc->ack_regs) { 743 731 for (i = 0; i < desc->nr_ack_regs; i++) 744 732 k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); 745 733 746 734 d->chip.mask_ack = intc_mask_ack; 747 735 } 748 - #endif 749 736 750 737 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ 751 738 ··· 865 856 866 857 return error; 867 858 } 868 - 869 859 device_initcall(register_intc_sysdevs); 860 + 861 + /* 862 + * Dynamic IRQ allocation and deallocation 863 + */ 864 + static unsigned int create_irq_on_node(unsigned int irq_want, int node) 865 + { 866 + unsigned int irq = 0, new; 867 + unsigned long flags; 868 + struct irq_desc *desc; 869 + 870 + spin_lock_irqsave(&vector_lock, flags); 871 + 872 + /* 873 + * First try the wanted IRQ, then scan. 874 + */ 875 + if (test_and_set_bit(irq_want, intc_irq_map)) { 876 + new = find_first_zero_bit(intc_irq_map, nr_irqs); 877 + if (unlikely(new == nr_irqs)) 878 + goto out_unlock; 879 + 880 + desc = irq_to_desc_alloc_node(new, node); 881 + if (unlikely(!desc)) { 882 + pr_info("can't get irq_desc for %d\n", new); 883 + goto out_unlock; 884 + } 885 + 886 + desc = move_irq_desc(desc, node); 887 + __set_bit(new, intc_irq_map); 888 + irq = new; 889 + } 890 + 891 + out_unlock: 892 + spin_unlock_irqrestore(&vector_lock, flags); 893 + 894 + if (irq > 0) 895 + dynamic_irq_init(irq); 896 + 897 + return irq; 898 + } 899 + 900 + int create_irq(void) 901 + { 902 + int nid = cpu_to_node(smp_processor_id()); 903 + int irq; 904 + 905 + irq = create_irq_on_node(NR_IRQS_LEGACY, nid); 906 + if (irq == 0) 907 + irq = -1; 908 + 909 + return irq; 910 + } 911 + 912 + void destroy_irq(unsigned int irq) 913 + { 914 + unsigned long flags; 915 + 916 + dynamic_irq_cleanup(irq); 917 + 918 + spin_lock_irqsave(&vector_lock, flags); 919 + __clear_bit(irq, intc_irq_map); 920 + spin_unlock_irqrestore(&vector_lock, flags); 921 + } 922 + 923 + int reserve_irq_vector(unsigned int irq) 924 + { 925 + unsigned long flags; 926 + int ret = 0; 927 + 928 + spin_lock_irqsave(&vector_lock, flags); 929 + if (test_and_set_bit(irq, intc_irq_map)) 930 + ret = -EBUSY; 931 + spin_unlock_irqrestore(&vector_lock, flags); 932 + 933 + return ret; 934 + } 935 + 936 + void reserve_irq_legacy(void) 937 + { 938 + unsigned long flags; 939 + int i, j; 940 + 941 + spin_lock_irqsave(&vector_lock, flags); 942 + j = find_first_bit(intc_irq_map, nr_irqs); 943 + for (i = 0; i < j; i++) 944 + __set_bit(i, intc_irq_map); 945 + spin_unlock_irqrestore(&vector_lock, flags); 946 + }
+2 -2
drivers/sh/maple/maple.c
··· 106 106 * max delay is 11 107 107 */ 108 108 ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(0xFFFF), MAPLE_SPEED); 109 - ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); 109 + ctrl_outl(virt_to_phys(maple_sendbuf), MAPLE_DMAADDR); 110 110 ctrl_outl(1, MAPLE_ENABLE); 111 111 } 112 112 ··· 258 258 maple_lastptr = maple_sendptr; 259 259 260 260 *maple_sendptr++ = (port << 16) | len | 0x80000000; 261 - *maple_sendptr++ = PHYSADDR(mq->recvbuf->buf); 261 + *maple_sendptr++ = virt_to_phys(mq->recvbuf->buf); 262 262 *maple_sendptr++ = 263 263 mq->command | (to << 8) | (from << 16) | (len << 24); 264 264 while (len-- > 0)
+23 -7
drivers/video/sh_mobile_lcdcfb.c
··· 281 281 struct list_head *pagelist) 282 282 { 283 283 struct sh_mobile_lcdc_chan *ch = info->par; 284 - unsigned int nr_pages; 285 284 286 285 /* enable clocks before accessing hardware */ 287 286 sh_mobile_lcdc_clk_on(ch->lcdc); 288 287 289 - nr_pages = sh_mobile_lcdc_sginit(info, pagelist); 290 - dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 288 + /* 289 + * It's possible to get here without anything on the pagelist via 290 + * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync() 291 + * invocation. In the former case, the acceleration routines are 292 + * stepped in to when using the framebuffer console causing the 293 + * workqueue to be scheduled without any dirty pages on the list. 294 + * 295 + * Despite this, a panel update is still needed given that the 296 + * acceleration routines have their own methods for writing in 297 + * that still need to be updated. 298 + * 299 + * The fsync() and empty pagelist case could be optimized for, 300 + * but we don't bother, as any application exhibiting such 301 + * behaviour is fundamentally broken anyways. 302 + */ 303 + if (!list_empty(pagelist)) { 304 + unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist); 291 305 292 - /* trigger panel update */ 293 - lcdc_write_chan(ch, LDSM2R, 1); 294 - 295 - dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 306 + /* trigger panel update */ 307 + dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 308 + lcdc_write_chan(ch, LDSM2R, 1); 309 + dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); 310 + } else 311 + lcdc_write_chan(ch, LDSM2R, 1); 296 312 } 297 313 298 314 static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
+8
include/linux/mfd/sh_mobile_sdhi.h
··· 1 + #ifndef __SH_MOBILE_SDHI_H__ 2 + #define __SH_MOBILE_SDHI_H__ 3 + 4 + struct sh_mobile_sdhi_info { 5 + void (*set_pwr)(struct platform_device *pdev, int state); 6 + }; 7 + 8 + #endif /* __SH_MOBILE_SDHI_H__ */
+3 -4
include/linux/sh_intc.h
··· 57 57 struct intc_sense_reg *sense_regs; 58 58 unsigned int nr_sense_regs; 59 59 char *name; 60 - #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 61 60 struct intc_mask_reg *ack_regs; 62 61 unsigned int nr_ack_regs; 63 - #endif 64 62 }; 65 63 66 64 #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) ··· 71 73 chipname, \ 72 74 } 73 75 74 - #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 75 76 #define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \ 76 77 mask_regs, prio_regs, sense_regs, ack_regs) \ 77 78 struct intc_desc symbol __initdata = { \ ··· 80 83 chipname, \ 81 84 _INTC_ARRAY(ack_regs), \ 82 85 } 83 - #endif 84 86 85 87 void __init register_intc_controller(struct intc_desc *desc); 86 88 int intc_set_priority(unsigned int irq, unsigned int prio); 89 + 90 + int reserve_irq_vector(unsigned int irq); 91 + void reserve_irq_legacy(void); 87 92 88 93 #endif /* __SH_INTC_H */
+96
include/linux/sh_pfc.h
··· 1 + /* 2 + * SuperH Pin Function Controller Support 3 + * 4 + * Copyright (c) 2008 Magnus Damm 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + 11 + #ifndef __SH_PFC_H 12 + #define __SH_PFC_H 13 + 14 + #include <asm-generic/gpio.h> 15 + 16 + typedef unsigned short pinmux_enum_t; 17 + typedef unsigned short pinmux_flag_t; 18 + 19 + #define PINMUX_TYPE_NONE 0 20 + #define PINMUX_TYPE_FUNCTION 1 21 + #define PINMUX_TYPE_GPIO 2 22 + #define PINMUX_TYPE_OUTPUT 3 23 + #define PINMUX_TYPE_INPUT 4 24 + #define PINMUX_TYPE_INPUT_PULLUP 5 25 + #define PINMUX_TYPE_INPUT_PULLDOWN 6 26 + 27 + #define PINMUX_FLAG_TYPE (0x7) 28 + #define PINMUX_FLAG_WANT_PULLUP (1 << 3) 29 + #define PINMUX_FLAG_WANT_PULLDOWN (1 << 4) 30 + 31 + #define PINMUX_FLAG_DBIT_SHIFT 5 32 + #define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT) 33 + #define PINMUX_FLAG_DREG_SHIFT 10 34 + #define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT) 35 + 36 + struct pinmux_gpio { 37 + pinmux_enum_t enum_id; 38 + pinmux_flag_t flags; 39 + }; 40 + 41 + #define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark } 42 + #define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0 43 + 44 + struct pinmux_cfg_reg { 45 + unsigned long reg, reg_width, field_width; 46 + unsigned long *cnt; 47 + pinmux_enum_t *enum_ids; 48 + }; 49 + 50 + #define PINMUX_CFG_REG(name, r, r_width, f_width) \ 51 + .reg = r, .reg_width = r_width, .field_width = f_width, \ 52 + .cnt = (unsigned long [r_width / f_width]) {}, \ 53 + .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \ 54 + 55 + struct pinmux_data_reg { 56 + unsigned long reg, reg_width, reg_shadow; 57 + pinmux_enum_t *enum_ids; 58 + }; 59 + 60 + #define PINMUX_DATA_REG(name, r, r_width) \ 61 + .reg = r, .reg_width = r_width, \ 62 + .enum_ids = (pinmux_enum_t [r_width]) \ 63 + 64 + struct pinmux_range { 65 + pinmux_enum_t begin; 66 + pinmux_enum_t end; 67 + pinmux_enum_t force; 68 + }; 69 + 70 + struct pinmux_info { 71 + char *name; 72 + pinmux_enum_t reserved_id; 73 + struct pinmux_range data; 74 + struct pinmux_range input; 75 + struct pinmux_range input_pd; 76 + struct pinmux_range input_pu; 77 + struct pinmux_range output; 78 + struct pinmux_range mark; 79 + struct pinmux_range function; 80 + 81 + unsigned first_gpio, last_gpio; 82 + 83 + struct pinmux_gpio *gpios; 84 + struct pinmux_cfg_reg *cfg_regs; 85 + struct pinmux_data_reg *data_regs; 86 + 87 + pinmux_enum_t *gpio_data; 88 + unsigned int gpio_data_size; 89 + 90 + unsigned long *gpio_in_use; 91 + struct gpio_chip chip; 92 + }; 93 + 94 + int register_pinmux(struct pinmux_info *pip); 95 + 96 + #endif /* __SH_PFC_H */