提交 241eb956 编写于 作者: L Linus Torvalds

Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6

* 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (34 commits)
  sh: Convert to generic show_interrupts.
  sh: Wire up new fhandle and clock_adjtime syscalls.
  sh: modify platform_device for sh_eth driver
  sh: add GETHER's platform_device in board-sh7757lcr
  sh: update sh7757lcr_defconfig
  sh: add platform_device of tmio_mmc and sh_mmcif to sh7757lcr
  sh: dmaengine support for SH7757
  sh: add mmc clock in clock-sh7757
  sh: add spi_board_info in sh7757lcr
  sh: add platform_device for SPI
  sh: add USB_ARCH_HAS_EHCI and OHCI for SH7757
  sh: Rename cpuidle states to fit general conventions
  serial: sh-sci: fix deadlock when resuming from S3 sleep
  sh: Enable CONFIG_GCOV_PROFILE_ALL for sh
  sh: Fix up async PCIe probing on SMP.
  serial: sh-sci: Kill off the special earlyprintk device.
  serial: sh-sci: Use dev_name() for region reservations.
  serial: sh-sci: Fix up earlyprintk port mapping.
  serial: sh-sci: Limit early console to one device.
  serial: sh-sci: Fix up break timer scheduling race.
  ...
......@@ -25,6 +25,7 @@ config SUPERH
select GENERIC_ATOMIC64
# Support the deprecated APIs until MFD and GPIOLIB catch up.
select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB
select GENERIC_IRQ_SHOW
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
......@@ -434,6 +435,8 @@ config CPU_SUBTYPE_SH7757
select CPU_SH4A
select CPU_SHX2
select ARCH_WANT_OPTIONAL_GPIOLIB
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
help
Select SH7757 if you have a SH4A SH7757 CPU.
......
......@@ -66,6 +66,11 @@ static struct resource sh_eth_resources[] = {
.end = 0xFEE00F7C - 1,
.flags = IORESOURCE_MEM,
}, {
.start = 0xFEE01800, /* TSU */
.end = 0xFEE01FFF,
.flags = IORESOURCE_MEM,
}, {
.start = 57, /* irq number */
.flags = IORESOURCE_IRQ,
},
......@@ -74,6 +79,8 @@ static struct resource sh_eth_resources[] = {
static struct sh_eth_plat_data sh7763_eth_pdata = {
.phy = 0,
.edmac_endian = EDMAC_LITTLE_ENDIAN,
.register_type = SH_ETH_REG_GIGABIT,
.phy_interface = PHY_INTERFACE_MODE_MII,
};
static struct platform_device espt_eth_device = {
......
......@@ -15,6 +15,9 @@
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/io.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
#include <linux/mfd/sh_mobile_sdhi.h>
#include <cpu/sh7757.h>
#include <asm/sh_eth.h>
#include <asm/heartbeat.h>
......@@ -44,6 +47,17 @@ static struct platform_device heartbeat_device = {
};
/* Fast Ethernet */
#define GBECONT 0xffc10100
#define GBECONT_RMII1 BIT(17)
#define GBECONT_RMII0 BIT(16)
static void sh7757_eth_set_mdio_gate(unsigned long addr)
{
if ((addr & 0x00000fff) < 0x0800)
writel(readl(GBECONT) | GBECONT_RMII0, GBECONT);
else
writel(readl(GBECONT) | GBECONT_RMII1, GBECONT);
}
static struct resource sh_eth0_resources[] = {
{
.start = 0xfef00000,
......@@ -59,6 +73,8 @@ static struct resource sh_eth0_resources[] = {
static struct sh_eth_plat_data sh7757_eth0_pdata = {
.phy = 1,
.edmac_endian = EDMAC_LITTLE_ENDIAN,
.register_type = SH_ETH_REG_FAST_SH4,
.set_mdio_gate = sh7757_eth_set_mdio_gate,
};
static struct platform_device sh7757_eth0_device = {
......@@ -86,6 +102,8 @@ static struct resource sh_eth1_resources[] = {
static struct sh_eth_plat_data sh7757_eth1_pdata = {
.phy = 1,
.edmac_endian = EDMAC_LITTLE_ENDIAN,
.register_type = SH_ETH_REG_FAST_SH4,
.set_mdio_gate = sh7757_eth_set_mdio_gate,
};
static struct platform_device sh7757_eth1_device = {
......@@ -98,10 +116,173 @@ static struct platform_device sh7757_eth1_device = {
},
};
static void sh7757_eth_giga_set_mdio_gate(unsigned long addr)
{
if ((addr & 0x00000fff) < 0x0800) {
gpio_set_value(GPIO_PTT4, 1);
writel(readl(GBECONT) & ~GBECONT_RMII0, GBECONT);
} else {
gpio_set_value(GPIO_PTT4, 0);
writel(readl(GBECONT) & ~GBECONT_RMII1, GBECONT);
}
}
static struct resource sh_eth_giga0_resources[] = {
{
.start = 0xfee00000,
.end = 0xfee007ff,
.flags = IORESOURCE_MEM,
}, {
/* TSU */
.start = 0xfee01800,
.end = 0xfee01fff,
.flags = IORESOURCE_MEM,
}, {
.start = 315,
.end = 315,
.flags = IORESOURCE_IRQ,
},
};
static struct sh_eth_plat_data sh7757_eth_giga0_pdata = {
.phy = 18,
.edmac_endian = EDMAC_LITTLE_ENDIAN,
.register_type = SH_ETH_REG_GIGABIT,
.set_mdio_gate = sh7757_eth_giga_set_mdio_gate,
.phy_interface = PHY_INTERFACE_MODE_RGMII_ID,
};
static struct platform_device sh7757_eth_giga0_device = {
.name = "sh-eth",
.resource = sh_eth_giga0_resources,
.id = 2,
.num_resources = ARRAY_SIZE(sh_eth_giga0_resources),
.dev = {
.platform_data = &sh7757_eth_giga0_pdata,
},
};
static struct resource sh_eth_giga1_resources[] = {
{
.start = 0xfee00800,
.end = 0xfee00fff,
.flags = IORESOURCE_MEM,
}, {
.start = 316,
.end = 316,
.flags = IORESOURCE_IRQ,
},
};
static struct sh_eth_plat_data sh7757_eth_giga1_pdata = {
.phy = 19,
.edmac_endian = EDMAC_LITTLE_ENDIAN,
.register_type = SH_ETH_REG_GIGABIT,
.set_mdio_gate = sh7757_eth_giga_set_mdio_gate,
.phy_interface = PHY_INTERFACE_MODE_RGMII_ID,
};
static struct platform_device sh7757_eth_giga1_device = {
.name = "sh-eth",
.resource = sh_eth_giga1_resources,
.id = 3,
.num_resources = ARRAY_SIZE(sh_eth_giga1_resources),
.dev = {
.platform_data = &sh7757_eth_giga1_pdata,
},
};
/* SH_MMCIF */
static struct resource sh_mmcif_resources[] = {
[0] = {
.start = 0xffcb0000,
.end = 0xffcb00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 211,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = 212,
.flags = IORESOURCE_IRQ,
},
};
static struct sh_mmcif_dma sh7757lcr_mmcif_dma = {
.chan_priv_tx = SHDMA_SLAVE_MMCIF_TX,
.chan_priv_rx = SHDMA_SLAVE_MMCIF_RX,
};
static struct sh_mmcif_plat_data sh_mmcif_plat = {
.dma = &sh7757lcr_mmcif_dma,
.sup_pclk = 0x0f,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.ocr = MMC_VDD_32_33 | MMC_VDD_33_34,
};
static struct platform_device sh_mmcif_device = {
.name = "sh_mmcif",
.id = 0,
.dev = {
.platform_data = &sh_mmcif_plat,
},
.num_resources = ARRAY_SIZE(sh_mmcif_resources),
.resource = sh_mmcif_resources,
};
/* SDHI0 */
static struct sh_mobile_sdhi_info sdhi_info = {
.dma_slave_tx = SHDMA_SLAVE_SDHI_TX,
.dma_slave_rx = SHDMA_SLAVE_SDHI_RX,
.tmio_caps = MMC_CAP_SD_HIGHSPEED,
};
static struct resource sdhi_resources[] = {
[0] = {
.start = 0xffe50000,
.end = 0xffe501ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 20,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sdhi_device = {
.name = "sh_mobile_sdhi",
.num_resources = ARRAY_SIZE(sdhi_resources),
.resource = sdhi_resources,
.id = 0,
.dev = {
.platform_data = &sdhi_info,
},
};
static struct platform_device *sh7757lcr_devices[] __initdata = {
&heartbeat_device,
&sh7757_eth0_device,
&sh7757_eth1_device,
&sh7757_eth_giga0_device,
&sh7757_eth_giga1_device,
&sh_mmcif_device,
&sdhi_device,
};
static struct flash_platform_data spi_flash_data = {
.name = "m25p80",
.type = "m25px64",
};
static struct spi_board_info spi_board_info[] = {
{
.modalias = "m25p80",
.max_speed_hz = 25000000,
.bus_num = 0,
.chip_select = 1,
.platform_data = &spi_flash_data,
},
};
static int __init sh7757lcr_devices_setup(void)
......@@ -332,6 +513,10 @@ static int __init sh7757lcr_devices_setup(void)
gpio_request(GPIO_PTT5, NULL); /* eMMC_PRST# */
gpio_direction_output(GPIO_PTT5, 1);
/* register SPI device information */
spi_register_board_info(spi_board_info,
ARRAY_SIZE(spi_board_info));
/* General platform */
return platform_add_devices(sh7757lcr_devices,
ARRAY_SIZE(sh7757lcr_devices));
......
......@@ -142,6 +142,8 @@ static struct resource sh_eth_resources[] = {
static struct sh_eth_plat_data sh_eth_plat = {
.phy = 0x1f, /* SMSC LAN8700 */
.edmac_endian = EDMAC_LITTLE_ENDIAN,
.register_type = SH_ETH_REG_FAST_SH4,
.phy_interface = PHY_INTERFACE_MODE_MII,
.ether_link_active_low = 1
};
......
......@@ -74,6 +74,10 @@ static struct resource sh_eth_resources[] = {
.start = 0xFEE00800, /* use eth1 */
.end = 0xFEE00F7C - 1,
.flags = IORESOURCE_MEM,
}, {
.start = 0xFEE01800, /* TSU */
.end = 0xFEE01FFF,
.flags = IORESOURCE_MEM,
}, {
.start = 57, /* irq number */
.flags = IORESOURCE_IRQ,
......@@ -83,6 +87,8 @@ static struct resource sh_eth_resources[] = {
static struct sh_eth_plat_data sh7763_eth_pdata = {
.phy = 1,
.edmac_endian = EDMAC_LITTLE_ENDIAN,
.register_type = SH_ETH_REG_GIGABIT,
.phy_interface = PHY_INTERFACE_MODE_MII,
};
static struct platform_device sh7763rdp_eth_device = {
......
......@@ -11,6 +11,8 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz \
OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
GCOV_PROFILE := n
#
# IMAGE_OFFSET is the load offset of the compression loader
#
......
......@@ -38,7 +38,15 @@ CONFIG_IPV6=y
# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_M25P80=y
CONFIG_BLK_DEV_RAM=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
CONFIG_VITESSE_PHY=y
CONFIG_NET_ETHERNET=y
......@@ -53,8 +61,17 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
CONFIG_SERIAL_SH_SCI_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_SPI=y
CONFIG_SPI_SH=y
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_MFD_SH_MOBILE_SDHI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_MMC=y
CONFIG_MMC_TMIO=y
CONFIG_MMC_SH_MMCIF=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_ISO9660_FS=y
......
/*
* Low-Level PCI Express Support for the SH7786
*
* Copyright (C) 2009 - 2010 Paul Mundt
* Copyright (C) 2009 - 2011 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#define pr_fmt(fmt) "PCI: " fmt
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/async.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/clk.h>
......@@ -31,7 +34,7 @@ static unsigned int nr_ports;
static struct sh7786_pcie_hwops {
int (*core_init)(void);
int (*port_init_hw)(struct sh7786_pcie_port *port);
async_func_ptr *port_init_hw;
} *sh7786_pcie_hwops;
static struct resource sh7786_pci0_resources[] = {
......@@ -474,8 +477,9 @@ static int __init sh7786_pcie_core_init(void)
return test_mode_pin(MODE_PIN12) ? 3 : 2;
}
static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
static void __init sh7786_pcie_init_hw(void *data, async_cookie_t cookie)
{
struct sh7786_pcie_port *port = data;
int ret;
/*
......@@ -488,18 +492,30 @@ static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
* Setup clocks, needed both for PHY and PCIe registers.
*/
ret = pcie_clk_init(port);
if (unlikely(ret < 0))
return ret;
if (unlikely(ret < 0)) {
pr_err("clock initialization failed for port#%d\n",
port->index);
return;
}
ret = phy_init(port);
if (unlikely(ret < 0))
return ret;
if (unlikely(ret < 0)) {
pr_err("phy initialization failed for port#%d\n",
port->index);
return;
}
ret = pcie_init(port);
if (unlikely(ret < 0))
return ret;
if (unlikely(ret < 0)) {
pr_err("core initialization failed for port#%d\n",
port->index);
return;
}
return register_pci_controller(port->hose);
/* In the interest of preserving device ordering, synchronize */
async_synchronize_cookie(cookie);
register_pci_controller(port->hose);
}
static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
......@@ -510,7 +526,7 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
static int __init sh7786_pcie_init(void)
{
struct clk *platclk;
int ret = 0, i;
int i;
printk(KERN_NOTICE "PCI: Starting initialization.\n");
......@@ -552,14 +568,10 @@ static int __init sh7786_pcie_init(void)
port->hose = sh7786_pci_channels + i;
port->hose->io_map_base = port->hose->resources[0].start;
ret |= sh7786_pcie_hwops->port_init_hw(port);
async_schedule(sh7786_pcie_hwops->port_init_hw, port);
}
if (unlikely(ret)) {
clk_disable(platclk);
clk_put(platclk);
return ret;
}
async_synchronize_full();
return 0;
}
......
......@@ -369,8 +369,11 @@
#define __NR_recvmsg 356
#define __NR_recvmmsg 357
#define __NR_accept4 358
#define __NR_name_to_handle_at 359
#define __NR_open_by_handle_at 360
#define __NR_clock_adjtime 361
#define NR_syscalls 359
#define NR_syscalls 362
#ifdef __KERNEL__
......
......@@ -390,10 +390,13 @@
#define __NR_fanotify_init 367
#define __NR_fanotify_mark 368
#define __NR_prlimit64 369
#define __NR_name_to_handle_at 370
#define __NR_open_by_handle_at 371
#define __NR_clock_adjtime 372
#ifdef __KERNEL__
#define NR_syscalls 370
#define NR_syscalls 373
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
......
......@@ -40,6 +40,11 @@
#define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0
#define CHCR_TS_HIGH_SHIFT 0
#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
#define CHCR_TS_LOW_MASK 0x00000018
#define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0x00100000
#define CHCR_TS_HIGH_SHIFT (20 - 2) /* 2 bits for shifted low TS */
#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
#define CHCR_TS_LOW_MASK 0x00000018
#define CHCR_TS_LOW_SHIFT 3
......
......@@ -251,4 +251,36 @@ enum {
GPIO_FN_ON_DQ3, GPIO_FN_ON_DQ2, GPIO_FN_ON_DQ1, GPIO_FN_ON_DQ0,
};
enum {
SHDMA_SLAVE_SDHI_TX,
SHDMA_SLAVE_SDHI_RX,
SHDMA_SLAVE_MMCIF_TX,
SHDMA_SLAVE_MMCIF_RX,
SHDMA_SLAVE_SCIF2_TX,
SHDMA_SLAVE_SCIF2_RX,
SHDMA_SLAVE_SCIF3_TX,
SHDMA_SLAVE_SCIF3_RX,
SHDMA_SLAVE_SCIF4_TX,
SHDMA_SLAVE_SCIF4_RX,
SHDMA_SLAVE_RIIC0_TX,
SHDMA_SLAVE_RIIC0_RX,
SHDMA_SLAVE_RIIC1_TX,
SHDMA_SLAVE_RIIC1_RX,
SHDMA_SLAVE_RIIC2_TX,
SHDMA_SLAVE_RIIC2_RX,
SHDMA_SLAVE_RIIC3_TX,
SHDMA_SLAVE_RIIC3_RX,
SHDMA_SLAVE_RIIC4_TX,
SHDMA_SLAVE_RIIC4_RX,
SHDMA_SLAVE_RIIC5_TX,
SHDMA_SLAVE_RIIC5_RX,
SHDMA_SLAVE_RIIC6_TX,
SHDMA_SLAVE_RIIC6_RX,
SHDMA_SLAVE_RIIC7_TX,
SHDMA_SLAVE_RIIC7_RX,
SHDMA_SLAVE_RIIC8_TX,
SHDMA_SLAVE_RIIC8_RX,
SHDMA_SLAVE_RIIC9_TX,
SHDMA_SLAVE_RIIC9_RX,
};
#endif /* __ASM_SH7757_H__ */
......@@ -77,9 +77,10 @@ struct clk div4_clks[DIV4_NR] = {
#define MSTPCR0 0xffc80030
#define MSTPCR1 0xffc80034
#define MSTPCR2 0xffc10028
enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112,
MSTP111, MSTP110, MSTP103, MSTP102,
MSTP111, MSTP110, MSTP103, MSTP102, MSTP220,
MSTP_NR };
static struct clk mstp_clks[MSTP_NR] = {
......@@ -95,6 +96,9 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0),
[MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0),
[MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0),
/* MSTPCR2 */
[MSTP220] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 20, 0),
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
......@@ -140,6 +144,7 @@ static struct clk_lookup lookups[] = {
.clk = &mstp_clks[MSTP110],
},
CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]),
CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]),
};
int __init arch_clk_init(void)
......
/*
* SH7757 Setup
*
* Copyright (C) 2009 Renesas Solutions Corp.
* Copyright (C) 2009, 2011 Renesas Solutions Corp.
*
* based on setup-sh7785.c : Copyright (C) 2007 Paul Mundt
*
......@@ -16,6 +16,10 @@
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/sh_timer.h>
#include <linux/sh_dma.h>
#include <cpu/dma-register.h>
#include <cpu/sh7757.h>
static struct plat_sci_port scif2_platform_data = {
.mapbase = 0xfe4b0000, /* SCIF2 */
......@@ -124,12 +128,548 @@ static struct platform_device tmu1_device = {
.num_resources = ARRAY_SIZE(tmu1_resources),
};
static struct resource spi0_resources[] = {
[0] = {
.start = 0xfe002000,
.end = 0xfe0020ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 86,
.flags = IORESOURCE_IRQ,
},
};
/* DMA */
static const struct sh_dmae_slave_config sh7757_dmae0_slaves[] = {
{
.slave_id = SHDMA_SLAVE_SDHI_TX,
.addr = 0x1fe50030,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xc5,
},
{
.slave_id = SHDMA_SLAVE_SDHI_RX,
.addr = 0x1fe50030,
.chcr = DM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xc6,
},
{
.slave_id = SHDMA_SLAVE_MMCIF_TX,
.addr = 0x1fcb0034,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_32BIT),
.mid_rid = 0xd3,
},
{
.slave_id = SHDMA_SLAVE_MMCIF_RX,
.addr = 0x1fcb0034,
.chcr = DM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_32BIT),
.mid_rid = 0xd7,
},
};
static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = {
{
.slave_id = SHDMA_SLAVE_SCIF2_TX,
.addr = 0x1f4b000c,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x21,
},
{
.slave_id = SHDMA_SLAVE_SCIF2_RX,
.addr = 0x1f4b0014,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x22,
},
{
.slave_id = SHDMA_SLAVE_SCIF3_TX,
.addr = 0x1f4c000c,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x29,
},
{
.slave_id = SHDMA_SLAVE_SCIF3_RX,
.addr = 0x1f4c0014,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x2a,
},
{
.slave_id = SHDMA_SLAVE_SCIF4_TX,
.addr = 0x1f4d000c,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x41,
},
{
.slave_id = SHDMA_SLAVE_SCIF4_RX,
.addr = 0x1f4d0014,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x42,
},
};
static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = {
{
.slave_id = SHDMA_SLAVE_RIIC0_TX,
.addr = 0x1e500012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x21,
},
{
.slave_id = SHDMA_SLAVE_RIIC0_RX,
.addr = 0x1e500013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x22,
},
{
.slave_id = SHDMA_SLAVE_RIIC1_TX,
.addr = 0x1e510012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x29,
},
{
.slave_id = SHDMA_SLAVE_RIIC1_RX,
.addr = 0x1e510013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x2a,
},
{
.slave_id = SHDMA_SLAVE_RIIC2_TX,
.addr = 0x1e520012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0xa1,
},
{
.slave_id = SHDMA_SLAVE_RIIC2_RX,
.addr = 0x1e520013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0xa2,
},
{
.slave_id = SHDMA_SLAVE_RIIC3_TX,
.addr = 0x1e530012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0xab,
},
{
.slave_id = SHDMA_SLAVE_RIIC3_RX,
.addr = 0x1e530013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0xaf,
},
{
.slave_id = SHDMA_SLAVE_RIIC4_TX,
.addr = 0x1e540012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0xc1,
},
{
.slave_id = SHDMA_SLAVE_RIIC4_RX,
.addr = 0x1e540013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0xc2,
},
};
static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = {
{
.slave_id = SHDMA_SLAVE_RIIC5_TX,
.addr = 0x1e550012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x21,
},
{
.slave_id = SHDMA_SLAVE_RIIC5_RX,
.addr = 0x1e550013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x22,
},
{
.slave_id = SHDMA_SLAVE_RIIC6_TX,
.addr = 0x1e560012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x29,
},
{
.slave_id = SHDMA_SLAVE_RIIC6_RX,
.addr = 0x1e560013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x2a,
},
{
.slave_id = SHDMA_SLAVE_RIIC7_TX,
.addr = 0x1e570012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x41,
},
{
.slave_id = SHDMA_SLAVE_RIIC7_RX,
.addr = 0x1e570013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x42,
},
{
.slave_id = SHDMA_SLAVE_RIIC8_TX,
.addr = 0x1e580012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x45,
},
{
.slave_id = SHDMA_SLAVE_RIIC8_RX,
.addr = 0x1e580013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x46,
},
{
.slave_id = SHDMA_SLAVE_RIIC9_TX,
.addr = 0x1e590012,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x51,
},
{
.slave_id = SHDMA_SLAVE_RIIC9_RX,
.addr = 0x1e590013,
.chcr = SM_INC | 0x800 | 0x40000000 |
TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x52,
},
};
static const struct sh_dmae_channel sh7757_dmae_channels[] = {
{
.offset = 0,
.dmars = 0,
.dmars_bit = 0,
}, {
.offset = 0x10,
.dmars = 0,
.dmars_bit = 8,
}, {
.offset = 0x20,
.dmars = 4,
.dmars_bit = 0,
}, {
.offset = 0x30,
.dmars = 4,
.dmars_bit = 8,
}, {
.offset = 0x50,
.dmars = 8,
.dmars_bit = 0,
}, {
.offset = 0x60,
.dmars = 8,
.dmars_bit = 8,
}
};
static const unsigned int ts_shift[] = TS_SHIFT;
static struct sh_dmae_pdata dma0_platform_data = {
.slave = sh7757_dmae0_slaves,
.slave_num = ARRAY_SIZE(sh7757_dmae0_slaves),
.channel = sh7757_dmae_channels,
.channel_num = ARRAY_SIZE(sh7757_dmae_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
static struct sh_dmae_pdata dma1_platform_data = {
.slave = sh7757_dmae1_slaves,
.slave_num = ARRAY_SIZE(sh7757_dmae1_slaves),
.channel = sh7757_dmae_channels,
.channel_num = ARRAY_SIZE(sh7757_dmae_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
static struct sh_dmae_pdata dma2_platform_data = {
.slave = sh7757_dmae2_slaves,
.slave_num = ARRAY_SIZE(sh7757_dmae2_slaves),
.channel = sh7757_dmae_channels,
.channel_num = ARRAY_SIZE(sh7757_dmae_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
static struct sh_dmae_pdata dma3_platform_data = {
.slave = sh7757_dmae3_slaves,
.slave_num = ARRAY_SIZE(sh7757_dmae3_slaves),
.channel = sh7757_dmae_channels,
.channel_num = ARRAY_SIZE(sh7757_dmae_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
/* channel 0 to 5 */
static struct resource sh7757_dmae0_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xff608020,
.end = 0xff60808f,
.flags = IORESOURCE_MEM,
},
[1] = {
/* DMARSx */
.start = 0xff609000,
.end = 0xff60900b,
.flags = IORESOURCE_MEM,
},
{
.start = 34,
.end = 34,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
};
/* channel 6 to 11 */
static struct resource sh7757_dmae1_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xff618020,
.end = 0xff61808f,
.flags = IORESOURCE_MEM,
},
[1] = {
/* DMARSx */
.start = 0xff619000,
.end = 0xff61900b,
.flags = IORESOURCE_MEM,
},
{
/* DMA error */
.start = 34,
.end = 34,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
{
/* IRQ for channels 4 */
.start = 46,
.end = 46,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
{
/* IRQ for channels 5 */
.start = 46,
.end = 46,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
{
/* IRQ for channels 6 */
.start = 88,
.end = 88,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
{
/* IRQ for channels 7 */
.start = 88,
.end = 88,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
{
/* IRQ for channels 8 */
.start = 88,
.end = 88,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
{
/* IRQ for channels 9 */
.start = 88,
.end = 88,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
{
/* IRQ for channels 10 */
.start = 88,
.end = 88,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
{
/* IRQ for channels 11 */
.start = 88,
.end = 88,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
};
/* channel 12 to 17 */
static struct resource sh7757_dmae2_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xff708020,
.end = 0xff70808f,
.flags = IORESOURCE_MEM,
},
[1] = {
/* DMARSx */
.start = 0xff709000,
.end = 0xff70900b,
.flags = IORESOURCE_MEM,
},
{
/* DMA error */
.start = 323,
.end = 323,
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 12 to 16 */
.start = 272,
.end = 276,
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channel 17 */
.start = 279,
.end = 279,
.flags = IORESOURCE_IRQ,
},
};
/* channel 18 to 23 */
static struct resource sh7757_dmae3_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xff718020,
.end = 0xff71808f,
.flags = IORESOURCE_MEM,
},
[1] = {
/* DMARSx */
.start = 0xff719000,
.end = 0xff71900b,
.flags = IORESOURCE_MEM,
},
{
/* DMA error */
.start = 324,
.end = 324,
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 18 to 22 */
.start = 280,
.end = 284,
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channel 23 */
.start = 288,
.end = 288,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dma0_device = {
.name = "sh-dma-engine",
.id = 0,
.resource = sh7757_dmae0_resources,
.num_resources = ARRAY_SIZE(sh7757_dmae0_resources),
.dev = {
.platform_data = &dma0_platform_data,
},
};
static struct platform_device dma1_device = {
.name = "sh-dma-engine",
.id = 1,
.resource = sh7757_dmae1_resources,
.num_resources = ARRAY_SIZE(sh7757_dmae1_resources),
.dev = {
.platform_data = &dma1_platform_data,
},
};
static struct platform_device dma2_device = {
.name = "sh-dma-engine",
.id = 2,
.resource = sh7757_dmae2_resources,
.num_resources = ARRAY_SIZE(sh7757_dmae2_resources),
.dev = {
.platform_data = &dma2_platform_data,
},
};
static struct platform_device dma3_device = {
.name = "sh-dma-engine",
.id = 3,
.resource = sh7757_dmae3_resources,
.num_resources = ARRAY_SIZE(sh7757_dmae3_resources),
.dev = {
.platform_data = &dma3_platform_data,
},
};
static struct platform_device spi0_device = {
.name = "sh_spi",
.id = 0,
.dev = {
.dma_mask = NULL,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(spi0_resources),
.resource = spi0_resources,
};
static struct platform_device *sh7757_devices[] __initdata = {
&scif2_device,
&scif3_device,
&scif4_device,
&tmu0_device,
&tmu1_device,
&dma0_device,
&dma1_device,
&dma2_device,
&dma3_device,
&spi0_device,
};
static int __init sh7757_devices_setup(void)
......
......@@ -75,7 +75,7 @@ void sh_mobile_setup_cpuidle(void)
i = CPUIDLE_DRIVER_STATE_START;
state = &dev->states[i++];
snprintf(state->name, CPUIDLE_NAME_LEN, "C0");
snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN);
state->exit_latency = 1;
state->target_residency = 1 * 2;
......@@ -88,7 +88,7 @@ void sh_mobile_setup_cpuidle(void)
if (sh_mobile_sleep_supported & SUSP_SH_SF) {
state = &dev->states[i++];
snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
strncpy(state->desc, "SuperH Sleep Mode [SF]",
CPUIDLE_DESC_LEN);
state->exit_latency = 100;
......@@ -101,7 +101,7 @@ void sh_mobile_setup_cpuidle(void)
if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
state = &dev->states[i++];
snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
snprintf(state->name, CPUIDLE_NAME_LEN, "C3");
strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
CPUIDLE_DESC_LEN);
state->exit_latency = 2300;
......
......@@ -34,9 +34,9 @@ void ack_bad_irq(unsigned int irq)
#if defined(CONFIG_PROC_FS)
/*
* /proc/interrupts printing:
* /proc/interrupts printing for arch specific interrupts
*/
static int show_other_interrupts(struct seq_file *p, int prec)
int arch_show_interrupts(struct seq_file *p, int prec)
{
int j;
......@@ -49,63 +49,6 @@ static int show_other_interrupts(struct seq_file *p, int prec)
return 0;
}
int show_interrupts(struct seq_file *p, void *v)
{
unsigned long flags, any_count = 0;
int i = *(loff_t *)v, j, prec;
struct irqaction *action;
struct irq_desc *desc;
struct irq_data *data;
struct irq_chip *chip;
if (i > nr_irqs)
return 0;
for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)
j *= 10;
if (i == nr_irqs)
return show_other_interrupts(p, prec);
if (i == 0) {
seq_printf(p, "%*s", prec + 8, "");
for_each_online_cpu(j)
seq_printf(p, "CPU%-8d", j);
seq_putc(p, '\n');
}
desc = irq_to_desc(i);
if (!desc)
return 0;
data = irq_get_irq_data(i);
chip = irq_data_get_irq_chip(data);
raw_spin_lock_irqsave(&desc->lock, flags);
for_each_online_cpu(j)
any_count |= kstat_irqs_cpu(i, j);
action = desc->action;
if (!action && !any_count)
goto out;
seq_printf(p, "%*d: ", prec, i);
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
seq_printf(p, " %14s", chip->name);
seq_printf(p, "-%-8s", desc->name);
if (action) {
seq_printf(p, " %s", action->name);
while ((action = action->next) != NULL)
seq_printf(p, ", %s", action->name);
}
seq_putc(p, '\n');
out:
raw_spin_unlock_irqrestore(&desc->lock, flags);
return 0;
}
#endif
#ifdef CONFIG_IRQSTACKS
......
......@@ -376,3 +376,6 @@ ENTRY(sys_call_table)
.long sys_recvmsg
.long sys_recvmmsg
.long sys_accept4
.long sys_name_to_handle_at
.long sys_open_by_handle_at /* 360 */
.long sys_clock_adjtime
......@@ -396,3 +396,6 @@ sys_call_table:
.long sys_fanotify_init
.long sys_fanotify_mark
.long sys_prlimit64
.long sys_name_to_handle_at /* 370 */
.long sys_open_by_handle_at
.long sys_clock_adjtime
......@@ -42,6 +42,8 @@ obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o
obj-$(CONFIG_UNCACHED_MAPPING) += uncached.o
obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o
GCOV_PROFILE_pmb.o := n
# Special flags for fault_64.o. This puts restrictions on the number of
# caller-save registers that the compiler can target when building this file.
# This is required because the code is called from a context in entry.S where
......
此差异已折叠。
......@@ -54,9 +54,6 @@
# define PBCR 0xa4050102
#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
# define SCSPTR0 0xffe00010 /* 16 bit SCIF */
# define SCSPTR1 0xffe10010 /* 16 bit SCIF */
# define SCSPTR2 0xffe20010 /* 16 bit SCIF */
# define SCSPTR3 0xffe30010 /* 16 bit SCIF */
#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
# define PADR 0xA4050120
# define PSDR 0xA405013e
......@@ -69,77 +66,42 @@
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
# define SCSPTR0 0xa4050160
# define SCSPTR1 0xa405013e
# define SCSPTR2 0xa4050160
# define SCSPTR3 0xa405013e
# define SCSPTR4 0xa4050128
# define SCSPTR5 0xa4050128
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
# define SCSPTR2 0xffe80020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
# define SCIF_PTR2_OFFS 0x0000020
# define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */
#elif defined(CONFIG_H83007) || defined(CONFIG_H83068)
# define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port)
#elif defined(CONFIG_H8S2678)
# define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port)
#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
# define SCSPTR0 0xfe4b0020
# define SCSPTR1 0xfe4b0020
# define SCSPTR2 0xfe4b0020
# define SCIF_ORER 0x0001
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# define SCSPTR1 0xffe08024 /* 16 bit SCIF */
# define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
# define SCSPTR0 0xff923020 /* 16 bit SCIF */
# define SCSPTR1 0xff924020 /* 16 bit SCIF */
# define SCSPTR2 0xff925020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# define SCSPTR1 0xffe10024 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
defined(CONFIG_CPU_SUBTYPE_SH7786)
# define SCSPTR0 0xffea0024 /* 16 bit SCIF */
# define SCSPTR1 0xffeb0024 /* 16 bit SCIF */
# define SCSPTR2 0xffec0024 /* 16 bit SCIF */
# define SCSPTR3 0xffed0024 /* 16 bit SCIF */
# define SCSPTR4 0xffee0024 /* 16 bit SCIF */
# define SCSPTR5 0xffef0024 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
defined(CONFIG_CPU_SUBTYPE_SH7203) || \
defined(CONFIG_CPU_SUBTYPE_SH7206) || \
defined(CONFIG_CPU_SUBTYPE_SH7263)
# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
# define SCSPTR1 0xfffe8820 /* 16 bit SCIF */
# define SCSPTR2 0xfffe9020 /* 16 bit SCIF */
# define SCSPTR3 0xfffe9820 /* 16 bit SCIF */
# if defined(CONFIG_CPU_SUBTYPE_SH7201)
# define SCSPTR4 0xfffeA020 /* 16 bit SCIF */
# define SCSPTR5 0xfffeA820 /* 16 bit SCIF */
# define SCSPTR6 0xfffeB020 /* 16 bit SCIF */
# define SCSPTR7 0xfffeB820 /* 16 bit SCIF */
# endif
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
# define SCSPTR0 0xf8400020 /* 16 bit SCIF */
# define SCSPTR1 0xf8410020 /* 16 bit SCIF */
# define SCSPTR2 0xf8420020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
# define SCSPTR0 0xffc30020 /* 16 bit SCIF */
# define SCSPTR1 0xffc40020 /* 16 bit SCIF */
# define SCSPTR2 0xffc50020 /* 16 bit SCIF */
# define SCSPTR3 0xffc60020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
#else
# error CPU subtype not defined
......@@ -411,7 +373,6 @@ SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
SCIF_FNS(SCFDR, 0, 0, 0x1C, 16)
SCIF_FNS(SCSPTR2, 0, 0, 0x20, 16)
SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
......
......@@ -1083,14 +1083,6 @@ config SH_WDT
To compile this driver as a module, choose M here: the
module will be called shwdt.
config SH_WDT_MMAP
bool "Allow mmap of SH WDT"
default n
depends on SH_WDT
help
If you say Y here, user applications will be able to mmap the
WDT/CPG registers.
# SPARC Architecture
# SPARC64 Architecture
......
/*
* drivers/char/watchdog/shwdt.c
* drivers/watchdog/shwdt.c
*
* Watchdog driver for integrated watchdog in the SuperH processors.
*
* Copyright (C) 2001, 2002, 2003 Paul Mundt <lethal@linux-sh.org>
* Copyright (C) 2001 - 2010 Paul Mundt <lethal@linux-sh.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
......@@ -19,6 +19,7 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
......@@ -28,11 +29,12 @@
#include <linux/ioport.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <asm/watchdog.h>
#define PFX "shwdt: "
#define DRV_NAME "sh-wdt"
/*
* Default clock division ratio is 5.25 msecs. For an additional table of
......@@ -62,37 +64,36 @@
* misses its deadline, the kernel timer will allow the WDT to overflow.
*/
static int clock_division_ratio = WTCSR_CKS_4096;
#define next_ping_period(cks) msecs_to_jiffies(cks - 4)
static void sh_wdt_ping(unsigned long data);
static unsigned long shwdt_is_open;
static const struct watchdog_info sh_wdt_info;
static char shwdt_expect_close;
static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0);
static unsigned long next_heartbeat;
static struct platform_device *sh_wdt_dev;
static DEFINE_SPINLOCK(shwdt_lock);
#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */
static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
static int nowayout = WATCHDOG_NOWAYOUT;
static unsigned long next_heartbeat;
/**
* sh_wdt_start - Start the Watchdog
*
* Starts the watchdog.
*/
static void sh_wdt_start(void)
struct sh_wdt {
void __iomem *base;
struct device *dev;
struct timer_list timer;
unsigned long enabled;
char expect_close;
};
static void sh_wdt_start(struct sh_wdt *wdt)
{
__u8 csr;
unsigned long flags;
u8 csr;
spin_lock_irqsave(&shwdt_lock, flags);
next_heartbeat = jiffies + (heartbeat * HZ);
mod_timer(&timer, next_ping_period(clock_division_ratio));
mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
csr = sh_wdt_read_csr();
csr |= WTCSR_WT | clock_division_ratio;
......@@ -114,15 +115,6 @@ static void sh_wdt_start(void)
sh_wdt_write_csr(csr);
#ifdef CONFIG_CPU_SH2
/*
* Whoever came up with the RSTCSR semantics must've been smoking
* some of the good stuff, since in addition to the WTCSR/WTCNT write
* brain-damage, it's managed to fuck things up one step further..
*
* If we need to clear the WOVF bit, the upper byte has to be 0xa5..
* but if we want to touch RSTE or RSTS, the upper byte has to be
* 0x5a..
*/
csr = sh_wdt_read_rstcsr();
csr &= ~RSTCSR_RSTS;
sh_wdt_write_rstcsr(csr);
......@@ -130,30 +122,23 @@ static void sh_wdt_start(void)
spin_unlock_irqrestore(&shwdt_lock, flags);
}
/**
* sh_wdt_stop - Stop the Watchdog
* Stops the watchdog.
*/
static void sh_wdt_stop(void)
static void sh_wdt_stop(struct sh_wdt *wdt)
{
__u8 csr;
unsigned long flags;
u8 csr;
spin_lock_irqsave(&shwdt_lock, flags);
del_timer(&timer);
del_timer(&wdt->timer);
csr = sh_wdt_read_csr();
csr &= ~WTCSR_TME;
sh_wdt_write_csr(csr);
spin_unlock_irqrestore(&shwdt_lock, flags);
}
/**
* sh_wdt_keepalive - Keep the Userspace Watchdog Alive
* The Userspace watchdog got a KeepAlive: schedule the next heartbeat.
*/
static inline void sh_wdt_keepalive(void)
static inline void sh_wdt_keepalive(struct sh_wdt *wdt)
{
unsigned long flags;
......@@ -162,10 +147,6 @@ static inline void sh_wdt_keepalive(void)
spin_unlock_irqrestore(&shwdt_lock, flags);
}
/**
* sh_wdt_set_heartbeat - Set the Userspace Watchdog heartbeat
* Set the Userspace Watchdog heartbeat
*/
static int sh_wdt_set_heartbeat(int t)
{
unsigned long flags;
......@@ -179,19 +160,14 @@ static int sh_wdt_set_heartbeat(int t)
return 0;
}
/**
* sh_wdt_ping - Ping the Watchdog
* @data: Unused
*
* Clears overflow bit, resets timer counter.
*/
static void sh_wdt_ping(unsigned long data)
{
struct sh_wdt *wdt = (struct sh_wdt *)data;
unsigned long flags;
spin_lock_irqsave(&shwdt_lock, flags);
if (time_before(jiffies, next_heartbeat)) {
__u8 csr;
u8 csr;
csr = sh_wdt_read_csr();
csr &= ~WTCSR_IOVF;
......@@ -199,148 +175,76 @@ static void sh_wdt_ping(unsigned long data)
sh_wdt_write_cnt(0);
mod_timer(&timer, next_ping_period(clock_division_ratio));
mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
} else
printk(KERN_WARNING PFX "Heartbeat lost! Will not ping "
"the watchdog\n");
dev_warn(wdt->dev, "Heartbeat lost! Will not ping "
"the watchdog\n");
spin_unlock_irqrestore(&shwdt_lock, flags);
}
/**
* sh_wdt_open - Open the Device
* @inode: inode of device
* @file: file handle of device
*
* Watchdog device is opened and started.
*/
static int sh_wdt_open(struct inode *inode, struct file *file)
{
if (test_and_set_bit(0, &shwdt_is_open))
struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev);
if (test_and_set_bit(0, &wdt->enabled))
return -EBUSY;
if (nowayout)
__module_get(THIS_MODULE);
sh_wdt_start();
file->private_data = wdt;
sh_wdt_start(wdt);
return nonseekable_open(inode, file);
}
/**
* sh_wdt_close - Close the Device
* @inode: inode of device
* @file: file handle of device
*
* Watchdog device is closed and stopped.
*/
static int sh_wdt_close(struct inode *inode, struct file *file)
{
if (shwdt_expect_close == 42) {
sh_wdt_stop();
struct sh_wdt *wdt = file->private_data;
if (wdt->expect_close == 42) {
sh_wdt_stop(wdt);
} else {
printk(KERN_CRIT PFX "Unexpected close, not "
"stopping watchdog!\n");
sh_wdt_keepalive();
dev_crit(wdt->dev, "Unexpected close, not "
"stopping watchdog!\n");
sh_wdt_keepalive(wdt);
}
clear_bit(0, &shwdt_is_open);
shwdt_expect_close = 0;
clear_bit(0, &wdt->enabled);
wdt->expect_close = 0;
return 0;
}
/**
* sh_wdt_write - Write to Device
* @file: file handle of device
* @buf: buffer to write
* @count: length of buffer
* @ppos: offset
*
* Pings the watchdog on write.
*/
static ssize_t sh_wdt_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
struct sh_wdt *wdt = file->private_data;
if (count) {
if (!nowayout) {
size_t i;
shwdt_expect_close = 0;
wdt->expect_close = 0;
for (i = 0; i != count; i++) {
char c;
if (get_user(c, buf + i))
return -EFAULT;
if (c == 'V')
shwdt_expect_close = 42;
wdt->expect_close = 42;
}
}
sh_wdt_keepalive();
sh_wdt_keepalive(wdt);
}
return count;
}
/**
* sh_wdt_mmap - map WDT/CPG registers into userspace
* @file: file structure for the device
* @vma: VMA to map the registers into
*
* A simple mmap() implementation for the corner cases where the counter
* needs to be mapped in userspace directly. Due to the relatively small
* size of the area, neighbouring registers not necessarily tied to the
* CPG will also be accessible through the register page, so this remains
* configurable for users that really know what they're doing.
*
* Additionaly, the register page maps in the CPG register base relative
* to the nearest page-aligned boundary, which requires that userspace do
* the appropriate CPU subtype math for calculating the page offset for
* the counter value.
*/
static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma)
{
int ret = -ENOSYS;
#ifdef CONFIG_SH_WDT_MMAP
unsigned long addr;
/* Only support the simple cases where we map in a register page. */
if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff)
return -EINVAL;
/*
* Pick WTCNT as the start, it's usually the first register after the
* FRQCR, and neither one are generally page-aligned out of the box.
*/
addr = WTCNT & ~(PAGE_SIZE - 1);
vma->vm_flags |= VM_IO;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
PAGE_SIZE, vma->vm_page_prot)) {
printk(KERN_ERR PFX "%s: io_remap_pfn_range failed\n",
__func__);
return -EAGAIN;
}
ret = 0;
#endif
return ret;
}
/**
* sh_wdt_ioctl - Query Device
* @file: file handle of device
* @cmd: watchdog command
* @arg: argument
*
* Query basic information from the device or ping it, as outlined by the
* watchdog API.
*/
static long sh_wdt_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct sh_wdt *wdt = file->private_data;
int new_heartbeat;
int options, retval = -EINVAL;
......@@ -356,18 +260,18 @@ static long sh_wdt_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
sh_wdt_stop();
sh_wdt_stop(wdt);
retval = 0;
}
if (options & WDIOS_ENABLECARD) {
sh_wdt_start();
sh_wdt_start(wdt);
retval = 0;
}
return retval;
case WDIOC_KEEPALIVE:
sh_wdt_keepalive();
sh_wdt_keepalive(wdt);
return 0;
case WDIOC_SETTIMEOUT:
if (get_user(new_heartbeat, (int *)arg))
......@@ -376,7 +280,7 @@ static long sh_wdt_ioctl(struct file *file, unsigned int cmd,
if (sh_wdt_set_heartbeat(new_heartbeat))
return -EINVAL;
sh_wdt_keepalive();
sh_wdt_keepalive(wdt);
/* Fall */
case WDIOC_GETTIMEOUT:
return put_user(heartbeat, (int *)arg);
......@@ -386,20 +290,13 @@ static long sh_wdt_ioctl(struct file *file, unsigned int cmd,
return 0;
}
/**
* sh_wdt_notify_sys - Notifier Handler
* @this: notifier block
* @code: notifier event
* @unused: unused
*
* Handles specific events, such as turning off the watchdog during a
* shutdown event.
*/
static int sh_wdt_notify_sys(struct notifier_block *this,
unsigned long code, void *unused)
{
struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev);
if (code == SYS_DOWN || code == SYS_HALT)
sh_wdt_stop();
sh_wdt_stop(wdt);
return NOTIFY_DONE;
}
......@@ -411,7 +308,6 @@ static const struct file_operations sh_wdt_fops = {
.unlocked_ioctl = sh_wdt_ioctl,
.open = sh_wdt_open,
.release = sh_wdt_close,
.mmap = sh_wdt_mmap,
};
static const struct watchdog_info sh_wdt_info = {
......@@ -431,66 +327,148 @@ static struct miscdevice sh_wdt_miscdev = {
.fops = &sh_wdt_fops,
};
/**
* sh_wdt_init - Initialize module
* Registers the device and notifier handler. Actual device
* initialization is handled by sh_wdt_open().
*/
static int __init sh_wdt_init(void)
static int __devinit sh_wdt_probe(struct platform_device *pdev)
{
struct sh_wdt *wdt;
struct resource *res;
int rc;
if (clock_division_ratio < 0x5 || clock_division_ratio > 0x7) {
clock_division_ratio = WTCSR_CKS_4096;
printk(KERN_INFO PFX
"clock_division_ratio value must be 0x5<=x<=0x7, using %d\n",
clock_division_ratio);
/*
* As this driver only covers the global watchdog case, reject
* any attempts to register per-CPU watchdogs.
*/
if (pdev->id != -1)
return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!res))
return -EINVAL;
if (!devm_request_mem_region(&pdev->dev, res->start,
resource_size(res), DRV_NAME))
return -EBUSY;
wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL);
if (unlikely(!wdt)) {
rc = -ENOMEM;
goto out_release;
}
rc = sh_wdt_set_heartbeat(heartbeat);
if (unlikely(rc)) {
heartbeat = WATCHDOG_HEARTBEAT;
printk(KERN_INFO PFX
"heartbeat value must be 1<=x<=3600, using %d\n",
heartbeat);
wdt->dev = &pdev->dev;
wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (unlikely(!wdt->base)) {
rc = -ENXIO;
goto out_err;
}
rc = register_reboot_notifier(&sh_wdt_notifier);
if (unlikely(rc)) {
printk(KERN_ERR PFX
dev_err(&pdev->dev,
"Can't register reboot notifier (err=%d)\n", rc);
return rc;
goto out_unmap;
}
sh_wdt_miscdev.parent = wdt->dev;
rc = misc_register(&sh_wdt_miscdev);
if (unlikely(rc)) {
printk(KERN_ERR PFX
dev_err(&pdev->dev,
"Can't register miscdev on minor=%d (err=%d)\n",
sh_wdt_miscdev.minor, rc);
unregister_reboot_notifier(&sh_wdt_notifier);
return rc;
goto out_unreg;
}
printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
heartbeat, nowayout);
init_timer(&wdt->timer);
wdt->timer.function = sh_wdt_ping;
wdt->timer.data = (unsigned long)wdt;
wdt->timer.expires = next_ping_period(clock_division_ratio);
platform_set_drvdata(pdev, wdt);
sh_wdt_dev = pdev;
dev_info(&pdev->dev, "initialized.\n");
return 0;
out_unreg:
unregister_reboot_notifier(&sh_wdt_notifier);
out_unmap:
devm_iounmap(&pdev->dev, wdt->base);
out_err:
devm_kfree(&pdev->dev, wdt);
out_release:
devm_release_mem_region(&pdev->dev, res->start, resource_size(res));
return rc;
}
/**
* sh_wdt_exit - Deinitialize module
* Unregisters the device and notifier handler. Actual device
* deinitialization is handled by sh_wdt_close().
*/
static void __exit sh_wdt_exit(void)
static int __devexit sh_wdt_remove(struct platform_device *pdev)
{
struct sh_wdt *wdt = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
platform_set_drvdata(pdev, NULL);
misc_deregister(&sh_wdt_miscdev);
sh_wdt_dev = NULL;
unregister_reboot_notifier(&sh_wdt_notifier);
devm_release_mem_region(&pdev->dev, res->start, resource_size(res));
devm_iounmap(&pdev->dev, wdt->base);
devm_kfree(&pdev->dev, wdt);
return 0;
}
static struct platform_driver sh_wdt_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
},
.probe = sh_wdt_probe,
.remove = __devexit_p(sh_wdt_remove),
};
static int __init sh_wdt_init(void)
{
int rc;
if (unlikely(clock_division_ratio < 0x5 ||
clock_division_ratio > 0x7)) {
clock_division_ratio = WTCSR_CKS_4096;
pr_info("%s: divisor must be 0x5<=x<=0x7, using %d\n",
DRV_NAME, clock_division_ratio);
}
rc = sh_wdt_set_heartbeat(heartbeat);
if (unlikely(rc)) {
heartbeat = WATCHDOG_HEARTBEAT;
pr_info("%s: heartbeat value must be 1<=x<=3600, using %d\n",
DRV_NAME, heartbeat);
}
pr_info("%s: configured with heartbeat=%d sec (nowayout=%d)\n",
DRV_NAME, heartbeat, nowayout);
return platform_driver_register(&sh_wdt_driver);
}
static void __exit sh_wdt_exit(void)
{
platform_driver_unregister(&sh_wdt_driver);
}
module_init(sh_wdt_init);
module_exit(sh_wdt_exit);
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
MODULE_DESCRIPTION("SuperH watchdog driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
module_param(clock_division_ratio, int, 0);
......@@ -507,6 +485,3 @@ module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
module_init(sh_wdt_init);
module_exit(sh_wdt_exit);
......@@ -34,28 +34,32 @@ enum {
SCIx_NR_IRQS,
};
#define SCIx_IRQ_MUXED(irq) \
{ \
[SCIx_ERI_IRQ] = (irq), \
[SCIx_RXI_IRQ] = (irq), \
[SCIx_TXI_IRQ] = (irq), \
[SCIx_BRI_IRQ] = (irq), \
}
struct device;
/*
* Platform device specific platform_data struct
*/
struct plat_sci_port {
void __iomem *membase; /* io cookie */
unsigned long mapbase; /* resource base */
unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */
unsigned int type; /* SCI / SCIF / IRDA */
upf_t flags; /* UPF_* flags */
char *clk; /* clock string */
unsigned int scbrr_algo_id; /* SCBRR calculation algo */
unsigned int scscr; /* SCSCR initialization */
struct device *dma_dev;
#ifdef CONFIG_SERIAL_SH_SCI_DMA
unsigned int dma_slave_tx;
unsigned int dma_slave_rx;
#endif
unsigned int dma_slave_tx;
unsigned int dma_slave_rx;
};
#endif /* __LINUX_SERIAL_SCI_H */
......@@ -34,7 +34,7 @@ config GCOV_KERNEL
config GCOV_PROFILE_ALL
bool "Profile entire Kernel"
depends on GCOV_KERNEL
depends on S390 || X86 || (PPC && EXPERIMENTAL) || MICROBLAZE
depends on SUPERH || S390 || X86 || (PPC && EXPERIMENTAL) || MICROBLAZE
default n
---help---
This options activates profiling for the entire kernel.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册