[xburst] jz4740 pm: Fix gpio suspend/resume. Turn pll off while in suspend and gate
authorLars-Peter Clausen <lars@metafoo.de>
Fri, 5 Mar 2010 02:56:25 +0000 (02:56 +0000)
committerLars-Peter Clausen <lars@metafoo.de>
Fri, 5 Mar 2010 02:56:25 +0000 (02:56 +0000)
clocks off which arn't handeld by their subsystems yet.

SVN-Revision: 19984

target/linux/xburst/files-2.6.32/arch/mips/jz4740/board-n526.c
target/linux/xburst/files-2.6.32/arch/mips/jz4740/board-qi_lb60.c
target/linux/xburst/files-2.6.32/arch/mips/jz4740/clock.c
target/linux/xburst/files-2.6.32/arch/mips/jz4740/clock.h
target/linux/xburst/files-2.6.32/arch/mips/jz4740/gpio.c
target/linux/xburst/files-2.6.32/arch/mips/jz4740/pm.c

index 6e65417..e3e6710 100644 (file)
@@ -321,7 +321,7 @@ static int __init n526_board_setup(void)
        if (jz_gpiolib_init())
                panic("Failed to initalize jz gpio\n");
 
-       jz4740_init_clocks();
+       jz4740_clock_init();
        board_gpio_setup();
 
        if (n526_init_platform_devices())
index 3866b8d..8004417 100644 (file)
@@ -412,7 +412,7 @@ static int __init qi_lb60_board_setup(void)
        if (jz_gpiolib_init())
                panic("Failed to initalize jz gpio\n");
 
-       jz_init_clocks();
+       jz4740_clock_init();
        board_gpio_setup();
 
        if (qi_lb60_init_platform_devices())
index 26ae08d..12a54ed 100644 (file)
@@ -158,7 +158,7 @@ static int jz_clk_enable_gating(struct clk *clk)
 {
        if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
                return -EINVAL;
-       
+
        jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
        return 0;
 }
@@ -873,7 +873,24 @@ void jz4740_clock_udc_enable_auto_suspend(void)
 }
 EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
 
-int jz_init_clocks(void)
+void jz4740_clock_suspend(void)
+{
+       jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
+               JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+
+       jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
+}
+
+void jz4740_clock_resume(void)
+{
+       jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
+       while ((jz_clk_reg_read(JZ_REG_CLOCK_PLL) & JZ_CLOCK_PLL_STABLE) == 0);
+
+       jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
+               JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+}
+
+int jz4740_clock_init(void)
 {
        uint32_t val;
 
@@ -905,5 +922,3 @@ int jz_init_clocks(void)
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(jz_init_clocks);
-
index e0fd9ec..9c91f0d 100644 (file)
@@ -23,7 +23,9 @@ struct jz4740_clock_board_data {
 
 extern struct jz4740_clock_board_data jz4740_clock_bdata;
 
-int jz_init_clocks(void);
+int jz4740_clock_init(void);
+void jz4740_clock_suspend(void);
+void jz4740_clock_resume(void);
 
 struct clk;
 
index 30f83fa..60d6053 100644 (file)
@@ -106,6 +106,7 @@ int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
                jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
        } else {
                jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
+               jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
                switch (function) {
                case JZ_GPIO_FUNC1:
                        jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
@@ -164,7 +165,8 @@ void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num
 
        for (i = 0; i < num; ++i, ++request) {
                jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
-               jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_SET);
+               jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
+               jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
        }
 }
 EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
@@ -431,20 +433,35 @@ static struct jz_gpio_chip jz_gpio_chips[] = {
        JZ_GPIO_CHIP(D),
 };
 
-static int jz_gpio_suspend(struct sys_device *dev, pm_message_t state)
+int jz_gpio_suspend(void)
 {
        struct jz_gpio_chip *chip = jz_gpio_chips;
        int i, gpio;
+
        for (i = 0; i < ARRAY_SIZE(jz_gpio_chips); ++i, ++chip) {
                gpio = chip->gpio_chip.base;
                chip->suspend_mask = readl(GPIO_TO_REG(gpio, JZ_REG_GPIO_MASK));
                writel(~(chip->wakeup), GPIO_TO_REG(gpio, JZ_REG_GPIO_MASK_SET));
        }
 
+       chip = jz_gpio_chips;
+#if 0
+       for (i = 0; i < ARRAY_SIZE(jz_gpio_chips); ++i, ++chip) {
+               printk("GPIO %d: \n", i);
+               printk("\tPin: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_PIN)));
+               printk("\tData: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_DATA)));
+               printk("\tPull: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_PULL)));
+               printk("\tFunc: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_FUNC)));
+               printk("\tSelect: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_SELECT)));
+               printk("\tDirection: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_DIRECTION)));
+               printk("\tTrigger: %.8x\n", readl(CHIP_TO_REG(&chip->gpio_chip, JZ_REG_GPIO_TRIGGER)));
+       }
+#endif
+
        return 0;
 }
 
-static int jz_gpio_resume(struct sys_device *dev)
+int jz_gpio_resume(void)
 {
        struct jz_gpio_chip *chip = jz_gpio_chips;
        int i;
@@ -455,12 +472,6 @@ static int jz_gpio_resume(struct sys_device *dev)
        return 0;
 }
 
-static struct sysdev_class jz_gpio_sysdev = {
-       .name = "JZ4740 GPIO",
-       .suspend = jz_gpio_suspend,
-       .resume = jz_gpio_resume,
-};
-
 int __init jz_gpiolib_init(void)
 {
        struct jz_gpio_chip *chip = jz_gpio_chips;
@@ -480,11 +491,7 @@ int __init jz_gpiolib_init(void)
                }
        }
 
-       sysdev_class_register(&jz_gpio_sysdev);
-
        printk("JZ GPIO initalized\n");
 
        return 0;
 }
-
-
index 9fb0ceb..e7e463e 100644 (file)
 #include <asm/mach-jz4740/regs.h>
 #include <asm/mach-jz4740/clock.h>
 
+#include "clock.h"
+
 extern void jz4740_intc_suspend(void);
 extern void jz4740_intc_resume(void);
+extern void jz_gpio_suspend(void);
+extern void jz_gpio_resume(void);
 
 static int jz_pm_enter(suspend_state_t state)
 {
+       jz_gpio_suspend();
        jz4740_intc_suspend();
+       jz4740_clock_suspend();
 
        jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
 
@@ -35,7 +41,9 @@ static int jz_pm_enter(suspend_state_t state)
 
        jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
 
+       jz4740_clock_resume();
        jz4740_intc_resume();
+       jz_gpio_resume();
 
        return 0;
 }