Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca15f790 authored by Russell King's avatar Russell King
Browse files

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

parents 418cf646 410d878b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
#

# Common objects
obj-y				:= timer.o console.o clock.o
obj-y				:= timer.o console.o clock.o pm_runtime.o

# CPU objects
obj-$(CONFIG_ARCH_SH7367)	+= setup-sh7367.o clock-sh7367.o intc-sh7367.o
+41 −15
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -39,6 +40,7 @@
#include <linux/sh_clk.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/leds.h>
#include <linux/input/sh_keysc.h>
#include <linux/usb/r8a66597.h>

@@ -307,6 +309,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = {
	.dma_slave_tx	= SHDMA_SLAVE_SDHI1_TX,
	.dma_slave_rx	= SHDMA_SLAVE_SDHI1_RX,
	.tmio_ocr_mask	= MMC_VDD_165_195,
	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE,
};

static struct resource sdhi1_resources[] = {
@@ -558,7 +561,7 @@ static struct resource fsi_resources[] = {

static struct platform_device fsi_device = {
	.name		= "sh_fsi2",
	.id		= 0,
	.id		= -1,
	.num_resources	= ARRAY_SIZE(fsi_resources),
	.resource	= fsi_resources,
	.dev	= {
@@ -650,7 +653,44 @@ static struct platform_device hdmi_device = {
	},
};

static struct gpio_led ap4evb_leds[] = {
	{
		.name			= "led4",
		.gpio			= GPIO_PORT185,
		.default_state	= LEDS_GPIO_DEFSTATE_ON,
	},
	{
		.name			= "led2",
		.gpio			= GPIO_PORT186,
		.default_state	= LEDS_GPIO_DEFSTATE_ON,
	},
	{
		.name			= "led3",
		.gpio			= GPIO_PORT187,
		.default_state	= LEDS_GPIO_DEFSTATE_ON,
	},
	{
		.name			= "led1",
		.gpio			= GPIO_PORT188,
		.default_state	= LEDS_GPIO_DEFSTATE_ON,
	}
};

static struct gpio_led_platform_data ap4evb_leds_pdata = {
	.num_leds = ARRAY_SIZE(ap4evb_leds),
	.leds = ap4evb_leds,
};

static struct platform_device leds_device = {
	.name = "leds-gpio",
	.id = 0,
	.dev = {
		.platform_data  = &ap4evb_leds_pdata,
	},
};

static struct platform_device *ap4evb_devices[] __initdata = {
	&leds_device,
	&nor_flash_device,
	&smc911x_device,
	&sdhi0_device,
@@ -840,20 +880,6 @@ static void __init ap4evb_init(void)
	gpio_request(GPIO_FN_CS5A,	NULL);
	gpio_request(GPIO_FN_IRQ6_39,	NULL);

	/* enable LED 1 - 4 */
	gpio_request(GPIO_PORT185, NULL);
	gpio_request(GPIO_PORT186, NULL);
	gpio_request(GPIO_PORT187, NULL);
	gpio_request(GPIO_PORT188, NULL);
	gpio_direction_output(GPIO_PORT185, 1);
	gpio_direction_output(GPIO_PORT186, 1);
	gpio_direction_output(GPIO_PORT187, 1);
	gpio_direction_output(GPIO_PORT188, 1);
	gpio_export(GPIO_PORT185, 0);
	gpio_export(GPIO_PORT186, 0);
	gpio_export(GPIO_PORT187, 0);
	gpio_export(GPIO_PORT188, 0);

	/* enable Debug switch (S6) */
	gpio_request(GPIO_PORT32, NULL);
	gpio_request(GPIO_PORT33, NULL);
+6 −3
Original line number Diff line number Diff line
@@ -286,7 +286,6 @@ static struct clk_ops pllc2_clk_ops = {

struct clk pllc2_clk = {
	.ops		= &pllc2_clk_ops,
	.flags		= CLK_ENABLE_ON_INIT,
	.parent		= &extal1_div2_clk,
	.freq_table	= pllc2_freq_table,
	.parent_table	= pllc2_parent,
@@ -395,7 +394,7 @@ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {

enum { MSTP001,
       MSTP131, MSTP130,
       MSTP129, MSTP128,
       MSTP129, MSTP128, MSTP127, MSTP126,
       MSTP118, MSTP117, MSTP116,
       MSTP106, MSTP101, MSTP100,
       MSTP223,
@@ -413,6 +412,8 @@ static struct clk mstp_clks[MSTP_NR] = {
	[MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
	[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
	[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
	[MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
	[MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
	[MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
	[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
@@ -428,7 +429,7 @@ static struct clk mstp_clks[MSTP_NR] = {
	[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
	[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
	[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
	[MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, CLK_ENABLE_ON_INIT), /* FSIA */
	[MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */
	[MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
	[MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
	[MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
@@ -498,6 +499,8 @@ static struct clk_lookup lookups[] = {
	CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
	CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
	CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
	CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
	CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
+3 −1
Original line number Diff line number Diff line
/*
 * SH-Mobile Timer
 * SH-Mobile Clock Framework
 *
 * Copyright (C) 2010  Magnus Damm
 *
 * Used together with arch/arm/common/clkdev.c and drivers/sh/clk.c.
 *
 * 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; version 2 of the License.
+169 −0
Original line number Diff line number Diff line
/*
 * arch/arm/mach-shmobile/pm_runtime.c
 *
 * Runtime PM support code for SuperH Mobile ARM
 *
 *  Copyright (C) 2009-2010 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/clk.h>
#include <linux/sh_clk.h>
#include <linux/bitmap.h>

#ifdef CONFIG_PM_RUNTIME
#define BIT_ONCE 0
#define BIT_ACTIVE 1
#define BIT_CLK_ENABLED 2

struct pm_runtime_data {
	unsigned long flags;
	struct clk *clk;
};

static void __devres_release(struct device *dev, void *res)
{
	struct pm_runtime_data *prd = res;

	dev_dbg(dev, "__devres_release()\n");

	if (test_bit(BIT_CLK_ENABLED, &prd->flags))
		clk_disable(prd->clk);

	if (test_bit(BIT_ACTIVE, &prd->flags))
		clk_put(prd->clk);
}

static struct pm_runtime_data *__to_prd(struct device *dev)
{
	return devres_find(dev, __devres_release, NULL, NULL);
}

static void platform_pm_runtime_init(struct device *dev,
				     struct pm_runtime_data *prd)
{
	if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) {
		prd->clk = clk_get(dev, NULL);
		if (!IS_ERR(prd->clk)) {
			set_bit(BIT_ACTIVE, &prd->flags);
			dev_info(dev, "clocks managed by runtime pm\n");
		}
	}
}

static void platform_pm_runtime_bug(struct device *dev,
				    struct pm_runtime_data *prd)
{
	if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags))
		dev_err(dev, "runtime pm suspend before resume\n");
}

int platform_pm_runtime_suspend(struct device *dev)
{
	struct pm_runtime_data *prd = __to_prd(dev);

	dev_dbg(dev, "platform_pm_runtime_suspend()\n");

	platform_pm_runtime_bug(dev, prd);

	if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
		clk_disable(prd->clk);
		clear_bit(BIT_CLK_ENABLED, &prd->flags);
	}

	return 0;
}

int platform_pm_runtime_resume(struct device *dev)
{
	struct pm_runtime_data *prd = __to_prd(dev);

	dev_dbg(dev, "platform_pm_runtime_resume()\n");

	platform_pm_runtime_init(dev, prd);

	if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
		clk_enable(prd->clk);
		set_bit(BIT_CLK_ENABLED, &prd->flags);
	}

	return 0;
}

int platform_pm_runtime_idle(struct device *dev)
{
	/* suspend synchronously to disable clocks immediately */
	return pm_runtime_suspend(dev);
}

static int platform_bus_notify(struct notifier_block *nb,
			       unsigned long action, void *data)
{
	struct device *dev = data;
	struct pm_runtime_data *prd;

	dev_dbg(dev, "platform_bus_notify() %ld !\n", action);

	if (action == BUS_NOTIFY_BIND_DRIVER) {
		prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL);
		if (prd)
			devres_add(dev, prd);
		else
			dev_err(dev, "unable to alloc memory for runtime pm\n");
	}

	return 0;
}

#else /* CONFIG_PM_RUNTIME */

static int platform_bus_notify(struct notifier_block *nb,
			       unsigned long action, void *data)
{
	struct device *dev = data;
	struct clk *clk;

	dev_dbg(dev, "platform_bus_notify() %ld !\n", action);

	switch (action) {
	case BUS_NOTIFY_BIND_DRIVER:
		clk = clk_get(dev, NULL);
		if (!IS_ERR(clk)) {
			clk_enable(clk);
			clk_put(clk);
			dev_info(dev, "runtime pm disabled, clock forced on\n");
		}
		break;
	case BUS_NOTIFY_UNBOUND_DRIVER:
		clk = clk_get(dev, NULL);
		if (!IS_ERR(clk)) {
			clk_disable(clk);
			clk_put(clk);
			dev_info(dev, "runtime pm disabled, clock forced off\n");
		}
		break;
	}

	return 0;
}

#endif /* CONFIG_PM_RUNTIME */

static struct notifier_block platform_bus_notifier = {
	.notifier_call = platform_bus_notify
};

static int __init sh_pm_runtime_init(void)
{
	bus_register_notifier(&platform_bus_type, &platform_bus_notifier);
	return 0;
}
core_initcall(sh_pm_runtime_init);