Commit 56c8bc3b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sh-for-linus' of git://github.com/pmundt/linux-sh

SuperH updates for 3.3 merge window.

* tag 'sh-for-linus' of git://github.com/pmundt/linux-sh: (38 commits)
  sh: magicpanelr2: Update for parse_mtd_partitions() fallout.
  sh: mach-rsk: Update for parse_mtd_partitions() fallout.
  sh: sh2a: Improve cache flush/invalidate functions
  sh: also without PM_RUNTIME pm_runtime.o must be built
  sh: add a resource name for shdma
  sh: Remove redundant try_to_freeze() invocations.
  sh: Ensure IRQs are enabled across do_notify_resume().
  sh: Fix up store queue code for subsys_interface changes.
  sh: clkfwk: sh_clk_init_parent() should be called after clk_register()
  sh: add platform_device for renesas_usbhs in board-sh7757lcr
  sh: modify clock-sh7757 for renesas_usbhs
  sh: pfc: ioremap() support
  sh: use ioread32/iowrite32 and mapped_reg for div6
  sh: use ioread32/iowrite32 and mapped_reg for div4
  sh: use ioread32/iowrite32 and mapped_reg for mstp32
  sh: extend clock struct with mapped_reg member
  sh: clkfwk: clock-sh73a0: all div6_clks use SH_CLK_DIV6_EXT()
  sh: clkfwk: clock-sh7724: all div6_clks use SH_CLK_DIV6_EXT()
  sh: clock-sh7723: add CLKDEV_ICK_ID for cleanup
  serial: sh-sci: Handle GPIO function requests.
  ...
parents b8bf17d3 1c1744cc
...@@ -411,11 +411,11 @@ static struct clk *fsibckcr_parent[] = { ...@@ -411,11 +411,11 @@ static struct clk *fsibckcr_parent[] = {
}; };
static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
[DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0, [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
[DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0, [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2), fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
[DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0, [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2), fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
}; };
......
...@@ -92,6 +92,24 @@ static struct clk_ops div2_clk_ops = { ...@@ -92,6 +92,24 @@ static struct clk_ops div2_clk_ops = {
.recalc = div2_recalc, .recalc = div2_recalc,
}; };
static unsigned long div7_recalc(struct clk *clk)
{
return clk->parent->rate / 7;
}
static struct clk_ops div7_clk_ops = {
.recalc = div7_recalc,
};
static unsigned long div13_recalc(struct clk *clk)
{
return clk->parent->rate / 13;
}
static struct clk_ops div13_clk_ops = {
.recalc = div13_recalc,
};
/* Divide extal1 by two */ /* Divide extal1 by two */
static struct clk extal1_div2_clk = { static struct clk extal1_div2_clk = {
.ops = &div2_clk_ops, .ops = &div2_clk_ops,
...@@ -174,12 +192,29 @@ static struct clk pll3_clk = { ...@@ -174,12 +192,29 @@ static struct clk pll3_clk = {
.enable_bit = 3, .enable_bit = 3,
}; };
/* Divide PLL1 by two */ /* Divide PLL */
static struct clk pll1_div2_clk = { static struct clk pll1_div2_clk = {
.ops = &div2_clk_ops, .ops = &div2_clk_ops,
.parent = &pll1_clk, .parent = &pll1_clk,
}; };
static struct clk pll1_div7_clk = {
.ops = &div7_clk_ops,
.parent = &pll1_clk,
};
static struct clk pll1_div13_clk = {
.ops = &div13_clk_ops,
.parent = &pll1_clk,
};
/* External input clock */
struct clk sh73a0_extcki_clk = {
};
struct clk sh73a0_extalr_clk = {
};
static struct clk *main_clks[] = { static struct clk *main_clks[] = {
&r_clk, &r_clk,
&sh73a0_extal1_clk, &sh73a0_extal1_clk,
...@@ -193,6 +228,10 @@ static struct clk *main_clks[] = { ...@@ -193,6 +228,10 @@ static struct clk *main_clks[] = {
&pll2_clk, &pll2_clk,
&pll3_clk, &pll3_clk,
&pll1_div2_clk, &pll1_div2_clk,
&pll1_div7_clk,
&pll1_div13_clk,
&sh73a0_extcki_clk,
&sh73a0_extalr_clk,
}; };
static void div4_kick(struct clk *clk) static void div4_kick(struct clk *clk)
...@@ -246,27 +285,84 @@ enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, ...@@ -246,27 +285,84 @@ enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
DIV6_NR }; DIV6_NR };
static struct clk *vck_parent[8] = {
[0] = &pll1_div2_clk,
[1] = &pll2_clk,
[2] = &sh73a0_extcki_clk,
[3] = &sh73a0_extal2_clk,
[4] = &main_div2_clk,
[5] = &sh73a0_extalr_clk,
[6] = &main_clk,
};
static struct clk *pll_parent[4] = {
[0] = &pll1_div2_clk,
[1] = &pll2_clk,
[2] = &pll1_div13_clk,
};
static struct clk *hsi_parent[4] = {
[0] = &pll1_div2_clk,
[1] = &pll2_clk,
[2] = &pll1_div7_clk,
};
static struct clk *pll_extal2_parent[] = {
[0] = &pll1_div2_clk,
[1] = &pll2_clk,
[2] = &sh73a0_extal2_clk,
[3] = &sh73a0_extal2_clk,
};
static struct clk *dsi_parent[8] = {
[0] = &pll1_div2_clk,
[1] = &pll2_clk,
[2] = &main_clk,
[3] = &sh73a0_extal2_clk,
[4] = &sh73a0_extcki_clk,
};
static struct clk div6_clks[DIV6_NR] = { static struct clk div6_clks[DIV6_NR] = {
[DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0), [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
[DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0), vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
[DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0), [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
[DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, CLK_ENABLE_ON_INIT), vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
[DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0), [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
[DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0), vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
[DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0), [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
[DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0), pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
[DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0), [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
[DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0), pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
[DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0), [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
[DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0), pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
[DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0), [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
[DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0), pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
[DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0), [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
[DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0), pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
[DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0), [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
[DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0), pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
[DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0), [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
[DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0), pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
[DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
[DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
[DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
[DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
[DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
[DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
[DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
[DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
[DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
[DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
}; };
enum { MSTP001, enum { MSTP001,
...@@ -403,7 +499,7 @@ void __init sh73a0_clock_init(void) ...@@ -403,7 +499,7 @@ void __init sh73a0_clock_init(void)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret) if (!ret)
ret = sh_clk_div6_register(div6_clks, DIV6_NR); ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
if (!ret) if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
......
...@@ -46,6 +46,8 @@ extern void sh73a0_clock_init(void); ...@@ -46,6 +46,8 @@ extern void sh73a0_clock_init(void);
extern void sh73a0_pinmux_init(void); extern void sh73a0_pinmux_init(void);
extern struct clk sh73a0_extal1_clk; extern struct clk sh73a0_extal1_clk;
extern struct clk sh73a0_extal2_clk; extern struct clk sh73a0_extal2_clk;
extern struct clk sh73a0_extcki_clk;
extern struct clk sh73a0_extalr_clk;
extern unsigned int sh73a0_get_core_count(void); extern unsigned int sh73a0_get_core_count(void);
extern void sh73a0_secondary_init(unsigned int cpu); extern void sh73a0_secondary_init(unsigned int cpu);
......
...@@ -25,9 +25,6 @@ ...@@ -25,9 +25,6 @@
#define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL) #define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL)
/* Prefer cmdline over RedBoot */
static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
/* Wait until reset finished. Timeout is 100ms. */ /* Wait until reset finished. Timeout is 100ms. */
static int __init ethernet_reset_finished(void) static int __init ethernet_reset_finished(void)
{ {
...@@ -293,8 +290,6 @@ static struct platform_device heartbeat_device = { ...@@ -293,8 +290,6 @@ static struct platform_device heartbeat_device = {
.resource = heartbeat_resources, .resource = heartbeat_resources,
}; };
static struct mtd_partition *parsed_partitions;
static struct mtd_partition mpr2_partitions[] = { static struct mtd_partition mpr2_partitions[] = {
/* Reserved for bootloader, read-only */ /* Reserved for bootloader, read-only */
{ {
...@@ -318,6 +313,8 @@ static struct mtd_partition mpr2_partitions[] = { ...@@ -318,6 +313,8 @@ static struct mtd_partition mpr2_partitions[] = {
}; };
static struct physmap_flash_data flash_data = { static struct physmap_flash_data flash_data = {
.parts = mpr2_partitions,
.nr_parts = ARRAY_SIZE(mpr2_partitions),
.width = 2, .width = 2,
}; };
...@@ -337,32 +334,6 @@ static struct platform_device flash_device = { ...@@ -337,32 +334,6 @@ static struct platform_device flash_device = {
}, },
}; };
static struct mtd_info *flash_mtd;
static struct map_info mpr2_flash_map = {
.name = "Magic Panel R2 Flash",
.size = 0x2000000UL,
.bankwidth = 2,
};
static void __init set_mtd_partitions(void)
{
int nr_parts = 0;
simple_map_init(&mpr2_flash_map);
flash_mtd = do_map_probe("cfi_probe", &mpr2_flash_map);
nr_parts = parse_mtd_partitions(flash_mtd, probes,
&parsed_partitions, 0);
/* If there is no partition table, used the hard coded table */
if (nr_parts <= 0) {
flash_data.parts = mpr2_partitions;
flash_data.nr_parts = ARRAY_SIZE(mpr2_partitions);
} else {
flash_data.nr_parts = nr_parts;
flash_data.parts = parsed_partitions;
}
}
/* /*
* Add all resources to the platform_device * Add all resources to the platform_device
*/ */
...@@ -376,7 +347,6 @@ static struct platform_device *mpr2_devices[] __initdata = { ...@@ -376,7 +347,6 @@ static struct platform_device *mpr2_devices[] __initdata = {
static int __init mpr2_devices_setup(void) static int __init mpr2_devices_setup(void)
{ {
set_mtd_partitions();
return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices));
} }
device_initcall(mpr2_devices_setup); device_initcall(mpr2_devices_setup);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/mmc/sh_mmcif.h> #include <linux/mmc/sh_mmcif.h>
#include <linux/mmc/sh_mobile_sdhi.h> #include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/sh_eth.h> #include <linux/sh_eth.h>
#include <linux/usb/renesas_usbhs.h>
#include <cpu/sh7757.h> #include <cpu/sh7757.h>
#include <asm/heartbeat.h> #include <asm/heartbeat.h>
...@@ -264,6 +265,43 @@ static struct platform_device sdhi_device = { ...@@ -264,6 +265,43 @@ static struct platform_device sdhi_device = {
}, },
}; };
static int usbhs0_get_id(struct platform_device *pdev)
{
return USBHS_GADGET;
}
static struct renesas_usbhs_platform_info usb0_data = {
.platform_callback = {
.get_id = usbhs0_get_id,
},
.driver_param = {
.buswait_bwait = 5,
}
};
static struct resource usb0_resources[] = {
[0] = {
.start = 0xfe450000,
.end = 0xfe4501ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 50,
.end = 50,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device usb0_device = {
.name = "renesas_usbhs",
.id = 0,
.dev = {
.platform_data = &usb0_data,
},
.num_resources = ARRAY_SIZE(usb0_resources),
.resource = usb0_resources,
};
static struct platform_device *sh7757lcr_devices[] __initdata = { static struct platform_device *sh7757lcr_devices[] __initdata = {
&heartbeat_device, &heartbeat_device,
&sh7757_eth0_device, &sh7757_eth0_device,
...@@ -272,6 +310,7 @@ static struct platform_device *sh7757lcr_devices[] __initdata = { ...@@ -272,6 +310,7 @@ static struct platform_device *sh7757lcr_devices[] __initdata = {
&sh7757_eth_giga1_device, &sh7757_eth_giga1_device,
&sh_mmcif_device, &sh_mmcif_device,
&sdhi_device, &sdhi_device,
&usb0_device,
}; };
static struct flash_platform_data spi_flash_data = { static struct flash_platform_data spi_flash_data = {
......
...@@ -249,9 +249,6 @@ static struct platform_device lcdc_device = { ...@@ -249,9 +249,6 @@ static struct platform_device lcdc_device = {
.dev = { .dev = {
.platform_data = &lcdc_info, .platform_data = &lcdc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
}; };
static void camera_power(int val) static void camera_power(int val)
...@@ -424,9 +421,6 @@ static struct platform_device ceu_device = { ...@@ -424,9 +421,6 @@ static struct platform_device ceu_device = {
.dev = { .dev = {
.platform_data = &sh_mobile_ceu_info, .platform_data = &sh_mobile_ceu_info,
}, },
.archdata = {
.hwblk_id = HWBLK_CEU,
},
}; };
static struct resource sdhi0_cn3_resources[] = { static struct resource sdhi0_cn3_resources[] = {
...@@ -454,9 +448,6 @@ static struct platform_device sdhi0_cn3_device = { ...@@ -454,9 +448,6 @@ static struct platform_device sdhi0_cn3_device = {
.dev = { .dev = {
.platform_data = &sdhi0_cn3_data, .platform_data = &sdhi0_cn3_data,
}, },
.archdata = {
.hwblk_id = HWBLK_SDHI0,
},
}; };
static struct resource sdhi1_cn7_resources[] = { static struct resource sdhi1_cn7_resources[] = {
...@@ -484,9 +475,6 @@ static struct platform_device sdhi1_cn7_device = { ...@@ -484,9 +475,6 @@ static struct platform_device sdhi1_cn7_device = {
.dev = { .dev = {
.platform_data = &sdhi1_cn7_data, .platform_data = &sdhi1_cn7_data,
}, },
.archdata = {
.hwblk_id = HWBLK_SDHI1,
},
}; };
static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = { static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
......
...@@ -156,9 +156,6 @@ static struct platform_device sh_eth_device = { ...@@ -156,9 +156,6 @@ static struct platform_device sh_eth_device = {
}, },
.num_resources = ARRAY_SIZE(sh_eth_resources), .num_resources = ARRAY_SIZE(sh_eth_resources),
.resource = sh_eth_resources, .resource = sh_eth_resources,
.archdata = {
.hwblk_id = HWBLK_ETHER,
},
}; };
/* USB0 host */ /* USB0 host */
...@@ -278,9 +275,6 @@ static struct platform_device usbhs_device = { ...@@ -278,9 +275,6 @@ static struct platform_device usbhs_device = {
}, },
.num_resources = ARRAY_SIZE(usbhs_resources), .num_resources = ARRAY_SIZE(usbhs_resources),
.resource = usbhs_resources, .resource = usbhs_resources,
.archdata = {
.hwblk_id = HWBLK_USB1,
},
}; };
/* LCDC */ /* LCDC */
...@@ -366,9 +360,6 @@ static struct platform_device lcdc_device = { ...@@ -366,9 +360,6 @@ static struct platform_device lcdc_device = {
.dev = { .dev = {
.platform_data = &lcdc_info, .platform_data = &lcdc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
}; };
/* CEU0 */ /* CEU0 */
...@@ -400,9 +391,6 @@ static struct platform_device ceu0_device = { ...@@ -400,9 +391,6 @@ static struct platform_device ceu0_device = {
.dev = { .dev = {
.platform_data = &sh_mobile_ceu0_info, .platform_data = &sh_mobile_ceu0_info,
}, },
.archdata = {
.hwblk_id = HWBLK_CEU0,
},
}; };
/* CEU1 */ /* CEU1 */
...@@ -434,9 +422,6 @@ static struct platform_device ceu1_device = { ...@@ -434,9 +422,6 @@ static struct platform_device ceu1_device = {
.dev = { .dev = {
.platform_data = &sh_mobile_ceu1_info, .platform_data = &sh_mobile_ceu1_info,
}, },
.archdata = {
.hwblk_id = HWBLK_CEU1,
},
}; };
/* I2C device */ /* I2C device */
...@@ -491,9 +476,6 @@ static struct platform_device keysc_device = { ...@@ -491,9 +476,6 @@ static struct platform_device keysc_device = {
.dev = { .dev = {
.platform_data = &keysc_info, .platform_data = &keysc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
}; };
/* TouchScreen */ /* TouchScreen */
...@@ -568,9 +550,6 @@ static struct platform_device sdhi0_device = { ...@@ -568,9 +550,6 @@ static struct platform_device sdhi0_device = {
.dev = { .dev = {
.platform_data = &sdhi0_info, .platform_data = &sdhi0_info,
}, },
.archdata = {
.hwblk_id = HWBLK_SDHI0,
},
}; };
#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
...@@ -608,9 +587,6 @@ static struct platform_device sdhi1_device = { ...@@ -608,9 +587,6 @@ static struct platform_device sdhi1_device = {
.dev = { .dev = {
.platform_data = &sdhi1_info, .platform_data = &sdhi1_info,
}, },
.archdata = {
.hwblk_id = HWBLK_SDHI1,
},
}; };
#endif /* CONFIG_MMC_SH_MMCIF */ #endif /* CONFIG_MMC_SH_MMCIF */
...@@ -676,9 +652,6 @@ static struct platform_device msiof0_device = { ...@@ -676,9 +652,6 @@ static struct platform_device msiof0_device = {
}, },
.num_resources = ARRAY_SIZE(msiof0_resources), .num_resources = ARRAY_SIZE(msiof0_resources),
.resource = msiof0_resources, .resource = msiof0_resources,
.archdata = {
.hwblk_id = HWBLK_MSIOF0,
},
}; };
#endif #endif
...@@ -818,9 +791,6 @@ static struct platform_device fsi_device = { ...@@ -818,9 +791,6 @@ static struct platform_device fsi_device = {
.dev = { .dev = {
.platform_data = &fsi_info, .platform_data = &fsi_info,
}, },
.archdata = {
.hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */
},
}; };
/* IrDA */ /* IrDA */
...@@ -882,9 +852,6 @@ static struct platform_device vou_device = { ...@@ -882,9 +852,6 @@ static struct platform_device vou_device = {
.dev = { .dev = {
.platform_data = &sh_vou_pdata, .platform_data = &sh_vou_pdata,
}, },
.archdata = {
.hwblk_id = HWBLK_VOU,
},
}; };
#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
...@@ -936,9 +903,6 @@ static struct platform_device sh_mmcif_device = { ...@@ -936,9 +903,6 @@ static struct platform_device sh_mmcif_device = {
}, },
.num_resources = ARRAY_SIZE(sh_mmcif_resources), .num_resources = ARRAY_SIZE(sh_mmcif_resources),
.resource = sh_mmcif_resources, .resource = sh_mmcif_resources,
.archdata = {
.hwblk_id = HWBLK_MMC,
},
}; };
#endif #endif
......
...@@ -122,9 +122,6 @@ static struct platform_device kfr2r09_sh_keysc_device = { ...@@ -122,9 +122,6 @@ static struct platform_device kfr2r09_sh_keysc_device = {
.dev = { .dev = {
.platform_data = &kfr2r09_sh_keysc_info, .platform_data = &kfr2r09_sh_keysc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
}; };
static const struct fb_videomode kfr2r09_lcdc_modes[] = { static const struct fb_videomode kfr2r09_lcdc_modes[] = {
...@@ -191,9 +188,6 @@ static struct platform_device kfr2r09_sh_lcdc_device = { ...@@ -191,9 +188,6 @@ static struct platform_device kfr2r09_sh_lcdc_device = {
.dev = { .dev = {
.platform_data = &kfr2r09_sh_lcdc_info, .platform_data = &kfr2r09_sh_lcdc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
}; };
static struct r8a66597_platdata kfr2r09_usb0_gadget_data = { static struct r8a66597_platdata kfr2r09_usb0_gadget_data = {
...@@ -254,9 +248,6 @@ static struct platform_device kfr2r09_ceu_device = { ...@@ -254,9 +248,6 @@ static struct platform_device kfr2r09_ceu_device = {
.dev = { .dev = {
.platform_data = &sh_mobile_ceu_info, .platform_data = &sh_mobile_ceu_info,
}, },
.archdata = {
.hwblk_id = HWBLK_CEU0,
},
}; };
static struct i2c_board_info kfr2r09_i2c_camera = { static struct i2c_board_info kfr2r09_i2c_camera = {
...@@ -377,9 +368,6 @@ static struct platform_device kfr2r09_sh_sdhi0_device = { ...@@ -377,9 +368,6 @@ static struct platform_device kfr2r09_sh_sdhi0_device = {
.dev = { .dev = {
.platform_data = &sh7724_sdhi0_data, .platform_data = &sh7724_sdhi0_data,
}, },
.archdata = {
.hwblk_id = HWBLK_SDHI0,
},
}; };
static struct platform_device *kfr2r09_devices[] __initdata = { static struct platform_device *kfr2r09_devices[] __initdata = {
......
...@@ -99,9 +99,6 @@ static struct platform_device sh_keysc_device = { ...@@ -99,9 +99,6 @@ static struct platform_device sh_keysc_device = {
.dev = { .dev = {
.platform_data = &sh_keysc_info, .platform_data = &sh_keysc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
}; };
static struct mtd_partition migor_nor_flash_partitions[] = static struct mtd_partition migor_nor_flash_partitions[] =
...@@ -300,9 +297,6 @@ static struct platform_device migor_lcdc_device = { ...@@ -300,9 +297,6 @@ static struct platform_device migor_lcdc_device = {
.dev = { .dev = {
.platform_data = &sh_mobile_lcdc_info, .platform_data = &sh_mobile_lcdc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
}; };
static struct clk *camera_clk; static struct clk *camera_clk;
...@@ -390,9 +384,6 @@ static struct platform_device migor_ceu_device = { ...@@ -390,9 +384,6 @@ static struct platform_device migor_ceu_device = {
.dev = { .dev = {
.platform_data = &sh_mobile_ceu_info, .platform_data = &sh_mobile_ceu_info,
}, },
.archdata = {
.hwblk_id = HWBLK_CEU,
},
}; };
static struct resource sdhi_cn9_resources[] = { static struct resource sdhi_cn9_resources[] = {
...@@ -421,9 +412,6 @@ static struct platform_device sdhi_cn9_device = { ...@@ -421,9 +412,6 @@ static struct platform_device sdhi_cn9_device = {
.dev = { .dev = {
.platform_data = &sh7724_sdhi_data, .platform_data = &sh7724_sdhi_data,
}, },
.archdata = {
.hwblk_id = HWBLK_SDHI,
},
}; };
static struct i2c_board_info migor_i2c_devices[] = { static struct i2c_board_info migor_i2c_devices[] = {
......
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#ifdef CONFIG_MTD
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#endif
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/io.h> #include <asm/io.h>
static const char *part_probes[] = { "cmdlinepart", NULL };
static struct mtd_partition rsk_partitions[] = { static struct mtd_partition rsk_partitions[] = {
{ {
.name = "Bootloader", .name = "Bootloader",
...@@ -42,6 +42,7 @@ static struct physmap_flash_data flash_data = { ...@@ -42,6 +42,7 @@ static struct physmap_flash_data flash_data = {
.parts = rsk_partitions, .parts = rsk_partitions,
.nr_parts = ARRAY_SIZE(rsk_partitions), .nr_parts = ARRAY_SIZE(rsk_partitions),
.width = 2, .width = 2,
.part_probe_types = part_probes,
}; };
static struct resource flash_resource = { static struct resource flash_resource = {
...@@ -60,44 +61,12 @@ static struct platform_device flash_device = { ...@@ -60,44 +61,12 @@ static struct platform_device flash_device = {
}, },
}; };
#ifdef CONFIG_MTD
static const char *probes[] = { "cmdlinepart", NULL };
static struct map_info rsk_flash_map = {
.name = "RSK+ Flash",
.size = 0x400000,
.bankwidth = 2,
};
static struct mtd_info *flash_mtd;
static struct mtd_partition *parsed_partitions;
static void __init set_mtd_partitions(void)
{
int nr_parts = 0;
simple_map_init(&rsk_flash_map);
flash_mtd = do_map_probe("cfi_probe", &rsk_flash_map);
nr_parts = parse_mtd_partitions(flash_mtd, probes,
&parsed_partitions, 0);
/* If there is no partition table, used the hard coded table */
if (nr_parts > 0) {
flash_data.nr_parts = nr_parts;
flash_data.parts = parsed_partitions;
}
}
#else
static inline void set_mtd_partitions(void) {}
#endif
static struct platform_device *rsk_devices[] __initdata = { static struct platform_device *rsk_devices[] __initdata = {
&flash_device, &flash_device,
}; };
static int __init rsk_devices_setup(void) static int __init rsk_devices_setup(void)
{ {
set_mtd_partitions();
return platform_add_devices(rsk_devices, return platform_add_devices(rsk_devices,
ARRAY_SIZE(rsk_devices)); ARRAY_SIZE(rsk_devices));
} }
......
...@@ -127,9 +127,6 @@ static struct platform_device sh_keysc_device = { ...@@ -127,9 +127,6 @@ static struct platform_device sh_keysc_device = {
.dev = { .dev = {
.platform_data = &sh_keysc_info, .platform_data = &sh_keysc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
}; };
static struct platform_device *se7722_devices[] __initdata = { static struct platform_device *se7722_devices[] __initdata = {
......
...@@ -210,9 +210,6 @@ static struct platform_device lcdc_device = { ...@@ -210,9 +210,6 @@ static struct platform_device lcdc_device = {
.dev = { .dev = {
.platform_data = &lcdc_info, .platform_data = &lcdc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_LCDC,
},
}; };
/* CEU0 */ /* CEU0 */
...@@ -244,9 +241,6 @@ static struct platform_device ceu0_device = { ...@@ -244,9 +241,6 @@ static struct platform_device ceu0_device = {
.dev = { .dev = {
.platform_data = &sh_mobile_ceu0_info, .platform_data = &sh_mobile_ceu0_info,
}, },
.archdata = {
.hwblk_id = HWBLK_CEU0,
},
}; };
/* CEU1 */ /* CEU1 */
...@@ -278,9 +272,6 @@ static struct platform_device ceu1_device = { ...@@ -278,9 +272,6 @@ static struct platform_device ceu1_device = {
.dev = { .dev = {
.platform_data = &sh_mobile_ceu1_info, .platform_data = &sh_mobile_ceu1_info,
}, },
.archdata = {
.hwblk_id = HWBLK_CEU1,
},
}; };
/* FSI */ /* FSI */
...@@ -310,9 +301,6 @@ static struct platform_device fsi_device = { ...@@ -310,9 +301,6 @@ static struct platform_device fsi_device = {
.dev = { .dev = {
.platform_data = &fsi_info, .platform_data = &fsi_info,
}, },
.archdata = {
.hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */
},
}; };
static struct platform_device fsi_ak4642_device = { static struct platform_device fsi_ak4642_device = {
...@@ -355,9 +343,6 @@ static struct platform_device keysc_device = { ...@@ -355,9 +343,6 @@ static struct platform_device keysc_device = {
.dev = { .dev = {
.platform_data = &keysc_info, .platform_data = &keysc_info,
}, },
.archdata = {
.hwblk_id = HWBLK_KEYSC,
},
}; };
/* SH Eth */ /* SH Eth */
...@@ -386,9 +371,6 @@ static struct platform_device sh_eth_device = { ...@@ -386,9 +371,6 @@ static struct platform_device sh_eth_device = {
}, },
.num_resources = ARRAY_SIZE(sh_eth_resources), .num_resources = ARRAY_SIZE(sh_eth_resources),
.resource = sh_eth_resources, .resource = sh_eth_resources,
.archdata = {
.hwblk_id = HWBLK_ETHER,
},
}; };
static struct r8a66597_platdata sh7724_usb0_host_data = { static struct r8a66597_platdata sh7724_usb0_host_data = {
...@@ -418,9 +400,6 @@ static struct platform_device sh7724_usb0_host_device = { ...@@ -418,9 +400,6 @@ static struct platform_device sh7724_usb0_host_device = {
}, },
.num_resources = ARRAY_SIZE(sh7724_usb0_host_resources), .num_resources = ARRAY_SIZE(sh7724_usb0_host_resources),
.resource = sh7724_usb0_host_resources, .resource = sh7724_usb0_host_resources,
.archdata = {
.hwblk_id = HWBLK_USB0,
},
}; };
static struct r8a66597_platdata sh7724_usb1_gadget_data = { static struct r8a66597_platdata sh7724_usb1_gadget_data = {
...@@ -479,9 +458,6 @@ static struct platform_device sdhi0_cn7_device = { ...@@ -479,9 +458,6 @@ static struct platform_device sdhi0_cn7_device = {
.dev = { .dev = {
.platform_data = &sh7724_sdhi0_data, .platform_data = &sh7724_sdhi0_data,
}, },
.archdata = {
.hwblk_id = HWBLK_SDHI0,
},
}; };
static struct resource sdhi1_cn8_resources[] = { static struct resource sdhi1_cn8_resources[] = {
...@@ -511,9 +487,6 @@ static struct platform_device sdhi1_cn8_device = { ...@@ -511,9 +487,6 @@ static struct platform_device sdhi1_cn8_device = {
.dev = { .dev = {
.platform_data = &sh7724_sdhi1_data, .platform_data = &sh7724_sdhi1_data,
}, },
.archdata = {
.hwblk_id = HWBLK_SDHI1,
},
}; };
/* IrDA */ /* IrDA */
...@@ -576,9 +549,6 @@ static struct platform_device vou_device = { ...@@ -576,9 +549,6 @@ static struct platform_device vou_device = {
.dev = { .dev = {
.platform_data = &sh_vou_pdata, .platform_data = &sh_vou_pdata,
}, },
.archdata = {
.hwblk_id = HWBLK_VOU,
},
}; };
static struct platform_device *ms7724se_devices[] __initdata = { static struct platform_device *ms7724se_devices[] __initdata = {
......
...@@ -14,15 +14,5 @@ int platform_resource_setup_memory(struct platform_device *pdev, ...@@ -14,15 +14,5 @@ int platform_resource_setup_memory(struct platform_device *pdev,
void plat_early_device_setup(void); void plat_early_device_setup(void);
#define PDEV_ARCHDATA_FLAG_INIT 0
#define PDEV_ARCHDATA_FLAG_IDLE 1
#define PDEV_ARCHDATA_FLAG_SUSP 2
struct pdev_archdata { struct pdev_archdata {
int hwblk_id;
#ifdef CONFIG_PM_RUNTIME
unsigned long flags;
struct list_head entry;
struct mutex mutex;
#endif
}; };
#ifndef __ASM_SH_HWBLK_H
#define __ASM_SH_HWBLK_H
#include <asm/clock.h>
#include <asm/io.h>
#define HWBLK_CNT_USAGE 0
#define HWBLK_CNT_IDLE 1
#define HWBLK_CNT_DEVICES 2
#define HWBLK_CNT_NR 3
#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */
#define HWBLK_AREA(_flags, _parent) \
{ \
.flags = _flags, \
.parent = _parent, \
}
struct hwblk_area {
int cnt[HWBLK_CNT_NR];
unsigned char parent;
unsigned char flags;
};
#define HWBLK(_mstp, _bit, _area) \
{ \
.mstp = (void __iomem *)_mstp, \
.bit = _bit, \
.area = _area, \
}
struct hwblk {
void __iomem *mstp;
unsigned char bit;
unsigned char area;
int cnt[HWBLK_CNT_NR];
};
struct hwblk_info {
struct hwblk_area *areas;
int nr_areas;
struct hwblk *hwblks;
int nr_hwblks;
};
/* Should be defined by processor-specific code */
int arch_hwblk_init(void);
int arch_hwblk_sleep_mode(void);
int hwblk_register(struct hwblk_info *info);
int hwblk_init(void);
void hwblk_enable(struct hwblk_info *info, int hwblk);
void hwblk_disable(struct hwblk_info *info, int hwblk);
void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
/* allow clocks to enable and disable hardware blocks */
#define SH_HWBLK_CLK(_hwblk, _parent, _flags) \
[_hwblk] = { \
.parent = _parent, \
.arch_flags = _hwblk, \
.flags = _flags, \
}
int sh_hwblk_clk_register(struct clk *clks, int nr);
#endif /* __ASM_SH_HWBLK_H */
...@@ -222,14 +222,11 @@ enum { ...@@ -222,14 +222,11 @@ enum {
}; };
enum { enum {
HWBLK_UNKNOWN = 0, HWBLK_URAM, HWBLK_XYMEM,
HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_URAM, HWBLK_XYMEM, HWBLK_TMU, HWBLK_CMT, HWBLK_RWDT, HWBLK_FLCTL,
HWBLK_INTC, HWBLK_DMAC, HWBLK_SHYWAY, HWBLK_HUDI, HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_IIC, HWBLK_RTC,
HWBLK_UBC, HWBLK_TMU, HWBLK_CMT, HWBLK_RWDT, HWBLK_FLCTL, HWBLK_SDHI, HWBLK_KEYSC,
HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SIO, HWBLK_USBF, HWBLK_2DG, HWBLK_SIU, HWBLK_VOU,
HWBLK_SIOF0, HWBLK_SIOF1, HWBLK_IIC, HWBLK_RTC,
HWBLK_TPU, HWBLK_IRDA, HWBLK_SDHI, HWBLK_SIM, HWBLK_KEYSC,
HWBLK_TSIF, HWBLK_USBF, HWBLK_2DG, HWBLK_SIU, HWBLK_VOU,
HWBLK_JPU, HWBLK_BEU, HWBLK_CEU, HWBLK_VEU, HWBLK_VPU, HWBLK_JPU, HWBLK_BEU, HWBLK_CEU, HWBLK_VEU, HWBLK_VPU,
HWBLK_LCDC, HWBLK_LCDC,
HWBLK_NR, HWBLK_NR,
......
...@@ -266,10 +266,9 @@ enum { ...@@ -266,10 +266,9 @@ enum {
}; };
enum { enum {
HWBLK_UNKNOWN = 0,
HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_L2C, HWBLK_ILMEM, HWBLK_FPU, HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_L2C, HWBLK_ILMEM, HWBLK_FPU,
HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY, HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC, HWBLK_SUBC, HWBLK_HUDI, HWBLK_UBC,
HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1, HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
HWBLK_FLCTL, HWBLK_FLCTL,
HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2,
......
...@@ -268,10 +268,9 @@ enum { ...@@ -268,10 +268,9 @@ enum {
}; };
enum { enum {
HWBLK_UNKNOWN = 0,
HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_RSMEM, HWBLK_ILMEM, HWBLK_L2C, HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_RSMEM, HWBLK_ILMEM, HWBLK_L2C,
HWBLK_FPU, HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY, HWBLK_FPU, HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC, HWBLK_HUDI, HWBLK_UBC,
HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1, HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SCIF3, HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SCIF3,
HWBLK_SCIF4, HWBLK_SCIF5, HWBLK_MSIOF0, HWBLK_MSIOF1, HWBLK_SCIF4, HWBLK_SCIF5, HWBLK_MSIOF0, HWBLK_MSIOF1,
...@@ -314,5 +313,6 @@ enum { ...@@ -314,5 +313,6 @@ enum {
extern struct clk sh7724_fsimcka_clk; extern struct clk sh7724_fsimcka_clk;
extern struct clk sh7724_fsimckb_clk; extern struct clk sh7724_fsimckb_clk;
extern struct clk sh7724_dv_clki;
#endif /* __ASM_SH7724_H__ */ #endif /* __ASM_SH7724_H__ */
...@@ -18,4 +18,4 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/ ...@@ -18,4 +18,4 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
obj-$(CONFIG_SH_ADC) += adc.o obj-$(CONFIG_SH_ADC) += adc.o
obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o
obj-y += irq/ init.o clock.o fpu.o hwblk.o proc.o obj-y += irq/ init.o clock.o fpu.o proc.o
#include <linux/clk.h>
#include <linux/compiler.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <asm/clock.h>
static DEFINE_SPINLOCK(hwblk_lock);
static void hwblk_area_mod_cnt(struct hwblk_info *info,
int area, int counter, int value, int goal)
{
struct hwblk_area *hap = info->areas + area;
hap->cnt[counter] += value;
if (hap->cnt[counter] != goal)
return;
if (hap->flags & HWBLK_AREA_FLAG_PARENT)
hwblk_area_mod_cnt(info, hap->parent, counter, value, goal);
}
static int __hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
int counter, int value, int goal)
{
struct hwblk *hp = info->hwblks + hwblk;
hp->cnt[counter] += value;
if (hp->cnt[counter] == goal)
hwblk_area_mod_cnt(info, hp->area, counter, value, goal);
return hp->cnt[counter];
}
static void hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
int counter, int value, int goal)
{
unsigned long flags;
spin_lock_irqsave(&hwblk_lock, flags);
__hwblk_mod_cnt(info, hwblk, counter, value, goal);
spin_unlock_irqrestore(&hwblk_lock, flags);
}
void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int counter)
{
hwblk_mod_cnt(info, hwblk, counter, 1, 1);
}
void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int counter)
{
hwblk_mod_cnt(info, hwblk, counter, -1, 0);
}
void hwblk_enable(struct hwblk_info *info, int hwblk)
{
struct hwblk *hp = info->hwblks + hwblk;
unsigned long tmp;
unsigned long flags;
int ret;
spin_lock_irqsave(&hwblk_lock, flags);
ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, 1, 1);
if (ret == 1) {
tmp = __raw_readl(hp->mstp);
tmp &= ~(1 << hp->bit);
__raw_writel(tmp, hp->mstp);
}
spin_unlock_irqrestore(&hwblk_lock, flags);
}
void hwblk_disable(struct hwblk_info *info, int hwblk)
{
struct hwblk *hp = info->hwblks + hwblk;
unsigned long tmp;
unsigned long flags;
int ret;
spin_lock_irqsave(&hwblk_lock, flags);
ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, -1, 0);
if (ret == 0) {
tmp = __raw_readl(hp->mstp);
tmp |= 1 << hp->bit;
__raw_writel(tmp, hp->mstp);
}
spin_unlock_irqrestore(&hwblk_lock, flags);
}
struct hwblk_info *hwblk_info;
int __init hwblk_register(struct hwblk_info *info)
{
hwblk_info = info;
return 0;
}
int __init __weak arch_hwblk_init(void)
{
return 0;
}
int __weak arch_hwblk_sleep_mode(void)
{
return SUSP_SH_SLEEP;
}
int __init hwblk_init(void)
{
return arch_hwblk_init();
}
/* allow clocks to enable and disable hardware blocks */
static int sh_hwblk_clk_enable(struct clk *clk)
{
if (!hwblk_info)
return -ENOENT;
hwblk_enable(hwblk_info, clk->arch_flags);
return 0;
}
static void sh_hwblk_clk_disable(struct clk *clk)
{
if (hwblk_info)
hwblk_disable(hwblk_info, clk->arch_flags);
}
static struct clk_ops sh_hwblk_clk_ops = {
.enable = sh_hwblk_clk_enable,
.disable = sh_hwblk_clk_disable,
.recalc = followparent_recalc,
};
int __init sh_hwblk_clk_register(struct clk *clks, int nr)
{
struct clk *clkp;
int ret = 0;
int k;
for (k = 0; !ret && (k < nr); k++) {
clkp = clks + k;
/* skip over clocks using hwblk 0 (HWBLK_UNKNOWN) */
if (!clkp->arch_flags)
continue;
clkp->ops = &sh_hwblk_clk_ops;
ret |= clk_register(clkp);
}
return ret;
}
...@@ -337,7 +337,7 @@ static struct kobj_type ktype_percpu_entry = { ...@@ -337,7 +337,7 @@ static struct kobj_type ktype_percpu_entry = {
.default_attrs = sq_sysfs_attrs, .default_attrs = sq_sysfs_attrs,
}; };
static int __devinit sq_dev_add(struct device *dev) static int sq_dev_add(struct device *dev, struct subsys_interface *sif)
{ {
unsigned int cpu = dev->id; unsigned int cpu = dev->id;
struct kobject *kobj; struct kobject *kobj;
...@@ -355,7 +355,7 @@ static int __devinit sq_dev_add(struct device *dev) ...@@ -355,7 +355,7 @@ static int __devinit sq_dev_add(struct device *dev)
return error; return error;
} }
static int __devexit sq_dev_remove(struct device *dev) static int sq_dev_remove(struct device *dev, struct subsys_interface *sif)
{ {
unsigned int cpu = dev->id; unsigned int cpu = dev->id;
struct kobject *kobj = sq_kobject[cpu]; struct kobject *kobj = sq_kobject[cpu];
...@@ -365,10 +365,10 @@ static int __devexit sq_dev_remove(struct device *dev) ...@@ -365,10 +365,10 @@ static int __devexit sq_dev_remove(struct device *dev)
} }
static struct subsys_interface sq_interface = { static struct subsys_interface sq_interface = {
.name = "sq" .name = "sq",
.subsys = &cpu_subsys, .subsys = &cpu_subsys,
.add_dev = sq_dev_add, .add_dev = sq_dev_add,
.remove_dev = __devexit_p(sq_dev_remove), .remove_dev = sq_dev_remove,
}; };
static int __init sq_api_init(void) static int __init sq_api_init(void)
......
...@@ -27,9 +27,9 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o ...@@ -27,9 +27,9 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o hwblk-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o hwblk-sh7723.o clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o
clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o hwblk-sh7724.o clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o
clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7366.o clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7366.o
clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/sh_clk.h>
#include <asm/clock.h> #include <asm/clock.h>
#include <asm/hwblk.h>
#include <cpu/sh7722.h> #include <cpu/sh7722.h>
/* SH7722 registers */ /* SH7722 registers */
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
#define SCLKBCR 0xa415000c #define SCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018 #define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024 #define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050 #define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */ /* Fixed 32 KHz root clock for RTC and Power Management purposes */
...@@ -148,31 +151,31 @@ struct clk div6_clks[DIV6_NR] = { ...@@ -148,31 +151,31 @@ struct clk div6_clks[DIV6_NR] = {
}; };
static struct clk mstp_clks[HWBLK_NR] = { static struct clk mstp_clks[HWBLK_NR] = {
SH_HWBLK_CLK(HWBLK_URAM, &div4_clks[DIV4_U], CLK_ENABLE_ON_INIT), [HWBLK_URAM] = SH_CLK_MSTP32(&div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK(HWBLK_XYMEM, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT), [HWBLK_XYMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
SH_HWBLK_CLK(HWBLK_TMU, &div4_clks[DIV4_P], 0), [HWBLK_TMU] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0), [HWBLK_CMT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 14, 0),
SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0), [HWBLK_RWDT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 13, 0),
SH_HWBLK_CLK(HWBLK_FLCTL, &div4_clks[DIV4_P], 0), [HWBLK_FLCTL] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0), [HWBLK_SCIF0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0), [HWBLK_SCIF1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0), [HWBLK_SCIF2] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
SH_HWBLK_CLK(HWBLK_IIC, &div4_clks[DIV4_P], 0), [HWBLK_IIC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0), [HWBLK_RTC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 8, 0),
SH_HWBLK_CLK(HWBLK_SDHI, &div4_clks[DIV4_P], 0), [HWBLK_SDHI] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0), [HWBLK_KEYSC] = SH_CLK_MSTP32(&r_clk, MSTPCR2, 14, 0),
SH_HWBLK_CLK(HWBLK_USBF, &div4_clks[DIV4_P], 0), [HWBLK_USBF] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0), [HWBLK_2DG] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 9, 0),
SH_HWBLK_CLK(HWBLK_SIU, &div4_clks[DIV4_B], 0), [HWBLK_SIU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0), [HWBLK_JPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 6, 0),
SH_HWBLK_CLK(HWBLK_JPU, &div4_clks[DIV4_B], 0), [HWBLK_VOU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
SH_HWBLK_CLK(HWBLK_BEU, &div4_clks[DIV4_B], 0), [HWBLK_BEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
SH_HWBLK_CLK(HWBLK_CEU, &div4_clks[DIV4_B], 0), [HWBLK_CEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
SH_HWBLK_CLK(HWBLK_VEU, &div4_clks[DIV4_B], 0), [HWBLK_VEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 2, 0),
SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0), [HWBLK_VPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 1, 0),
SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_P], 0), [HWBLK_LCDC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 0, 0),
}; };
static struct clk_lookup lookups[] = { static struct clk_lookup lookups[] = {
...@@ -205,27 +208,27 @@ static struct clk_lookup lookups[] = { ...@@ -205,27 +208,27 @@ static struct clk_lookup lookups[] = {
CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU]), CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU]),
CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]), CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]), CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]), CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]), CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC]), CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC]),
CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]), CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI]), CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI]),
CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]), CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[HWBLK_KEYSC]),
CLKDEV_CON_ID("usbf0", &mstp_clks[HWBLK_USBF]), CLKDEV_CON_ID("usbf0", &mstp_clks[HWBLK_USBF]),
CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
CLKDEV_CON_ID("siu0", &mstp_clks[HWBLK_SIU]), CLKDEV_DEV_ID("siu-pcm-audio", &mstp_clks[HWBLK_SIU]),
CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]), CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]), CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]), CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]),
CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU]), CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU]),
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]), CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]),
CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]), CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),
}; };
int __init arch_clk_init(void) int __init arch_clk_init(void)
...@@ -258,7 +261,7 @@ int __init arch_clk_init(void) ...@@ -258,7 +261,7 @@ int __init arch_clk_init(void)
ret = sh_clk_div6_register(div6_clks, DIV6_NR); ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret) if (!ret)
ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR); ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR);
return ret; return ret;
} }
This diff is collapsed.
This diff is collapsed.
...@@ -129,7 +129,7 @@ static struct clk_lookup lookups[] = { ...@@ -129,7 +129,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]), CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]),
CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]), CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]),
CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]), CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]),
CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]),
}; };
......
/*
* arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
*
* SH7722 hardware block support
*
* Copyright (C) 2009 Magnus Damm
*
* 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 Free Software Foundation; either version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <cpu/sh7722.h>
/* SH7722 registers */
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
/* SH7722 Power Domains */
enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
static struct hwblk_area sh7722_hwblk_area[] = {
[CORE_AREA] = HWBLK_AREA(0, 0),
[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
[SUB_AREA] = HWBLK_AREA(0, 0),
};
/* Table mapping HWBLK to Module Stop Bit and Power Domain */
static struct hwblk sh7722_hwblk[HWBLK_NR] = {
[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
[HWBLK_URAM] = HWBLK(MSTPCR0, 28, CORE_AREA),
[HWBLK_XYMEM] = HWBLK(MSTPCR0, 26, CORE_AREA),
[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
[HWBLK_DMAC] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
[HWBLK_TMU] = HWBLK(MSTPCR0, 15, CORE_AREA),
[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
[HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
[HWBLK_SCIF0] = HWBLK(MSTPCR0, 7, CORE_AREA),
[HWBLK_SCIF1] = HWBLK(MSTPCR0, 6, CORE_AREA),
[HWBLK_SCIF2] = HWBLK(MSTPCR0, 5, CORE_AREA),
[HWBLK_SIO] = HWBLK(MSTPCR0, 3, CORE_AREA),
[HWBLK_SIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
[HWBLK_SIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
[HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
[HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
[HWBLK_SDHI] = HWBLK(MSTPCR2, 18, CORE_AREA),
[HWBLK_SIM] = HWBLK(MSTPCR2, 16, CORE_AREA),
[HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
[HWBLK_TSIF] = HWBLK(MSTPCR2, 13, SUB_AREA),
[HWBLK_USBF] = HWBLK(MSTPCR2, 11, CORE_AREA),
[HWBLK_2DG] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
[HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
[HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
[HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
[HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
[HWBLK_VEU] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
};
static struct hwblk_info sh7722_hwblk_info = {
.areas = sh7722_hwblk_area,
.nr_areas = ARRAY_SIZE(sh7722_hwblk_area),
.hwblks = sh7722_hwblk,
.nr_hwblks = ARRAY_SIZE(sh7722_hwblk),
};
int arch_hwblk_sleep_mode(void)
{
if (!sh7722_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_STANDBY | SUSP_SH_SF;
if (!sh7722_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_SLEEP | SUSP_SH_SF;
return SUSP_SH_SLEEP;
}
int __init arch_hwblk_init(void)
{
return hwblk_register(&sh7722_hwblk_info);
}
/*
* arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
*
* SH7723 hardware block support
*
* Copyright (C) 2009 Magnus Damm
*
* 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 Free Software Foundation; either version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <cpu/sh7723.h>
/* SH7723 registers */
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
/* SH7723 Power Domains */
enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
static struct hwblk_area sh7723_hwblk_area[] = {
[CORE_AREA] = HWBLK_AREA(0, 0),
[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
[SUB_AREA] = HWBLK_AREA(0, 0),
};
/* Table mapping HWBLK to Module Stop Bit and Power Domain */
static struct hwblk sh7723_hwblk[HWBLK_NR] = {
[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
[HWBLK_L2C] = HWBLK(MSTPCR0, 28, CORE_AREA),
[HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
[HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
[HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
[HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
[HWBLK_SUBC] = HWBLK(MSTPCR0, 16, CORE_AREA),
[HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
[HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
[HWBLK_TMU1] = HWBLK(MSTPCR0, 11, CORE_AREA),
[HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
[HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
[HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
[HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
[HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
[HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
[HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
[HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
[HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
[HWBLK_MERAM] = HWBLK(MSTPCR0, 0, CORE_AREA),
[HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
[HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
[HWBLK_ATAPI] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
[HWBLK_ADC] = HWBLK(MSTPCR2, 27, CORE_AREA),
[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
[HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
[HWBLK_ICB] = HWBLK(MSTPCR2, 21, CORE_AREA_BM),
[HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
[HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
[HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
[HWBLK_USB] = HWBLK(MSTPCR2, 11, CORE_AREA),
[HWBLK_2DG] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
[HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
[HWBLK_VEU2H1] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
[HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
[HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
[HWBLK_VEU2H0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
};
static struct hwblk_info sh7723_hwblk_info = {
.areas = sh7723_hwblk_area,
.nr_areas = ARRAY_SIZE(sh7723_hwblk_area),
.hwblks = sh7723_hwblk,
.nr_hwblks = ARRAY_SIZE(sh7723_hwblk),
};
int arch_hwblk_sleep_mode(void)
{
if (!sh7723_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_STANDBY | SUSP_SH_SF;
if (!sh7723_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_SLEEP | SUSP_SH_SF;
return SUSP_SH_SLEEP;
}
int __init arch_hwblk_init(void)
{
return hwblk_register(&sh7723_hwblk_info);
}
/*
* arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
*
* SH7724 hardware block support
*
* Copyright (C) 2009 Magnus Damm
*
* 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 Free Software Foundation; either version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <cpu/sh7724.h>
/* SH7724 registers */
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
/* SH7724 Power Domains */
enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
static struct hwblk_area sh7724_hwblk_area[] = {
[CORE_AREA] = HWBLK_AREA(0, 0),
[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
[SUB_AREA] = HWBLK_AREA(0, 0),
};
/* Table mapping HWBLK to Module Stop Bit and Power Domain */
static struct hwblk sh7724_hwblk[HWBLK_NR] = {
[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
[HWBLK_RSMEM] = HWBLK(MSTPCR0, 28, CORE_AREA),
[HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
[HWBLK_L2C] = HWBLK(MSTPCR0, 26, CORE_AREA),
[HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
[HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
[HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
[HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
[HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
[HWBLK_TMU1] = HWBLK(MSTPCR0, 10, CORE_AREA),
[HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
[HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
[HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
[HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
[HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
[HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
[HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
[HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
[HWBLK_KEYSC] = HWBLK(MSTPCR1, 12, SUB_AREA),
[HWBLK_RTC] = HWBLK(MSTPCR1, 11, SUB_AREA),
[HWBLK_IIC0] = HWBLK(MSTPCR1, 9, CORE_AREA),
[HWBLK_IIC1] = HWBLK(MSTPCR1, 8, CORE_AREA),
[HWBLK_MMC] = HWBLK(MSTPCR2, 29, CORE_AREA),
[HWBLK_ETHER] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
[HWBLK_ATAPI] = HWBLK(MSTPCR2, 26, CORE_AREA_BM),
[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
[HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
[HWBLK_USB1] = HWBLK(MSTPCR2, 21, CORE_AREA),
[HWBLK_USB0] = HWBLK(MSTPCR2, 20, CORE_AREA),
[HWBLK_2DG] = HWBLK(MSTPCR2, 19, CORE_AREA_BM),
[HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
[HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
[HWBLK_VEU1] = HWBLK(MSTPCR2, 15, CORE_AREA_BM),
[HWBLK_CEU1] = HWBLK(MSTPCR2, 13, CORE_AREA_BM),
[HWBLK_BEU1] = HWBLK(MSTPCR2, 12, CORE_AREA_BM),
[HWBLK_2DDMAC] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
[HWBLK_SPU] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
[HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
[HWBLK_BEU0] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
[HWBLK_CEU0] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
[HWBLK_VEU0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
};
static struct hwblk_info sh7724_hwblk_info = {
.areas = sh7724_hwblk_area,
.nr_areas = ARRAY_SIZE(sh7724_hwblk_area),
.hwblks = sh7724_hwblk,
.nr_hwblks = ARRAY_SIZE(sh7724_hwblk),
};
int arch_hwblk_sleep_mode(void)
{
if (!sh7724_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_STANDBY | SUSP_SH_SF;
if (!sh7724_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
return SUSP_SH_SLEEP | SUSP_SH_SF;
return SUSP_SH_SLEEP;
}
int __init arch_hwblk_init(void)
{
return hwblk_register(&sh7724_hwblk_info);
}
...@@ -146,7 +146,7 @@ static struct resource sh7722_dmae_resources[] = { ...@@ -146,7 +146,7 @@ static struct resource sh7722_dmae_resources[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
/* DMA error IRQ */ .name = "error_irq",
.start = 78, .start = 78,
.end = 78, .end = 78,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
...@@ -173,9 +173,6 @@ struct platform_device dma_device = { ...@@ -173,9 +173,6 @@ struct platform_device dma_device = {
.dev = { .dev = {
.platform_data = &dma_platform_data, .platform_data = &dma_platform_data,
}, },
.archdata = {
.hwblk_id = HWBLK_DMAC,
},
}; };
/* Serial */ /* Serial */
...@@ -264,9 +261,6 @@ static struct platform_device rtc_device = { ...@@ -264,9 +261,6 @@ static struct platform_device rtc_device = {
.id = -1, .id = -1,
.num_resources = ARRAY_SIZE(rtc_resources), .num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources, .resource = rtc_resources,
.archdata = {
.hwblk_id = HWBLK_RTC,
},
}; };
static struct m66592_platdata usbf_platdata = { static struct m66592_platdata usbf_platdata = {
...@@ -297,9 +291,6 @@ static struct platform_device usbf_device = { ...@@ -297,9 +291,6 @@ static struct platform_device usbf_device = {
}, },
.num_resources = ARRAY_SIZE(usbf_resources), .num_resources = ARRAY_SIZE(usbf_resources),
.resource = usbf_resources, .resource = usbf_resources,
.archdata = {
.hwblk_id = HWBLK_USBF,
},
}; };
static struct resource iic_resources[] = { static struct resource iic_resources[] = {
...@@ -321,9 +312,6 @@ static struct platform_device iic_device = { ...@@ -321,9 +312,6 @@ static struct platform_device iic_device = {
.id = 0, /* "i2c0" clock */ .id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources), .num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources, .resource = iic_resources,
.archdata = {
.hwblk_id = HWBLK_IIC,
},
}; };
static struct uio_info vpu_platform_data = { static struct uio_info vpu_platform_data = {
...@@ -352,9 +340,6 @@ static struct platform_device vpu_device = { ...@@ -352,9 +340,6 @@ static struct platform_device vpu_device = {
}, },
.resource = vpu_resources, .resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources), .num_resources = ARRAY_SIZE(vpu_resources),
.archdata = {
.hwblk_id = HWBLK_VPU,
},
}; };
static struct uio_info veu_platform_data = { static struct uio_info veu_platform_data = {
...@@ -383,9 +368,6 @@ static struct platform_device veu_device = { ...@@ -383,9 +368,6 @@ static struct platform_device veu_device = {
}, },
.resource = veu_resources, .resource = veu_resources,
.num_resources = ARRAY_SIZE(veu_resources), .num_resources = ARRAY_SIZE(veu_resources),
.archdata = {
.hwblk_id = HWBLK_VEU,
},
}; };
static struct uio_info jpu_platform_data = { static struct uio_info jpu_platform_data = {
...@@ -414,9 +396,6 @@ static struct platform_device jpu_device = { ...@@ -414,9 +396,6 @@ static struct platform_device jpu_device = {
}, },
.resource = jpu_resources, .resource = jpu_resources,
.num_resources = ARRAY_SIZE(jpu_resources), .num_resources = ARRAY_SIZE(jpu_resources),
.archdata = {
.hwblk_id = HWBLK_JPU,
},
}; };
static struct sh_timer_config cmt_platform_data = { static struct sh_timer_config cmt_platform_data = {
...@@ -446,9 +425,6 @@ static struct platform_device cmt_device = { ...@@ -446,9 +425,6 @@ static struct platform_device cmt_device = {
}, },
.resource = cmt_resources, .resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources), .num_resources = ARRAY_SIZE(cmt_resources),
.archdata = {
.hwblk_id = HWBLK_CMT,
},
}; };
static struct sh_timer_config tmu0_platform_data = { static struct sh_timer_config tmu0_platform_data = {
...@@ -477,9 +453,6 @@ static struct platform_device tmu0_device = { ...@@ -477,9 +453,6 @@ static struct platform_device tmu0_device = {
}, },
.resource = tmu0_resources, .resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources), .num_resources = ARRAY_SIZE(tmu0_resources),
.archdata = {
.hwblk_id = HWBLK_TMU,
},
}; };
static struct sh_timer_config tmu1_platform_data = { static struct sh_timer_config tmu1_platform_data = {
...@@ -508,9 +481,6 @@ static struct platform_device tmu1_device = { ...@@ -508,9 +481,6 @@ static struct platform_device tmu1_device = {
}, },
.resource = tmu1_resources, .resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources), .num_resources = ARRAY_SIZE(tmu1_resources),
.archdata = {
.hwblk_id = HWBLK_TMU,
},
}; };
static struct sh_timer_config tmu2_platform_data = { static struct sh_timer_config tmu2_platform_data = {
...@@ -538,9 +508,6 @@ static struct platform_device tmu2_device = { ...@@ -538,9 +508,6 @@ static struct platform_device tmu2_device = {
}, },
.resource = tmu2_resources, .resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources), .num_resources = ARRAY_SIZE(tmu2_resources),
.archdata = {
.hwblk_id = HWBLK_TMU,
},
}; };
static struct siu_platform siu_platform_data = { static struct siu_platform siu_platform_data = {
...@@ -571,9 +538,6 @@ static struct platform_device siu_device = { ...@@ -571,9 +538,6 @@ static struct platform_device siu_device = {
}, },
.resource = siu_resources, .resource = siu_resources,
.num_resources = ARRAY_SIZE(siu_resources), .num_resources = ARRAY_SIZE(siu_resources),
.archdata = {
.hwblk_id = HWBLK_SIU,
},
}; };
static struct platform_device *sh7722_devices[] __initdata = { static struct platform_device *sh7722_devices[] __initdata = {
......
...@@ -158,9 +158,6 @@ static struct platform_device vpu_device = { ...@@ -158,9 +158,6 @@ static struct platform_device vpu_device = {
}, },
.resource = vpu_resources, .resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources), .num_resources = ARRAY_SIZE(vpu_resources),
.archdata = {
.hwblk_id = HWBLK_VPU,
},
}; };
static struct uio_info veu0_platform_data = { static struct uio_info veu0_platform_data = {
...@@ -189,9 +186,6 @@ static struct platform_device veu0_device = { ...@@ -189,9 +186,6 @@ static struct platform_device veu0_device = {
}, },
.resource = veu0_resources, .resource = veu0_resources,
.num_resources = ARRAY_SIZE(veu0_resources), .num_resources = ARRAY_SIZE(veu0_resources),
.archdata = {
.hwblk_id = HWBLK_VEU2H0,
},
}; };
static struct uio_info veu1_platform_data = { static struct uio_info veu1_platform_data = {
...@@ -220,9 +214,6 @@ static struct platform_device veu1_device = { ...@@ -220,9 +214,6 @@ static struct platform_device veu1_device = {
}, },
.resource = veu1_resources, .resource = veu1_resources,
.num_resources = ARRAY_SIZE(veu1_resources), .num_resources = ARRAY_SIZE(veu1_resources),
.archdata = {
.hwblk_id = HWBLK_VEU2H1,
},
}; };
static struct sh_timer_config cmt_platform_data = { static struct sh_timer_config cmt_platform_data = {
...@@ -252,9 +243,6 @@ static struct platform_device cmt_device = { ...@@ -252,9 +243,6 @@ static struct platform_device cmt_device = {
}, },
.resource = cmt_resources, .resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources), .num_resources = ARRAY_SIZE(cmt_resources),
.archdata = {
.hwblk_id = HWBLK_CMT,
},
}; };
static struct sh_timer_config tmu0_platform_data = { static struct sh_timer_config tmu0_platform_data = {
...@@ -283,9 +271,6 @@ static struct platform_device tmu0_device = { ...@@ -283,9 +271,6 @@ static struct platform_device tmu0_device = {
}, },
.resource = tmu0_resources, .resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources), .num_resources = ARRAY_SIZE(tmu0_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
}; };
static struct sh_timer_config tmu1_platform_data = { static struct sh_timer_config tmu1_platform_data = {
...@@ -314,9 +299,6 @@ static struct platform_device tmu1_device = { ...@@ -314,9 +299,6 @@ static struct platform_device tmu1_device = {
}, },
.resource = tmu1_resources, .resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources), .num_resources = ARRAY_SIZE(tmu1_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
}; };
static struct sh_timer_config tmu2_platform_data = { static struct sh_timer_config tmu2_platform_data = {
...@@ -344,9 +326,6 @@ static struct platform_device tmu2_device = { ...@@ -344,9 +326,6 @@ static struct platform_device tmu2_device = {
}, },
.resource = tmu2_resources, .resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources), .num_resources = ARRAY_SIZE(tmu2_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
}; };
static struct sh_timer_config tmu3_platform_data = { static struct sh_timer_config tmu3_platform_data = {
...@@ -374,9 +353,6 @@ static struct platform_device tmu3_device = { ...@@ -374,9 +353,6 @@ static struct platform_device tmu3_device = {
}, },
.resource = tmu3_resources, .resource = tmu3_resources,
.num_resources = ARRAY_SIZE(tmu3_resources), .num_resources = ARRAY_SIZE(tmu3_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
}; };
static struct sh_timer_config tmu4_platform_data = { static struct sh_timer_config tmu4_platform_data = {
...@@ -404,9 +380,6 @@ static struct platform_device tmu4_device = { ...@@ -404,9 +380,6 @@ static struct platform_device tmu4_device = {
}, },
.resource = tmu4_resources, .resource = tmu4_resources,
.num_resources = ARRAY_SIZE(tmu4_resources), .num_resources = ARRAY_SIZE(tmu4_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
}; };
static struct sh_timer_config tmu5_platform_data = { static struct sh_timer_config tmu5_platform_data = {
...@@ -434,9 +407,6 @@ static struct platform_device tmu5_device = { ...@@ -434,9 +407,6 @@ static struct platform_device tmu5_device = {
}, },
.resource = tmu5_resources, .resource = tmu5_resources,
.num_resources = ARRAY_SIZE(tmu5_resources), .num_resources = ARRAY_SIZE(tmu5_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
}; };
static struct resource rtc_resources[] = { static struct resource rtc_resources[] = {
...@@ -467,9 +437,6 @@ static struct platform_device rtc_device = { ...@@ -467,9 +437,6 @@ static struct platform_device rtc_device = {
.id = -1, .id = -1,
.num_resources = ARRAY_SIZE(rtc_resources), .num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources, .resource = rtc_resources,
.archdata = {
.hwblk_id = HWBLK_RTC,
},
}; };
static struct r8a66597_platdata r8a66597_data = { static struct r8a66597_platdata r8a66597_data = {
...@@ -499,9 +466,6 @@ static struct platform_device sh7723_usb_host_device = { ...@@ -499,9 +466,6 @@ static struct platform_device sh7723_usb_host_device = {
}, },
.num_resources = ARRAY_SIZE(sh7723_usb_host_resources), .num_resources = ARRAY_SIZE(sh7723_usb_host_resources),
.resource = sh7723_usb_host_resources, .resource = sh7723_usb_host_resources,
.archdata = {
.hwblk_id = HWBLK_USB,
},
}; };
static struct resource iic_resources[] = { static struct resource iic_resources[] = {
...@@ -523,9 +487,6 @@ static struct platform_device iic_device = { ...@@ -523,9 +487,6 @@ static struct platform_device iic_device = {
.id = 0, /* "i2c0" clock */ .id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources), .num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources, .resource = iic_resources,
.archdata = {
.hwblk_id = HWBLK_IIC,
},
}; };
static struct platform_device *sh7723_devices[] __initdata = { static struct platform_device *sh7723_devices[] __initdata = {
......
...@@ -214,7 +214,7 @@ static struct resource sh7724_dmae0_resources[] = { ...@@ -214,7 +214,7 @@ static struct resource sh7724_dmae0_resources[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
/* DMA error IRQ */ .name = "error_irq",
.start = 78, .start = 78,
.end = 78, .end = 78,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
...@@ -248,7 +248,7 @@ static struct resource sh7724_dmae1_resources[] = { ...@@ -248,7 +248,7 @@ static struct resource sh7724_dmae1_resources[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
/* DMA error IRQ */ .name = "error_irq",
.start = 74, .start = 74,
.end = 74, .end = 74,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
...@@ -275,9 +275,6 @@ static struct platform_device dma0_device = { ...@@ -275,9 +275,6 @@ static struct platform_device dma0_device = {
.dev = { .dev = {
.platform_data = &dma_platform_data, .platform_data = &dma_platform_data,
}, },
.archdata = {
.hwblk_id = HWBLK_DMAC0,
},
}; };
static struct platform_device dma1_device = { static struct platform_device dma1_device = {
...@@ -288,9 +285,6 @@ static struct platform_device dma1_device = { ...@@ -288,9 +285,6 @@ static struct platform_device dma1_device = {
.dev = { .dev = {
.platform_data = &dma_platform_data, .platform_data = &dma_platform_data,
}, },
.archdata = {
.hwblk_id = HWBLK_DMAC1,
},
}; };
/* Serial */ /* Serial */
...@@ -434,9 +428,6 @@ static struct platform_device rtc_device = { ...@@ -434,9 +428,6 @@ static struct platform_device rtc_device = {
.id = -1, .id = -1,
.num_resources = ARRAY_SIZE(rtc_resources), .num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources, .resource = rtc_resources,
.archdata = {
.hwblk_id = HWBLK_RTC,
},
}; };
/* I2C0 */ /* I2C0 */
...@@ -459,9 +450,6 @@ static struct platform_device iic0_device = { ...@@ -459,9 +450,6 @@ static struct platform_device iic0_device = {
.id = 0, /* "i2c0" clock */ .id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic0_resources), .num_resources = ARRAY_SIZE(iic0_resources),
.resource = iic0_resources, .resource = iic0_resources,
.archdata = {
.hwblk_id = HWBLK_IIC0,
},
}; };
/* I2C1 */ /* I2C1 */
...@@ -484,9 +472,6 @@ static struct platform_device iic1_device = { ...@@ -484,9 +472,6 @@ static struct platform_device iic1_device = {
.id = 1, /* "i2c1" clock */ .id = 1, /* "i2c1" clock */
.num_resources = ARRAY_SIZE(iic1_resources), .num_resources = ARRAY_SIZE(iic1_resources),
.resource = iic1_resources, .resource = iic1_resources,
.archdata = {
.hwblk_id = HWBLK_IIC1,
},
}; };
/* VPU */ /* VPU */
...@@ -516,9 +501,6 @@ static struct platform_device vpu_device = { ...@@ -516,9 +501,6 @@ static struct platform_device vpu_device = {
}, },
.resource = vpu_resources, .resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources), .num_resources = ARRAY_SIZE(vpu_resources),
.archdata = {
.hwblk_id = HWBLK_VPU,
},
}; };
/* VEU0 */ /* VEU0 */
...@@ -548,9 +530,6 @@ static struct platform_device veu0_device = { ...@@ -548,9 +530,6 @@ static struct platform_device veu0_device = {
}, },
.resource = veu0_resources, .resource = veu0_resources,
.num_resources = ARRAY_SIZE(veu0_resources), .num_resources = ARRAY_SIZE(veu0_resources),
.archdata = {
.hwblk_id = HWBLK_VEU0,
},
}; };
/* VEU1 */ /* VEU1 */
...@@ -580,9 +559,6 @@ static struct platform_device veu1_device = { ...@@ -580,9 +559,6 @@ static struct platform_device veu1_device = {
}, },
.resource = veu1_resources, .resource = veu1_resources,
.num_resources = ARRAY_SIZE(veu1_resources), .num_resources = ARRAY_SIZE(veu1_resources),
.archdata = {
.hwblk_id = HWBLK_VEU1,
},
}; };
/* BEU0 */ /* BEU0 */
...@@ -612,9 +588,6 @@ static struct platform_device beu0_device = { ...@@ -612,9 +588,6 @@ static struct platform_device beu0_device = {
}, },
.resource = beu0_resources, .resource = beu0_resources,
.num_resources = ARRAY_SIZE(beu0_resources), .num_resources = ARRAY_SIZE(beu0_resources),
.archdata = {
.hwblk_id = HWBLK_BEU0,
},
}; };
/* BEU1 */ /* BEU1 */
...@@ -644,9 +617,6 @@ static struct platform_device beu1_device = { ...@@ -644,9 +617,6 @@ static struct platform_device beu1_device = {
}, },
.resource = beu1_resources, .resource = beu1_resources,
.num_resources = ARRAY_SIZE(beu1_resources), .num_resources = ARRAY_SIZE(beu1_resources),
.archdata = {
.hwblk_id = HWBLK_BEU1,
},
}; };
static struct sh_timer_config cmt_platform_data = { static struct sh_timer_config cmt_platform_data = {
...@@ -676,9 +646,6 @@ static struct platform_device cmt_device = { ...@@ -676,9 +646,6 @@ static struct platform_device cmt_device = {
}, },
.resource = cmt_resources, .resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources), .num_resources = ARRAY_SIZE(cmt_resources),
.archdata = {
.hwblk_id = HWBLK_CMT,
},
}; };
static struct sh_timer_config tmu0_platform_data = { static struct sh_timer_config tmu0_platform_data = {
...@@ -707,9 +674,6 @@ static struct platform_device tmu0_device = { ...@@ -707,9 +674,6 @@ static struct platform_device tmu0_device = {
}, },
.resource = tmu0_resources, .resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources), .num_resources = ARRAY_SIZE(tmu0_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
}; };
static struct sh_timer_config tmu1_platform_data = { static struct sh_timer_config tmu1_platform_data = {
...@@ -738,9 +702,6 @@ static struct platform_device tmu1_device = { ...@@ -738,9 +702,6 @@ static struct platform_device tmu1_device = {
}, },
.resource = tmu1_resources, .resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources), .num_resources = ARRAY_SIZE(tmu1_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
}; };
static struct sh_timer_config tmu2_platform_data = { static struct sh_timer_config tmu2_platform_data = {
...@@ -768,9 +729,6 @@ static struct platform_device tmu2_device = { ...@@ -768,9 +729,6 @@ static struct platform_device tmu2_device = {
}, },
.resource = tmu2_resources, .resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources), .num_resources = ARRAY_SIZE(tmu2_resources),
.archdata = {
.hwblk_id = HWBLK_TMU0,
},
}; };
...@@ -799,9 +757,6 @@ static struct platform_device tmu3_device = { ...@@ -799,9 +757,6 @@ static struct platform_device tmu3_device = {
}, },
.resource = tmu3_resources, .resource = tmu3_resources,
.num_resources = ARRAY_SIZE(tmu3_resources), .num_resources = ARRAY_SIZE(tmu3_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
}; };
static struct sh_timer_config tmu4_platform_data = { static struct sh_timer_config tmu4_platform_data = {
...@@ -829,9 +784,6 @@ static struct platform_device tmu4_device = { ...@@ -829,9 +784,6 @@ static struct platform_device tmu4_device = {
}, },
.resource = tmu4_resources, .resource = tmu4_resources,
.num_resources = ARRAY_SIZE(tmu4_resources), .num_resources = ARRAY_SIZE(tmu4_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
}; };
static struct sh_timer_config tmu5_platform_data = { static struct sh_timer_config tmu5_platform_data = {
...@@ -859,9 +811,6 @@ static struct platform_device tmu5_device = { ...@@ -859,9 +811,6 @@ static struct platform_device tmu5_device = {
}, },
.resource = tmu5_resources, .resource = tmu5_resources,
.num_resources = ARRAY_SIZE(tmu5_resources), .num_resources = ARRAY_SIZE(tmu5_resources),
.archdata = {
.hwblk_id = HWBLK_TMU1,
},
}; };
/* JPU */ /* JPU */
...@@ -891,9 +840,6 @@ static struct platform_device jpu_device = { ...@@ -891,9 +840,6 @@ static struct platform_device jpu_device = {
}, },
.resource = jpu_resources, .resource = jpu_resources,
.num_resources = ARRAY_SIZE(jpu_resources), .num_resources = ARRAY_SIZE(jpu_resources),
.archdata = {
.hwblk_id = HWBLK_JPU,
},
}; };
/* SPU2DSP0 */ /* SPU2DSP0 */
...@@ -923,9 +869,6 @@ static struct platform_device spu0_device = { ...@@ -923,9 +869,6 @@ static struct platform_device spu0_device = {
}, },
.resource = spu0_resources, .resource = spu0_resources,
.num_resources = ARRAY_SIZE(spu0_resources), .num_resources = ARRAY_SIZE(spu0_resources),
.archdata = {
.hwblk_id = HWBLK_SPU,
},
}; };
/* SPU2DSP1 */ /* SPU2DSP1 */
...@@ -955,9 +898,6 @@ static struct platform_device spu1_device = { ...@@ -955,9 +898,6 @@ static struct platform_device spu1_device = {
}, },
.resource = spu1_resources, .resource = spu1_resources,
.num_resources = ARRAY_SIZE(spu1_resources), .num_resources = ARRAY_SIZE(spu1_resources),
.archdata = {
.hwblk_id = HWBLK_SPU,
},
}; };
static struct platform_device *sh7724_devices[] __initdata = { static struct platform_device *sh7724_devices[] __initdata = {
......
...@@ -465,6 +465,7 @@ static struct resource sh7757_dmae0_resources[] = { ...@@ -465,6 +465,7 @@ static struct resource sh7757_dmae0_resources[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
.name = "error_irq",
.start = 34, .start = 34,
.end = 34, .end = 34,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
...@@ -486,7 +487,7 @@ static struct resource sh7757_dmae1_resources[] = { ...@@ -486,7 +487,7 @@ static struct resource sh7757_dmae1_resources[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
/* DMA error */ .name = "error_irq",
.start = 34, .start = 34,
.end = 34, .end = 34,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
...@@ -556,7 +557,7 @@ static struct resource sh7757_dmae2_resources[] = { ...@@ -556,7 +557,7 @@ static struct resource sh7757_dmae2_resources[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
/* DMA error */ .name = "error_irq",
.start = 323, .start = 323,
.end = 323, .end = 323,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
...@@ -590,7 +591,7 @@ static struct resource sh7757_dmae3_resources[] = { ...@@ -590,7 +591,7 @@ static struct resource sh7757_dmae3_resources[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
/* DMA error */ .name = "error_irq",
.start = 324, .start = 324,
.end = 324, .end = 324,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
......
...@@ -322,6 +322,7 @@ static struct resource sh7780_dmae0_resources[] = { ...@@ -322,6 +322,7 @@ static struct resource sh7780_dmae0_resources[] = {
}, },
{ {
/* Real DMA error IRQ is 38, and channel IRQs are 34-37, 44-45 */ /* Real DMA error IRQ is 38, and channel IRQs are 34-37, 44-45 */
.name = "error_irq",
.start = 34, .start = 34,
.end = 34, .end = 34,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
...@@ -338,6 +339,7 @@ static struct resource sh7780_dmae1_resources[] = { ...@@ -338,6 +339,7 @@ static struct resource sh7780_dmae1_resources[] = {
/* DMAC1 has no DMARS */ /* DMAC1 has no DMARS */
{ {
/* Real DMA error IRQ is 38, and channel IRQs are 46-47, 92-95 */ /* Real DMA error IRQ is 38, and channel IRQs are 46-47, 92-95 */
.name = "error_irq",
.start = 46, .start = 46,
.end = 46, .end = 46,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
......
...@@ -376,6 +376,7 @@ static struct resource sh7785_dmae0_resources[] = { ...@@ -376,6 +376,7 @@ static struct resource sh7785_dmae0_resources[] = {
}, },
{ {
/* Real DMA error IRQ is 39, and channel IRQs are 33-38 */ /* Real DMA error IRQ is 39, and channel IRQs are 33-38 */
.name = "error_irq",
.start = 33, .start = 33,
.end = 33, .end = 33,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
...@@ -392,6 +393,7 @@ static struct resource sh7785_dmae1_resources[] = { ...@@ -392,6 +393,7 @@ static struct resource sh7785_dmae1_resources[] = {
/* DMAC1 has no DMARS */ /* DMAC1 has no DMARS */
{ {
/* Real DMA error IRQ is 58, and channel IRQs are 52-57 */ /* Real DMA error IRQ is 58, and channel IRQs are 52-57 */
.name = "error_irq",
.start = 52, .start = 52,
.end = 52, .end = 52,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
......
...@@ -518,7 +518,7 @@ static struct resource dmac0_resources[] = { ...@@ -518,7 +518,7 @@ static struct resource dmac0_resources[] = {
.end = 0xfe00900b, .end = 0xfe00900b,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, { }, {
/* DMA error IRQ */ .name = "error_irq",
.start = evt2irq(0x5c0), .start = evt2irq(0x5c0),
.end = evt2irq(0x5c0), .end = evt2irq(0x5c0),
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
......
...@@ -5,4 +5,3 @@ ...@@ -5,4 +5,3 @@
# Power Management & Sleep mode # Power Management & Sleep mode
obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_PM_RUNTIME) += pm_runtime.o
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <linux/export.h> #include <linux/export.h>
#include <asm/suspend.h> #include <asm/suspend.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/hwblk.h>
static unsigned long cpuidle_mode[] = { static unsigned long cpuidle_mode[] = {
SUSP_SH_SLEEP, /* regular sleep mode */ SUSP_SH_SLEEP, /* regular sleep mode */
...@@ -29,7 +28,7 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev, ...@@ -29,7 +28,7 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,
struct cpuidle_driver *drv, struct cpuidle_driver *drv,
int index) int index)
{ {
unsigned long allowed_mode = arch_hwblk_sleep_mode(); unsigned long allowed_mode = SUSP_SH_SLEEP;
ktime_t before, after; ktime_t before, after;
int requested_state = index; int requested_state = index;
int allowed_state; int allowed_state;
......
/*
* arch/sh/kernel/cpu/shmobile/pm_runtime.c
*
* Runtime PM support code for SuperH Mobile
*
* Copyright (C) 2009 Magnus Damm
*
* 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.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <asm/hwblk.h>
static DEFINE_SPINLOCK(hwblk_lock);
static LIST_HEAD(hwblk_idle_list);
static struct work_struct hwblk_work;
extern struct hwblk_info *hwblk_info;
static void platform_pm_runtime_not_idle(struct platform_device *pdev)
{
unsigned long flags;
/* remove device from idle list */
spin_lock_irqsave(&hwblk_lock, flags);
if (test_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags)) {
list_del(&pdev->archdata.entry);
__clear_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags);
}
spin_unlock_irqrestore(&hwblk_lock, flags);
}
static int __platform_pm_runtime_resume(struct platform_device *pdev)
{
struct device *d = &pdev->dev;
struct pdev_archdata *ad = &pdev->archdata;
int hwblk = ad->hwblk_id;
int ret = -ENOSYS;
dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk);
if (d->driver) {
hwblk_enable(hwblk_info, hwblk);
ret = 0;
if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) {
if (d->driver->pm && d->driver->pm->runtime_resume)
ret = d->driver->pm->runtime_resume(d);
if (!ret)
clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
else
hwblk_disable(hwblk_info, hwblk);
}
}
dev_dbg(d, "__platform_pm_runtime_resume() [%d] - returns %d\n",
hwblk, ret);
return ret;
}
static int __platform_pm_runtime_suspend(struct platform_device *pdev)
{
struct device *d = &pdev->dev;
struct pdev_archdata *ad = &pdev->archdata;
int hwblk = ad->hwblk_id;
int ret = -ENOSYS;
dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk);
if (d->driver) {
BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags));
ret = 0;
if (d->driver->pm && d->driver->pm->runtime_suspend) {
hwblk_enable(hwblk_info, hwblk);
ret = d->driver->pm->runtime_suspend(d);
hwblk_disable(hwblk_info, hwblk);
}
if (!ret) {
set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
platform_pm_runtime_not_idle(pdev);
hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
}
}
dev_dbg(d, "__platform_pm_runtime_suspend() [%d] - returns %d\n",
hwblk, ret);
return ret;
}
static void platform_pm_runtime_work(struct work_struct *work)
{
struct platform_device *pdev;
unsigned long flags;
int ret;
/* go through the idle list and suspend one device at a time */
do {
spin_lock_irqsave(&hwblk_lock, flags);
if (list_empty(&hwblk_idle_list))
pdev = NULL;
else
pdev = list_first_entry(&hwblk_idle_list,
struct platform_device,
archdata.entry);
spin_unlock_irqrestore(&hwblk_lock, flags);
if (pdev) {
mutex_lock(&pdev->archdata.mutex);
ret = __platform_pm_runtime_suspend(pdev);
/* at this point the platform device may be:
* suspended: ret = 0, FLAG_SUSP set, clock stopped
* failed: ret < 0, FLAG_IDLE set, clock stopped
*/
mutex_unlock(&pdev->archdata.mutex);
} else {
ret = -ENODEV;
}
} while (!ret);
}
/* this function gets called from cpuidle context when all devices in the
* main power domain are unused but some are counted as idle, ie the hwblk
* counter values are (HWBLK_CNT_USAGE == 0) && (HWBLK_CNT_IDLE != 0)
*/
void platform_pm_runtime_suspend_idle(void)
{
queue_work(pm_wq, &hwblk_work);
}
static int default_platform_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct pdev_archdata *ad = &pdev->archdata;
unsigned long flags;
int hwblk = ad->hwblk_id;
int ret = 0;
dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
/* ignore off-chip platform devices */
if (!hwblk)
goto out;
/* interrupt context not allowed */
might_sleep();
/* catch misconfigured drivers not starting with resume */
if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &ad->flags)) {
ret = -EINVAL;
goto out;
}
/* serialize */
mutex_lock(&ad->mutex);
/* disable clock */
hwblk_disable(hwblk_info, hwblk);
/* put device on idle list */
spin_lock_irqsave(&hwblk_lock, flags);
list_add_tail(&ad->entry, &hwblk_idle_list);
__set_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags);
spin_unlock_irqrestore(&hwblk_lock, flags);
/* increase idle count */
hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_IDLE);
/* at this point the platform device is:
* idle: ret = 0, FLAG_IDLE set, clock stopped
*/
mutex_unlock(&ad->mutex);
out:
dev_dbg(dev, "%s() [%d] returns %d\n",
__func__, hwblk, ret);
return ret;
}
static int default_platform_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct pdev_archdata *ad = &pdev->archdata;
int hwblk = ad->hwblk_id;
int ret = 0;
dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
/* ignore off-chip platform devices */
if (!hwblk)
goto out;
/* interrupt context not allowed */
might_sleep();
/* serialize */
mutex_lock(&ad->mutex);
/* make sure device is removed from idle list */
platform_pm_runtime_not_idle(pdev);
/* decrease idle count */
if (!test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags) &&
!test_bit(PDEV_ARCHDATA_FLAG_SUSP, &pdev->archdata.flags))
hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
/* resume the device if needed */
ret = __platform_pm_runtime_resume(pdev);
/* the driver has been initialized now, so clear the init flag */
clear_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
/* at this point the platform device may be:
* resumed: ret = 0, flags = 0, clock started
* failed: ret < 0, FLAG_SUSP set, clock stopped
*/
mutex_unlock(&ad->mutex);
out:
dev_dbg(dev, "%s() [%d] returns %d\n",
__func__, hwblk, ret);
return ret;
}
static int default_platform_runtime_idle(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
int hwblk = pdev->archdata.hwblk_id;
int ret = 0;
dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
/* ignore off-chip platform devices */
if (!hwblk)
goto out;
/* interrupt context not allowed, use pm_runtime_put()! */
might_sleep();
/* suspend synchronously to disable clocks immediately */
ret = pm_runtime_suspend(dev);
out:
dev_dbg(dev, "%s() [%d] done!\n", __func__, hwblk);
return ret;
}
static struct dev_pm_domain default_pm_domain = {
.ops = {
.runtime_suspend = default_platform_runtime_suspend,
.runtime_resume = default_platform_runtime_resume,
.runtime_idle = default_platform_runtime_idle,
USE_PLATFORM_PM_SLEEP_OPS
},
};
static int platform_bus_notify(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;
struct platform_device *pdev = to_platform_device(dev);
int hwblk = pdev->archdata.hwblk_id;
/* ignore off-chip platform devices */
if (!hwblk)
return 0;
switch (action) {
case BUS_NOTIFY_ADD_DEVICE:
INIT_LIST_HEAD(&pdev->archdata.entry);
mutex_init(&pdev->archdata.mutex);
/* platform devices without drivers should be disabled */
hwblk_enable(hwblk_info, hwblk);
hwblk_disable(hwblk_info, hwblk);
/* make sure driver re-inits itself once */
__set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
dev->pm_domain = &default_pm_domain;
break;
/* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */
case BUS_NOTIFY_BOUND_DRIVER:
/* keep track of number of devices in use per hwblk */
hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
break;
case BUS_NOTIFY_UNBOUND_DRIVER:
/* keep track of number of devices in use per hwblk */
hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
/* make sure driver re-inits itself once */
__set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
break;
case BUS_NOTIFY_DEL_DEVICE:
dev->pm_domain = NULL;
break;
}
return 0;
}
static struct notifier_block platform_bus_notifier = {
.notifier_call = platform_bus_notify
};
static int __init sh_pm_runtime_init(void)
{
INIT_WORK(&hwblk_work, platform_pm_runtime_work);
bus_register_notifier(&platform_bus_type, &platform_bus_notifier);
return 0;
}
core_initcall(sh_pm_runtime_init);
...@@ -145,6 +145,7 @@ work_notifysig: ...@@ -145,6 +145,7 @@ work_notifysig:
mov r15, r4 mov r15, r4
mov r12, r5 ! set arg1(save_r0) mov r12, r5 ! set arg1(save_r0)
mov r0, r6 mov r0, r6
sti
mov.l 2f, r1 mov.l 2f, r1
mov.l 3f, r0 mov.l 3f, r0
jmp @r1 jmp @r1
......
...@@ -588,9 +588,6 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) ...@@ -588,9 +588,6 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
if (!user_mode(regs)) if (!user_mode(regs))
return; return;
if (try_to_freeze())
goto no_signal;
if (current_thread_info()->status & TS_RESTORE_SIGMASK) if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = &current->saved_sigmask; oldset = &current->saved_sigmask;
else else
...@@ -618,7 +615,6 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) ...@@ -618,7 +615,6 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
return; return;
} }
no_signal:
/* Did we come from a system call? */ /* Did we come from a system call? */
if (regs->tra >= 0) { if (regs->tra >= 0) {
/* Restart the system call - no handlers present */ /* Restart the system call - no handlers present */
......
...@@ -98,9 +98,6 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -98,9 +98,6 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!user_mode(regs)) if (!user_mode(regs))
return 1; return 1;
if (try_to_freeze())
goto no_signal;
if (current_thread_info()->status & TS_RESTORE_SIGMASK) if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = &current->saved_sigmask; oldset = &current->saved_sigmask;
else if (!oldset) else if (!oldset)
...@@ -125,7 +122,6 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -125,7 +122,6 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
} }
} }
no_signal:
/* Did we come from a system call? */ /* Did we come from a system call? */
if (regs->syscall_nr >= 0) { if (regs->syscall_nr >= 0) {
/* Restart the system call - no handlers present */ /* Restart the system call - no handlers present */
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <asm/clock.h> #include <asm/clock.h>
#include <asm/hwblk.h>
#include <asm/rtc.h> #include <asm/rtc.h>
/* Dummy RTC ops */ /* Dummy RTC ops */
...@@ -110,7 +109,6 @@ void __init time_init(void) ...@@ -110,7 +109,6 @@ void __init time_init(void)
if (board_time_init) if (board_time_init)
board_time_init(); board_time_init();
hwblk_init();
clk_init(); clk_init();
late_time_init = sh_late_time_init; late_time_init = sh_late_time_init;
......
...@@ -15,35 +15,78 @@ ...@@ -15,35 +15,78 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/io.h> #include <asm/io.h>
/*
* The maximum number of pages we support up to when doing ranged dcache
* flushing. Anything exceeding this will simply flush the dcache in its
* entirety.
*/
#define MAX_OCACHE_PAGES 32
#define MAX_ICACHE_PAGES 32
static void sh2a_flush_oc_line(unsigned long v, int way)
{
unsigned long addr = (v & 0x000007f0) | (way << 11);
unsigned long data;
data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr);
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
data &= ~SH_CACHE_UPDATED;
__raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr);
}
}
static void sh2a_invalidate_line(unsigned long cache_addr, unsigned long v)
{
/* Set associative bit to hit all ways */
unsigned long addr = (v & 0x000007f0) | SH_CACHE_ASSOC;
__raw_writel((addr & CACHE_PHYSADDR_MASK), cache_addr | addr);
}
/*
* Write back the dirty D-caches, but not invalidate them.
*/
static void sh2a__flush_wback_region(void *start, int size) static void sh2a__flush_wback_region(void *start, int size)
{ {
#ifdef CONFIG_CACHE_WRITEBACK
unsigned long v; unsigned long v;
unsigned long begin, end; unsigned long begin, end;
unsigned long flags; unsigned long flags;
int nr_ways;
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
end = ((unsigned long)start + size + L1_CACHE_BYTES-1) end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
& ~(L1_CACHE_BYTES-1); & ~(L1_CACHE_BYTES-1);
nr_ways = current_cpu_data.dcache.ways;
local_irq_save(flags); local_irq_save(flags);
jump_to_uncached(); jump_to_uncached();
for (v = begin; v < end; v+=L1_CACHE_BYTES) { /* If there are too many pages then flush the entire cache */
unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0); if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
int way; begin = CACHE_OC_ADDRESS_ARRAY;
for (way = 0; way < 4; way++) { end = begin + (nr_ways * current_cpu_data.dcache.way_size);
unsigned long data = __raw_readl(addr | (way << 11));
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { for (v = begin; v < end; v += L1_CACHE_BYTES) {
data &= ~SH_CACHE_UPDATED; unsigned long data = __raw_readl(v);
__raw_writel(data, addr | (way << 11)); if (data & SH_CACHE_UPDATED)
__raw_writel(data & ~SH_CACHE_UPDATED, v);
} }
} else {
int way;
for (way = 0; way < nr_ways; way++) {
for (v = begin; v < end; v += L1_CACHE_BYTES)
sh2a_flush_oc_line(v, way);
} }
} }
back_to_cached(); back_to_cached();
local_irq_restore(flags); local_irq_restore(flags);
#endif
} }
/*
* Write back the dirty D-caches and invalidate them.
*/
static void sh2a__flush_purge_region(void *start, int size) static void sh2a__flush_purge_region(void *start, int size)
{ {
unsigned long v; unsigned long v;
...@@ -58,13 +101,22 @@ static void sh2a__flush_purge_region(void *start, int size) ...@@ -58,13 +101,22 @@ static void sh2a__flush_purge_region(void *start, int size)
jump_to_uncached(); jump_to_uncached();
for (v = begin; v < end; v+=L1_CACHE_BYTES) { for (v = begin; v < end; v+=L1_CACHE_BYTES) {
__raw_writel((v & CACHE_PHYSADDR_MASK), #ifdef CONFIG_CACHE_WRITEBACK
CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); int way;
int nr_ways = current_cpu_data.dcache.ways;
for (way = 0; way < nr_ways; way++)
sh2a_flush_oc_line(v, way);
#endif
sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v);
} }
back_to_cached(); back_to_cached();
local_irq_restore(flags); local_irq_restore(flags);
} }
/*
* Invalidate the D-caches, but no write back please
*/
static void sh2a__flush_invalidate_region(void *start, int size) static void sh2a__flush_invalidate_region(void *start, int size)
{ {
unsigned long v; unsigned long v;
...@@ -74,29 +126,25 @@ static void sh2a__flush_invalidate_region(void *start, int size) ...@@ -74,29 +126,25 @@ static void sh2a__flush_invalidate_region(void *start, int size)
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
end = ((unsigned long)start + size + L1_CACHE_BYTES-1) end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
& ~(L1_CACHE_BYTES-1); & ~(L1_CACHE_BYTES-1);
local_irq_save(flags); local_irq_save(flags);
jump_to_uncached(); jump_to_uncached();
#ifdef CONFIG_CACHE_WRITEBACK /* If there are too many pages then just blow the cache */
if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
__raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR); __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
/* I-cache invalidate */ } else {
for (v = begin; v < end; v+=L1_CACHE_BYTES) { for (v = begin; v < end; v += L1_CACHE_BYTES)
__raw_writel((v & CACHE_PHYSADDR_MASK), sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v);
CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
}
#else
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
__raw_writel((v & CACHE_PHYSADDR_MASK),
CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
__raw_writel((v & CACHE_PHYSADDR_MASK),
CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
} }
#endif
back_to_cached(); back_to_cached();
local_irq_restore(flags); local_irq_restore(flags);
} }
/* WBack O-Cache and flush I-Cache */ /*
* Write back the range of D-cache, and purge the I-cache.
*/
static void sh2a_flush_icache_range(void *args) static void sh2a_flush_icache_range(void *args)
{ {
struct flusher_data *data = args; struct flusher_data *data = args;
...@@ -107,23 +155,20 @@ static void sh2a_flush_icache_range(void *args) ...@@ -107,23 +155,20 @@ static void sh2a_flush_icache_range(void *args)
start = data->addr1 & ~(L1_CACHE_BYTES-1); start = data->addr1 & ~(L1_CACHE_BYTES-1);
end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
#ifdef CONFIG_CACHE_WRITEBACK
sh2a__flush_wback_region((void *)start, end-start);
#endif
local_irq_save(flags); local_irq_save(flags);
jump_to_uncached(); jump_to_uncached();
for (v = start; v < end; v+=L1_CACHE_BYTES) {
unsigned long addr = (v & 0x000007f0);
int way;
/* O-Cache writeback */
for (way = 0; way < 4; way++) {
unsigned long data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
data &= ~SH_CACHE_UPDATED;
__raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
}
}
/* I-Cache invalidate */ /* I-Cache invalidate */
__raw_writel(addr, /* If there are too many pages then just blow the cache */
CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008); if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
__raw_writel(__raw_readl(CCR) | CCR_ICACHE_INVALIDATE, CCR);
} else {
for (v = start; v < end; v += L1_CACHE_BYTES)
sh2a_invalidate_line(CACHE_IC_ADDRESS_ARRAY, v);
} }
back_to_cached(); back_to_cached();
......
...@@ -7,11 +7,4 @@ obj-$(CONFIG_HAVE_CLK) += clk/ ...@@ -7,11 +7,4 @@ obj-$(CONFIG_HAVE_CLK) += clk/
obj-$(CONFIG_MAPLE) += maple/ obj-$(CONFIG_MAPLE) += maple/
obj-$(CONFIG_SUPERHYWAY) += superhyway/ obj-$(CONFIG_SUPERHYWAY) += superhyway/
obj-$(CONFIG_GENERIC_GPIO) += pfc.o obj-$(CONFIG_GENERIC_GPIO) += pfc.o
obj-y += pm_runtime.o
#
# For the moment we only use this framework for ARM-based SH/R-Mobile
# platforms and generic SH. SH-based SH-Mobile platforms are still using
# an older framework that is pending up-porting, at which point this
# special casing can go away.
#
obj-$(CONFIG_SUPERH)$(CONFIG_ARCH_SHMOBILE) += pm_runtime.o
...@@ -355,7 +355,7 @@ static int clk_establish_mapping(struct clk *clk) ...@@ -355,7 +355,7 @@ static int clk_establish_mapping(struct clk *clk)
*/ */
if (!clk->parent) { if (!clk->parent) {
clk->mapping = &dummy_mapping; clk->mapping = &dummy_mapping;
return 0; goto out;
} }
/* /*
...@@ -384,6 +384,9 @@ static int clk_establish_mapping(struct clk *clk) ...@@ -384,6 +384,9 @@ static int clk_establish_mapping(struct clk *clk)
} }
clk->mapping = mapping; clk->mapping = mapping;
out:
clk->mapped_reg = clk->mapping->base;
clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys;
return 0; return 0;
} }
...@@ -402,10 +405,12 @@ static void clk_teardown_mapping(struct clk *clk) ...@@ -402,10 +405,12 @@ static void clk_teardown_mapping(struct clk *clk)
/* Nothing to do */ /* Nothing to do */
if (mapping == &dummy_mapping) if (mapping == &dummy_mapping)
return; goto out;
kref_put(&mapping->ref, clk_destroy_mapping); kref_put(&mapping->ref, clk_destroy_mapping);
clk->mapping = NULL; clk->mapping = NULL;
out:
clk->mapped_reg = NULL;
} }
int clk_register(struct clk *clk) int clk_register(struct clk *clk)
......
...@@ -15,15 +15,15 @@ ...@@ -15,15 +15,15 @@
static int sh_clk_mstp32_enable(struct clk *clk) static int sh_clk_mstp32_enable(struct clk *clk)
{ {
__raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit), iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
clk->enable_reg); clk->mapped_reg);
return 0; return 0;
} }
static void sh_clk_mstp32_disable(struct clk *clk) static void sh_clk_mstp32_disable(struct clk *clk)
{ {
__raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit), iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
clk->enable_reg); clk->mapped_reg);
} }
static struct clk_ops sh_clk_mstp32_clk_ops = { static struct clk_ops sh_clk_mstp32_clk_ops = {
...@@ -72,7 +72,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk) ...@@ -72,7 +72,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk)
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
table, NULL); table, NULL);
idx = __raw_readl(clk->enable_reg) & 0x003f; idx = ioread32(clk->mapped_reg) & 0x003f;
return clk->freq_table[idx].frequency; return clk->freq_table[idx].frequency;
} }
...@@ -98,10 +98,10 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) ...@@ -98,10 +98,10 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
if (ret < 0) if (ret < 0)
return ret; return ret;
value = __raw_readl(clk->enable_reg) & value = ioread32(clk->mapped_reg) &
~(((1 << clk->src_width) - 1) << clk->src_shift); ~(((1 << clk->src_width) - 1) << clk->src_shift);
__raw_writel(value | (i << clk->src_shift), clk->enable_reg); iowrite32(value | (i << clk->src_shift), clk->mapped_reg);
/* Rebuild the frequency table */ /* Rebuild the frequency table */
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
...@@ -119,10 +119,10 @@ static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate) ...@@ -119,10 +119,10 @@ static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
if (idx < 0) if (idx < 0)
return idx; return idx;
value = __raw_readl(clk->enable_reg); value = ioread32(clk->mapped_reg);
value &= ~0x3f; value &= ~0x3f;
value |= idx; value |= idx;
__raw_writel(value, clk->enable_reg); iowrite32(value, clk->mapped_reg);
return 0; return 0;
} }
...@@ -133,9 +133,9 @@ static int sh_clk_div6_enable(struct clk *clk) ...@@ -133,9 +133,9 @@ static int sh_clk_div6_enable(struct clk *clk)
ret = sh_clk_div6_set_rate(clk, clk->rate); ret = sh_clk_div6_set_rate(clk, clk->rate);
if (ret == 0) { if (ret == 0) {
value = __raw_readl(clk->enable_reg); value = ioread32(clk->mapped_reg);
value &= ~0x100; /* clear stop bit to enable clock */ value &= ~0x100; /* clear stop bit to enable clock */
__raw_writel(value, clk->enable_reg); iowrite32(value, clk->mapped_reg);
} }
return ret; return ret;
} }
...@@ -144,10 +144,10 @@ static void sh_clk_div6_disable(struct clk *clk) ...@@ -144,10 +144,10 @@ static void sh_clk_div6_disable(struct clk *clk)
{ {
unsigned long value; unsigned long value;
value = __raw_readl(clk->enable_reg); value = ioread32(clk->mapped_reg);
value |= 0x100; /* stop clock */ value |= 0x100; /* stop clock */
value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
__raw_writel(value, clk->enable_reg); iowrite32(value, clk->mapped_reg);
} }
static struct clk_ops sh_clk_div6_clk_ops = { static struct clk_ops sh_clk_div6_clk_ops = {
...@@ -167,6 +167,38 @@ static struct clk_ops sh_clk_div6_reparent_clk_ops = { ...@@ -167,6 +167,38 @@ static struct clk_ops sh_clk_div6_reparent_clk_ops = {
.set_parent = sh_clk_div6_set_parent, .set_parent = sh_clk_div6_set_parent,
}; };
static int __init sh_clk_init_parent(struct clk *clk)
{
u32 val;
if (clk->parent)
return 0;
if (!clk->parent_table || !clk->parent_num)
return 0;
if (!clk->src_width) {
pr_err("sh_clk_init_parent: cannot select parent clock\n");
return -EINVAL;
}
val = (ioread32(clk->mapped_reg) >> clk->src_shift);
val &= (1 << clk->src_width) - 1;
if (val >= clk->parent_num) {
pr_err("sh_clk_init_parent: parent table size failed\n");
return -EINVAL;
}
clk->parent = clk->parent_table[val];
if (!clk->parent) {
pr_err("sh_clk_init_parent: unable to set parent");
return -EINVAL;
}
return 0;
}
static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
struct clk_ops *ops) struct clk_ops *ops)
{ {
...@@ -190,8 +222,11 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, ...@@ -190,8 +222,11 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
clkp->ops = ops; clkp->ops = ops;
clkp->freq_table = freq_table + (k * freq_table_size); clkp->freq_table = freq_table + (k * freq_table_size);
clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
ret = clk_register(clkp); ret = clk_register(clkp);
if (ret < 0)
break;
ret = sh_clk_init_parent(clkp);
} }
return ret; return ret;
...@@ -217,7 +252,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk) ...@@ -217,7 +252,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
table, &clk->arch_flags); table, &clk->arch_flags);
idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f; idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f;
return clk->freq_table[idx].frequency; return clk->freq_table[idx].frequency;
} }
...@@ -235,15 +270,15 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) ...@@ -235,15 +270,15 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
*/ */
if (parent->flags & CLK_ENABLE_ON_INIT) if (parent->flags & CLK_ENABLE_ON_INIT)
value = __raw_readl(clk->enable_reg) & ~(1 << 7); value = ioread32(clk->mapped_reg) & ~(1 << 7);
else else
value = __raw_readl(clk->enable_reg) | (1 << 7); value = ioread32(clk->mapped_reg) | (1 << 7);
ret = clk_reparent(clk, parent); ret = clk_reparent(clk, parent);
if (ret < 0) if (ret < 0)
return ret; return ret;
__raw_writel(value, clk->enable_reg); iowrite32(value, clk->mapped_reg);
/* Rebiuld the frequency table */ /* Rebiuld the frequency table */
clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
...@@ -260,10 +295,10 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) ...@@ -260,10 +295,10 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
if (idx < 0) if (idx < 0)
return idx; return idx;
value = __raw_readl(clk->enable_reg); value = ioread32(clk->mapped_reg);
value &= ~(0xf << clk->enable_bit); value &= ~(0xf << clk->enable_bit);
value |= (idx << clk->enable_bit); value |= (idx << clk->enable_bit);
__raw_writel(value, clk->enable_reg); iowrite32(value, clk->mapped_reg);
if (d4t->kick) if (d4t->kick)
d4t->kick(clk); d4t->kick(clk);
...@@ -273,13 +308,13 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) ...@@ -273,13 +308,13 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
static int sh_clk_div4_enable(struct clk *clk) static int sh_clk_div4_enable(struct clk *clk)
{ {
__raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg); iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg);
return 0; return 0;
} }
static void sh_clk_div4_disable(struct clk *clk) static void sh_clk_div4_disable(struct clk *clk)
{ {
__raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg); iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg);
} }
static struct clk_ops sh_clk_div4_clk_ops = { static struct clk_ops sh_clk_div4_clk_ops = {
......
...@@ -19,6 +19,75 @@ ...@@ -19,6 +19,75 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/ioport.h>
static void pfc_iounmap(struct pinmux_info *pip)
{
int k;
for (k = 0; k < pip->num_resources; k++)
if (pip->window[k].virt)
iounmap(pip->window[k].virt);
kfree(pip->window);
pip->window = NULL;
}
static int pfc_ioremap(struct pinmux_info *pip)
{
struct resource *res;
int k;
if (!pip->num_resources)
return 0;
pip->window = kzalloc(pip->num_resources * sizeof(*pip->window),
GFP_NOWAIT);
if (!pip->window)
goto err1;
for (k = 0; k < pip->num_resources; k++) {
res = pip->resource + k;
WARN_ON(resource_type(res) != IORESOURCE_MEM);
pip->window[k].phys = res->start;
pip->window[k].size = resource_size(res);
pip->window[k].virt = ioremap_nocache(res->start,
resource_size(res));
if (!pip->window[k].virt)
goto err2;
}
return 0;
err2:
pfc_iounmap(pip);
err1:
return -1;
}
static void __iomem *pfc_phys_to_virt(struct pinmux_info *pip,
unsigned long address)
{
struct pfc_window *window;
int k;
/* scan through physical windows and convert address */
for (k = 0; k < pip->num_resources; k++) {
window = pip->window + k;
if (address < window->phys)
continue;
if (address >= (window->phys + window->size))
continue;
return window->virt + (address - window->phys);
}
/* no windows defined, register must be 1:1 mapped virt:phys */
return (void __iomem *)address;
}
static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
{ {
...@@ -31,35 +100,35 @@ static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) ...@@ -31,35 +100,35 @@ static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
return 1; return 1;
} }
static unsigned long gpio_read_raw_reg(unsigned long reg, static unsigned long gpio_read_raw_reg(void __iomem *mapped_reg,
unsigned long reg_width) unsigned long reg_width)
{ {
switch (reg_width) { switch (reg_width) {
case 8: case 8:
return __raw_readb(reg); return ioread8(mapped_reg);
case 16: case 16:
return __raw_readw(reg); return ioread16(mapped_reg);
case 32: case 32:
return __raw_readl(reg); return ioread32(mapped_reg);
} }
BUG(); BUG();
return 0; return 0;
} }
static void gpio_write_raw_reg(unsigned long reg, static void gpio_write_raw_reg(void __iomem *mapped_reg,
unsigned long reg_width, unsigned long reg_width,
unsigned long data) unsigned long data)
{ {
switch (reg_width) { switch (reg_width) {
case 8: case 8:
__raw_writeb(data, reg); iowrite8(data, mapped_reg);
return; return;
case 16: case 16:
__raw_writew(data, reg); iowrite16(data, mapped_reg);
return; return;
case 32: case 32:
__raw_writel(data, reg); iowrite32(data, mapped_reg);
return; return;
} }
...@@ -82,11 +151,12 @@ static void gpio_write_bit(struct pinmux_data_reg *dr, ...@@ -82,11 +151,12 @@ static void gpio_write_bit(struct pinmux_data_reg *dr,
else else
clear_bit(pos, &dr->reg_shadow); clear_bit(pos, &dr->reg_shadow);
gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow); gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
} }
static int gpio_read_reg(unsigned long reg, unsigned long reg_width, static int gpio_read_reg(void __iomem *mapped_reg, unsigned long reg_width,
unsigned long field_width, unsigned long in_pos) unsigned long field_width, unsigned long in_pos,
unsigned long reg)
{ {
unsigned long data, mask, pos; unsigned long data, mask, pos;
...@@ -98,13 +168,13 @@ static int gpio_read_reg(unsigned long reg, unsigned long reg_width, ...@@ -98,13 +168,13 @@ static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
"r_width = %ld, f_width = %ld\n", "r_width = %ld, f_width = %ld\n",
reg, pos, reg_width, field_width); reg, pos, reg_width, field_width);
data = gpio_read_raw_reg(reg, reg_width); data = gpio_read_raw_reg(mapped_reg, reg_width);
return (data >> pos) & mask; return (data >> pos) & mask;
} }
static void gpio_write_reg(unsigned long reg, unsigned long reg_width, static void gpio_write_reg(void __iomem *mapped_reg, unsigned long reg_width,
unsigned long field_width, unsigned long in_pos, unsigned long field_width, unsigned long in_pos,
unsigned long value) unsigned long value, unsigned long reg)
{ {
unsigned long mask, pos; unsigned long mask, pos;
...@@ -120,13 +190,13 @@ static void gpio_write_reg(unsigned long reg, unsigned long reg_width, ...@@ -120,13 +190,13 @@ static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
switch (reg_width) { switch (reg_width) {
case 8: case 8:
__raw_writeb((__raw_readb(reg) & mask) | value, reg); iowrite8((ioread8(mapped_reg) & mask) | value, mapped_reg);
break; break;
case 16: case 16:
__raw_writew((__raw_readw(reg) & mask) | value, reg); iowrite16((ioread16(mapped_reg) & mask) | value, mapped_reg);
break; break;
case 32: case 32:
__raw_writel((__raw_readl(reg) & mask) | value, reg); iowrite32((ioread32(mapped_reg) & mask) | value, mapped_reg);
break; break;
} }
} }
...@@ -147,6 +217,8 @@ static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio) ...@@ -147,6 +217,8 @@ static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
if (!data_reg->reg_width) if (!data_reg->reg_width)
break; break;
data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
for (n = 0; n < data_reg->reg_width; n++) { for (n = 0; n < data_reg->reg_width; n++) {
if (data_reg->enum_ids[n] == gpiop->enum_id) { if (data_reg->enum_ids[n] == gpiop->enum_id) {
gpiop->flags &= ~PINMUX_FLAG_DREG; gpiop->flags &= ~PINMUX_FLAG_DREG;
...@@ -179,7 +251,8 @@ static void setup_data_regs(struct pinmux_info *gpioc) ...@@ -179,7 +251,8 @@ static void setup_data_regs(struct pinmux_info *gpioc)
if (!drp->reg_width) if (!drp->reg_width)
break; break;
drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width); drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
drp->reg_width);
k++; k++;
} }
} }
...@@ -266,12 +339,16 @@ static void write_config_reg(struct pinmux_info *gpioc, ...@@ -266,12 +339,16 @@ static void write_config_reg(struct pinmux_info *gpioc,
int index) int index)
{ {
unsigned long ncomb, pos, value; unsigned long ncomb, pos, value;
void __iomem *mapped_reg;
ncomb = 1 << crp->field_width; ncomb = 1 << crp->field_width;
pos = index / ncomb; pos = index / ncomb;
value = index % ncomb; value = index % ncomb;
gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value); mapped_reg = pfc_phys_to_virt(gpioc, crp->reg);
gpio_write_reg(mapped_reg, crp->reg_width, crp->field_width,
pos, value, crp->reg);
} }
static int check_config_reg(struct pinmux_info *gpioc, static int check_config_reg(struct pinmux_info *gpioc,
...@@ -279,13 +356,16 @@ static int check_config_reg(struct pinmux_info *gpioc, ...@@ -279,13 +356,16 @@ static int check_config_reg(struct pinmux_info *gpioc,
int index) int index)
{ {
unsigned long ncomb, pos, value; unsigned long ncomb, pos, value;
void __iomem *mapped_reg;
ncomb = 1 << crp->field_width; ncomb = 1 << crp->field_width;
pos = index / ncomb; pos = index / ncomb;
value = index % ncomb; value = index % ncomb;
if (gpio_read_reg(crp->reg, crp->reg_width, mapped_reg = pfc_phys_to_virt(gpioc, crp->reg);
crp->field_width, pos) == value)
if (gpio_read_reg(mapped_reg, crp->reg_width,
crp->field_width, pos, crp->reg) == value)
return 0; return 0;
return -1; return -1;
...@@ -564,7 +644,7 @@ static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio) ...@@ -564,7 +644,7 @@ static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
return -EINVAL; return -EINVAL;
return gpio_read_reg(dr->reg, dr->reg_width, 1, bit); return gpio_read_reg(dr->mapped_reg, dr->reg_width, 1, bit, dr->reg);
} }
static int sh_gpio_get(struct gpio_chip *chip, unsigned offset) static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
...@@ -606,10 +686,15 @@ static int sh_gpio_to_irq(struct gpio_chip *chip, unsigned offset) ...@@ -606,10 +686,15 @@ static int sh_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
int register_pinmux(struct pinmux_info *pip) int register_pinmux(struct pinmux_info *pip)
{ {
struct gpio_chip *chip = &pip->chip; struct gpio_chip *chip = &pip->chip;
int ret;
pr_info("%s handling gpio %d -> %d\n", pr_info("%s handling gpio %d -> %d\n",
pip->name, pip->first_gpio, pip->last_gpio); pip->name, pip->first_gpio, pip->last_gpio);
ret = pfc_ioremap(pip);
if (ret < 0)
return ret;
setup_data_regs(pip); setup_data_regs(pip);
chip->request = sh_gpio_request; chip->request = sh_gpio_request;
...@@ -627,12 +712,16 @@ int register_pinmux(struct pinmux_info *pip) ...@@ -627,12 +712,16 @@ int register_pinmux(struct pinmux_info *pip)
chip->base = pip->first_gpio; chip->base = pip->first_gpio;
chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1; chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
return gpiochip_add(chip); ret = gpiochip_add(chip);
if (ret < 0)
pfc_iounmap(pip);
return ret;
} }
int unregister_pinmux(struct pinmux_info *pip) int unregister_pinmux(struct pinmux_info *pip)
{ {
pr_info("%s deregistering\n", pip->name); pr_info("%s deregistering\n", pip->name);
pfc_iounmap(pip);
return gpiochip_remove(&pip->chip); return gpiochip_remove(&pip->chip);
} }
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gpio.h>
#ifdef CONFIG_SUPERH #ifdef CONFIG_SUPERH
#include <asm/sh_bios.h> #include <asm/sh_bios.h>
...@@ -73,6 +74,7 @@ struct sci_port { ...@@ -73,6 +74,7 @@ struct sci_port {
struct clk *fclk; struct clk *fclk;
char *irqstr[SCIx_NR_IRQS]; char *irqstr[SCIx_NR_IRQS];
char *gpiostr[SCIx_NR_FNS];
struct dma_chan *chan_tx; struct dma_chan *chan_tx;
struct dma_chan *chan_rx; struct dma_chan *chan_rx;
...@@ -474,8 +476,15 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag) ...@@ -474,8 +476,15 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
if (!reg->size) if (!reg->size)
return; return;
if (!(cflag & CRTSCTS)) if ((s->cfg->capabilities & SCIx_HAVE_RTSCTS) &&
sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */ ((!(cflag & CRTSCTS)))) {
unsigned short status;
status = sci_in(port, SCSPTR);
status &= ~SCSPTR_CTSIO;
status |= SCSPTR_RTSIO;
sci_out(port, SCSPTR, status); /* Set RTS = 1 */
}
} }
static int sci_txfill(struct uart_port *port) static int sci_txfill(struct uart_port *port)
...@@ -621,6 +630,7 @@ static void sci_receive_chars(struct uart_port *port) ...@@ -621,6 +630,7 @@ static void sci_receive_chars(struct uart_port *port)
} else { } else {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
char c = sci_in(port, SCxRDR); char c = sci_in(port, SCxRDR);
status = sci_in(port, SCxSR); status = sci_in(port, SCxSR);
#if defined(CONFIG_CPU_SH3) #if defined(CONFIG_CPU_SH3)
/* Skip "chars" during break */ /* Skip "chars" during break */
...@@ -649,9 +659,11 @@ static void sci_receive_chars(struct uart_port *port) ...@@ -649,9 +659,11 @@ static void sci_receive_chars(struct uart_port *port)
/* Store data and status */ /* Store data and status */
if (status & SCxSR_FER(port)) { if (status & SCxSR_FER(port)) {
flag = TTY_FRAME; flag = TTY_FRAME;
port->icount.frame++;
dev_notice(port->dev, "frame error\n"); dev_notice(port->dev, "frame error\n");
} else if (status & SCxSR_PER(port)) { } else if (status & SCxSR_PER(port)) {
flag = TTY_PARITY; flag = TTY_PARITY;
port->icount.parity++;
dev_notice(port->dev, "parity error\n"); dev_notice(port->dev, "parity error\n");
} else } else
flag = TTY_NORMAL; flag = TTY_NORMAL;
...@@ -723,6 +735,8 @@ static int sci_handle_errors(struct uart_port *port) ...@@ -723,6 +735,8 @@ static int sci_handle_errors(struct uart_port *port)
*/ */
if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) { if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) {
if (status & (1 << s->cfg->overrun_bit)) { if (status & (1 << s->cfg->overrun_bit)) {
port->icount.overrun++;
/* overrun error */ /* overrun error */
if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) if (tty_insert_flip_char(tty, 0, TTY_OVERRUN))
copied++; copied++;
...@@ -737,6 +751,8 @@ static int sci_handle_errors(struct uart_port *port) ...@@ -737,6 +751,8 @@ static int sci_handle_errors(struct uart_port *port)
struct sci_port *sci_port = to_sci_port(port); struct sci_port *sci_port = to_sci_port(port);
if (!sci_port->break_flag) { if (!sci_port->break_flag) {
port->icount.brk++;
sci_port->break_flag = 1; sci_port->break_flag = 1;
sci_schedule_break_timer(sci_port); sci_schedule_break_timer(sci_port);
...@@ -752,6 +768,8 @@ static int sci_handle_errors(struct uart_port *port) ...@@ -752,6 +768,8 @@ static int sci_handle_errors(struct uart_port *port)
} else { } else {
/* frame error */ /* frame error */
port->icount.frame++;
if (tty_insert_flip_char(tty, 0, TTY_FRAME)) if (tty_insert_flip_char(tty, 0, TTY_FRAME))
copied++; copied++;
...@@ -761,6 +779,8 @@ static int sci_handle_errors(struct uart_port *port) ...@@ -761,6 +779,8 @@ static int sci_handle_errors(struct uart_port *port)
if (status & SCxSR_PER(port)) { if (status & SCxSR_PER(port)) {
/* parity error */ /* parity error */
port->icount.parity++;
if (tty_insert_flip_char(tty, 0, TTY_PARITY)) if (tty_insert_flip_char(tty, 0, TTY_PARITY))
copied++; copied++;
...@@ -787,6 +807,8 @@ static int sci_handle_fifo_overrun(struct uart_port *port) ...@@ -787,6 +807,8 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) { if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
sci_out(port, SCLSR, 0); sci_out(port, SCLSR, 0);
port->icount.overrun++;
tty_insert_flip_char(tty, 0, TTY_OVERRUN); tty_insert_flip_char(tty, 0, TTY_OVERRUN);
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty);
...@@ -812,6 +834,9 @@ static int sci_handle_breaks(struct uart_port *port) ...@@ -812,6 +834,9 @@ static int sci_handle_breaks(struct uart_port *port)
/* Debounce break */ /* Debounce break */
s->break_flag = 1; s->break_flag = 1;
#endif #endif
port->icount.brk++;
/* Notify of BREAK */ /* Notify of BREAK */
if (tty_insert_flip_char(tty, 0, TTY_BREAK)) if (tty_insert_flip_char(tty, 0, TTY_BREAK))
copied++; copied++;
...@@ -1082,6 +1107,67 @@ static void sci_free_irq(struct sci_port *port) ...@@ -1082,6 +1107,67 @@ static void sci_free_irq(struct sci_port *port)
} }
} }
static const char *sci_gpio_names[SCIx_NR_FNS] = {
"sck", "rxd", "txd", "cts", "rts",
};
static const char *sci_gpio_str(unsigned int index)
{
return sci_gpio_names[index];
}
static void __devinit sci_init_gpios(struct sci_port *port)
{
struct uart_port *up = &port->port;
int i;
if (!port->cfg)
return;
for (i = 0; i < SCIx_NR_FNS; i++) {
const char *desc;
int ret;
if (!port->cfg->gpios[i])
continue;
desc = sci_gpio_str(i);
port->gpiostr[i] = kasprintf(GFP_KERNEL, "%s:%s",
dev_name(up->dev), desc);
/*
* If we've failed the allocation, we can still continue
* on with a NULL string.
*/
if (!port->gpiostr[i])
dev_notice(up->dev, "%s string allocation failure\n",
desc);
ret = gpio_request(port->cfg->gpios[i], port->gpiostr[i]);
if (unlikely(ret != 0)) {
dev_notice(up->dev, "failed %s gpio request\n", desc);
/*
* If we can't get the GPIO for whatever reason,
* no point in keeping the verbose string around.
*/
kfree(port->gpiostr[i]);
}
}
}
static void sci_free_gpios(struct sci_port *port)
{
int i;
for (i = 0; i < SCIx_NR_FNS; i++)
if (port->cfg->gpios[i]) {
gpio_free(port->cfg->gpios[i]);
kfree(port->gpiostr[i]);
}
}
static unsigned int sci_tx_empty(struct uart_port *port) static unsigned int sci_tx_empty(struct uart_port *port)
{ {
unsigned short status = sci_in(port, SCxSR); unsigned short status = sci_in(port, SCxSR);
...@@ -1090,19 +1176,39 @@ static unsigned int sci_tx_empty(struct uart_port *port) ...@@ -1090,19 +1176,39 @@ static unsigned int sci_tx_empty(struct uart_port *port)
return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
} }
/*
* Modem control is a bit of a mixed bag for SCI(F) ports. Generally
* CTS/RTS is supported in hardware by at least one port and controlled
* via SCSPTR (SCxPCR for SCIFA/B parts), or external pins (presently
* handled via the ->init_pins() op, which is a bit of a one-way street,
* lacking any ability to defer pin control -- this will later be
* converted over to the GPIO framework).
*
* Other modes (such as loopback) are supported generically on certain
* port types, but not others. For these it's sufficient to test for the
* existence of the support register and simply ignore the port type.
*/
static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
{ {
/* This routine is used for seting signals of: DTR, DCD, CTS/RTS */ if (mctrl & TIOCM_LOOP) {
/* We use SCIF's hardware for CTS/RTS, so don't need any for that. */ struct plat_sci_reg *reg;
/* If you have signals for DTR and DCD, please implement here. */
/*
* Standard loopback mode for SCFCR ports.
*/
reg = sci_getreg(port, SCFCR);
if (reg->size)
sci_out(port, SCFCR, sci_in(port, SCFCR) | 1);
}
} }
static unsigned int sci_get_mctrl(struct uart_port *port) static unsigned int sci_get_mctrl(struct uart_port *port)
{ {
/* This routine is used for getting signals of: DTR, DCD, DSR, RI, /*
and CTS/RTS */ * CTS/RTS is handled in hardware when supported, while nothing
* else is wired up. Keep it simple and simply assert DSR/CAR.
return TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR; */
return TIOCM_DSR | TIOCM_CAR;
} }
#ifdef CONFIG_SERIAL_SH_SCI_DMA #ifdef CONFIG_SERIAL_SH_SCI_DMA
...@@ -1449,12 +1555,17 @@ static void sci_stop_rx(struct uart_port *port) ...@@ -1449,12 +1555,17 @@ static void sci_stop_rx(struct uart_port *port)
static void sci_enable_ms(struct uart_port *port) static void sci_enable_ms(struct uart_port *port)
{ {
/* Nothing here yet .. */ /*
* Not supported by hardware, always a nop.
*/
} }
static void sci_break_ctl(struct uart_port *port, int break_state) static void sci_break_ctl(struct uart_port *port, int break_state)
{ {
/* Nothing here yet .. */ /*
* Not supported by hardware. Most parts couple break and rx
* interrupts together, with break detection always enabled.
*/
} }
#ifdef CONFIG_SERIAL_SH_SCI_DMA #ifdef CONFIG_SERIAL_SH_SCI_DMA
...@@ -1652,6 +1763,7 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, ...@@ -1652,6 +1763,7 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
static void sci_reset(struct uart_port *port) static void sci_reset(struct uart_port *port)
{ {
struct plat_sci_reg *reg;
unsigned int status; unsigned int status;
do { do {
...@@ -1660,7 +1772,8 @@ static void sci_reset(struct uart_port *port) ...@@ -1660,7 +1772,8 @@ static void sci_reset(struct uart_port *port)
sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
if (port->type != PORT_SCI) reg = sci_getreg(port, SCFCR);
if (reg->size)
sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
} }
...@@ -1668,9 +1781,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -1668,9 +1781,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old) struct ktermios *old)
{ {
struct sci_port *s = to_sci_port(port); struct sci_port *s = to_sci_port(port);
struct plat_sci_reg *reg;
unsigned int baud, smr_val, max_baud; unsigned int baud, smr_val, max_baud;
int t = -1; int t = -1;
u16 scfcr = 0;
/* /*
* earlyprintk comes here early on with port->uartclk set to zero. * earlyprintk comes here early on with port->uartclk set to zero.
...@@ -1720,7 +1833,27 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -1720,7 +1833,27 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
} }
sci_init_pins(port, termios->c_cflag); sci_init_pins(port, termios->c_cflag);
sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0));
reg = sci_getreg(port, SCFCR);
if (reg->size) {
unsigned short ctrl = sci_in(port, SCFCR);
if (s->cfg->capabilities & SCIx_HAVE_RTSCTS) {
if (termios->c_cflag & CRTSCTS)
ctrl |= SCFCR_MCE;
else
ctrl &= ~SCFCR_MCE;
}
/*
* As we've done a sci_reset() above, ensure we don't
* interfere with the FIFOs while toggling MCE. As the
* reset values could still be set, simply mask them out.
*/
ctrl &= ~(SCFCR_RFRST | SCFCR_TFRST);
sci_out(port, SCFCR, ctrl);
}
sci_out(port, SCSCR, s->cfg->scscr); sci_out(port, SCSCR, s->cfg->scscr);
...@@ -1892,6 +2025,8 @@ static int __devinit sci_init_single(struct platform_device *dev, ...@@ -1892,6 +2025,8 @@ static int __devinit sci_init_single(struct platform_device *dev,
struct uart_port *port = &sci_port->port; struct uart_port *port = &sci_port->port;
int ret; int ret;
sci_port->cfg = p;
port->ops = &sci_uart_ops; port->ops = &sci_uart_ops;
port->iotype = UPIO_MEM; port->iotype = UPIO_MEM;
port->line = index; port->line = index;
...@@ -1937,6 +2072,8 @@ static int __devinit sci_init_single(struct platform_device *dev, ...@@ -1937,6 +2072,8 @@ static int __devinit sci_init_single(struct platform_device *dev,
port->dev = &dev->dev; port->dev = &dev->dev;
sci_init_gpios(sci_port);
pm_runtime_irq_safe(&dev->dev); pm_runtime_irq_safe(&dev->dev);
pm_runtime_enable(&dev->dev); pm_runtime_enable(&dev->dev);
} }
...@@ -1971,8 +2108,6 @@ static int __devinit sci_init_single(struct platform_device *dev, ...@@ -1971,8 +2108,6 @@ static int __devinit sci_init_single(struct platform_device *dev,
p->error_mask |= (1 << p->overrun_bit); p->error_mask |= (1 << p->overrun_bit);
} }
sci_port->cfg = p;
port->mapbase = p->mapbase; port->mapbase = p->mapbase;
port->type = p->type; port->type = p->type;
port->flags = p->flags; port->flags = p->flags;
...@@ -2113,9 +2248,16 @@ static int sci_runtime_suspend(struct device *dev) ...@@ -2113,9 +2248,16 @@ static int sci_runtime_suspend(struct device *dev)
struct uart_port *port = &sci_port->port; struct uart_port *port = &sci_port->port;
if (uart_console(port)) { if (uart_console(port)) {
struct plat_sci_reg *reg;
sci_port->saved_smr = sci_in(port, SCSMR); sci_port->saved_smr = sci_in(port, SCSMR);
sci_port->saved_brr = sci_in(port, SCBRR); sci_port->saved_brr = sci_in(port, SCBRR);
reg = sci_getreg(port, SCFCR);
if (reg->size)
sci_port->saved_fcr = sci_in(port, SCFCR); sci_port->saved_fcr = sci_in(port, SCFCR);
else
sci_port->saved_fcr = 0;
} }
return 0; return 0;
} }
...@@ -2129,7 +2271,10 @@ static int sci_runtime_resume(struct device *dev) ...@@ -2129,7 +2271,10 @@ static int sci_runtime_resume(struct device *dev)
sci_reset(port); sci_reset(port);
sci_out(port, SCSMR, sci_port->saved_smr); sci_out(port, SCSMR, sci_port->saved_smr);
sci_out(port, SCBRR, sci_port->saved_brr); sci_out(port, SCBRR, sci_port->saved_brr);
if (sci_port->saved_fcr)
sci_out(port, SCFCR, sci_port->saved_fcr); sci_out(port, SCFCR, sci_port->saved_fcr);
sci_out(port, SCSCR, sci_port->cfg->scscr); sci_out(port, SCSCR, sci_port->cfg->scscr);
} }
return 0; return 0;
...@@ -2169,6 +2314,8 @@ static int sci_remove(struct platform_device *dev) ...@@ -2169,6 +2314,8 @@ static int sci_remove(struct platform_device *dev)
cpufreq_unregister_notifier(&port->freq_transition, cpufreq_unregister_notifier(&port->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER); CPUFREQ_TRANSITION_NOTIFIER);
sci_free_gpios(port);
uart_remove_one_port(&sci_uart_driver, &port->port); uart_remove_one_port(&sci_uart_driver, &port->port);
clk_put(port->iclk); clk_put(port->iclk);
......
...@@ -49,6 +49,10 @@ enum { ...@@ -49,6 +49,10 @@ enum {
#define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK) #define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
/* SCSPTR, optional */
#define SCSPTR_RTSIO (1 << 7)
#define SCSPTR_CTSIO (1 << 5)
/* Offsets into the sci_port->irqs array */ /* Offsets into the sci_port->irqs array */
enum { enum {
SCIx_ERI_IRQ, SCIx_ERI_IRQ,
...@@ -60,6 +64,17 @@ enum { ...@@ -60,6 +64,17 @@ enum {
SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */ SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */
}; };
/* Offsets into the sci_port->gpios array */
enum {
SCIx_SCK,
SCIx_RXD,
SCIx_TXD,
SCIx_CTS,
SCIx_RTS,
SCIx_NR_FNS,
};
enum { enum {
SCIx_PROBE_REGTYPE, SCIx_PROBE_REGTYPE,
...@@ -108,14 +123,21 @@ struct plat_sci_port_ops { ...@@ -108,14 +123,21 @@ struct plat_sci_port_ops {
void (*init_pins)(struct uart_port *, unsigned int cflag); void (*init_pins)(struct uart_port *, unsigned int cflag);
}; };
/*
* Port-specific capabilities
*/
#define SCIx_HAVE_RTSCTS (1 << 0)
/* /*
* Platform device specific platform_data struct * Platform device specific platform_data struct
*/ */
struct plat_sci_port { struct plat_sci_port {
unsigned long mapbase; /* resource base */ unsigned long mapbase; /* resource base */
unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */
unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */
unsigned int type; /* SCI / SCIF / IRDA */ unsigned int type; /* SCI / SCIF / IRDA */
upf_t flags; /* UPF_* flags */ upf_t flags; /* UPF_* flags */
unsigned long capabilities; /* Port features/capabilities */
unsigned int scbrr_algo_id; /* SCBRR calculation algo */ unsigned int scbrr_algo_id; /* SCBRR calculation algo */
unsigned int scscr; /* SCSCR initialization */ unsigned int scscr; /* SCSCR initialization */
......
...@@ -49,6 +49,7 @@ struct clk { ...@@ -49,6 +49,7 @@ struct clk {
void __iomem *enable_reg; void __iomem *enable_reg;
unsigned int enable_bit; unsigned int enable_bit;
void __iomem *mapped_reg;
unsigned long arch_flags; unsigned long arch_flags;
void *priv; void *priv;
...@@ -131,10 +132,9 @@ int sh_clk_div4_enable_register(struct clk *clks, int nr, ...@@ -131,10 +132,9 @@ int sh_clk_div4_enable_register(struct clk *clks, int nr,
int sh_clk_div4_reparent_register(struct clk *clks, int nr, int sh_clk_div4_reparent_register(struct clk *clks, int nr,
struct clk_div4_table *table); struct clk_div4_table *table);
#define SH_CLK_DIV6_EXT(_parent, _reg, _flags, _parents, \ #define SH_CLK_DIV6_EXT(_reg, _flags, _parents, \
_num_parents, _src_shift, _src_width) \ _num_parents, _src_shift, _src_width) \
{ \ { \
.parent = _parent, \
.enable_reg = (void __iomem *)_reg, \ .enable_reg = (void __iomem *)_reg, \
.flags = _flags, \ .flags = _flags, \
.parent_table = _parents, \ .parent_table = _parents, \
...@@ -144,7 +144,11 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr, ...@@ -144,7 +144,11 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
} }
#define SH_CLK_DIV6(_parent, _reg, _flags) \ #define SH_CLK_DIV6(_parent, _reg, _flags) \
SH_CLK_DIV6_EXT(_parent, _reg, _flags, NULL, 0, 0, 0) { \
.parent = _parent, \
.enable_reg = (void __iomem *)_reg, \
.flags = _flags, \
}
int sh_clk_div6_register(struct clk *clks, int nr); int sh_clk_div6_register(struct clk *clks, int nr);
int sh_clk_div6_reparent_register(struct clk *clks, int nr); int sh_clk_div6_reparent_register(struct clk *clks, int nr);
......
...@@ -55,6 +55,7 @@ struct pinmux_cfg_reg { ...@@ -55,6 +55,7 @@ struct pinmux_cfg_reg {
struct pinmux_data_reg { struct pinmux_data_reg {
unsigned long reg, reg_width, reg_shadow; unsigned long reg, reg_width, reg_shadow;
pinmux_enum_t *enum_ids; pinmux_enum_t *enum_ids;
void __iomem *mapped_reg;
}; };
#define PINMUX_DATA_REG(name, r, r_width) \ #define PINMUX_DATA_REG(name, r, r_width) \
...@@ -75,6 +76,12 @@ struct pinmux_range { ...@@ -75,6 +76,12 @@ struct pinmux_range {
pinmux_enum_t force; pinmux_enum_t force;
}; };
struct pfc_window {
phys_addr_t phys;
void __iomem *virt;
unsigned long size;
};
struct pinmux_info { struct pinmux_info {
char *name; char *name;
pinmux_enum_t reserved_id; pinmux_enum_t reserved_id;
...@@ -98,6 +105,10 @@ struct pinmux_info { ...@@ -98,6 +105,10 @@ struct pinmux_info {
struct pinmux_irq *gpio_irq; struct pinmux_irq *gpio_irq;
unsigned int gpio_irq_size; unsigned int gpio_irq_size;
struct resource *resource;
unsigned int num_resources;
struct pfc_window *window;
struct gpio_chip chip; struct gpio_chip chip;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment