diff options
25 files changed, 1250 insertions, 552 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8a9011dced14..2d264fa84959 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
| @@ -25,6 +25,7 @@ config SUPERH | |||
| 25 | select GENERIC_ATOMIC64 | 25 | select GENERIC_ATOMIC64 |
| 26 | # Support the deprecated APIs until MFD and GPIOLIB catch up. | 26 | # Support the deprecated APIs until MFD and GPIOLIB catch up. |
| 27 | select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB | 27 | select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB |
| 28 | select GENERIC_IRQ_SHOW | ||
| 28 | help | 29 | help |
| 29 | The SuperH is a RISC processor targeted for use in embedded systems | 30 | The SuperH is a RISC processor targeted for use in embedded systems |
| 30 | and consumer electronics; it was also used in the Sega Dreamcast | 31 | and consumer electronics; it was also used in the Sega Dreamcast |
| @@ -434,6 +435,8 @@ config CPU_SUBTYPE_SH7757 | |||
| 434 | select CPU_SH4A | 435 | select CPU_SH4A |
| 435 | select CPU_SHX2 | 436 | select CPU_SHX2 |
| 436 | select ARCH_WANT_OPTIONAL_GPIOLIB | 437 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 438 | select USB_ARCH_HAS_OHCI | ||
| 439 | select USB_ARCH_HAS_EHCI | ||
| 437 | help | 440 | help |
| 438 | Select SH7757 if you have a SH4A SH7757 CPU. | 441 | Select SH7757 if you have a SH4A SH7757 CPU. |
| 439 | 442 | ||
diff --git a/arch/sh/boards/board-espt.c b/arch/sh/boards/board-espt.c index d5ce5e18eb37..9da92ac36533 100644 --- a/arch/sh/boards/board-espt.c +++ b/arch/sh/boards/board-espt.c | |||
| @@ -66,6 +66,11 @@ static struct resource sh_eth_resources[] = { | |||
| 66 | .end = 0xFEE00F7C - 1, | 66 | .end = 0xFEE00F7C - 1, |
| 67 | .flags = IORESOURCE_MEM, | 67 | .flags = IORESOURCE_MEM, |
| 68 | }, { | 68 | }, { |
| 69 | .start = 0xFEE01800, /* TSU */ | ||
| 70 | .end = 0xFEE01FFF, | ||
| 71 | .flags = IORESOURCE_MEM, | ||
| 72 | }, { | ||
| 73 | |||
| 69 | .start = 57, /* irq number */ | 74 | .start = 57, /* irq number */ |
| 70 | .flags = IORESOURCE_IRQ, | 75 | .flags = IORESOURCE_IRQ, |
| 71 | }, | 76 | }, |
| @@ -74,6 +79,8 @@ static struct resource sh_eth_resources[] = { | |||
| 74 | static struct sh_eth_plat_data sh7763_eth_pdata = { | 79 | static struct sh_eth_plat_data sh7763_eth_pdata = { |
| 75 | .phy = 0, | 80 | .phy = 0, |
| 76 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 81 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
| 82 | .register_type = SH_ETH_REG_GIGABIT, | ||
| 83 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
| 77 | }; | 84 | }; |
| 78 | 85 | ||
| 79 | static struct platform_device espt_eth_device = { | 86 | static struct platform_device espt_eth_device = { |
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c index c475f1056ab4..a9e33569ad38 100644 --- a/arch/sh/boards/board-sh7757lcr.c +++ b/arch/sh/boards/board-sh7757lcr.c | |||
| @@ -15,6 +15,9 @@ | |||
| 15 | #include <linux/spi/spi.h> | 15 | #include <linux/spi/spi.h> |
| 16 | #include <linux/spi/flash.h> | 16 | #include <linux/spi/flash.h> |
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | #include <linux/mmc/host.h> | ||
| 19 | #include <linux/mmc/sh_mmcif.h> | ||
| 20 | #include <linux/mfd/sh_mobile_sdhi.h> | ||
| 18 | #include <cpu/sh7757.h> | 21 | #include <cpu/sh7757.h> |
| 19 | #include <asm/sh_eth.h> | 22 | #include <asm/sh_eth.h> |
| 20 | #include <asm/heartbeat.h> | 23 | #include <asm/heartbeat.h> |
| @@ -44,6 +47,17 @@ static struct platform_device heartbeat_device = { | |||
| 44 | }; | 47 | }; |
| 45 | 48 | ||
| 46 | /* Fast Ethernet */ | 49 | /* Fast Ethernet */ |
| 50 | #define GBECONT 0xffc10100 | ||
| 51 | #define GBECONT_RMII1 BIT(17) | ||
| 52 | #define GBECONT_RMII0 BIT(16) | ||
| 53 | static void sh7757_eth_set_mdio_gate(unsigned long addr) | ||
| 54 | { | ||
| 55 | if ((addr & 0x00000fff) < 0x0800) | ||
| 56 | writel(readl(GBECONT) | GBECONT_RMII0, GBECONT); | ||
| 57 | else | ||
| 58 | writel(readl(GBECONT) | GBECONT_RMII1, GBECONT); | ||
| 59 | } | ||
| 60 | |||
| 47 | static struct resource sh_eth0_resources[] = { | 61 | static struct resource sh_eth0_resources[] = { |
| 48 | { | 62 | { |
| 49 | .start = 0xfef00000, | 63 | .start = 0xfef00000, |
| @@ -59,6 +73,8 @@ static struct resource sh_eth0_resources[] = { | |||
| 59 | static struct sh_eth_plat_data sh7757_eth0_pdata = { | 73 | static struct sh_eth_plat_data sh7757_eth0_pdata = { |
| 60 | .phy = 1, | 74 | .phy = 1, |
| 61 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 75 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
| 76 | .register_type = SH_ETH_REG_FAST_SH4, | ||
| 77 | .set_mdio_gate = sh7757_eth_set_mdio_gate, | ||
| 62 | }; | 78 | }; |
| 63 | 79 | ||
| 64 | static struct platform_device sh7757_eth0_device = { | 80 | static struct platform_device sh7757_eth0_device = { |
| @@ -86,6 +102,8 @@ static struct resource sh_eth1_resources[] = { | |||
| 86 | static struct sh_eth_plat_data sh7757_eth1_pdata = { | 102 | static struct sh_eth_plat_data sh7757_eth1_pdata = { |
| 87 | .phy = 1, | 103 | .phy = 1, |
| 88 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 104 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
| 105 | .register_type = SH_ETH_REG_FAST_SH4, | ||
| 106 | .set_mdio_gate = sh7757_eth_set_mdio_gate, | ||
| 89 | }; | 107 | }; |
| 90 | 108 | ||
| 91 | static struct platform_device sh7757_eth1_device = { | 109 | static struct platform_device sh7757_eth1_device = { |
| @@ -98,10 +116,173 @@ static struct platform_device sh7757_eth1_device = { | |||
| 98 | }, | 116 | }, |
| 99 | }; | 117 | }; |
| 100 | 118 | ||
| 119 | static void sh7757_eth_giga_set_mdio_gate(unsigned long addr) | ||
| 120 | { | ||
| 121 | if ((addr & 0x00000fff) < 0x0800) { | ||
| 122 | gpio_set_value(GPIO_PTT4, 1); | ||
| 123 | writel(readl(GBECONT) & ~GBECONT_RMII0, GBECONT); | ||
| 124 | } else { | ||
| 125 | gpio_set_value(GPIO_PTT4, 0); | ||
| 126 | writel(readl(GBECONT) & ~GBECONT_RMII1, GBECONT); | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | static struct resource sh_eth_giga0_resources[] = { | ||
| 131 | { | ||
| 132 | .start = 0xfee00000, | ||
| 133 | .end = 0xfee007ff, | ||
| 134 | .flags = IORESOURCE_MEM, | ||
| 135 | }, { | ||
| 136 | /* TSU */ | ||
| 137 | .start = 0xfee01800, | ||
| 138 | .end = 0xfee01fff, | ||
| 139 | .flags = IORESOURCE_MEM, | ||
| 140 | }, { | ||
| 141 | .start = 315, | ||
| 142 | .end = 315, | ||
| 143 | .flags = IORESOURCE_IRQ, | ||
| 144 | }, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static struct sh_eth_plat_data sh7757_eth_giga0_pdata = { | ||
| 148 | .phy = 18, | ||
| 149 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | ||
| 150 | .register_type = SH_ETH_REG_GIGABIT, | ||
| 151 | .set_mdio_gate = sh7757_eth_giga_set_mdio_gate, | ||
| 152 | .phy_interface = PHY_INTERFACE_MODE_RGMII_ID, | ||
| 153 | }; | ||
| 154 | |||
| 155 | static struct platform_device sh7757_eth_giga0_device = { | ||
| 156 | .name = "sh-eth", | ||
| 157 | .resource = sh_eth_giga0_resources, | ||
| 158 | .id = 2, | ||
| 159 | .num_resources = ARRAY_SIZE(sh_eth_giga0_resources), | ||
| 160 | .dev = { | ||
| 161 | .platform_data = &sh7757_eth_giga0_pdata, | ||
| 162 | }, | ||
| 163 | }; | ||
| 164 | |||
| 165 | static struct resource sh_eth_giga1_resources[] = { | ||
| 166 | { | ||
| 167 | .start = 0xfee00800, | ||
| 168 | .end = 0xfee00fff, | ||
| 169 | .flags = IORESOURCE_MEM, | ||
| 170 | }, { | ||
| 171 | .start = 316, | ||
| 172 | .end = 316, | ||
| 173 | .flags = IORESOURCE_IRQ, | ||
| 174 | }, | ||
| 175 | }; | ||
| 176 | |||
| 177 | static struct sh_eth_plat_data sh7757_eth_giga1_pdata = { | ||
| 178 | .phy = 19, | ||
| 179 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | ||
| 180 | .register_type = SH_ETH_REG_GIGABIT, | ||
| 181 | .set_mdio_gate = sh7757_eth_giga_set_mdio_gate, | ||
| 182 | .phy_interface = PHY_INTERFACE_MODE_RGMII_ID, | ||
| 183 | }; | ||
| 184 | |||
| 185 | static struct platform_device sh7757_eth_giga1_device = { | ||
| 186 | .name = "sh-eth", | ||
| 187 | .resource = sh_eth_giga1_resources, | ||
| 188 | .id = 3, | ||
| 189 | .num_resources = ARRAY_SIZE(sh_eth_giga1_resources), | ||
| 190 | .dev = { | ||
| 191 | .platform_data = &sh7757_eth_giga1_pdata, | ||
| 192 | }, | ||
| 193 | }; | ||
| 194 | |||
| 195 | /* SH_MMCIF */ | ||
| 196 | static struct resource sh_mmcif_resources[] = { | ||
| 197 | [0] = { | ||
| 198 | .start = 0xffcb0000, | ||
| 199 | .end = 0xffcb00ff, | ||
| 200 | .flags = IORESOURCE_MEM, | ||
| 201 | }, | ||
| 202 | [1] = { | ||
| 203 | .start = 211, | ||
| 204 | .flags = IORESOURCE_IRQ, | ||
| 205 | }, | ||
| 206 | [2] = { | ||
| 207 | .start = 212, | ||
| 208 | .flags = IORESOURCE_IRQ, | ||
| 209 | }, | ||
| 210 | }; | ||
| 211 | |||
| 212 | static struct sh_mmcif_dma sh7757lcr_mmcif_dma = { | ||
| 213 | .chan_priv_tx = SHDMA_SLAVE_MMCIF_TX, | ||
| 214 | .chan_priv_rx = SHDMA_SLAVE_MMCIF_RX, | ||
| 215 | }; | ||
| 216 | |||
| 217 | static struct sh_mmcif_plat_data sh_mmcif_plat = { | ||
| 218 | .dma = &sh7757lcr_mmcif_dma, | ||
| 219 | .sup_pclk = 0x0f, | ||
| 220 | .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, | ||
| 221 | .ocr = MMC_VDD_32_33 | MMC_VDD_33_34, | ||
| 222 | }; | ||
| 223 | |||
| 224 | static struct platform_device sh_mmcif_device = { | ||
| 225 | .name = "sh_mmcif", | ||
| 226 | .id = 0, | ||
| 227 | .dev = { | ||
| 228 | .platform_data = &sh_mmcif_plat, | ||
| 229 | }, | ||
| 230 | .num_resources = ARRAY_SIZE(sh_mmcif_resources), | ||
| 231 | .resource = sh_mmcif_resources, | ||
| 232 | }; | ||
| 233 | |||
| 234 | /* SDHI0 */ | ||
| 235 | static struct sh_mobile_sdhi_info sdhi_info = { | ||
| 236 | .dma_slave_tx = SHDMA_SLAVE_SDHI_TX, | ||
| 237 | .dma_slave_rx = SHDMA_SLAVE_SDHI_RX, | ||
| 238 | .tmio_caps = MMC_CAP_SD_HIGHSPEED, | ||
| 239 | }; | ||
| 240 | |||
| 241 | static struct resource sdhi_resources[] = { | ||
| 242 | [0] = { | ||
| 243 | .start = 0xffe50000, | ||
| 244 | .end = 0xffe501ff, | ||
| 245 | .flags = IORESOURCE_MEM, | ||
| 246 | }, | ||
| 247 | [1] = { | ||
| 248 | .start = 20, | ||
| 249 | .flags = IORESOURCE_IRQ, | ||
| 250 | }, | ||
| 251 | }; | ||
| 252 | |||
| 253 | static struct platform_device sdhi_device = { | ||
| 254 | .name = "sh_mobile_sdhi", | ||
| 255 | .num_resources = ARRAY_SIZE(sdhi_resources), | ||
| 256 | .resource = sdhi_resources, | ||
| 257 | .id = 0, | ||
| 258 | .dev = { | ||
| 259 | .platform_data = &sdhi_info, | ||
| 260 | }, | ||
| 261 | }; | ||
| 262 | |||
| 101 | static struct platform_device *sh7757lcr_devices[] __initdata = { | 263 | static struct platform_device *sh7757lcr_devices[] __initdata = { |
| 102 | &heartbeat_device, | 264 | &heartbeat_device, |
| 103 | &sh7757_eth0_device, | 265 | &sh7757_eth0_device, |
| 104 | &sh7757_eth1_device, | 266 | &sh7757_eth1_device, |
| 267 | &sh7757_eth_giga0_device, | ||
| 268 | &sh7757_eth_giga1_device, | ||
| 269 | &sh_mmcif_device, | ||
| 270 | &sdhi_device, | ||
| 271 | }; | ||
| 272 | |||
| 273 | static struct flash_platform_data spi_flash_data = { | ||
| 274 | .name = "m25p80", | ||
| 275 | .type = "m25px64", | ||
| 276 | }; | ||
| 277 | |||
| 278 | static struct spi_board_info spi_board_info[] = { | ||
| 279 | { | ||
| 280 | .modalias = "m25p80", | ||
| 281 | .max_speed_hz = 25000000, | ||
| 282 | .bus_num = 0, | ||
| 283 | .chip_select = 1, | ||
| 284 | .platform_data = &spi_flash_data, | ||
| 285 | }, | ||
| 105 | }; | 286 | }; |
| 106 | 287 | ||
| 107 | static int __init sh7757lcr_devices_setup(void) | 288 | static int __init sh7757lcr_devices_setup(void) |
| @@ -332,6 +513,10 @@ static int __init sh7757lcr_devices_setup(void) | |||
| 332 | gpio_request(GPIO_PTT5, NULL); /* eMMC_PRST# */ | 513 | gpio_request(GPIO_PTT5, NULL); /* eMMC_PRST# */ |
| 333 | gpio_direction_output(GPIO_PTT5, 1); | 514 | gpio_direction_output(GPIO_PTT5, 1); |
| 334 | 515 | ||
| 516 | /* register SPI device information */ | ||
| 517 | spi_register_board_info(spi_board_info, | ||
| 518 | ARRAY_SIZE(spi_board_info)); | ||
| 519 | |||
| 335 | /* General platform */ | 520 | /* General platform */ |
| 336 | return platform_add_devices(sh7757lcr_devices, | 521 | return platform_add_devices(sh7757lcr_devices, |
| 337 | ARRAY_SIZE(sh7757lcr_devices)); | 522 | ARRAY_SIZE(sh7757lcr_devices)); |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 701667acfd89..3b71d2190de1 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
| @@ -142,6 +142,8 @@ static struct resource sh_eth_resources[] = { | |||
| 142 | static struct sh_eth_plat_data sh_eth_plat = { | 142 | static struct sh_eth_plat_data sh_eth_plat = { |
| 143 | .phy = 0x1f, /* SMSC LAN8700 */ | 143 | .phy = 0x1f, /* SMSC LAN8700 */ |
| 144 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 144 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
| 145 | .register_type = SH_ETH_REG_FAST_SH4, | ||
| 146 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
| 145 | .ether_link_active_low = 1 | 147 | .ether_link_active_low = 1 |
| 146 | }; | 148 | }; |
| 147 | 149 | ||
diff --git a/arch/sh/boards/mach-sh7763rdp/setup.c b/arch/sh/boards/mach-sh7763rdp/setup.c index f64a6918224c..f3d828f133e5 100644 --- a/arch/sh/boards/mach-sh7763rdp/setup.c +++ b/arch/sh/boards/mach-sh7763rdp/setup.c | |||
| @@ -75,6 +75,10 @@ static struct resource sh_eth_resources[] = { | |||
| 75 | .end = 0xFEE00F7C - 1, | 75 | .end = 0xFEE00F7C - 1, |
| 76 | .flags = IORESOURCE_MEM, | 76 | .flags = IORESOURCE_MEM, |
| 77 | }, { | 77 | }, { |
| 78 | .start = 0xFEE01800, /* TSU */ | ||
| 79 | .end = 0xFEE01FFF, | ||
| 80 | .flags = IORESOURCE_MEM, | ||
| 81 | }, { | ||
| 78 | .start = 57, /* irq number */ | 82 | .start = 57, /* irq number */ |
| 79 | .flags = IORESOURCE_IRQ, | 83 | .flags = IORESOURCE_IRQ, |
| 80 | }, | 84 | }, |
| @@ -83,6 +87,8 @@ static struct resource sh_eth_resources[] = { | |||
| 83 | static struct sh_eth_plat_data sh7763_eth_pdata = { | 87 | static struct sh_eth_plat_data sh7763_eth_pdata = { |
| 84 | .phy = 1, | 88 | .phy = 1, |
| 85 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 89 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
| 90 | .register_type = SH_ETH_REG_GIGABIT, | ||
| 91 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
| 86 | }; | 92 | }; |
| 87 | 93 | ||
| 88 | static struct platform_device sh7763rdp_eth_device = { | 94 | static struct platform_device sh7763rdp_eth_device = { |
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index e0b0293bae63..780e083e4d17 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile | |||
| @@ -11,6 +11,8 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz \ | |||
| 11 | 11 | ||
| 12 | OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o | 12 | OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o |
| 13 | 13 | ||
| 14 | GCOV_PROFILE := n | ||
| 15 | |||
| 14 | # | 16 | # |
| 15 | # IMAGE_OFFSET is the load offset of the compression loader | 17 | # IMAGE_OFFSET is the load offset of the compression loader |
| 16 | # | 18 | # |
diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig index 5f7f667b9f3b..fa0ecf87034c 100644 --- a/arch/sh/configs/sh7757lcr_defconfig +++ b/arch/sh/configs/sh7757lcr_defconfig | |||
| @@ -38,7 +38,15 @@ CONFIG_IPV6=y | |||
| 38 | # CONFIG_WIRELESS is not set | 38 | # CONFIG_WIRELESS is not set |
| 39 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 39 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 40 | # CONFIG_FW_LOADER is not set | 40 | # CONFIG_FW_LOADER is not set |
| 41 | CONFIG_MTD=y | ||
| 42 | CONFIG_MTD_CONCAT=y | ||
| 43 | CONFIG_MTD_PARTITIONS=y | ||
| 44 | CONFIG_MTD_CHAR=y | ||
| 45 | CONFIG_MTD_BLOCK=y | ||
| 46 | CONFIG_MTD_M25P80=y | ||
| 41 | CONFIG_BLK_DEV_RAM=y | 47 | CONFIG_BLK_DEV_RAM=y |
| 48 | CONFIG_SCSI=y | ||
| 49 | CONFIG_BLK_DEV_SD=y | ||
| 42 | CONFIG_NETDEVICES=y | 50 | CONFIG_NETDEVICES=y |
| 43 | CONFIG_VITESSE_PHY=y | 51 | CONFIG_VITESSE_PHY=y |
| 44 | CONFIG_NET_ETHERNET=y | 52 | CONFIG_NET_ETHERNET=y |
| @@ -53,8 +61,17 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 | |||
| 53 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | 61 | CONFIG_SERIAL_SH_SCI_CONSOLE=y |
| 54 | # CONFIG_LEGACY_PTYS is not set | 62 | # CONFIG_LEGACY_PTYS is not set |
| 55 | # CONFIG_HW_RANDOM is not set | 63 | # CONFIG_HW_RANDOM is not set |
| 64 | CONFIG_SPI=y | ||
| 65 | CONFIG_SPI_SH=y | ||
| 56 | # CONFIG_HWMON is not set | 66 | # CONFIG_HWMON is not set |
| 57 | # CONFIG_USB_SUPPORT is not set | 67 | CONFIG_MFD_SH_MOBILE_SDHI=y |
| 68 | CONFIG_USB=y | ||
| 69 | CONFIG_USB_EHCI_HCD=y | ||
| 70 | CONFIG_USB_OHCI_HCD=y | ||
| 71 | CONFIG_USB_STORAGE=y | ||
| 72 | CONFIG_MMC=y | ||
| 73 | CONFIG_MMC_TMIO=y | ||
| 74 | CONFIG_MMC_SH_MMCIF=y | ||
| 58 | CONFIG_EXT2_FS=y | 75 | CONFIG_EXT2_FS=y |
| 59 | CONFIG_EXT3_FS=y | 76 | CONFIG_EXT3_FS=y |
| 60 | CONFIG_ISO9660_FS=y | 77 | CONFIG_ISO9660_FS=y |
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 96e9b058aa1d..4418f9070ed1 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c | |||
| @@ -1,16 +1,19 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Low-Level PCI Express Support for the SH7786 | 2 | * Low-Level PCI Express Support for the SH7786 |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 - 2010 Paul Mundt | 4 | * Copyright (C) 2009 - 2011 Paul Mundt |
| 5 | * | 5 | * |
| 6 | * This file is subject to the terms and conditions of the GNU General Public | 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 | 7 | * License. See the file "COPYING" in the main directory of this archive |
| 8 | * for more details. | 8 | * for more details. |
| 9 | */ | 9 | */ |
| 10 | #define pr_fmt(fmt) "PCI: " fmt | ||
| 11 | |||
| 10 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
| 11 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 12 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 13 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <linux/async.h> | ||
| 14 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
| 15 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 16 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
| @@ -31,7 +34,7 @@ static unsigned int nr_ports; | |||
| 31 | 34 | ||
| 32 | static struct sh7786_pcie_hwops { | 35 | static struct sh7786_pcie_hwops { |
| 33 | int (*core_init)(void); | 36 | int (*core_init)(void); |
| 34 | int (*port_init_hw)(struct sh7786_pcie_port *port); | 37 | async_func_ptr *port_init_hw; |
| 35 | } *sh7786_pcie_hwops; | 38 | } *sh7786_pcie_hwops; |
| 36 | 39 | ||
| 37 | static struct resource sh7786_pci0_resources[] = { | 40 | static struct resource sh7786_pci0_resources[] = { |
| @@ -474,8 +477,9 @@ static int __init sh7786_pcie_core_init(void) | |||
| 474 | return test_mode_pin(MODE_PIN12) ? 3 : 2; | 477 | return test_mode_pin(MODE_PIN12) ? 3 : 2; |
| 475 | } | 478 | } |
| 476 | 479 | ||
| 477 | static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port) | 480 | static void __init sh7786_pcie_init_hw(void *data, async_cookie_t cookie) |
| 478 | { | 481 | { |
| 482 | struct sh7786_pcie_port *port = data; | ||
| 479 | int ret; | 483 | int ret; |
| 480 | 484 | ||
| 481 | /* | 485 | /* |
| @@ -488,18 +492,30 @@ static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port) | |||
| 488 | * Setup clocks, needed both for PHY and PCIe registers. | 492 | * Setup clocks, needed both for PHY and PCIe registers. |
| 489 | */ | 493 | */ |
| 490 | ret = pcie_clk_init(port); | 494 | ret = pcie_clk_init(port); |
| 491 | if (unlikely(ret < 0)) | 495 | if (unlikely(ret < 0)) { |
| 492 | return ret; | 496 | pr_err("clock initialization failed for port#%d\n", |
| 497 | port->index); | ||
| 498 | return; | ||
| 499 | } | ||
| 493 | 500 | ||
| 494 | ret = phy_init(port); | 501 | ret = phy_init(port); |
| 495 | if (unlikely(ret < 0)) | 502 | if (unlikely(ret < 0)) { |
| 496 | return ret; | 503 | pr_err("phy initialization failed for port#%d\n", |
| 504 | port->index); | ||
| 505 | return; | ||
| 506 | } | ||
| 497 | 507 | ||
| 498 | ret = pcie_init(port); | 508 | ret = pcie_init(port); |
| 499 | if (unlikely(ret < 0)) | 509 | if (unlikely(ret < 0)) { |
| 500 | return ret; | 510 | pr_err("core initialization failed for port#%d\n", |
| 511 | port->index); | ||
| 512 | return; | ||
| 513 | } | ||
| 501 | 514 | ||
| 502 | return register_pci_controller(port->hose); | 515 | /* In the interest of preserving device ordering, synchronize */ |
| 516 | async_synchronize_cookie(cookie); | ||
| 517 | |||
| 518 | register_pci_controller(port->hose); | ||
| 503 | } | 519 | } |
| 504 | 520 | ||
| 505 | static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = { | 521 | static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = { |
| @@ -510,7 +526,7 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = { | |||
| 510 | static int __init sh7786_pcie_init(void) | 526 | static int __init sh7786_pcie_init(void) |
| 511 | { | 527 | { |
| 512 | struct clk *platclk; | 528 | struct clk *platclk; |
| 513 | int ret = 0, i; | 529 | int i; |
| 514 | 530 | ||
| 515 | printk(KERN_NOTICE "PCI: Starting initialization.\n"); | 531 | printk(KERN_NOTICE "PCI: Starting initialization.\n"); |
| 516 | 532 | ||
| @@ -552,14 +568,10 @@ static int __init sh7786_pcie_init(void) | |||
| 552 | port->hose = sh7786_pci_channels + i; | 568 | port->hose = sh7786_pci_channels + i; |
| 553 | port->hose->io_map_base = port->hose->resources[0].start; | 569 | port->hose->io_map_base = port->hose->resources[0].start; |
| 554 | 570 | ||
| 555 | ret |= sh7786_pcie_hwops->port_init_hw(port); | 571 | async_schedule(sh7786_pcie_hwops->port_init_hw, port); |
| 556 | } | 572 | } |
| 557 | 573 | ||
| 558 | if (unlikely(ret)) { | 574 | async_synchronize_full(); |
| 559 | clk_disable(platclk); | ||
| 560 | clk_put(platclk); | ||
| 561 | return ret; | ||
| 562 | } | ||
| 563 | 575 | ||
| 564 | return 0; | 576 | return 0; |
| 565 | } | 577 | } |
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index d6741fca89a4..b5a74e88028d 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h | |||
| @@ -369,8 +369,11 @@ | |||
| 369 | #define __NR_recvmsg 356 | 369 | #define __NR_recvmsg 356 |
| 370 | #define __NR_recvmmsg 357 | 370 | #define __NR_recvmmsg 357 |
| 371 | #define __NR_accept4 358 | 371 | #define __NR_accept4 358 |
| 372 | #define __NR_name_to_handle_at 359 | ||
| 373 | #define __NR_open_by_handle_at 360 | ||
| 374 | #define __NR_clock_adjtime 361 | ||
| 372 | 375 | ||
| 373 | #define NR_syscalls 359 | 376 | #define NR_syscalls 362 |
| 374 | 377 | ||
| 375 | #ifdef __KERNEL__ | 378 | #ifdef __KERNEL__ |
| 376 | 379 | ||
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h index 09aa93f9eb70..953da4a52199 100644 --- a/arch/sh/include/asm/unistd_64.h +++ b/arch/sh/include/asm/unistd_64.h | |||
| @@ -390,10 +390,13 @@ | |||
| 390 | #define __NR_fanotify_init 367 | 390 | #define __NR_fanotify_init 367 |
| 391 | #define __NR_fanotify_mark 368 | 391 | #define __NR_fanotify_mark 368 |
| 392 | #define __NR_prlimit64 369 | 392 | #define __NR_prlimit64 369 |
| 393 | #define __NR_name_to_handle_at 370 | ||
| 394 | #define __NR_open_by_handle_at 371 | ||
| 395 | #define __NR_clock_adjtime 372 | ||
| 393 | 396 | ||
| 394 | #ifdef __KERNEL__ | 397 | #ifdef __KERNEL__ |
| 395 | 398 | ||
| 396 | #define NR_syscalls 370 | 399 | #define NR_syscalls 373 |
| 397 | 400 | ||
| 398 | #define __ARCH_WANT_IPC_PARSE_VERSION | 401 | #define __ARCH_WANT_IPC_PARSE_VERSION |
| 399 | #define __ARCH_WANT_OLD_READDIR | 402 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-register.h b/arch/sh/include/cpu-sh4/cpu/dma-register.h index 9a6125eb0079..18fa80aba15e 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma-register.h +++ b/arch/sh/include/cpu-sh4/cpu/dma-register.h | |||
| @@ -40,6 +40,11 @@ | |||
| 40 | #define CHCR_TS_LOW_SHIFT 3 | 40 | #define CHCR_TS_LOW_SHIFT 3 |
| 41 | #define CHCR_TS_HIGH_MASK 0 | 41 | #define CHCR_TS_HIGH_MASK 0 |
| 42 | #define CHCR_TS_HIGH_SHIFT 0 | 42 | #define CHCR_TS_HIGH_SHIFT 0 |
| 43 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) | ||
| 44 | #define CHCR_TS_LOW_MASK 0x00000018 | ||
| 45 | #define CHCR_TS_LOW_SHIFT 3 | ||
| 46 | #define CHCR_TS_HIGH_MASK 0x00100000 | ||
| 47 | #define CHCR_TS_HIGH_SHIFT (20 - 2) /* 2 bits for shifted low TS */ | ||
| 43 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | 48 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) |
| 44 | #define CHCR_TS_LOW_MASK 0x00000018 | 49 | #define CHCR_TS_LOW_MASK 0x00000018 |
| 45 | #define CHCR_TS_LOW_SHIFT 3 | 50 | #define CHCR_TS_LOW_SHIFT 3 |
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h index 15f3de11c55a..05b8196c7753 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7757.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h | |||
| @@ -251,4 +251,36 @@ enum { | |||
| 251 | GPIO_FN_ON_DQ3, GPIO_FN_ON_DQ2, GPIO_FN_ON_DQ1, GPIO_FN_ON_DQ0, | 251 | GPIO_FN_ON_DQ3, GPIO_FN_ON_DQ2, GPIO_FN_ON_DQ1, GPIO_FN_ON_DQ0, |
| 252 | }; | 252 | }; |
| 253 | 253 | ||
| 254 | enum { | ||
| 255 | SHDMA_SLAVE_SDHI_TX, | ||
| 256 | SHDMA_SLAVE_SDHI_RX, | ||
| 257 | SHDMA_SLAVE_MMCIF_TX, | ||
| 258 | SHDMA_SLAVE_MMCIF_RX, | ||
| 259 | SHDMA_SLAVE_SCIF2_TX, | ||
| 260 | SHDMA_SLAVE_SCIF2_RX, | ||
| 261 | SHDMA_SLAVE_SCIF3_TX, | ||
| 262 | SHDMA_SLAVE_SCIF3_RX, | ||
| 263 | SHDMA_SLAVE_SCIF4_TX, | ||
| 264 | SHDMA_SLAVE_SCIF4_RX, | ||
| 265 | SHDMA_SLAVE_RIIC0_TX, | ||
| 266 | SHDMA_SLAVE_RIIC0_RX, | ||
| 267 | SHDMA_SLAVE_RIIC1_TX, | ||
| 268 | SHDMA_SLAVE_RIIC1_RX, | ||
| 269 | SHDMA_SLAVE_RIIC2_TX, | ||
| 270 | SHDMA_SLAVE_RIIC2_RX, | ||
| 271 | SHDMA_SLAVE_RIIC3_TX, | ||
| 272 | SHDMA_SLAVE_RIIC3_RX, | ||
| 273 | SHDMA_SLAVE_RIIC4_TX, | ||
| 274 | SHDMA_SLAVE_RIIC4_RX, | ||
| 275 | SHDMA_SLAVE_RIIC5_TX, | ||
| 276 | SHDMA_SLAVE_RIIC5_RX, | ||
| 277 | SHDMA_SLAVE_RIIC6_TX, | ||
| 278 | SHDMA_SLAVE_RIIC6_RX, | ||
| 279 | SHDMA_SLAVE_RIIC7_TX, | ||
| 280 | SHDMA_SLAVE_RIIC7_RX, | ||
| 281 | SHDMA_SLAVE_RIIC8_TX, | ||
| 282 | SHDMA_SLAVE_RIIC8_RX, | ||
| 283 | SHDMA_SLAVE_RIIC9_TX, | ||
| 284 | SHDMA_SLAVE_RIIC9_RX, | ||
| 285 | }; | ||
| 254 | #endif /* __ASM_SH7757_H__ */ | 286 | #endif /* __ASM_SH7757_H__ */ |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index e073e3eb4c3d..eedddad13835 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c | |||
| @@ -77,9 +77,10 @@ struct clk div4_clks[DIV4_NR] = { | |||
| 77 | 77 | ||
| 78 | #define MSTPCR0 0xffc80030 | 78 | #define MSTPCR0 0xffc80030 |
| 79 | #define MSTPCR1 0xffc80034 | 79 | #define MSTPCR1 0xffc80034 |
| 80 | #define MSTPCR2 0xffc10028 | ||
| 80 | 81 | ||
| 81 | enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112, | 82 | enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112, |
| 82 | MSTP111, MSTP110, MSTP103, MSTP102, | 83 | MSTP111, MSTP110, MSTP103, MSTP102, MSTP220, |
| 83 | MSTP_NR }; | 84 | MSTP_NR }; |
| 84 | 85 | ||
| 85 | static struct clk mstp_clks[MSTP_NR] = { | 86 | static struct clk mstp_clks[MSTP_NR] = { |
| @@ -95,6 +96,9 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
| 95 | [MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0), | 96 | [MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0), |
| 96 | [MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0), | 97 | [MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0), |
| 97 | [MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0), | 98 | [MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0), |
| 99 | |||
| 100 | /* MSTPCR2 */ | ||
| 101 | [MSTP220] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 20, 0), | ||
| 98 | }; | 102 | }; |
| 99 | 103 | ||
| 100 | #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } | 104 | #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } |
| @@ -140,6 +144,7 @@ static struct clk_lookup lookups[] = { | |||
| 140 | .clk = &mstp_clks[MSTP110], | 144 | .clk = &mstp_clks[MSTP110], |
| 141 | }, | 145 | }, |
| 142 | CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]), | 146 | CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]), |
| 147 | CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), | ||
| 143 | }; | 148 | }; |
| 144 | 149 | ||
| 145 | int __init arch_clk_init(void) | 150 | int __init arch_clk_init(void) |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 9c1de2633ac3..423dabf542d3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * SH7757 Setup | 2 | * SH7757 Setup |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 Renesas Solutions Corp. | 4 | * Copyright (C) 2009, 2011 Renesas Solutions Corp. |
| 5 | * | 5 | * |
| 6 | * based on setup-sh7785.c : Copyright (C) 2007 Paul Mundt | 6 | * based on setup-sh7785.c : Copyright (C) 2007 Paul Mundt |
| 7 | * | 7 | * |
| @@ -16,6 +16,10 @@ | |||
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <linux/sh_timer.h> | 18 | #include <linux/sh_timer.h> |
| 19 | #include <linux/sh_dma.h> | ||
| 20 | |||
| 21 | #include <cpu/dma-register.h> | ||
| 22 | #include <cpu/sh7757.h> | ||
| 19 | 23 | ||
| 20 | static struct plat_sci_port scif2_platform_data = { | 24 | static struct plat_sci_port scif2_platform_data = { |
| 21 | .mapbase = 0xfe4b0000, /* SCIF2 */ | 25 | .mapbase = 0xfe4b0000, /* SCIF2 */ |
| @@ -124,12 +128,548 @@ static struct platform_device tmu1_device = { | |||
| 124 | .num_resources = ARRAY_SIZE(tmu1_resources), | 128 | .num_resources = ARRAY_SIZE(tmu1_resources), |
| 125 | }; | 129 | }; |
| 126 | 130 | ||
| 131 | static struct resource spi0_resources[] = { | ||
| 132 | [0] = { | ||
| 133 | .start = 0xfe002000, | ||
| 134 | .end = 0xfe0020ff, | ||
| 135 | .flags = IORESOURCE_MEM, | ||
| 136 | }, | ||
| 137 | [1] = { | ||
| 138 | .start = 86, | ||
| 139 | .flags = IORESOURCE_IRQ, | ||
| 140 | }, | ||
| 141 | }; | ||
| 142 | |||
| 143 | /* DMA */ | ||
| 144 | static const struct sh_dmae_slave_config sh7757_dmae0_slaves[] = { | ||
| 145 | { | ||
| 146 | .slave_id = SHDMA_SLAVE_SDHI_TX, | ||
| 147 | .addr = 0x1fe50030, | ||
| 148 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 149 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
| 150 | .mid_rid = 0xc5, | ||
| 151 | }, | ||
| 152 | { | ||
| 153 | .slave_id = SHDMA_SLAVE_SDHI_RX, | ||
| 154 | .addr = 0x1fe50030, | ||
| 155 | .chcr = DM_INC | 0x800 | 0x40000000 | | ||
| 156 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
| 157 | .mid_rid = 0xc6, | ||
| 158 | }, | ||
| 159 | { | ||
| 160 | .slave_id = SHDMA_SLAVE_MMCIF_TX, | ||
| 161 | .addr = 0x1fcb0034, | ||
| 162 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 163 | TS_INDEX2VAL(XMIT_SZ_32BIT), | ||
| 164 | .mid_rid = 0xd3, | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | .slave_id = SHDMA_SLAVE_MMCIF_RX, | ||
| 168 | .addr = 0x1fcb0034, | ||
| 169 | .chcr = DM_INC | 0x800 | 0x40000000 | | ||
| 170 | TS_INDEX2VAL(XMIT_SZ_32BIT), | ||
| 171 | .mid_rid = 0xd7, | ||
| 172 | }, | ||
| 173 | }; | ||
| 174 | |||
| 175 | static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { | ||
| 176 | { | ||
| 177 | .slave_id = SHDMA_SLAVE_SCIF2_TX, | ||
| 178 | .addr = 0x1f4b000c, | ||
| 179 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 180 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 181 | .mid_rid = 0x21, | ||
| 182 | }, | ||
| 183 | { | ||
| 184 | .slave_id = SHDMA_SLAVE_SCIF2_RX, | ||
| 185 | .addr = 0x1f4b0014, | ||
| 186 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 187 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 188 | .mid_rid = 0x22, | ||
| 189 | }, | ||
| 190 | { | ||
| 191 | .slave_id = SHDMA_SLAVE_SCIF3_TX, | ||
| 192 | .addr = 0x1f4c000c, | ||
| 193 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 194 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 195 | .mid_rid = 0x29, | ||
| 196 | }, | ||
| 197 | { | ||
| 198 | .slave_id = SHDMA_SLAVE_SCIF3_RX, | ||
| 199 | .addr = 0x1f4c0014, | ||
| 200 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 201 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 202 | .mid_rid = 0x2a, | ||
| 203 | }, | ||
| 204 | { | ||
| 205 | .slave_id = SHDMA_SLAVE_SCIF4_TX, | ||
| 206 | .addr = 0x1f4d000c, | ||
| 207 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 208 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 209 | .mid_rid = 0x41, | ||
| 210 | }, | ||
| 211 | { | ||
| 212 | .slave_id = SHDMA_SLAVE_SCIF4_RX, | ||
| 213 | .addr = 0x1f4d0014, | ||
| 214 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 215 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 216 | .mid_rid = 0x42, | ||
| 217 | }, | ||
| 218 | }; | ||
| 219 | |||
| 220 | static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { | ||
| 221 | { | ||
| 222 | .slave_id = SHDMA_SLAVE_RIIC0_TX, | ||
| 223 | .addr = 0x1e500012, | ||
| 224 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 225 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 226 | .mid_rid = 0x21, | ||
| 227 | }, | ||
| 228 | { | ||
| 229 | .slave_id = SHDMA_SLAVE_RIIC0_RX, | ||
| 230 | .addr = 0x1e500013, | ||
| 231 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 232 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 233 | .mid_rid = 0x22, | ||
| 234 | }, | ||
| 235 | { | ||
| 236 | .slave_id = SHDMA_SLAVE_RIIC1_TX, | ||
| 237 | .addr = 0x1e510012, | ||
| 238 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 239 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 240 | .mid_rid = 0x29, | ||
| 241 | }, | ||
| 242 | { | ||
| 243 | .slave_id = SHDMA_SLAVE_RIIC1_RX, | ||
| 244 | .addr = 0x1e510013, | ||
| 245 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 246 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 247 | .mid_rid = 0x2a, | ||
| 248 | }, | ||
| 249 | { | ||
| 250 | .slave_id = SHDMA_SLAVE_RIIC2_TX, | ||
| 251 | .addr = 0x1e520012, | ||
| 252 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 253 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 254 | .mid_rid = 0xa1, | ||
| 255 | }, | ||
| 256 | { | ||
| 257 | .slave_id = SHDMA_SLAVE_RIIC2_RX, | ||
| 258 | .addr = 0x1e520013, | ||
| 259 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 260 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 261 | .mid_rid = 0xa2, | ||
| 262 | }, | ||
| 263 | { | ||
| 264 | .slave_id = SHDMA_SLAVE_RIIC3_TX, | ||
| 265 | .addr = 0x1e530012, | ||
| 266 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 267 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 268 | .mid_rid = 0xab, | ||
| 269 | }, | ||
| 270 | { | ||
| 271 | .slave_id = SHDMA_SLAVE_RIIC3_RX, | ||
| 272 | .addr = 0x1e530013, | ||
| 273 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 274 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 275 | .mid_rid = 0xaf, | ||
| 276 | }, | ||
| 277 | { | ||
| 278 | .slave_id = SHDMA_SLAVE_RIIC4_TX, | ||
| 279 | .addr = 0x1e540012, | ||
| 280 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 281 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 282 | .mid_rid = 0xc1, | ||
| 283 | }, | ||
| 284 | { | ||
| 285 | .slave_id = SHDMA_SLAVE_RIIC4_RX, | ||
| 286 | .addr = 0x1e540013, | ||
| 287 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 288 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 289 | .mid_rid = 0xc2, | ||
| 290 | }, | ||
| 291 | }; | ||
| 292 | |||
| 293 | static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { | ||
| 294 | { | ||
| 295 | .slave_id = SHDMA_SLAVE_RIIC5_TX, | ||
| 296 | .addr = 0x1e550012, | ||
| 297 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 298 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 299 | .mid_rid = 0x21, | ||
| 300 | }, | ||
| 301 | { | ||
| 302 | .slave_id = SHDMA_SLAVE_RIIC5_RX, | ||
| 303 | .addr = 0x1e550013, | ||
| 304 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 305 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 306 | .mid_rid = 0x22, | ||
| 307 | }, | ||
| 308 | { | ||
| 309 | .slave_id = SHDMA_SLAVE_RIIC6_TX, | ||
| 310 | .addr = 0x1e560012, | ||
| 311 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 312 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 313 | .mid_rid = 0x29, | ||
| 314 | }, | ||
| 315 | { | ||
| 316 | .slave_id = SHDMA_SLAVE_RIIC6_RX, | ||
| 317 | .addr = 0x1e560013, | ||
| 318 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 319 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 320 | .mid_rid = 0x2a, | ||
| 321 | }, | ||
| 322 | { | ||
| 323 | .slave_id = SHDMA_SLAVE_RIIC7_TX, | ||
| 324 | .addr = 0x1e570012, | ||
| 325 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 326 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 327 | .mid_rid = 0x41, | ||
| 328 | }, | ||
| 329 | { | ||
| 330 | .slave_id = SHDMA_SLAVE_RIIC7_RX, | ||
| 331 | .addr = 0x1e570013, | ||
| 332 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 333 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 334 | .mid_rid = 0x42, | ||
| 335 | }, | ||
| 336 | { | ||
| 337 | .slave_id = SHDMA_SLAVE_RIIC8_TX, | ||
| 338 | .addr = 0x1e580012, | ||
| 339 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 340 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 341 | .mid_rid = 0x45, | ||
| 342 | }, | ||
| 343 | { | ||
| 344 | .slave_id = SHDMA_SLAVE_RIIC8_RX, | ||
| 345 | .addr = 0x1e580013, | ||
| 346 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 347 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 348 | .mid_rid = 0x46, | ||
| 349 | }, | ||
| 350 | { | ||
| 351 | .slave_id = SHDMA_SLAVE_RIIC9_TX, | ||
| 352 | .addr = 0x1e590012, | ||
| 353 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 354 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 355 | .mid_rid = 0x51, | ||
| 356 | }, | ||
| 357 | { | ||
| 358 | .slave_id = SHDMA_SLAVE_RIIC9_RX, | ||
| 359 | .addr = 0x1e590013, | ||
| 360 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
| 361 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
| 362 | .mid_rid = 0x52, | ||
| 363 | }, | ||
| 364 | }; | ||
| 365 | |||
| 366 | static const struct sh_dmae_channel sh7757_dmae_channels[] = { | ||
| 367 | { | ||
| 368 | .offset = 0, | ||
| 369 | .dmars = 0, | ||
| 370 | .dmars_bit = 0, | ||
| 371 | }, { | ||
| 372 | .offset = 0x10, | ||
| 373 | .dmars = 0, | ||
| 374 | .dmars_bit = 8, | ||
| 375 | }, { | ||
| 376 | .offset = 0x20, | ||
| 377 | .dmars = 4, | ||
| 378 | .dmars_bit = 0, | ||
| 379 | }, { | ||
| 380 | .offset = 0x30, | ||
| 381 | .dmars = 4, | ||
| 382 | .dmars_bit = 8, | ||
| 383 | }, { | ||
| 384 | .offset = 0x50, | ||
| 385 | .dmars = 8, | ||
| 386 | .dmars_bit = 0, | ||
| 387 | }, { | ||
| 388 | .offset = 0x60, | ||
| 389 | .dmars = 8, | ||
| 390 | .dmars_bit = 8, | ||
| 391 | } | ||
| 392 | }; | ||
| 393 | |||
| 394 | static const unsigned int ts_shift[] = TS_SHIFT; | ||
| 395 | |||
| 396 | static struct sh_dmae_pdata dma0_platform_data = { | ||
| 397 | .slave = sh7757_dmae0_slaves, | ||
| 398 | .slave_num = ARRAY_SIZE(sh7757_dmae0_slaves), | ||
| 399 | .channel = sh7757_dmae_channels, | ||
| 400 | .channel_num = ARRAY_SIZE(sh7757_dmae_channels), | ||
| 401 | .ts_low_shift = CHCR_TS_LOW_SHIFT, | ||
| 402 | .ts_low_mask = CHCR_TS_LOW_MASK, | ||
| 403 | .ts_high_shift = CHCR_TS_HIGH_SHIFT, | ||
| 404 | .ts_high_mask = CHCR_TS_HIGH_MASK, | ||
| 405 | .ts_shift = ts_shift, | ||
| 406 | .ts_shift_num = ARRAY_SIZE(ts_shift), | ||
| 407 | .dmaor_init = DMAOR_INIT, | ||
| 408 | }; | ||
| 409 | |||
| 410 | static struct sh_dmae_pdata dma1_platform_data = { | ||
| 411 | .slave = sh7757_dmae1_slaves, | ||
| 412 | .slave_num = ARRAY_SIZE(sh7757_dmae1_slaves), | ||
| 413 | .channel = sh7757_dmae_channels, | ||
| 414 | .channel_num = ARRAY_SIZE(sh7757_dmae_channels), | ||
| 415 | .ts_low_shift = CHCR_TS_LOW_SHIFT, | ||
| 416 | .ts_low_mask = CHCR_TS_LOW_MASK, | ||
| 417 | .ts_high_shift = CHCR_TS_HIGH_SHIFT, | ||
| 418 | .ts_high_mask = CHCR_TS_HIGH_MASK, | ||
| 419 | .ts_shift = ts_shift, | ||
| 420 | .ts_shift_num = ARRAY_SIZE(ts_shift), | ||
| 421 | .dmaor_init = DMAOR_INIT, | ||
| 422 | }; | ||
| 423 | |||
| 424 | static struct sh_dmae_pdata dma2_platform_data = { | ||
| 425 | .slave = sh7757_dmae2_slaves, | ||
| 426 | .slave_num = ARRAY_SIZE(sh7757_dmae2_slaves), | ||
| 427 | .channel = sh7757_dmae_channels, | ||
| 428 | .channel_num = ARRAY_SIZE(sh7757_dmae_channels), | ||
| 429 | .ts_low_shift = CHCR_TS_LOW_SHIFT, | ||
| 430 | .ts_low_mask = CHCR_TS_LOW_MASK, | ||
| 431 | .ts_high_shift = CHCR_TS_HIGH_SHIFT, | ||
| 432 | .ts_high_mask = CHCR_TS_HIGH_MASK, | ||
| 433 | .ts_shift = ts_shift, | ||
| 434 | .ts_shift_num = ARRAY_SIZE(ts_shift), | ||
| 435 | .dmaor_init = DMAOR_INIT, | ||
| 436 | }; | ||
| 437 | |||
| 438 | static struct sh_dmae_pdata dma3_platform_data = { | ||
| 439 | .slave = sh7757_dmae3_slaves, | ||
| 440 | .slave_num = ARRAY_SIZE(sh7757_dmae3_slaves), | ||
| 441 | .channel = sh7757_dmae_channels, | ||
| 442 | .channel_num = ARRAY_SIZE(sh7757_dmae_channels), | ||
| 443 | .ts_low_shift = CHCR_TS_LOW_SHIFT, | ||
| 444 | .ts_low_mask = CHCR_TS_LOW_MASK, | ||
| 445 | .ts_high_shift = CHCR_TS_HIGH_SHIFT, | ||
| 446 | .ts_high_mask = CHCR_TS_HIGH_MASK, | ||
| 447 | .ts_shift = ts_shift, | ||
| 448 | .ts_shift_num = ARRAY_SIZE(ts_shift), | ||
| 449 | .dmaor_init = DMAOR_INIT, | ||
| 450 | }; | ||
| 451 | |||
| 452 | /* channel 0 to 5 */ | ||
| 453 | static struct resource sh7757_dmae0_resources[] = { | ||
| 454 | [0] = { | ||
| 455 | /* Channel registers and DMAOR */ | ||
| 456 | .start = 0xff608020, | ||
| 457 | .end = 0xff60808f, | ||
| 458 | .flags = IORESOURCE_MEM, | ||
| 459 | }, | ||
| 460 | [1] = { | ||
| 461 | /* DMARSx */ | ||
| 462 | .start = 0xff609000, | ||
| 463 | .end = 0xff60900b, | ||
| 464 | .flags = IORESOURCE_MEM, | ||
| 465 | }, | ||
| 466 | { | ||
| 467 | .start = 34, | ||
| 468 | .end = 34, | ||
| 469 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 470 | }, | ||
| 471 | }; | ||
| 472 | |||
| 473 | /* channel 6 to 11 */ | ||
| 474 | static struct resource sh7757_dmae1_resources[] = { | ||
| 475 | [0] = { | ||
| 476 | /* Channel registers and DMAOR */ | ||
| 477 | .start = 0xff618020, | ||
| 478 | .end = 0xff61808f, | ||
| 479 | .flags = IORESOURCE_MEM, | ||
| 480 | }, | ||
| 481 | [1] = { | ||
| 482 | /* DMARSx */ | ||
| 483 | .start = 0xff619000, | ||
| 484 | .end = 0xff61900b, | ||
| 485 | .flags = IORESOURCE_MEM, | ||
| 486 | }, | ||
| 487 | { | ||
| 488 | /* DMA error */ | ||
| 489 | .start = 34, | ||
| 490 | .end = 34, | ||
| 491 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 492 | }, | ||
| 493 | { | ||
| 494 | /* IRQ for channels 4 */ | ||
| 495 | .start = 46, | ||
| 496 | .end = 46, | ||
| 497 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 498 | }, | ||
| 499 | { | ||
| 500 | /* IRQ for channels 5 */ | ||
| 501 | .start = 46, | ||
| 502 | .end = 46, | ||
| 503 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 504 | }, | ||
| 505 | { | ||
| 506 | /* IRQ for channels 6 */ | ||
| 507 | .start = 88, | ||
| 508 | .end = 88, | ||
| 509 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 510 | }, | ||
| 511 | { | ||
| 512 | /* IRQ for channels 7 */ | ||
| 513 | .start = 88, | ||
| 514 | .end = 88, | ||
| 515 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 516 | }, | ||
| 517 | { | ||
| 518 | /* IRQ for channels 8 */ | ||
| 519 | .start = 88, | ||
| 520 | .end = 88, | ||
| 521 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 522 | }, | ||
| 523 | { | ||
| 524 | /* IRQ for channels 9 */ | ||
| 525 | .start = 88, | ||
| 526 | .end = 88, | ||
| 527 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 528 | }, | ||
| 529 | { | ||
| 530 | /* IRQ for channels 10 */ | ||
| 531 | .start = 88, | ||
| 532 | .end = 88, | ||
| 533 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 534 | }, | ||
| 535 | { | ||
| 536 | /* IRQ for channels 11 */ | ||
| 537 | .start = 88, | ||
| 538 | .end = 88, | ||
| 539 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, | ||
| 540 | }, | ||
| 541 | }; | ||
| 542 | |||
| 543 | /* channel 12 to 17 */ | ||
| 544 | static struct resource sh7757_dmae2_resources[] = { | ||
| 545 | [0] = { | ||
| 546 | /* Channel registers and DMAOR */ | ||
| 547 | .start = 0xff708020, | ||
| 548 | .end = 0xff70808f, | ||
| 549 | .flags = IORESOURCE_MEM, | ||
| 550 | }, | ||
| 551 | [1] = { | ||
| 552 | /* DMARSx */ | ||
| 553 | .start = 0xff709000, | ||
| 554 | .end = 0xff70900b, | ||
| 555 | .flags = IORESOURCE_MEM, | ||
| 556 | }, | ||
| 557 | { | ||
| 558 | /* DMA error */ | ||
| 559 | .start = 323, | ||
| 560 | .end = 323, | ||
| 561 | .flags = IORESOURCE_IRQ, | ||
| 562 | }, | ||
| 563 | { | ||
| 564 | /* IRQ for channels 12 to 16 */ | ||
| 565 | .start = 272, | ||
| 566 | .end = 276, | ||
| 567 | .flags = IORESOURCE_IRQ, | ||
| 568 | }, | ||
| 569 | { | ||
| 570 | /* IRQ for channel 17 */ | ||
| 571 | .start = 279, | ||
| 572 | .end = 279, | ||
| 573 | .flags = IORESOURCE_IRQ, | ||
| 574 | }, | ||
| 575 | }; | ||
| 576 | |||
| 577 | /* channel 18 to 23 */ | ||
| 578 | static struct resource sh7757_dmae3_resources[] = { | ||
| 579 | [0] = { | ||
| 580 | /* Channel registers and DMAOR */ | ||
| 581 | .start = 0xff718020, | ||
| 582 | .end = 0xff71808f, | ||
| 583 | .flags = IORESOURCE_MEM, | ||
| 584 | }, | ||
| 585 | [1] = { | ||
| 586 | /* DMARSx */ | ||
| 587 | .start = 0xff719000, | ||
| 588 | .end = 0xff71900b, | ||
| 589 | .flags = IORESOURCE_MEM, | ||
| 590 | }, | ||
| 591 | { | ||
| 592 | /* DMA error */ | ||
| 593 | .start = 324, | ||
| 594 | .end = 324, | ||
| 595 | .flags = IORESOURCE_IRQ, | ||
| 596 | }, | ||
| 597 | { | ||
| 598 | /* IRQ for channels 18 to 22 */ | ||
| 599 | .start = 280, | ||
| 600 | .end = 284, | ||
| 601 | .flags = IORESOURCE_IRQ, | ||
| 602 | }, | ||
| 603 | { | ||
| 604 | /* IRQ for channel 23 */ | ||
| 605 | .start = 288, | ||
| 606 | .end = 288, | ||
| 607 | .flags = IORESOURCE_IRQ, | ||
| 608 | }, | ||
| 609 | }; | ||
| 610 | |||
| 611 | static struct platform_device dma0_device = { | ||
| 612 | .name = "sh-dma-engine", | ||
| 613 | .id = 0, | ||
| 614 | .resource = sh7757_dmae0_resources, | ||
| 615 | .num_resources = ARRAY_SIZE(sh7757_dmae0_resources), | ||
| 616 | .dev = { | ||
| 617 | .platform_data = &dma0_platform_data, | ||
| 618 | }, | ||
| 619 | }; | ||
| 620 | |||
| 621 | static struct platform_device dma1_device = { | ||
| 622 | .name = "sh-dma-engine", | ||
| 623 | .id = 1, | ||
| 624 | .resource = sh7757_dmae1_resources, | ||
| 625 | .num_resources = ARRAY_SIZE(sh7757_dmae1_resources), | ||
| 626 | .dev = { | ||
| 627 | .platform_data = &dma1_platform_data, | ||
| 628 | }, | ||
| 629 | }; | ||
| 630 | |||
| 631 | static struct platform_device dma2_device = { | ||
| 632 | .name = "sh-dma-engine", | ||
| 633 | .id = 2, | ||
| 634 | .resource = sh7757_dmae2_resources, | ||
| 635 | .num_resources = ARRAY_SIZE(sh7757_dmae2_resources), | ||
| 636 | .dev = { | ||
| 637 | .platform_data = &dma2_platform_data, | ||
| 638 | }, | ||
| 639 | }; | ||
| 640 | |||
| 641 | static struct platform_device dma3_device = { | ||
| 642 | .name = "sh-dma-engine", | ||
| 643 | .id = 3, | ||
| 644 | .resource = sh7757_dmae3_resources, | ||
| 645 | .num_resources = ARRAY_SIZE(sh7757_dmae3_resources), | ||
| 646 | .dev = { | ||
| 647 | .platform_data = &dma3_platform_data, | ||
| 648 | }, | ||
| 649 | }; | ||
| 650 | |||
| 651 | static struct platform_device spi0_device = { | ||
| 652 | .name = "sh_spi", | ||
| 653 | .id = 0, | ||
| 654 | .dev = { | ||
| 655 | .dma_mask = NULL, | ||
| 656 | .coherent_dma_mask = 0xffffffff, | ||
| 657 | }, | ||
| 658 | .num_resources = ARRAY_SIZE(spi0_resources), | ||
| 659 | .resource = spi0_resources, | ||
| 660 | }; | ||
| 661 | |||
| 127 | static struct platform_device *sh7757_devices[] __initdata = { | 662 | static struct platform_device *sh7757_devices[] __initdata = { |
| 128 | &scif2_device, | 663 | &scif2_device, |
| 129 | &scif3_device, | 664 | &scif3_device, |
| 130 | &scif4_device, | 665 | &scif4_device, |
| 131 | &tmu0_device, | 666 | &tmu0_device, |
| 132 | &tmu1_device, | 667 | &tmu1_device, |
| 668 | &dma0_device, | ||
| 669 | &dma1_device, | ||
| 670 | &dma2_device, | ||
| 671 | &dma3_device, | ||
| 672 | &spi0_device, | ||
| 133 | }; | 673 | }; |
| 134 | 674 | ||
| 135 | static int __init sh7757_devices_setup(void) | 675 | static int __init sh7757_devices_setup(void) |
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c index c19e2a940e3f..e4469e7233cb 100644 --- a/arch/sh/kernel/cpu/shmobile/cpuidle.c +++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c | |||
| @@ -75,7 +75,7 @@ void sh_mobile_setup_cpuidle(void) | |||
| 75 | i = CPUIDLE_DRIVER_STATE_START; | 75 | i = CPUIDLE_DRIVER_STATE_START; |
| 76 | 76 | ||
| 77 | state = &dev->states[i++]; | 77 | state = &dev->states[i++]; |
| 78 | snprintf(state->name, CPUIDLE_NAME_LEN, "C0"); | 78 | snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); |
| 79 | strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN); | 79 | strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN); |
| 80 | state->exit_latency = 1; | 80 | state->exit_latency = 1; |
| 81 | state->target_residency = 1 * 2; | 81 | state->target_residency = 1 * 2; |
| @@ -88,7 +88,7 @@ void sh_mobile_setup_cpuidle(void) | |||
| 88 | 88 | ||
| 89 | if (sh_mobile_sleep_supported & SUSP_SH_SF) { | 89 | if (sh_mobile_sleep_supported & SUSP_SH_SF) { |
| 90 | state = &dev->states[i++]; | 90 | state = &dev->states[i++]; |
| 91 | snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); | 91 | snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); |
| 92 | strncpy(state->desc, "SuperH Sleep Mode [SF]", | 92 | strncpy(state->desc, "SuperH Sleep Mode [SF]", |
| 93 | CPUIDLE_DESC_LEN); | 93 | CPUIDLE_DESC_LEN); |
| 94 | state->exit_latency = 100; | 94 | state->exit_latency = 100; |
| @@ -101,7 +101,7 @@ void sh_mobile_setup_cpuidle(void) | |||
| 101 | 101 | ||
| 102 | if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) { | 102 | if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) { |
| 103 | state = &dev->states[i++]; | 103 | state = &dev->states[i++]; |
| 104 | snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); | 104 | snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); |
| 105 | strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", | 105 | strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", |
| 106 | CPUIDLE_DESC_LEN); | 106 | CPUIDLE_DESC_LEN); |
| 107 | state->exit_latency = 2300; | 107 | state->exit_latency = 2300; |
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 68ecbe6c881a..64ea0b165399 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
| @@ -34,9 +34,9 @@ void ack_bad_irq(unsigned int irq) | |||
| 34 | 34 | ||
| 35 | #if defined(CONFIG_PROC_FS) | 35 | #if defined(CONFIG_PROC_FS) |
| 36 | /* | 36 | /* |
| 37 | * /proc/interrupts printing: | 37 | * /proc/interrupts printing for arch specific interrupts |
| 38 | */ | 38 | */ |
| 39 | static int show_other_interrupts(struct seq_file *p, int prec) | 39 | int arch_show_interrupts(struct seq_file *p, int prec) |
| 40 | { | 40 | { |
| 41 | int j; | 41 | int j; |
| 42 | 42 | ||
| @@ -49,63 +49,6 @@ static int show_other_interrupts(struct seq_file *p, int prec) | |||
| 49 | 49 | ||
| 50 | return 0; | 50 | return 0; |
| 51 | } | 51 | } |
| 52 | |||
| 53 | int show_interrupts(struct seq_file *p, void *v) | ||
| 54 | { | ||
| 55 | unsigned long flags, any_count = 0; | ||
| 56 | int i = *(loff_t *)v, j, prec; | ||
| 57 | struct irqaction *action; | ||
| 58 | struct irq_desc *desc; | ||
| 59 | struct irq_data *data; | ||
| 60 | struct irq_chip *chip; | ||
| 61 | |||
| 62 | if (i > nr_irqs) | ||
| 63 | return 0; | ||
| 64 | |||
| 65 | for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec) | ||
| 66 | j *= 10; | ||
| 67 | |||
| 68 | if (i == nr_irqs) | ||
| 69 | return show_other_interrupts(p, prec); | ||
| 70 | |||
| 71 | if (i == 0) { | ||
| 72 | seq_printf(p, "%*s", prec + 8, ""); | ||
| 73 | for_each_online_cpu(j) | ||
| 74 | seq_printf(p, "CPU%-8d", j); | ||
| 75 | seq_putc(p, '\n'); | ||
| 76 | } | ||
| 77 | |||
| 78 | desc = irq_to_desc(i); | ||
| 79 | if (!desc) | ||
| 80 | return 0; | ||
| 81 | |||
| 82 | data = irq_get_irq_data(i); | ||
| 83 | chip = irq_data_get_irq_chip(data); | ||
| 84 | |||
| 85 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
| 86 | for_each_online_cpu(j) | ||
| 87 | any_count |= kstat_irqs_cpu(i, j); | ||
| 88 | action = desc->action; | ||
| 89 | if (!action && !any_count) | ||
| 90 | goto out; | ||
| 91 | |||
| 92 | seq_printf(p, "%*d: ", prec, i); | ||
| 93 | for_each_online_cpu(j) | ||
| 94 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | ||
| 95 | seq_printf(p, " %14s", chip->name); | ||
| 96 | seq_printf(p, "-%-8s", desc->name); | ||
| 97 | |||
| 98 | if (action) { | ||
| 99 | seq_printf(p, " %s", action->name); | ||
| 100 | while ((action = action->next) != NULL) | ||
| 101 | seq_printf(p, ", %s", action->name); | ||
| 102 | } | ||
| 103 | |||
| 104 | seq_putc(p, '\n'); | ||
| 105 | out: | ||
| 106 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | #endif | 52 | #endif |
| 110 | 53 | ||
| 111 | #ifdef CONFIG_IRQSTACKS | 54 | #ifdef CONFIG_IRQSTACKS |
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 6fc347ebe59d..768fb33fdd35 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S | |||
| @@ -376,3 +376,6 @@ ENTRY(sys_call_table) | |||
| 376 | .long sys_recvmsg | 376 | .long sys_recvmsg |
| 377 | .long sys_recvmmsg | 377 | .long sys_recvmmsg |
| 378 | .long sys_accept4 | 378 | .long sys_accept4 |
| 379 | .long sys_name_to_handle_at | ||
| 380 | .long sys_open_by_handle_at /* 360 */ | ||
| 381 | .long sys_clock_adjtime | ||
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index 66585708ce90..44e7b00c8067 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S | |||
| @@ -396,3 +396,6 @@ sys_call_table: | |||
| 396 | .long sys_fanotify_init | 396 | .long sys_fanotify_init |
| 397 | .long sys_fanotify_mark | 397 | .long sys_fanotify_mark |
| 398 | .long sys_prlimit64 | 398 | .long sys_prlimit64 |
| 399 | .long sys_name_to_handle_at /* 370 */ | ||
| 400 | .long sys_open_by_handle_at | ||
| 401 | .long sys_clock_adjtime | ||
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 150aa326afff..2228c8cee4d6 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile | |||
| @@ -42,6 +42,8 @@ obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o | |||
| 42 | obj-$(CONFIG_UNCACHED_MAPPING) += uncached.o | 42 | obj-$(CONFIG_UNCACHED_MAPPING) += uncached.o |
| 43 | obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o | 43 | obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o |
| 44 | 44 | ||
| 45 | GCOV_PROFILE_pmb.o := n | ||
| 46 | |||
| 45 | # Special flags for fault_64.o. This puts restrictions on the number of | 47 | # Special flags for fault_64.o. This puts restrictions on the number of |
| 46 | # caller-save registers that the compiler can target when building this file. | 48 | # caller-save registers that the compiler can target when building this file. |
| 47 | # This is required because the code is called from a context in entry.S where | 49 | # This is required because the code is called from a context in entry.S where |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 92c91c83edde..eb7958c675a8 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
| @@ -47,7 +47,6 @@ | |||
| 47 | #include <linux/clk.h> | 47 | #include <linux/clk.h> |
| 48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
| 49 | #include <linux/err.h> | 49 | #include <linux/err.h> |
| 50 | #include <linux/list.h> | ||
| 51 | #include <linux/dmaengine.h> | 50 | #include <linux/dmaengine.h> |
| 52 | #include <linux/scatterlist.h> | 51 | #include <linux/scatterlist.h> |
| 53 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
| @@ -65,11 +64,8 @@ | |||
| 65 | struct sci_port { | 64 | struct sci_port { |
| 66 | struct uart_port port; | 65 | struct uart_port port; |
| 67 | 66 | ||
| 68 | /* Port type */ | 67 | /* Platform configuration */ |
| 69 | unsigned int type; | 68 | struct plat_sci_port *cfg; |
| 70 | |||
| 71 | /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ | ||
| 72 | unsigned int irqs[SCIx_NR_IRQS]; | ||
| 73 | 69 | ||
| 74 | /* Port enable callback */ | 70 | /* Port enable callback */ |
| 75 | void (*enable)(struct uart_port *port); | 71 | void (*enable)(struct uart_port *port); |
| @@ -81,26 +77,15 @@ struct sci_port { | |||
| 81 | struct timer_list break_timer; | 77 | struct timer_list break_timer; |
| 82 | int break_flag; | 78 | int break_flag; |
| 83 | 79 | ||
| 84 | /* SCSCR initialization */ | ||
| 85 | unsigned int scscr; | ||
| 86 | |||
| 87 | /* SCBRR calculation algo */ | ||
| 88 | unsigned int scbrr_algo_id; | ||
| 89 | |||
| 90 | /* Interface clock */ | 80 | /* Interface clock */ |
| 91 | struct clk *iclk; | 81 | struct clk *iclk; |
| 92 | /* Function clock */ | 82 | /* Function clock */ |
| 93 | struct clk *fclk; | 83 | struct clk *fclk; |
| 94 | 84 | ||
| 95 | struct list_head node; | ||
| 96 | |||
| 97 | struct dma_chan *chan_tx; | 85 | struct dma_chan *chan_tx; |
| 98 | struct dma_chan *chan_rx; | 86 | struct dma_chan *chan_rx; |
| 99 | 87 | ||
| 100 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 88 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
| 101 | struct device *dma_dev; | ||
| 102 | unsigned int slave_tx; | ||
| 103 | unsigned int slave_rx; | ||
| 104 | struct dma_async_tx_descriptor *desc_tx; | 89 | struct dma_async_tx_descriptor *desc_tx; |
| 105 | struct dma_async_tx_descriptor *desc_rx[2]; | 90 | struct dma_async_tx_descriptor *desc_rx[2]; |
| 106 | dma_cookie_t cookie_tx; | 91 | dma_cookie_t cookie_tx; |
| @@ -117,16 +102,14 @@ struct sci_port { | |||
| 117 | struct timer_list rx_timer; | 102 | struct timer_list rx_timer; |
| 118 | unsigned int rx_timeout; | 103 | unsigned int rx_timeout; |
| 119 | #endif | 104 | #endif |
| 120 | }; | ||
| 121 | 105 | ||
| 122 | struct sh_sci_priv { | 106 | struct notifier_block freq_transition; |
| 123 | spinlock_t lock; | ||
| 124 | struct list_head ports; | ||
| 125 | struct notifier_block clk_nb; | ||
| 126 | }; | 107 | }; |
| 127 | 108 | ||
| 128 | /* Function prototypes */ | 109 | /* Function prototypes */ |
| 110 | static void sci_start_tx(struct uart_port *port); | ||
| 129 | static void sci_stop_tx(struct uart_port *port); | 111 | static void sci_stop_tx(struct uart_port *port); |
| 112 | static void sci_start_rx(struct uart_port *port); | ||
| 130 | 113 | ||
| 131 | #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS | 114 | #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS |
| 132 | 115 | ||
| @@ -142,12 +125,6 @@ to_sci_port(struct uart_port *uart) | |||
| 142 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | 125 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) |
| 143 | 126 | ||
| 144 | #ifdef CONFIG_CONSOLE_POLL | 127 | #ifdef CONFIG_CONSOLE_POLL |
| 145 | static inline void handle_error(struct uart_port *port) | ||
| 146 | { | ||
| 147 | /* Clear error flags */ | ||
| 148 | sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); | ||
| 149 | } | ||
| 150 | |||
| 151 | static int sci_poll_get_char(struct uart_port *port) | 128 | static int sci_poll_get_char(struct uart_port *port) |
| 152 | { | 129 | { |
| 153 | unsigned short status; | 130 | unsigned short status; |
| @@ -156,7 +133,7 @@ static int sci_poll_get_char(struct uart_port *port) | |||
| 156 | do { | 133 | do { |
| 157 | status = sci_in(port, SCxSR); | 134 | status = sci_in(port, SCxSR); |
| 158 | if (status & SCxSR_ERRORS(port)) { | 135 | if (status & SCxSR_ERRORS(port)) { |
| 159 | handle_error(port); | 136 | sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); |
| 160 | continue; | 137 | continue; |
| 161 | } | 138 | } |
| 162 | break; | 139 | break; |
| @@ -475,7 +452,7 @@ static void sci_transmit_chars(struct uart_port *port) | |||
| 475 | /* On SH3, SCIF may read end-of-break as a space->mark char */ | 452 | /* On SH3, SCIF may read end-of-break as a space->mark char */ |
| 476 | #define STEPFN(c) ({int __c = (c); (((__c-1)|(__c)) == -1); }) | 453 | #define STEPFN(c) ({int __c = (c); (((__c-1)|(__c)) == -1); }) |
| 477 | 454 | ||
| 478 | static inline void sci_receive_chars(struct uart_port *port) | 455 | static void sci_receive_chars(struct uart_port *port) |
| 479 | { | 456 | { |
| 480 | struct sci_port *sci_port = to_sci_port(port); | 457 | struct sci_port *sci_port = to_sci_port(port); |
| 481 | struct tty_struct *tty = port->state->port.tty; | 458 | struct tty_struct *tty = port->state->port.tty; |
| @@ -566,18 +543,20 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
| 566 | } | 543 | } |
| 567 | 544 | ||
| 568 | #define SCI_BREAK_JIFFIES (HZ/20) | 545 | #define SCI_BREAK_JIFFIES (HZ/20) |
| 569 | /* The sci generates interrupts during the break, | 546 | |
| 547 | /* | ||
| 548 | * The sci generates interrupts during the break, | ||
| 570 | * 1 per millisecond or so during the break period, for 9600 baud. | 549 | * 1 per millisecond or so during the break period, for 9600 baud. |
| 571 | * So dont bother disabling interrupts. | 550 | * So dont bother disabling interrupts. |
| 572 | * But dont want more than 1 break event. | 551 | * But dont want more than 1 break event. |
| 573 | * Use a kernel timer to periodically poll the rx line until | 552 | * Use a kernel timer to periodically poll the rx line until |
| 574 | * the break is finished. | 553 | * the break is finished. |
| 575 | */ | 554 | */ |
| 576 | static void sci_schedule_break_timer(struct sci_port *port) | 555 | static inline void sci_schedule_break_timer(struct sci_port *port) |
| 577 | { | 556 | { |
| 578 | port->break_timer.expires = jiffies + SCI_BREAK_JIFFIES; | 557 | mod_timer(&port->break_timer, jiffies + SCI_BREAK_JIFFIES); |
| 579 | add_timer(&port->break_timer); | ||
| 580 | } | 558 | } |
| 559 | |||
| 581 | /* Ensure that two consecutive samples find the break over. */ | 560 | /* Ensure that two consecutive samples find the break over. */ |
| 582 | static void sci_break_timer(unsigned long data) | 561 | static void sci_break_timer(unsigned long data) |
| 583 | { | 562 | { |
| @@ -594,7 +573,7 @@ static void sci_break_timer(unsigned long data) | |||
| 594 | port->break_flag = 0; | 573 | port->break_flag = 0; |
| 595 | } | 574 | } |
| 596 | 575 | ||
| 597 | static inline int sci_handle_errors(struct uart_port *port) | 576 | static int sci_handle_errors(struct uart_port *port) |
| 598 | { | 577 | { |
| 599 | int copied = 0; | 578 | int copied = 0; |
| 600 | unsigned short status = sci_in(port, SCxSR); | 579 | unsigned short status = sci_in(port, SCxSR); |
| @@ -650,7 +629,7 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
| 650 | return copied; | 629 | return copied; |
| 651 | } | 630 | } |
| 652 | 631 | ||
| 653 | static inline int sci_handle_fifo_overrun(struct uart_port *port) | 632 | static int sci_handle_fifo_overrun(struct uart_port *port) |
| 654 | { | 633 | { |
| 655 | struct tty_struct *tty = port->state->port.tty; | 634 | struct tty_struct *tty = port->state->port.tty; |
| 656 | int copied = 0; | 635 | int copied = 0; |
| @@ -671,7 +650,7 @@ static inline int sci_handle_fifo_overrun(struct uart_port *port) | |||
| 671 | return copied; | 650 | return copied; |
| 672 | } | 651 | } |
| 673 | 652 | ||
| 674 | static inline int sci_handle_breaks(struct uart_port *port) | 653 | static int sci_handle_breaks(struct uart_port *port) |
| 675 | { | 654 | { |
| 676 | int copied = 0; | 655 | int copied = 0; |
| 677 | unsigned short status = sci_in(port, SCxSR); | 656 | unsigned short status = sci_in(port, SCxSR); |
| @@ -794,7 +773,7 @@ static inline unsigned long port_rx_irq_mask(struct uart_port *port) | |||
| 794 | * it's unset, it's logically inferred that there's no point in | 773 | * it's unset, it's logically inferred that there's no point in |
| 795 | * testing for it. | 774 | * testing for it. |
| 796 | */ | 775 | */ |
| 797 | return SCSCR_RIE | (to_sci_port(port)->scscr & SCSCR_REIE); | 776 | return SCSCR_RIE | (to_sci_port(port)->cfg->scscr & SCSCR_REIE); |
| 798 | } | 777 | } |
| 799 | 778 | ||
| 800 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | 779 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) |
| @@ -839,17 +818,18 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
| 839 | static int sci_notifier(struct notifier_block *self, | 818 | static int sci_notifier(struct notifier_block *self, |
| 840 | unsigned long phase, void *p) | 819 | unsigned long phase, void *p) |
| 841 | { | 820 | { |
| 842 | struct sh_sci_priv *priv = container_of(self, | ||
| 843 | struct sh_sci_priv, clk_nb); | ||
| 844 | struct sci_port *sci_port; | 821 | struct sci_port *sci_port; |
| 845 | unsigned long flags; | 822 | unsigned long flags; |
| 846 | 823 | ||
| 824 | sci_port = container_of(self, struct sci_port, freq_transition); | ||
| 825 | |||
| 847 | if ((phase == CPUFREQ_POSTCHANGE) || | 826 | if ((phase == CPUFREQ_POSTCHANGE) || |
| 848 | (phase == CPUFREQ_RESUMECHANGE)) { | 827 | (phase == CPUFREQ_RESUMECHANGE)) { |
| 849 | spin_lock_irqsave(&priv->lock, flags); | 828 | struct uart_port *port = &sci_port->port; |
| 850 | list_for_each_entry(sci_port, &priv->ports, node) | 829 | |
| 851 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); | 830 | spin_lock_irqsave(&port->lock, flags); |
| 852 | spin_unlock_irqrestore(&priv->lock, flags); | 831 | port->uartclk = clk_get_rate(sci_port->iclk); |
| 832 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 853 | } | 833 | } |
| 854 | 834 | ||
| 855 | return NOTIFY_OK; | 835 | return NOTIFY_OK; |
| @@ -882,21 +862,21 @@ static int sci_request_irq(struct sci_port *port) | |||
| 882 | const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full", | 862 | const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full", |
| 883 | "SCI Transmit Data Empty", "SCI Break" }; | 863 | "SCI Transmit Data Empty", "SCI Break" }; |
| 884 | 864 | ||
| 885 | if (port->irqs[0] == port->irqs[1]) { | 865 | if (port->cfg->irqs[0] == port->cfg->irqs[1]) { |
| 886 | if (unlikely(!port->irqs[0])) | 866 | if (unlikely(!port->cfg->irqs[0])) |
| 887 | return -ENODEV; | 867 | return -ENODEV; |
| 888 | 868 | ||
| 889 | if (request_irq(port->irqs[0], sci_mpxed_interrupt, | 869 | if (request_irq(port->cfg->irqs[0], sci_mpxed_interrupt, |
| 890 | IRQF_DISABLED, "sci", port)) { | 870 | IRQF_DISABLED, "sci", port)) { |
| 891 | dev_err(port->port.dev, "Can't allocate IRQ\n"); | 871 | dev_err(port->port.dev, "Can't allocate IRQ\n"); |
| 892 | return -ENODEV; | 872 | return -ENODEV; |
| 893 | } | 873 | } |
| 894 | } else { | 874 | } else { |
| 895 | for (i = 0; i < ARRAY_SIZE(handlers); i++) { | 875 | for (i = 0; i < ARRAY_SIZE(handlers); i++) { |
| 896 | if (unlikely(!port->irqs[i])) | 876 | if (unlikely(!port->cfg->irqs[i])) |
| 897 | continue; | 877 | continue; |
| 898 | 878 | ||
| 899 | if (request_irq(port->irqs[i], handlers[i], | 879 | if (request_irq(port->cfg->irqs[i], handlers[i], |
| 900 | IRQF_DISABLED, desc[i], port)) { | 880 | IRQF_DISABLED, desc[i], port)) { |
| 901 | dev_err(port->port.dev, "Can't allocate IRQ\n"); | 881 | dev_err(port->port.dev, "Can't allocate IRQ\n"); |
| 902 | return -ENODEV; | 882 | return -ENODEV; |
| @@ -911,14 +891,14 @@ static void sci_free_irq(struct sci_port *port) | |||
| 911 | { | 891 | { |
| 912 | int i; | 892 | int i; |
| 913 | 893 | ||
| 914 | if (port->irqs[0] == port->irqs[1]) | 894 | if (port->cfg->irqs[0] == port->cfg->irqs[1]) |
| 915 | free_irq(port->irqs[0], port); | 895 | free_irq(port->cfg->irqs[0], port); |
| 916 | else { | 896 | else { |
| 917 | for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { | 897 | for (i = 0; i < ARRAY_SIZE(port->cfg->irqs); i++) { |
| 918 | if (!port->irqs[i]) | 898 | if (!port->cfg->irqs[i]) |
| 919 | continue; | 899 | continue; |
| 920 | 900 | ||
| 921 | free_irq(port->irqs[i], port); | 901 | free_irq(port->cfg->irqs[i], port); |
| 922 | } | 902 | } |
| 923 | } | 903 | } |
| 924 | } | 904 | } |
| @@ -1037,9 +1017,6 @@ static void sci_dma_rx_complete(void *arg) | |||
| 1037 | schedule_work(&s->work_rx); | 1017 | schedule_work(&s->work_rx); |
| 1038 | } | 1018 | } |
| 1039 | 1019 | ||
| 1040 | static void sci_start_rx(struct uart_port *port); | ||
| 1041 | static void sci_start_tx(struct uart_port *port); | ||
| 1042 | |||
| 1043 | static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) | 1020 | static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) |
| 1044 | { | 1021 | { |
| 1045 | struct dma_chan *chan = s->chan_rx; | 1022 | struct dma_chan *chan = s->chan_rx; |
| @@ -1325,7 +1302,7 @@ static void rx_timer_fn(unsigned long arg) | |||
| 1325 | 1302 | ||
| 1326 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | 1303 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
| 1327 | scr &= ~0x4000; | 1304 | scr &= ~0x4000; |
| 1328 | enable_irq(s->irqs[1]); | 1305 | enable_irq(s->cfg->irqs[1]); |
| 1329 | } | 1306 | } |
| 1330 | sci_out(port, SCSCR, scr | SCSCR_RIE); | 1307 | sci_out(port, SCSCR, scr | SCSCR_RIE); |
| 1331 | dev_dbg(port->dev, "DMA Rx timed out\n"); | 1308 | dev_dbg(port->dev, "DMA Rx timed out\n"); |
| @@ -1341,9 +1318,9 @@ static void sci_request_dma(struct uart_port *port) | |||
| 1341 | int nent; | 1318 | int nent; |
| 1342 | 1319 | ||
| 1343 | dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__, | 1320 | dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__, |
| 1344 | port->line, s->dma_dev); | 1321 | port->line, s->cfg->dma_dev); |
| 1345 | 1322 | ||
| 1346 | if (!s->dma_dev) | 1323 | if (!s->cfg->dma_dev) |
| 1347 | return; | 1324 | return; |
| 1348 | 1325 | ||
| 1349 | dma_cap_zero(mask); | 1326 | dma_cap_zero(mask); |
| @@ -1352,8 +1329,8 @@ static void sci_request_dma(struct uart_port *port) | |||
| 1352 | param = &s->param_tx; | 1329 | param = &s->param_tx; |
| 1353 | 1330 | ||
| 1354 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ | 1331 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ |
| 1355 | param->slave_id = s->slave_tx; | 1332 | param->slave_id = s->cfg->dma_slave_tx; |
| 1356 | param->dma_dev = s->dma_dev; | 1333 | param->dma_dev = s->cfg->dma_dev; |
| 1357 | 1334 | ||
| 1358 | s->cookie_tx = -EINVAL; | 1335 | s->cookie_tx = -EINVAL; |
| 1359 | chan = dma_request_channel(mask, filter, param); | 1336 | chan = dma_request_channel(mask, filter, param); |
| @@ -1381,8 +1358,8 @@ static void sci_request_dma(struct uart_port *port) | |||
| 1381 | param = &s->param_rx; | 1358 | param = &s->param_rx; |
| 1382 | 1359 | ||
| 1383 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ | 1360 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ |
| 1384 | param->slave_id = s->slave_rx; | 1361 | param->slave_id = s->cfg->dma_slave_rx; |
| 1385 | param->dma_dev = s->dma_dev; | 1362 | param->dma_dev = s->cfg->dma_dev; |
| 1386 | 1363 | ||
| 1387 | chan = dma_request_channel(mask, filter, param); | 1364 | chan = dma_request_channel(mask, filter, param); |
| 1388 | dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); | 1365 | dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); |
| @@ -1427,7 +1404,7 @@ static void sci_free_dma(struct uart_port *port) | |||
| 1427 | { | 1404 | { |
| 1428 | struct sci_port *s = to_sci_port(port); | 1405 | struct sci_port *s = to_sci_port(port); |
| 1429 | 1406 | ||
| 1430 | if (!s->dma_dev) | 1407 | if (!s->cfg->dma_dev) |
| 1431 | return; | 1408 | return; |
| 1432 | 1409 | ||
| 1433 | if (s->chan_tx) | 1410 | if (s->chan_tx) |
| @@ -1435,21 +1412,32 @@ static void sci_free_dma(struct uart_port *port) | |||
| 1435 | if (s->chan_rx) | 1412 | if (s->chan_rx) |
| 1436 | sci_rx_dma_release(s, false); | 1413 | sci_rx_dma_release(s, false); |
| 1437 | } | 1414 | } |
| 1415 | #else | ||
| 1416 | static inline void sci_request_dma(struct uart_port *port) | ||
| 1417 | { | ||
| 1418 | } | ||
| 1419 | |||
| 1420 | static inline void sci_free_dma(struct uart_port *port) | ||
| 1421 | { | ||
| 1422 | } | ||
| 1438 | #endif | 1423 | #endif |
| 1439 | 1424 | ||
| 1440 | static int sci_startup(struct uart_port *port) | 1425 | static int sci_startup(struct uart_port *port) |
| 1441 | { | 1426 | { |
| 1442 | struct sci_port *s = to_sci_port(port); | 1427 | struct sci_port *s = to_sci_port(port); |
| 1428 | int ret; | ||
| 1443 | 1429 | ||
| 1444 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 1430 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); |
| 1445 | 1431 | ||
| 1446 | if (s->enable) | 1432 | if (s->enable) |
| 1447 | s->enable(port); | 1433 | s->enable(port); |
| 1448 | 1434 | ||
| 1449 | sci_request_irq(s); | 1435 | ret = sci_request_irq(s); |
| 1450 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1436 | if (unlikely(ret < 0)) |
| 1437 | return ret; | ||
| 1438 | |||
| 1451 | sci_request_dma(port); | 1439 | sci_request_dma(port); |
| 1452 | #endif | 1440 | |
| 1453 | sci_start_tx(port); | 1441 | sci_start_tx(port); |
| 1454 | sci_start_rx(port); | 1442 | sci_start_rx(port); |
| 1455 | 1443 | ||
| @@ -1464,9 +1452,8 @@ static void sci_shutdown(struct uart_port *port) | |||
| 1464 | 1452 | ||
| 1465 | sci_stop_rx(port); | 1453 | sci_stop_rx(port); |
| 1466 | sci_stop_tx(port); | 1454 | sci_stop_tx(port); |
| 1467 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1455 | |
| 1468 | sci_free_dma(port); | 1456 | sci_free_dma(port); |
| 1469 | #endif | ||
| 1470 | sci_free_irq(s); | 1457 | sci_free_irq(s); |
| 1471 | 1458 | ||
| 1472 | if (s->disable) | 1459 | if (s->disable) |
| @@ -1491,6 +1478,7 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | |||
| 1491 | 1478 | ||
| 1492 | /* Warn, but use a safe default */ | 1479 | /* Warn, but use a safe default */ |
| 1493 | WARN_ON(1); | 1480 | WARN_ON(1); |
| 1481 | |||
| 1494 | return ((freq + 16 * bps) / (32 * bps) - 1); | 1482 | return ((freq + 16 * bps) / (32 * bps) - 1); |
| 1495 | } | 1483 | } |
| 1496 | 1484 | ||
| @@ -1514,7 +1502,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1514 | 1502 | ||
| 1515 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); | 1503 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); |
| 1516 | if (likely(baud && port->uartclk)) | 1504 | if (likely(baud && port->uartclk)) |
| 1517 | t = sci_scbrr_calc(s->scbrr_algo_id, baud, port->uartclk); | 1505 | t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); |
| 1506 | |||
| 1507 | if (s->enable) | ||
| 1508 | s->enable(port); | ||
| 1518 | 1509 | ||
| 1519 | do { | 1510 | do { |
| 1520 | status = sci_in(port, SCxSR); | 1511 | status = sci_in(port, SCxSR); |
| @@ -1526,6 +1517,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1526 | sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); | 1517 | sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); |
| 1527 | 1518 | ||
| 1528 | smr_val = sci_in(port, SCSMR) & 3; | 1519 | smr_val = sci_in(port, SCSMR) & 3; |
| 1520 | |||
| 1529 | if ((termios->c_cflag & CSIZE) == CS7) | 1521 | if ((termios->c_cflag & CSIZE) == CS7) |
| 1530 | smr_val |= 0x40; | 1522 | smr_val |= 0x40; |
| 1531 | if (termios->c_cflag & PARENB) | 1523 | if (termios->c_cflag & PARENB) |
| @@ -1540,7 +1532,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1540 | sci_out(port, SCSMR, smr_val); | 1532 | sci_out(port, SCSMR, smr_val); |
| 1541 | 1533 | ||
| 1542 | dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, | 1534 | dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, |
| 1543 | s->scscr); | 1535 | s->cfg->scscr); |
| 1544 | 1536 | ||
| 1545 | if (t > 0) { | 1537 | if (t > 0) { |
| 1546 | if (t >= 256) { | 1538 | if (t >= 256) { |
| @@ -1556,7 +1548,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1556 | sci_init_pins(port, termios->c_cflag); | 1548 | sci_init_pins(port, termios->c_cflag); |
| 1557 | sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0)); | 1549 | sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0)); |
| 1558 | 1550 | ||
| 1559 | sci_out(port, SCSCR, s->scscr); | 1551 | sci_out(port, SCSCR, s->cfg->scscr); |
| 1560 | 1552 | ||
| 1561 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1553 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
| 1562 | /* | 1554 | /* |
| @@ -1582,6 +1574,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1582 | 1574 | ||
| 1583 | if ((termios->c_cflag & CREAD) != 0) | 1575 | if ((termios->c_cflag & CREAD) != 0) |
| 1584 | sci_start_rx(port); | 1576 | sci_start_rx(port); |
| 1577 | |||
| 1578 | if (s->disable) | ||
| 1579 | s->disable(port); | ||
| 1585 | } | 1580 | } |
| 1586 | 1581 | ||
| 1587 | static const char *sci_type(struct uart_port *port) | 1582 | static const char *sci_type(struct uart_port *port) |
| @@ -1602,31 +1597,33 @@ static const char *sci_type(struct uart_port *port) | |||
| 1602 | return NULL; | 1597 | return NULL; |
| 1603 | } | 1598 | } |
| 1604 | 1599 | ||
| 1605 | static void sci_release_port(struct uart_port *port) | 1600 | static inline unsigned long sci_port_size(struct uart_port *port) |
| 1606 | { | 1601 | { |
| 1607 | /* Nothing here yet .. */ | 1602 | /* |
| 1608 | } | 1603 | * Pick an arbitrary size that encapsulates all of the base |
| 1609 | 1604 | * registers by default. This can be optimized later, or derived | |
| 1610 | static int sci_request_port(struct uart_port *port) | 1605 | * from platform resource data at such a time that ports begin to |
| 1611 | { | 1606 | * behave more erratically. |
| 1612 | /* Nothing here yet .. */ | 1607 | */ |
| 1613 | return 0; | 1608 | return 64; |
| 1614 | } | 1609 | } |
| 1615 | 1610 | ||
| 1616 | static void sci_config_port(struct uart_port *port, int flags) | 1611 | static int sci_remap_port(struct uart_port *port) |
| 1617 | { | 1612 | { |
| 1618 | struct sci_port *s = to_sci_port(port); | 1613 | unsigned long size = sci_port_size(port); |
| 1619 | |||
| 1620 | port->type = s->type; | ||
| 1621 | 1614 | ||
| 1615 | /* | ||
| 1616 | * Nothing to do if there's already an established membase. | ||
| 1617 | */ | ||
| 1622 | if (port->membase) | 1618 | if (port->membase) |
| 1623 | return; | 1619 | return 0; |
| 1624 | 1620 | ||
| 1625 | if (port->flags & UPF_IOREMAP) { | 1621 | if (port->flags & UPF_IOREMAP) { |
| 1626 | port->membase = ioremap_nocache(port->mapbase, 0x40); | 1622 | port->membase = ioremap_nocache(port->mapbase, size); |
| 1627 | 1623 | if (unlikely(!port->membase)) { | |
| 1628 | if (IS_ERR(port->membase)) | ||
| 1629 | dev_err(port->dev, "can't remap port#%d\n", port->line); | 1624 | dev_err(port->dev, "can't remap port#%d\n", port->line); |
| 1625 | return -ENXIO; | ||
| 1626 | } | ||
| 1630 | } else { | 1627 | } else { |
| 1631 | /* | 1628 | /* |
| 1632 | * For the simple (and majority of) cases where we don't | 1629 | * For the simple (and majority of) cases where we don't |
| @@ -1635,13 +1632,54 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
| 1635 | */ | 1632 | */ |
| 1636 | port->membase = (void __iomem *)port->mapbase; | 1633 | port->membase = (void __iomem *)port->mapbase; |
| 1637 | } | 1634 | } |
| 1635 | |||
| 1636 | return 0; | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | static void sci_release_port(struct uart_port *port) | ||
| 1640 | { | ||
| 1641 | if (port->flags & UPF_IOREMAP) { | ||
| 1642 | iounmap(port->membase); | ||
| 1643 | port->membase = NULL; | ||
| 1644 | } | ||
| 1645 | |||
| 1646 | release_mem_region(port->mapbase, sci_port_size(port)); | ||
| 1647 | } | ||
| 1648 | |||
| 1649 | static int sci_request_port(struct uart_port *port) | ||
| 1650 | { | ||
| 1651 | unsigned long size = sci_port_size(port); | ||
| 1652 | struct resource *res; | ||
| 1653 | int ret; | ||
| 1654 | |||
| 1655 | res = request_mem_region(port->mapbase, size, dev_name(port->dev)); | ||
| 1656 | if (unlikely(res == NULL)) | ||
| 1657 | return -EBUSY; | ||
| 1658 | |||
| 1659 | ret = sci_remap_port(port); | ||
| 1660 | if (unlikely(ret != 0)) { | ||
| 1661 | release_resource(res); | ||
| 1662 | return ret; | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | return 0; | ||
| 1666 | } | ||
| 1667 | |||
| 1668 | static void sci_config_port(struct uart_port *port, int flags) | ||
| 1669 | { | ||
| 1670 | if (flags & UART_CONFIG_TYPE) { | ||
| 1671 | struct sci_port *sport = to_sci_port(port); | ||
| 1672 | |||
| 1673 | port->type = sport->cfg->type; | ||
| 1674 | sci_request_port(port); | ||
| 1675 | } | ||
| 1638 | } | 1676 | } |
| 1639 | 1677 | ||
| 1640 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) | 1678 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) |
| 1641 | { | 1679 | { |
| 1642 | struct sci_port *s = to_sci_port(port); | 1680 | struct sci_port *s = to_sci_port(port); |
| 1643 | 1681 | ||
| 1644 | if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs) | 1682 | if (ser->irq != s->cfg->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs) |
| 1645 | return -EINVAL; | 1683 | return -EINVAL; |
| 1646 | if (ser->baud_base < 2400) | 1684 | if (ser->baud_base < 2400) |
| 1647 | /* No paper tape reader for Mitch.. */ | 1685 | /* No paper tape reader for Mitch.. */ |
| @@ -1726,36 +1764,29 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
| 1726 | sci_port->break_timer.function = sci_break_timer; | 1764 | sci_port->break_timer.function = sci_break_timer; |
| 1727 | init_timer(&sci_port->break_timer); | 1765 | init_timer(&sci_port->break_timer); |
| 1728 | 1766 | ||
| 1729 | port->mapbase = p->mapbase; | 1767 | sci_port->cfg = p; |
| 1730 | port->membase = p->membase; | ||
| 1731 | 1768 | ||
| 1732 | port->irq = p->irqs[SCIx_TXI_IRQ]; | 1769 | port->mapbase = p->mapbase; |
| 1770 | port->type = p->type; | ||
| 1733 | port->flags = p->flags; | 1771 | port->flags = p->flags; |
| 1734 | sci_port->type = port->type = p->type; | ||
| 1735 | sci_port->scscr = p->scscr; | ||
| 1736 | sci_port->scbrr_algo_id = p->scbrr_algo_id; | ||
| 1737 | 1772 | ||
| 1738 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1773 | /* |
| 1739 | sci_port->dma_dev = p->dma_dev; | 1774 | * The UART port needs an IRQ value, so we peg this to the TX IRQ |
| 1740 | sci_port->slave_tx = p->dma_slave_tx; | 1775 | * for the multi-IRQ ports, which is where we are primarily |
| 1741 | sci_port->slave_rx = p->dma_slave_rx; | 1776 | * concerned with the shutdown path synchronization. |
| 1777 | * | ||
| 1778 | * For the muxed case there's nothing more to do. | ||
| 1779 | */ | ||
| 1780 | port->irq = p->irqs[SCIx_TXI_IRQ]; | ||
| 1742 | 1781 | ||
| 1743 | dev_dbg(port->dev, "%s: DMA device %p, tx %d, rx %d\n", __func__, | 1782 | if (p->dma_dev) |
| 1744 | p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); | 1783 | dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n", |
| 1745 | #endif | 1784 | p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); |
| 1746 | 1785 | ||
| 1747 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | ||
| 1748 | return 0; | 1786 | return 0; |
| 1749 | } | 1787 | } |
| 1750 | 1788 | ||
| 1751 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 1789 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE |
| 1752 | static struct tty_driver *serial_console_device(struct console *co, int *index) | ||
| 1753 | { | ||
| 1754 | struct uart_driver *p = &sci_uart_driver; | ||
| 1755 | *index = co->index; | ||
| 1756 | return p->tty_driver; | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | static void serial_console_putchar(struct uart_port *port, int ch) | 1790 | static void serial_console_putchar(struct uart_port *port, int ch) |
| 1760 | { | 1791 | { |
| 1761 | sci_poll_put_char(port, ch); | 1792 | sci_poll_put_char(port, ch); |
| @@ -1768,8 +1799,8 @@ static void serial_console_putchar(struct uart_port *port, int ch) | |||
| 1768 | static void serial_console_write(struct console *co, const char *s, | 1799 | static void serial_console_write(struct console *co, const char *s, |
| 1769 | unsigned count) | 1800 | unsigned count) |
| 1770 | { | 1801 | { |
| 1771 | struct uart_port *port = co->data; | 1802 | struct sci_port *sci_port = &sci_ports[co->index]; |
| 1772 | struct sci_port *sci_port = to_sci_port(port); | 1803 | struct uart_port *port = &sci_port->port; |
| 1773 | unsigned short bits; | 1804 | unsigned short bits; |
| 1774 | 1805 | ||
| 1775 | if (sci_port->enable) | 1806 | if (sci_port->enable) |
| @@ -1797,32 +1828,17 @@ static int __devinit serial_console_setup(struct console *co, char *options) | |||
| 1797 | int ret; | 1828 | int ret; |
| 1798 | 1829 | ||
| 1799 | /* | 1830 | /* |
| 1800 | * Check whether an invalid uart number has been specified, and | 1831 | * Refuse to handle any bogus ports. |
| 1801 | * if so, search for the first available port that does have | ||
| 1802 | * console support. | ||
| 1803 | */ | ||
| 1804 | if (co->index >= SCI_NPORTS) | ||
| 1805 | co->index = 0; | ||
| 1806 | |||
| 1807 | if (co->data) { | ||
| 1808 | port = co->data; | ||
| 1809 | sci_port = to_sci_port(port); | ||
| 1810 | } else { | ||
| 1811 | sci_port = &sci_ports[co->index]; | ||
| 1812 | port = &sci_port->port; | ||
| 1813 | co->data = port; | ||
| 1814 | } | ||
| 1815 | |||
| 1816 | /* | ||
| 1817 | * Also need to check port->type, we don't actually have any | ||
| 1818 | * UPIO_PORT ports, but uart_report_port() handily misreports | ||
| 1819 | * it anyways if we don't have a port available by the time this is | ||
| 1820 | * called. | ||
| 1821 | */ | 1832 | */ |
| 1822 | if (!port->type) | 1833 | if (co->index < 0 || co->index >= SCI_NPORTS) |
| 1823 | return -ENODEV; | 1834 | return -ENODEV; |
| 1824 | 1835 | ||
| 1825 | sci_config_port(port, 0); | 1836 | sci_port = &sci_ports[co->index]; |
| 1837 | port = &sci_port->port; | ||
| 1838 | |||
| 1839 | ret = sci_remap_port(port); | ||
| 1840 | if (unlikely(ret != 0)) | ||
| 1841 | return ret; | ||
| 1826 | 1842 | ||
| 1827 | if (sci_port->enable) | 1843 | if (sci_port->enable) |
| 1828 | sci_port->enable(port); | 1844 | sci_port->enable(port); |
| @@ -1842,11 +1858,12 @@ static int __devinit serial_console_setup(struct console *co, char *options) | |||
| 1842 | 1858 | ||
| 1843 | static struct console serial_console = { | 1859 | static struct console serial_console = { |
| 1844 | .name = "ttySC", | 1860 | .name = "ttySC", |
| 1845 | .device = serial_console_device, | 1861 | .device = uart_console_device, |
| 1846 | .write = serial_console_write, | 1862 | .write = serial_console_write, |
| 1847 | .setup = serial_console_setup, | 1863 | .setup = serial_console_setup, |
| 1848 | .flags = CON_PRINTBUFFER, | 1864 | .flags = CON_PRINTBUFFER, |
| 1849 | .index = -1, | 1865 | .index = -1, |
| 1866 | .data = &sci_uart_driver, | ||
| 1850 | }; | 1867 | }; |
| 1851 | 1868 | ||
| 1852 | static int __init sci_console_init(void) | 1869 | static int __init sci_console_init(void) |
| @@ -1856,14 +1873,39 @@ static int __init sci_console_init(void) | |||
| 1856 | } | 1873 | } |
| 1857 | console_initcall(sci_console_init); | 1874 | console_initcall(sci_console_init); |
| 1858 | 1875 | ||
| 1859 | static struct sci_port early_serial_port; | ||
| 1860 | static struct console early_serial_console = { | 1876 | static struct console early_serial_console = { |
| 1861 | .name = "early_ttySC", | 1877 | .name = "early_ttySC", |
| 1862 | .write = serial_console_write, | 1878 | .write = serial_console_write, |
| 1863 | .flags = CON_PRINTBUFFER, | 1879 | .flags = CON_PRINTBUFFER, |
| 1880 | .index = -1, | ||
| 1864 | }; | 1881 | }; |
| 1882 | |||
| 1865 | static char early_serial_buf[32]; | 1883 | static char early_serial_buf[32]; |
| 1866 | 1884 | ||
| 1885 | static int __devinit sci_probe_earlyprintk(struct platform_device *pdev) | ||
| 1886 | { | ||
| 1887 | struct plat_sci_port *cfg = pdev->dev.platform_data; | ||
| 1888 | |||
| 1889 | if (early_serial_console.data) | ||
| 1890 | return -EEXIST; | ||
| 1891 | |||
| 1892 | early_serial_console.index = pdev->id; | ||
| 1893 | |||
| 1894 | sci_init_single(NULL, &sci_ports[pdev->id], pdev->id, cfg); | ||
| 1895 | |||
| 1896 | serial_console_setup(&early_serial_console, early_serial_buf); | ||
| 1897 | |||
| 1898 | if (!strstr(early_serial_buf, "keep")) | ||
| 1899 | early_serial_console.flags |= CON_BOOT; | ||
| 1900 | |||
| 1901 | register_console(&early_serial_console); | ||
| 1902 | return 0; | ||
| 1903 | } | ||
| 1904 | #else | ||
| 1905 | static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev) | ||
| 1906 | { | ||
| 1907 | return -EINVAL; | ||
| 1908 | } | ||
| 1867 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 1909 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
| 1868 | 1910 | ||
| 1869 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | 1911 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) |
| @@ -1885,24 +1927,18 @@ static struct uart_driver sci_uart_driver = { | |||
| 1885 | .cons = SCI_CONSOLE, | 1927 | .cons = SCI_CONSOLE, |
| 1886 | }; | 1928 | }; |
| 1887 | 1929 | ||
| 1888 | |||
| 1889 | static int sci_remove(struct platform_device *dev) | 1930 | static int sci_remove(struct platform_device *dev) |
| 1890 | { | 1931 | { |
| 1891 | struct sh_sci_priv *priv = platform_get_drvdata(dev); | 1932 | struct sci_port *port = platform_get_drvdata(dev); |
| 1892 | struct sci_port *p; | ||
| 1893 | unsigned long flags; | ||
| 1894 | 1933 | ||
| 1895 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1934 | cpufreq_unregister_notifier(&port->freq_transition, |
| 1935 | CPUFREQ_TRANSITION_NOTIFIER); | ||
| 1896 | 1936 | ||
| 1897 | spin_lock_irqsave(&priv->lock, flags); | 1937 | uart_remove_one_port(&sci_uart_driver, &port->port); |
| 1898 | list_for_each_entry(p, &priv->ports, node) { | 1938 | |
| 1899 | uart_remove_one_port(&sci_uart_driver, &p->port); | 1939 | clk_put(port->iclk); |
| 1900 | clk_put(p->iclk); | 1940 | clk_put(port->fclk); |
| 1901 | clk_put(p->fclk); | ||
| 1902 | } | ||
| 1903 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 1904 | 1941 | ||
| 1905 | kfree(priv); | ||
| 1906 | return 0; | 1942 | return 0; |
| 1907 | } | 1943 | } |
| 1908 | 1944 | ||
| @@ -1911,8 +1947,6 @@ static int __devinit sci_probe_single(struct platform_device *dev, | |||
| 1911 | struct plat_sci_port *p, | 1947 | struct plat_sci_port *p, |
| 1912 | struct sci_port *sciport) | 1948 | struct sci_port *sciport) |
| 1913 | { | 1949 | { |
| 1914 | struct sh_sci_priv *priv = platform_get_drvdata(dev); | ||
| 1915 | unsigned long flags; | ||
| 1916 | int ret; | 1950 | int ret; |
| 1917 | 1951 | ||
| 1918 | /* Sanity check */ | 1952 | /* Sanity check */ |
| @@ -1929,68 +1963,35 @@ static int __devinit sci_probe_single(struct platform_device *dev, | |||
| 1929 | if (ret) | 1963 | if (ret) |
| 1930 | return ret; | 1964 | return ret; |
| 1931 | 1965 | ||
| 1932 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); | 1966 | return uart_add_one_port(&sci_uart_driver, &sciport->port); |
| 1933 | if (ret) | ||
| 1934 | return ret; | ||
| 1935 | |||
| 1936 | INIT_LIST_HEAD(&sciport->node); | ||
| 1937 | |||
| 1938 | spin_lock_irqsave(&priv->lock, flags); | ||
| 1939 | list_add(&sciport->node, &priv->ports); | ||
| 1940 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 1941 | |||
| 1942 | return 0; | ||
| 1943 | } | 1967 | } |
| 1944 | 1968 | ||
| 1945 | /* | ||
| 1946 | * Register a set of serial devices attached to a platform device. The | ||
| 1947 | * list is terminated with a zero flags entry, which means we expect | ||
| 1948 | * all entries to have at least UPF_BOOT_AUTOCONF set. Platforms that need | ||
| 1949 | * remapping (such as sh64) should also set UPF_IOREMAP. | ||
| 1950 | */ | ||
| 1951 | static int __devinit sci_probe(struct platform_device *dev) | 1969 | static int __devinit sci_probe(struct platform_device *dev) |
| 1952 | { | 1970 | { |
| 1953 | struct plat_sci_port *p = dev->dev.platform_data; | 1971 | struct plat_sci_port *p = dev->dev.platform_data; |
| 1954 | struct sh_sci_priv *priv; | 1972 | struct sci_port *sp = &sci_ports[dev->id]; |
| 1955 | int i, ret = -EINVAL; | 1973 | int ret; |
| 1956 | 1974 | ||
| 1957 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 1975 | /* |
| 1958 | if (is_early_platform_device(dev)) { | 1976 | * If we've come here via earlyprintk initialization, head off to |
| 1959 | if (dev->id == -1) | 1977 | * the special early probe. We don't have sufficient device state |
| 1960 | return -ENOTSUPP; | 1978 | * to make it beyond this yet. |
| 1961 | early_serial_console.index = dev->id; | 1979 | */ |
| 1962 | early_serial_console.data = &early_serial_port.port; | 1980 | if (is_early_platform_device(dev)) |
| 1963 | sci_init_single(NULL, &early_serial_port, dev->id, p); | 1981 | return sci_probe_earlyprintk(dev); |
| 1964 | serial_console_setup(&early_serial_console, early_serial_buf); | ||
| 1965 | if (!strstr(early_serial_buf, "keep")) | ||
| 1966 | early_serial_console.flags |= CON_BOOT; | ||
| 1967 | register_console(&early_serial_console); | ||
| 1968 | return 0; | ||
| 1969 | } | ||
| 1970 | #endif | ||
| 1971 | 1982 | ||
| 1972 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 1983 | platform_set_drvdata(dev, sp); |
| 1973 | if (!priv) | ||
| 1974 | return -ENOMEM; | ||
| 1975 | 1984 | ||
| 1976 | INIT_LIST_HEAD(&priv->ports); | 1985 | ret = sci_probe_single(dev, dev->id, p, sp); |
| 1977 | spin_lock_init(&priv->lock); | 1986 | if (ret) |
| 1978 | platform_set_drvdata(dev, priv); | 1987 | goto err_unreg; |
| 1979 | 1988 | ||
| 1980 | priv->clk_nb.notifier_call = sci_notifier; | 1989 | sp->freq_transition.notifier_call = sci_notifier; |
| 1981 | cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | ||
| 1982 | 1990 | ||
| 1983 | if (dev->id != -1) { | 1991 | ret = cpufreq_register_notifier(&sp->freq_transition, |
| 1984 | ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]); | 1992 | CPUFREQ_TRANSITION_NOTIFIER); |
| 1985 | if (ret) | 1993 | if (unlikely(ret < 0)) |
| 1986 | goto err_unreg; | 1994 | goto err_unreg; |
| 1987 | } else { | ||
| 1988 | for (i = 0; p && p->flags != 0; p++, i++) { | ||
| 1989 | ret = sci_probe_single(dev, i, p, &sci_ports[i]); | ||
| 1990 | if (ret) | ||
| 1991 | goto err_unreg; | ||
| 1992 | } | ||
| 1993 | } | ||
| 1994 | 1995 | ||
| 1995 | #ifdef CONFIG_SH_STANDARD_BIOS | 1996 | #ifdef CONFIG_SH_STANDARD_BIOS |
| 1996 | sh_bios_gdb_detach(); | 1997 | sh_bios_gdb_detach(); |
| @@ -2005,28 +2006,20 @@ err_unreg: | |||
| 2005 | 2006 | ||
| 2006 | static int sci_suspend(struct device *dev) | 2007 | static int sci_suspend(struct device *dev) |
| 2007 | { | 2008 | { |
| 2008 | struct sh_sci_priv *priv = dev_get_drvdata(dev); | 2009 | struct sci_port *sport = dev_get_drvdata(dev); |
| 2009 | struct sci_port *p; | ||
| 2010 | unsigned long flags; | ||
| 2011 | 2010 | ||
| 2012 | spin_lock_irqsave(&priv->lock, flags); | 2011 | if (sport) |
| 2013 | list_for_each_entry(p, &priv->ports, node) | 2012 | uart_suspend_port(&sci_uart_driver, &sport->port); |
| 2014 | uart_suspend_port(&sci_uart_driver, &p->port); | ||
| 2015 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 2016 | 2013 | ||
| 2017 | return 0; | 2014 | return 0; |
| 2018 | } | 2015 | } |
| 2019 | 2016 | ||
| 2020 | static int sci_resume(struct device *dev) | 2017 | static int sci_resume(struct device *dev) |
| 2021 | { | 2018 | { |
| 2022 | struct sh_sci_priv *priv = dev_get_drvdata(dev); | 2019 | struct sci_port *sport = dev_get_drvdata(dev); |
| 2023 | struct sci_port *p; | ||
| 2024 | unsigned long flags; | ||
| 2025 | 2020 | ||
| 2026 | spin_lock_irqsave(&priv->lock, flags); | 2021 | if (sport) |
| 2027 | list_for_each_entry(p, &priv->ports, node) | 2022 | uart_resume_port(&sci_uart_driver, &sport->port); |
| 2028 | uart_resume_port(&sci_uart_driver, &p->port); | ||
| 2029 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 2030 | 2023 | ||
| 2031 | return 0; | 2024 | return 0; |
| 2032 | } | 2025 | } |
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index b223d6cbf33a..5fefed53fa42 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
| @@ -54,9 +54,6 @@ | |||
| 54 | # define PBCR 0xa4050102 | 54 | # define PBCR 0xa4050102 |
| 55 | #elif defined(CONFIG_CPU_SUBTYPE_SH7343) | 55 | #elif defined(CONFIG_CPU_SUBTYPE_SH7343) |
| 56 | # define SCSPTR0 0xffe00010 /* 16 bit SCIF */ | 56 | # define SCSPTR0 0xffe00010 /* 16 bit SCIF */ |
| 57 | # define SCSPTR1 0xffe10010 /* 16 bit SCIF */ | ||
| 58 | # define SCSPTR2 0xffe20010 /* 16 bit SCIF */ | ||
| 59 | # define SCSPTR3 0xffe30010 /* 16 bit SCIF */ | ||
| 60 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 57 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
| 61 | # define PADR 0xA4050120 | 58 | # define PADR 0xA4050120 |
| 62 | # define PSDR 0xA405013e | 59 | # define PSDR 0xA405013e |
| @@ -69,77 +66,42 @@ | |||
| 69 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 66 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 70 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | 67 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) |
| 71 | # define SCSPTR0 0xa4050160 | 68 | # define SCSPTR0 0xa4050160 |
| 72 | # define SCSPTR1 0xa405013e | ||
| 73 | # define SCSPTR2 0xa4050160 | ||
| 74 | # define SCSPTR3 0xa405013e | ||
| 75 | # define SCSPTR4 0xa4050128 | ||
| 76 | # define SCSPTR5 0xa4050128 | ||
| 77 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 69 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 78 | #elif defined(CONFIG_CPU_SUBTYPE_SH7724) | 70 | #elif defined(CONFIG_CPU_SUBTYPE_SH7724) |
| 79 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 71 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 80 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) | 72 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) |
| 81 | # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ | 73 | # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ |
| 82 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 74 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 83 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | ||
| 84 | # define SCIF_PTR2_OFFS 0x0000020 | ||
| 85 | # define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */ | ||
| 86 | #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) | 75 | #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) |
| 87 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) | 76 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) |
| 88 | #elif defined(CONFIG_H8S2678) | 77 | #elif defined(CONFIG_H8S2678) |
| 89 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) | 78 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) |
| 90 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) | 79 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) |
| 91 | # define SCSPTR0 0xfe4b0020 | 80 | # define SCSPTR0 0xfe4b0020 |
| 92 | # define SCSPTR1 0xfe4b0020 | ||
| 93 | # define SCSPTR2 0xfe4b0020 | ||
| 94 | # define SCIF_ORER 0x0001 | 81 | # define SCIF_ORER 0x0001 |
| 95 | # define SCIF_ONLY | ||
| 96 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 82 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
| 97 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ | 83 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ |
| 98 | # define SCSPTR1 0xffe08024 /* 16 bit SCIF */ | ||
| 99 | # define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */ | ||
| 100 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 84 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 101 | #elif defined(CONFIG_CPU_SUBTYPE_SH7770) | 85 | #elif defined(CONFIG_CPU_SUBTYPE_SH7770) |
| 102 | # define SCSPTR0 0xff923020 /* 16 bit SCIF */ | 86 | # define SCSPTR0 0xff923020 /* 16 bit SCIF */ |
| 103 | # define SCSPTR1 0xff924020 /* 16 bit SCIF */ | ||
| 104 | # define SCSPTR2 0xff925020 /* 16 bit SCIF */ | ||
| 105 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 87 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 106 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | 88 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) |
| 107 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ | 89 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ |
| 108 | # define SCSPTR1 0xffe10024 /* 16 bit SCIF */ | ||
| 109 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | 90 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
| 110 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 91 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
| 111 | defined(CONFIG_CPU_SUBTYPE_SH7786) | 92 | defined(CONFIG_CPU_SUBTYPE_SH7786) |
| 112 | # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ | 93 | # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ |
| 113 | # define SCSPTR1 0xffeb0024 /* 16 bit SCIF */ | ||
| 114 | # define SCSPTR2 0xffec0024 /* 16 bit SCIF */ | ||
| 115 | # define SCSPTR3 0xffed0024 /* 16 bit SCIF */ | ||
| 116 | # define SCSPTR4 0xffee0024 /* 16 bit SCIF */ | ||
| 117 | # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ | ||
| 118 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | 94 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
| 119 | #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ | 95 | #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ |
| 120 | defined(CONFIG_CPU_SUBTYPE_SH7203) || \ | 96 | defined(CONFIG_CPU_SUBTYPE_SH7203) || \ |
| 121 | defined(CONFIG_CPU_SUBTYPE_SH7206) || \ | 97 | defined(CONFIG_CPU_SUBTYPE_SH7206) || \ |
| 122 | defined(CONFIG_CPU_SUBTYPE_SH7263) | 98 | defined(CONFIG_CPU_SUBTYPE_SH7263) |
| 123 | # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ | 99 | # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ |
| 124 | # define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ | ||
| 125 | # define SCSPTR2 0xfffe9020 /* 16 bit SCIF */ | ||
| 126 | # define SCSPTR3 0xfffe9820 /* 16 bit SCIF */ | ||
| 127 | # if defined(CONFIG_CPU_SUBTYPE_SH7201) | ||
| 128 | # define SCSPTR4 0xfffeA020 /* 16 bit SCIF */ | ||
| 129 | # define SCSPTR5 0xfffeA820 /* 16 bit SCIF */ | ||
| 130 | # define SCSPTR6 0xfffeB020 /* 16 bit SCIF */ | ||
| 131 | # define SCSPTR7 0xfffeB820 /* 16 bit SCIF */ | ||
| 132 | # endif | ||
| 133 | #elif defined(CONFIG_CPU_SUBTYPE_SH7619) | 100 | #elif defined(CONFIG_CPU_SUBTYPE_SH7619) |
| 134 | # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ | 101 | # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ |
| 135 | # define SCSPTR1 0xf8410020 /* 16 bit SCIF */ | ||
| 136 | # define SCSPTR2 0xf8420020 /* 16 bit SCIF */ | ||
| 137 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 102 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 138 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) | 103 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) |
| 139 | # define SCSPTR0 0xffc30020 /* 16 bit SCIF */ | 104 | # define SCSPTR0 0xffc30020 /* 16 bit SCIF */ |
| 140 | # define SCSPTR1 0xffc40020 /* 16 bit SCIF */ | ||
| 141 | # define SCSPTR2 0xffc50020 /* 16 bit SCIF */ | ||
| 142 | # define SCSPTR3 0xffc60020 /* 16 bit SCIF */ | ||
| 143 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | 105 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
| 144 | #else | 106 | #else |
| 145 | # error CPU subtype not defined | 107 | # error CPU subtype not defined |
| @@ -411,7 +373,6 @@ SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) | |||
| 411 | SCIF_FNS(SCLSR, 0, 0, 0x28, 16) | 373 | SCIF_FNS(SCLSR, 0, 0, 0x28, 16) |
| 412 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 374 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
| 413 | SCIF_FNS(SCFDR, 0, 0, 0x1C, 16) | 375 | SCIF_FNS(SCFDR, 0, 0, 0x1C, 16) |
| 414 | SCIF_FNS(SCSPTR2, 0, 0, 0x20, 16) | ||
| 415 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) | 376 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) |
| 416 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) | 377 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) |
| 417 | SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) | 378 | SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 31649b7b672f..908160e938dc 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
| @@ -1083,14 +1083,6 @@ config SH_WDT | |||
| 1083 | To compile this driver as a module, choose M here: the | 1083 | To compile this driver as a module, choose M here: the |
| 1084 | module will be called shwdt. | 1084 | module will be called shwdt. |
| 1085 | 1085 | ||
| 1086 | config SH_WDT_MMAP | ||
| 1087 | bool "Allow mmap of SH WDT" | ||
| 1088 | default n | ||
| 1089 | depends on SH_WDT | ||
| 1090 | help | ||
| 1091 | If you say Y here, user applications will be able to mmap the | ||
| 1092 | WDT/CPG registers. | ||
| 1093 | |||
| 1094 | # SPARC Architecture | 1086 | # SPARC Architecture |
| 1095 | 1087 | ||
| 1096 | # SPARC64 Architecture | 1088 | # SPARC64 Architecture |
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 6fc74065abee..4e3e7eb5919c 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * drivers/char/watchdog/shwdt.c | 2 | * drivers/watchdog/shwdt.c |
| 3 | * | 3 | * |
| 4 | * Watchdog driver for integrated watchdog in the SuperH processors. | 4 | * Watchdog driver for integrated watchdog in the SuperH processors. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2001, 2002, 2003 Paul Mundt <lethal@linux-sh.org> | 6 | * Copyright (C) 2001 - 2010 Paul Mundt <lethal@linux-sh.org> |
| 7 | * | 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | 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 | 9 | * under the terms of the GNU General Public License as published by the |
| @@ -19,6 +19,7 @@ | |||
| 19 | */ | 19 | */ |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/moduleparam.h> | 21 | #include <linux/moduleparam.h> |
| 22 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 23 | #include <linux/types.h> | 24 | #include <linux/types.h> |
| 24 | #include <linux/miscdevice.h> | 25 | #include <linux/miscdevice.h> |
| @@ -28,11 +29,12 @@ | |||
| 28 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
| 29 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
| 30 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
| 32 | #include <linux/slab.h> | ||
| 31 | #include <linux/io.h> | 33 | #include <linux/io.h> |
| 32 | #include <linux/uaccess.h> | 34 | #include <linux/uaccess.h> |
| 33 | #include <asm/watchdog.h> | 35 | #include <asm/watchdog.h> |
| 34 | 36 | ||
| 35 | #define PFX "shwdt: " | 37 | #define DRV_NAME "sh-wdt" |
| 36 | 38 | ||
| 37 | /* | 39 | /* |
| 38 | * Default clock division ratio is 5.25 msecs. For an additional table of | 40 | * Default clock division ratio is 5.25 msecs. For an additional table of |
| @@ -62,37 +64,36 @@ | |||
| 62 | * misses its deadline, the kernel timer will allow the WDT to overflow. | 64 | * misses its deadline, the kernel timer will allow the WDT to overflow. |
| 63 | */ | 65 | */ |
| 64 | static int clock_division_ratio = WTCSR_CKS_4096; | 66 | static int clock_division_ratio = WTCSR_CKS_4096; |
| 65 | |||
| 66 | #define next_ping_period(cks) msecs_to_jiffies(cks - 4) | 67 | #define next_ping_period(cks) msecs_to_jiffies(cks - 4) |
| 67 | 68 | ||
| 68 | static void sh_wdt_ping(unsigned long data); | ||
| 69 | |||
| 70 | static unsigned long shwdt_is_open; | ||
| 71 | static const struct watchdog_info sh_wdt_info; | 69 | static const struct watchdog_info sh_wdt_info; |
| 72 | static char shwdt_expect_close; | 70 | static struct platform_device *sh_wdt_dev; |
| 73 | static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0); | ||
| 74 | static unsigned long next_heartbeat; | ||
| 75 | static DEFINE_SPINLOCK(shwdt_lock); | 71 | static DEFINE_SPINLOCK(shwdt_lock); |
| 76 | 72 | ||
| 77 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ | 73 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ |
| 78 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ | 74 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ |
| 79 | |||
| 80 | static int nowayout = WATCHDOG_NOWAYOUT; | 75 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 76 | static unsigned long next_heartbeat; | ||
| 81 | 77 | ||
| 82 | /** | 78 | struct sh_wdt { |
| 83 | * sh_wdt_start - Start the Watchdog | 79 | void __iomem *base; |
| 84 | * | 80 | struct device *dev; |
| 85 | * Starts the watchdog. | 81 | |
| 86 | */ | 82 | struct timer_list timer; |
| 87 | static void sh_wdt_start(void) | 83 | |
| 84 | unsigned long enabled; | ||
| 85 | char expect_close; | ||
| 86 | }; | ||
| 87 | |||
| 88 | static void sh_wdt_start(struct sh_wdt *wdt) | ||
| 88 | { | 89 | { |
| 89 | __u8 csr; | ||
| 90 | unsigned long flags; | 90 | unsigned long flags; |
| 91 | u8 csr; | ||
| 91 | 92 | ||
| 92 | spin_lock_irqsave(&shwdt_lock, flags); | 93 | spin_lock_irqsave(&shwdt_lock, flags); |
| 93 | 94 | ||
| 94 | next_heartbeat = jiffies + (heartbeat * HZ); | 95 | next_heartbeat = jiffies + (heartbeat * HZ); |
| 95 | mod_timer(&timer, next_ping_period(clock_division_ratio)); | 96 | mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); |
| 96 | 97 | ||
| 97 | csr = sh_wdt_read_csr(); | 98 | csr = sh_wdt_read_csr(); |
| 98 | csr |= WTCSR_WT | clock_division_ratio; | 99 | csr |= WTCSR_WT | clock_division_ratio; |
| @@ -114,15 +115,6 @@ static void sh_wdt_start(void) | |||
| 114 | sh_wdt_write_csr(csr); | 115 | sh_wdt_write_csr(csr); |
| 115 | 116 | ||
| 116 | #ifdef CONFIG_CPU_SH2 | 117 | #ifdef CONFIG_CPU_SH2 |
| 117 | /* | ||
| 118 | * Whoever came up with the RSTCSR semantics must've been smoking | ||
| 119 | * some of the good stuff, since in addition to the WTCSR/WTCNT write | ||
| 120 | * brain-damage, it's managed to fuck things up one step further.. | ||
| 121 | * | ||
| 122 | * If we need to clear the WOVF bit, the upper byte has to be 0xa5.. | ||
| 123 | * but if we want to touch RSTE or RSTS, the upper byte has to be | ||
| 124 | * 0x5a.. | ||
| 125 | */ | ||
| 126 | csr = sh_wdt_read_rstcsr(); | 118 | csr = sh_wdt_read_rstcsr(); |
| 127 | csr &= ~RSTCSR_RSTS; | 119 | csr &= ~RSTCSR_RSTS; |
| 128 | sh_wdt_write_rstcsr(csr); | 120 | sh_wdt_write_rstcsr(csr); |
| @@ -130,30 +122,23 @@ static void sh_wdt_start(void) | |||
| 130 | spin_unlock_irqrestore(&shwdt_lock, flags); | 122 | spin_unlock_irqrestore(&shwdt_lock, flags); |
| 131 | } | 123 | } |
| 132 | 124 | ||
| 133 | /** | 125 | static void sh_wdt_stop(struct sh_wdt *wdt) |
| 134 | * sh_wdt_stop - Stop the Watchdog | ||
| 135 | * Stops the watchdog. | ||
| 136 | */ | ||
| 137 | static void sh_wdt_stop(void) | ||
| 138 | { | 126 | { |
| 139 | __u8 csr; | ||
| 140 | unsigned long flags; | 127 | unsigned long flags; |
| 128 | u8 csr; | ||
| 141 | 129 | ||
| 142 | spin_lock_irqsave(&shwdt_lock, flags); | 130 | spin_lock_irqsave(&shwdt_lock, flags); |
| 143 | 131 | ||
| 144 | del_timer(&timer); | 132 | del_timer(&wdt->timer); |
| 145 | 133 | ||
| 146 | csr = sh_wdt_read_csr(); | 134 | csr = sh_wdt_read_csr(); |
| 147 | csr &= ~WTCSR_TME; | 135 | csr &= ~WTCSR_TME; |
| 148 | sh_wdt_write_csr(csr); | 136 | sh_wdt_write_csr(csr); |
| 137 | |||
| 149 | spin_unlock_irqrestore(&shwdt_lock, flags); | 138 | spin_unlock_irqrestore(&shwdt_lock, flags); |
| 150 | } | 139 | } |
| 151 | 140 | ||
| 152 | /** | 141 | static inline void sh_wdt_keepalive(struct sh_wdt *wdt) |
| 153 | * sh_wdt_keepalive - Keep the Userspace Watchdog Alive | ||
| 154 | * The Userspace watchdog got a KeepAlive: schedule the next heartbeat. | ||
| 155 | */ | ||
| 156 | static inline void sh_wdt_keepalive(void) | ||
| 157 | { | 142 | { |
| 158 | unsigned long flags; | 143 | unsigned long flags; |
| 159 | 144 | ||
| @@ -162,10 +147,6 @@ static inline void sh_wdt_keepalive(void) | |||
| 162 | spin_unlock_irqrestore(&shwdt_lock, flags); | 147 | spin_unlock_irqrestore(&shwdt_lock, flags); |
| 163 | } | 148 | } |
| 164 | 149 | ||
| 165 | /** | ||
| 166 | * sh_wdt_set_heartbeat - Set the Userspace Watchdog heartbeat | ||
| 167 | * Set the Userspace Watchdog heartbeat | ||
| 168 | */ | ||
| 169 | static int sh_wdt_set_heartbeat(int t) | 150 | static int sh_wdt_set_heartbeat(int t) |
| 170 | { | 151 | { |
| 171 | unsigned long flags; | 152 | unsigned long flags; |
| @@ -179,19 +160,14 @@ static int sh_wdt_set_heartbeat(int t) | |||
| 179 | return 0; | 160 | return 0; |
| 180 | } | 161 | } |
| 181 | 162 | ||
| 182 | /** | ||
| 183 | * sh_wdt_ping - Ping the Watchdog | ||
| 184 | * @data: Unused | ||
| 185 | * | ||
| 186 | * Clears overflow bit, resets timer counter. | ||
| 187 | */ | ||
| 188 | static void sh_wdt_ping(unsigned long data) | 163 | static void sh_wdt_ping(unsigned long data) |
| 189 | { | 164 | { |
| 165 | struct sh_wdt *wdt = (struct sh_wdt *)data; | ||
| 190 | unsigned long flags; | 166 | unsigned long flags; |
| 191 | 167 | ||
| 192 | spin_lock_irqsave(&shwdt_lock, flags); | 168 | spin_lock_irqsave(&shwdt_lock, flags); |
| 193 | if (time_before(jiffies, next_heartbeat)) { | 169 | if (time_before(jiffies, next_heartbeat)) { |
| 194 | __u8 csr; | 170 | u8 csr; |
| 195 | 171 | ||
| 196 | csr = sh_wdt_read_csr(); | 172 | csr = sh_wdt_read_csr(); |
| 197 | csr &= ~WTCSR_IOVF; | 173 | csr &= ~WTCSR_IOVF; |
| @@ -199,148 +175,76 @@ static void sh_wdt_ping(unsigned long data) | |||
| 199 | 175 | ||
| 200 | sh_wdt_write_cnt(0); | 176 | sh_wdt_write_cnt(0); |
| 201 | 177 | ||
| 202 | mod_timer(&timer, next_ping_period(clock_division_ratio)); | 178 | mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); |
| 203 | } else | 179 | } else |
| 204 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping " | 180 | dev_warn(wdt->dev, "Heartbeat lost! Will not ping " |
| 205 | "the watchdog\n"); | 181 | "the watchdog\n"); |
| 206 | spin_unlock_irqrestore(&shwdt_lock, flags); | 182 | spin_unlock_irqrestore(&shwdt_lock, flags); |
| 207 | } | 183 | } |
| 208 | 184 | ||
| 209 | /** | ||
| 210 | * sh_wdt_open - Open the Device | ||
| 211 | * @inode: inode of device | ||
| 212 | * @file: file handle of device | ||
| 213 | * | ||
| 214 | * Watchdog device is opened and started. | ||
| 215 | */ | ||
| 216 | static int sh_wdt_open(struct inode *inode, struct file *file) | 185 | static int sh_wdt_open(struct inode *inode, struct file *file) |
| 217 | { | 186 | { |
| 218 | if (test_and_set_bit(0, &shwdt_is_open)) | 187 | struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev); |
| 188 | |||
| 189 | if (test_and_set_bit(0, &wdt->enabled)) | ||
| 219 | return -EBUSY; | 190 | return -EBUSY; |
| 220 | if (nowayout) | 191 | if (nowayout) |
| 221 | __module_get(THIS_MODULE); | 192 | __module_get(THIS_MODULE); |
| 222 | 193 | ||
| 223 | sh_wdt_start(); | 194 | file->private_data = wdt; |
| 195 | |||
| 196 | sh_wdt_start(wdt); | ||
| 224 | 197 | ||
| 225 | return nonseekable_open(inode, file); | 198 | return nonseekable_open(inode, file); |
| 226 | } | 199 | } |
| 227 | 200 | ||
| 228 | /** | ||
| 229 | * sh_wdt_close - Close the Device | ||
| 230 | * @inode: inode of device | ||
| 231 | * @file: file handle of device | ||
| 232 | * | ||
| 233 | * Watchdog device is closed and stopped. | ||
| 234 | */ | ||
| 235 | static int sh_wdt_close(struct inode *inode, struct file *file) | 201 | static int sh_wdt_close(struct inode *inode, struct file *file) |
| 236 | { | 202 | { |
| 237 | if (shwdt_expect_close == 42) { | 203 | struct sh_wdt *wdt = file->private_data; |
| 238 | sh_wdt_stop(); | 204 | |
| 205 | if (wdt->expect_close == 42) { | ||
| 206 | sh_wdt_stop(wdt); | ||
| 239 | } else { | 207 | } else { |
| 240 | printk(KERN_CRIT PFX "Unexpected close, not " | 208 | dev_crit(wdt->dev, "Unexpected close, not " |
| 241 | "stopping watchdog!\n"); | 209 | "stopping watchdog!\n"); |
| 242 | sh_wdt_keepalive(); | 210 | sh_wdt_keepalive(wdt); |
| 243 | } | 211 | } |
| 244 | 212 | ||
| 245 | clear_bit(0, &shwdt_is_open); | 213 | clear_bit(0, &wdt->enabled); |
| 246 | shwdt_expect_close = 0; | 214 | wdt->expect_close = 0; |
| 247 | 215 | ||
| 248 | return 0; | 216 | return 0; |
| 249 | } | 217 | } |
| 250 | 218 | ||
| 251 | /** | ||
| 252 | * sh_wdt_write - Write to Device | ||
| 253 | * @file: file handle of device | ||
| 254 | * @buf: buffer to write | ||
| 255 | * @count: length of buffer | ||
| 256 | * @ppos: offset | ||
| 257 | * | ||
| 258 | * Pings the watchdog on write. | ||
| 259 | */ | ||
| 260 | static ssize_t sh_wdt_write(struct file *file, const char *buf, | 219 | static ssize_t sh_wdt_write(struct file *file, const char *buf, |
| 261 | size_t count, loff_t *ppos) | 220 | size_t count, loff_t *ppos) |
| 262 | { | 221 | { |
| 222 | struct sh_wdt *wdt = file->private_data; | ||
| 223 | |||
| 263 | if (count) { | 224 | if (count) { |
| 264 | if (!nowayout) { | 225 | if (!nowayout) { |
| 265 | size_t i; | 226 | size_t i; |
| 266 | 227 | ||
| 267 | shwdt_expect_close = 0; | 228 | wdt->expect_close = 0; |
| 268 | 229 | ||
| 269 | for (i = 0; i != count; i++) { | 230 | for (i = 0; i != count; i++) { |
| 270 | char c; | 231 | char c; |
| 271 | if (get_user(c, buf + i)) | 232 | if (get_user(c, buf + i)) |
| 272 | return -EFAULT; | 233 | return -EFAULT; |
| 273 | if (c == 'V') | 234 | if (c == 'V') |
| 274 | shwdt_expect_close = 42; | 235 | wdt->expect_close = 42; |
| 275 | } | 236 | } |
| 276 | } | 237 | } |
| 277 | sh_wdt_keepalive(); | 238 | sh_wdt_keepalive(wdt); |
| 278 | } | 239 | } |
| 279 | 240 | ||
| 280 | return count; | 241 | return count; |
| 281 | } | 242 | } |
| 282 | 243 | ||
| 283 | /** | ||
| 284 | * sh_wdt_mmap - map WDT/CPG registers into userspace | ||
| 285 | * @file: file structure for the device | ||
| 286 | * @vma: VMA to map the registers into | ||
| 287 | * | ||
| 288 | * A simple mmap() implementation for the corner cases where the counter | ||
| 289 | * needs to be mapped in userspace directly. Due to the relatively small | ||
| 290 | * size of the area, neighbouring registers not necessarily tied to the | ||
| 291 | * CPG will also be accessible through the register page, so this remains | ||
| 292 | * configurable for users that really know what they're doing. | ||
| 293 | * | ||
| 294 | * Additionaly, the register page maps in the CPG register base relative | ||
| 295 | * to the nearest page-aligned boundary, which requires that userspace do | ||
| 296 | * the appropriate CPU subtype math for calculating the page offset for | ||
| 297 | * the counter value. | ||
| 298 | */ | ||
| 299 | static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma) | ||
| 300 | { | ||
| 301 | int ret = -ENOSYS; | ||
| 302 | |||
| 303 | #ifdef CONFIG_SH_WDT_MMAP | ||
| 304 | unsigned long addr; | ||
| 305 | |||
| 306 | /* Only support the simple cases where we map in a register page. */ | ||
| 307 | if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) | ||
| 308 | return -EINVAL; | ||
| 309 | |||
| 310 | /* | ||
| 311 | * Pick WTCNT as the start, it's usually the first register after the | ||
| 312 | * FRQCR, and neither one are generally page-aligned out of the box. | ||
| 313 | */ | ||
| 314 | addr = WTCNT & ~(PAGE_SIZE - 1); | ||
| 315 | |||
| 316 | vma->vm_flags |= VM_IO; | ||
| 317 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
| 318 | |||
| 319 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, | ||
| 320 | PAGE_SIZE, vma->vm_page_prot)) { | ||
| 321 | printk(KERN_ERR PFX "%s: io_remap_pfn_range failed\n", | ||
| 322 | __func__); | ||
| 323 | return -EAGAIN; | ||
| 324 | } | ||
| 325 | |||
| 326 | ret = 0; | ||
| 327 | #endif | ||
| 328 | |||
| 329 | return ret; | ||
| 330 | } | ||
| 331 | |||
| 332 | /** | ||
| 333 | * sh_wdt_ioctl - Query Device | ||
| 334 | * @file: file handle of device | ||
| 335 | * @cmd: watchdog command | ||
| 336 | * @arg: argument | ||
| 337 | * | ||
| 338 | * Query basic information from the device or ping it, as outlined by the | ||
| 339 | * watchdog API. | ||
| 340 | */ | ||
| 341 | static long sh_wdt_ioctl(struct file *file, unsigned int cmd, | 244 | static long sh_wdt_ioctl(struct file *file, unsigned int cmd, |
| 342 | unsigned long arg) | 245 | unsigned long arg) |
| 343 | { | 246 | { |
| 247 | struct sh_wdt *wdt = file->private_data; | ||
| 344 | int new_heartbeat; | 248 | int new_heartbeat; |
| 345 | int options, retval = -EINVAL; | 249 | int options, retval = -EINVAL; |
| 346 | 250 | ||
| @@ -356,18 +260,18 @@ static long sh_wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 356 | return -EFAULT; | 260 | return -EFAULT; |
| 357 | 261 | ||
| 358 | if (options & WDIOS_DISABLECARD) { | 262 | if (options & WDIOS_DISABLECARD) { |
| 359 | sh_wdt_stop(); | 263 | sh_wdt_stop(wdt); |
| 360 | retval = 0; | 264 | retval = 0; |
| 361 | } | 265 | } |
| 362 | 266 | ||
| 363 | if (options & WDIOS_ENABLECARD) { | 267 | if (options & WDIOS_ENABLECARD) { |
| 364 | sh_wdt_start(); | 268 | sh_wdt_start(wdt); |
| 365 | retval = 0; | 269 | retval = 0; |
| 366 | } | 270 | } |
| 367 | 271 | ||
| 368 | return retval; | 272 | return retval; |
| 369 | case WDIOC_KEEPALIVE: | 273 | case WDIOC_KEEPALIVE: |
| 370 | sh_wdt_keepalive(); | 274 | sh_wdt_keepalive(wdt); |
| 371 | return 0; | 275 | return 0; |
| 372 | case WDIOC_SETTIMEOUT: | 276 | case WDIOC_SETTIMEOUT: |
| 373 | if (get_user(new_heartbeat, (int *)arg)) | 277 | if (get_user(new_heartbeat, (int *)arg)) |
| @@ -376,7 +280,7 @@ static long sh_wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 376 | if (sh_wdt_set_heartbeat(new_heartbeat)) | 280 | if (sh_wdt_set_heartbeat(new_heartbeat)) |
| 377 | return -EINVAL; | 281 | return -EINVAL; |
| 378 | 282 | ||
| 379 | sh_wdt_keepalive(); | 283 | sh_wdt_keepalive(wdt); |
| 380 | /* Fall */ | 284 | /* Fall */ |
| 381 | case WDIOC_GETTIMEOUT: | 285 | case WDIOC_GETTIMEOUT: |
| 382 | return put_user(heartbeat, (int *)arg); | 286 | return put_user(heartbeat, (int *)arg); |
| @@ -386,20 +290,13 @@ static long sh_wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 386 | return 0; | 290 | return 0; |
| 387 | } | 291 | } |
| 388 | 292 | ||
| 389 | /** | ||
| 390 | * sh_wdt_notify_sys - Notifier Handler | ||
| 391 | * @this: notifier block | ||
| 392 | * @code: notifier event | ||
| 393 | * @unused: unused | ||
| 394 | * | ||
| 395 | * Handles specific events, such as turning off the watchdog during a | ||
| 396 | * shutdown event. | ||
| 397 | */ | ||
| 398 | static int sh_wdt_notify_sys(struct notifier_block *this, | 293 | static int sh_wdt_notify_sys(struct notifier_block *this, |
| 399 | unsigned long code, void *unused) | 294 | unsigned long code, void *unused) |
| 400 | { | 295 | { |
| 296 | struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev); | ||
| 297 | |||
| 401 | if (code == SYS_DOWN || code == SYS_HALT) | 298 | if (code == SYS_DOWN || code == SYS_HALT) |
| 402 | sh_wdt_stop(); | 299 | sh_wdt_stop(wdt); |
| 403 | 300 | ||
| 404 | return NOTIFY_DONE; | 301 | return NOTIFY_DONE; |
| 405 | } | 302 | } |
| @@ -411,7 +308,6 @@ static const struct file_operations sh_wdt_fops = { | |||
| 411 | .unlocked_ioctl = sh_wdt_ioctl, | 308 | .unlocked_ioctl = sh_wdt_ioctl, |
| 412 | .open = sh_wdt_open, | 309 | .open = sh_wdt_open, |
| 413 | .release = sh_wdt_close, | 310 | .release = sh_wdt_close, |
| 414 | .mmap = sh_wdt_mmap, | ||
| 415 | }; | 311 | }; |
| 416 | 312 | ||
| 417 | static const struct watchdog_info sh_wdt_info = { | 313 | static const struct watchdog_info sh_wdt_info = { |
| @@ -431,66 +327,148 @@ static struct miscdevice sh_wdt_miscdev = { | |||
| 431 | .fops = &sh_wdt_fops, | 327 | .fops = &sh_wdt_fops, |
| 432 | }; | 328 | }; |
| 433 | 329 | ||
| 434 | /** | 330 | static int __devinit sh_wdt_probe(struct platform_device *pdev) |
| 435 | * sh_wdt_init - Initialize module | ||
| 436 | * Registers the device and notifier handler. Actual device | ||
| 437 | * initialization is handled by sh_wdt_open(). | ||
| 438 | */ | ||
| 439 | static int __init sh_wdt_init(void) | ||
| 440 | { | 331 | { |
| 332 | struct sh_wdt *wdt; | ||
| 333 | struct resource *res; | ||
| 441 | int rc; | 334 | int rc; |
| 442 | 335 | ||
| 443 | if (clock_division_ratio < 0x5 || clock_division_ratio > 0x7) { | 336 | /* |
| 444 | clock_division_ratio = WTCSR_CKS_4096; | 337 | * As this driver only covers the global watchdog case, reject |
| 445 | printk(KERN_INFO PFX | 338 | * any attempts to register per-CPU watchdogs. |
| 446 | "clock_division_ratio value must be 0x5<=x<=0x7, using %d\n", | 339 | */ |
| 447 | clock_division_ratio); | 340 | if (pdev->id != -1) |
| 341 | return -EINVAL; | ||
| 342 | |||
| 343 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 344 | if (unlikely(!res)) | ||
| 345 | return -EINVAL; | ||
| 346 | |||
| 347 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
| 348 | resource_size(res), DRV_NAME)) | ||
| 349 | return -EBUSY; | ||
| 350 | |||
| 351 | wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL); | ||
| 352 | if (unlikely(!wdt)) { | ||
| 353 | rc = -ENOMEM; | ||
| 354 | goto out_release; | ||
| 448 | } | 355 | } |
| 449 | 356 | ||
| 450 | rc = sh_wdt_set_heartbeat(heartbeat); | 357 | wdt->dev = &pdev->dev; |
| 451 | if (unlikely(rc)) { | 358 | |
| 452 | heartbeat = WATCHDOG_HEARTBEAT; | 359 | wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); |
| 453 | printk(KERN_INFO PFX | 360 | if (unlikely(!wdt->base)) { |
| 454 | "heartbeat value must be 1<=x<=3600, using %d\n", | 361 | rc = -ENXIO; |
| 455 | heartbeat); | 362 | goto out_err; |
| 456 | } | 363 | } |
| 457 | 364 | ||
| 458 | rc = register_reboot_notifier(&sh_wdt_notifier); | 365 | rc = register_reboot_notifier(&sh_wdt_notifier); |
| 459 | if (unlikely(rc)) { | 366 | if (unlikely(rc)) { |
| 460 | printk(KERN_ERR PFX | 367 | dev_err(&pdev->dev, |
| 461 | "Can't register reboot notifier (err=%d)\n", rc); | 368 | "Can't register reboot notifier (err=%d)\n", rc); |
| 462 | return rc; | 369 | goto out_unmap; |
| 463 | } | 370 | } |
| 464 | 371 | ||
| 372 | sh_wdt_miscdev.parent = wdt->dev; | ||
| 373 | |||
| 465 | rc = misc_register(&sh_wdt_miscdev); | 374 | rc = misc_register(&sh_wdt_miscdev); |
| 466 | if (unlikely(rc)) { | 375 | if (unlikely(rc)) { |
| 467 | printk(KERN_ERR PFX | 376 | dev_err(&pdev->dev, |
| 468 | "Can't register miscdev on minor=%d (err=%d)\n", | 377 | "Can't register miscdev on minor=%d (err=%d)\n", |
| 469 | sh_wdt_miscdev.minor, rc); | 378 | sh_wdt_miscdev.minor, rc); |
| 470 | unregister_reboot_notifier(&sh_wdt_notifier); | 379 | goto out_unreg; |
| 471 | return rc; | ||
| 472 | } | 380 | } |
| 473 | 381 | ||
| 474 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", | 382 | init_timer(&wdt->timer); |
| 475 | heartbeat, nowayout); | 383 | wdt->timer.function = sh_wdt_ping; |
| 384 | wdt->timer.data = (unsigned long)wdt; | ||
| 385 | wdt->timer.expires = next_ping_period(clock_division_ratio); | ||
| 386 | |||
| 387 | platform_set_drvdata(pdev, wdt); | ||
| 388 | sh_wdt_dev = pdev; | ||
| 389 | |||
| 390 | dev_info(&pdev->dev, "initialized.\n"); | ||
| 476 | 391 | ||
| 477 | return 0; | 392 | return 0; |
| 393 | |||
| 394 | out_unreg: | ||
| 395 | unregister_reboot_notifier(&sh_wdt_notifier); | ||
| 396 | out_unmap: | ||
| 397 | devm_iounmap(&pdev->dev, wdt->base); | ||
| 398 | out_err: | ||
| 399 | devm_kfree(&pdev->dev, wdt); | ||
| 400 | out_release: | ||
| 401 | devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); | ||
| 402 | |||
| 403 | return rc; | ||
| 478 | } | 404 | } |
| 479 | 405 | ||
| 480 | /** | 406 | static int __devexit sh_wdt_remove(struct platform_device *pdev) |
| 481 | * sh_wdt_exit - Deinitialize module | ||
| 482 | * Unregisters the device and notifier handler. Actual device | ||
| 483 | * deinitialization is handled by sh_wdt_close(). | ||
| 484 | */ | ||
| 485 | static void __exit sh_wdt_exit(void) | ||
| 486 | { | 407 | { |
| 408 | struct sh_wdt *wdt = platform_get_drvdata(pdev); | ||
| 409 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 410 | |||
| 411 | platform_set_drvdata(pdev, NULL); | ||
| 412 | |||
| 487 | misc_deregister(&sh_wdt_miscdev); | 413 | misc_deregister(&sh_wdt_miscdev); |
| 414 | |||
| 415 | sh_wdt_dev = NULL; | ||
| 416 | |||
| 488 | unregister_reboot_notifier(&sh_wdt_notifier); | 417 | unregister_reboot_notifier(&sh_wdt_notifier); |
| 418 | devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); | ||
| 419 | devm_iounmap(&pdev->dev, wdt->base); | ||
| 420 | devm_kfree(&pdev->dev, wdt); | ||
| 421 | |||
| 422 | return 0; | ||
| 489 | } | 423 | } |
| 490 | 424 | ||
| 425 | static struct platform_driver sh_wdt_driver = { | ||
| 426 | .driver = { | ||
| 427 | .name = DRV_NAME, | ||
| 428 | .owner = THIS_MODULE, | ||
| 429 | }, | ||
| 430 | |||
| 431 | .probe = sh_wdt_probe, | ||
| 432 | .remove = __devexit_p(sh_wdt_remove), | ||
| 433 | }; | ||
| 434 | |||
| 435 | static int __init sh_wdt_init(void) | ||
| 436 | { | ||
| 437 | int rc; | ||
| 438 | |||
| 439 | if (unlikely(clock_division_ratio < 0x5 || | ||
| 440 | clock_division_ratio > 0x7)) { | ||
| 441 | clock_division_ratio = WTCSR_CKS_4096; | ||
| 442 | |||
| 443 | pr_info("%s: divisor must be 0x5<=x<=0x7, using %d\n", | ||
| 444 | DRV_NAME, clock_division_ratio); | ||
| 445 | } | ||
| 446 | |||
| 447 | rc = sh_wdt_set_heartbeat(heartbeat); | ||
| 448 | if (unlikely(rc)) { | ||
| 449 | heartbeat = WATCHDOG_HEARTBEAT; | ||
| 450 | |||
| 451 | pr_info("%s: heartbeat value must be 1<=x<=3600, using %d\n", | ||
| 452 | DRV_NAME, heartbeat); | ||
| 453 | } | ||
| 454 | |||
| 455 | pr_info("%s: configured with heartbeat=%d sec (nowayout=%d)\n", | ||
| 456 | DRV_NAME, heartbeat, nowayout); | ||
| 457 | |||
| 458 | return platform_driver_register(&sh_wdt_driver); | ||
| 459 | } | ||
| 460 | |||
| 461 | static void __exit sh_wdt_exit(void) | ||
| 462 | { | ||
| 463 | platform_driver_unregister(&sh_wdt_driver); | ||
| 464 | } | ||
| 465 | module_init(sh_wdt_init); | ||
| 466 | module_exit(sh_wdt_exit); | ||
| 467 | |||
| 491 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | 468 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); |
| 492 | MODULE_DESCRIPTION("SuperH watchdog driver"); | 469 | MODULE_DESCRIPTION("SuperH watchdog driver"); |
| 493 | MODULE_LICENSE("GPL"); | 470 | MODULE_LICENSE("GPL"); |
| 471 | MODULE_ALIAS("platform:" DRV_NAME); | ||
| 494 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 472 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
| 495 | 473 | ||
| 496 | module_param(clock_division_ratio, int, 0); | 474 | module_param(clock_division_ratio, int, 0); |
| @@ -507,6 +485,3 @@ module_param(nowayout, int, 0); | |||
| 507 | MODULE_PARM_DESC(nowayout, | 485 | MODULE_PARM_DESC(nowayout, |
| 508 | "Watchdog cannot be stopped once started (default=" | 486 | "Watchdog cannot be stopped once started (default=" |
| 509 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 487 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
| 510 | |||
| 511 | module_init(sh_wdt_init); | ||
| 512 | module_exit(sh_wdt_exit); | ||
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 1630d9cae22a..a2afc9fbe186 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h | |||
| @@ -34,28 +34,32 @@ enum { | |||
| 34 | SCIx_NR_IRQS, | 34 | SCIx_NR_IRQS, |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | #define SCIx_IRQ_MUXED(irq) \ | ||
| 38 | { \ | ||
| 39 | [SCIx_ERI_IRQ] = (irq), \ | ||
| 40 | [SCIx_RXI_IRQ] = (irq), \ | ||
| 41 | [SCIx_TXI_IRQ] = (irq), \ | ||
| 42 | [SCIx_BRI_IRQ] = (irq), \ | ||
| 43 | } | ||
| 44 | |||
| 37 | struct device; | 45 | struct device; |
| 38 | 46 | ||
| 39 | /* | 47 | /* |
| 40 | * Platform device specific platform_data struct | 48 | * Platform device specific platform_data struct |
| 41 | */ | 49 | */ |
| 42 | struct plat_sci_port { | 50 | struct plat_sci_port { |
| 43 | void __iomem *membase; /* io cookie */ | ||
| 44 | unsigned long mapbase; /* resource base */ | 51 | unsigned long mapbase; /* resource base */ |
| 45 | unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ | 52 | unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ |
| 46 | unsigned int type; /* SCI / SCIF / IRDA */ | 53 | unsigned int type; /* SCI / SCIF / IRDA */ |
| 47 | upf_t flags; /* UPF_* flags */ | 54 | upf_t flags; /* UPF_* flags */ |
| 48 | char *clk; /* clock string */ | ||
| 49 | 55 | ||
| 50 | unsigned int scbrr_algo_id; /* SCBRR calculation algo */ | 56 | unsigned int scbrr_algo_id; /* SCBRR calculation algo */ |
| 51 | unsigned int scscr; /* SCSCR initialization */ | 57 | unsigned int scscr; /* SCSCR initialization */ |
| 52 | 58 | ||
| 53 | struct device *dma_dev; | 59 | struct device *dma_dev; |
| 54 | 60 | ||
| 55 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 61 | unsigned int dma_slave_tx; |
| 56 | unsigned int dma_slave_tx; | 62 | unsigned int dma_slave_rx; |
| 57 | unsigned int dma_slave_rx; | ||
| 58 | #endif | ||
| 59 | }; | 63 | }; |
| 60 | 64 | ||
| 61 | #endif /* __LINUX_SERIAL_SCI_H */ | 65 | #endif /* __LINUX_SERIAL_SCI_H */ |
diff --git a/kernel/gcov/Kconfig b/kernel/gcov/Kconfig index 70a298d6da71..b8cadf70b1fb 100644 --- a/kernel/gcov/Kconfig +++ b/kernel/gcov/Kconfig | |||
| @@ -34,7 +34,7 @@ config GCOV_KERNEL | |||
| 34 | config GCOV_PROFILE_ALL | 34 | config GCOV_PROFILE_ALL |
| 35 | bool "Profile entire Kernel" | 35 | bool "Profile entire Kernel" |
| 36 | depends on GCOV_KERNEL | 36 | depends on GCOV_KERNEL |
| 37 | depends on S390 || X86 || (PPC && EXPERIMENTAL) || MICROBLAZE | 37 | depends on SUPERH || S390 || X86 || (PPC && EXPERIMENTAL) || MICROBLAZE |
| 38 | default n | 38 | default n |
| 39 | ---help--- | 39 | ---help--- |
| 40 | This options activates profiling for the entire kernel. | 40 | This options activates profiling for the entire kernel. |
