• Nx32926 命令关机


    一. poweroff关机命令

    ~ # poweroff
    ~ # baud=115200, quot=102
    w-config: 8bits/char
    umount: devtmpfs busy - remounted read-only
    Cannot open value file.
    umount: can't remount rootfs reabaud=115200, quot=102
    w-config: 8bits/char
    d-only
    cannot run '/sbin/swapoff': No such file or dirRTL871X: rtw_cmd_thread(wlan0) _rtw_down_sema(&pcmdpriv->cmd_queue_sema) return _FAIL, break
    ectory
    The system is going down NOW!
    Sent SIGTERM to all processes
    videoin_close
    Sensor power down
    Sensor power down
    I2C removed
    Sent SIGKILL toPower down.
    enter to w55fa92_poweroff()

    二、内核代码

    void w55fa92_poweroff(void)
    {
        unsigned long volatile flags;
    #if defined(CONFIG_RTC_DRV_W55FA92)
        int rtc_time_out;
    #endif
    
        printk("enter to w55fa92_poweroff()
    ");
        msleep(10);
    
        // disable LVR
        __raw_writel(__raw_readl(REG_MISCR) & ~(LVR_RDY | LVR_EN), REG_MISCR);
    
        // turn off speaker
    #if defined(CONFIG_GIANTPLUS_GPM1006D0_320X240)
        __raw_writel(__raw_readl(REG_GPIOE_OMD) | (1 << 1), REG_GPIOE_OMD);
        __raw_writel(__raw_readl(REG_GPIOE_DOUT) & ~(1 << 1), REG_GPIOE_DOUT);
    #endif
    
        // turn off video out
        __raw_writel((__raw_readl(REG_LCM_TVCtl) & ~TVCtl_LCDSrc) | 0x800, REG_LCM_TVCtl);
    
        // disable system interrupts
        local_irq_save(flags);
    
    #if defined(CONFIG_RTC_DRV_W55FA92)
        __raw_writel(__raw_readl(REG_APBCLK) | RTC_CKE, REG_APBCLK);
        while (1) {
            rtc_time_out = 0;
            // enable long time press power disable
            if ((__raw_readl(REG_RTC_AER) & 0x10000) == 0x0) {
                // set RTC register access enable password
                __raw_writel(0xA965, REG_RTC_AER);
                // make sure RTC register read/write enable
                while ((__raw_readl(REG_RTC_AER) & 0x10000) == 0x0) {
                    rtc_time_out++;
                    if (rtc_time_out > 0xFFFFFF) {
                        printk("RTC Access Eanble Fail
    ");
                        break;
                    }
                }
    
                rtc_wait_ready();
    
                if ((__raw_readl(REG_RTC_AER) & 0x10000) == 0x10000)
                    break;
            }
            else
                break;
        }
    
        // RTC will power off
        __raw_writel((__raw_readl(REG_RTC_PWRON) & ~0x5) | 0x2, REG_RTC_PWRON);
    #else
        // turn off power
        __raw_writel(__raw_readl(REG_GPIOE_OMD) | (1<<9), REG_GPIOE_OMD);
        __raw_writel(__raw_readl(REG_GPIOE_DOUT) & ~(1<<9), REG_GPIOE_DOUT);
    #endif
    
        // enable system interrupts
        local_irq_restore(flags);
    
        // stop CPU clock
        //__raw_writel(__raw_readl(REG_AHBCLK) & ~CPU_CKE, REG_AHBCLK);
        // fix RTC may wakeup fail issue
        __raw_writel(0x0, REG_AHBCLK);
    
        // wait system enter power off
        while (1) ;
    }
    
    void w55fa92_reboot(void)
    {
        unsigned long volatile flags;
    
        local_irq_save(flags);
        printk("enter to w55fa92_reboot()
    ");
    
        // turn off speaker
    #if defined(CONFIG_GIANTPLUS_GPM1006D0_320X240)
        __raw_writel(__raw_readl(REG_GPIOE_OMD) | (1 << 1), REG_GPIOE_OMD);
        __raw_writel(__raw_readl(REG_GPIOE_DOUT) & ~(1 << 1), REG_GPIOE_DOUT);
    #endif
    
        // turn off video out
        __raw_writel((__raw_readl(REG_LCM_TVCtl) & ~TVCtl_LCDSrc) | 0x800, REG_LCM_TVCtl);
    
        // close NAND and SIC engine clock
        __raw_writel(__raw_readl(REG_AHBCLK) & ~(NAND_CKE|SIC_CKE), REG_AHBCLK);
    
        // watchdog reset
        __raw_writel((__raw_readl(REG_WTCR) & ~(3<<4|1<<10))|0x2C2, REG_WTCR);
    
        // wait system enter power off
        while (1) ;
        local_irq_restore(flags);
    }
    
    static ssize_t
    write_clk(struct device *dev, struct device_attribute *attr,
          const char *buffer, size_t count)
    {
        int i;
    
        // power down mode
        if (buffer[0] == 'p' && buffer[1] == 'd') {
            w55fa92_pm_suspend(1);
        }
    
    #if 0
        // idle mode or memory idle mode
        else if ((buffer[0] == 'i' && buffer[1] == 'd') || (buffer[0] == 'm' && buffer[1] == 'i')) {
            w55fa92_pm_idle();
        }
    #endif
    
    #if defined(CONFIG_RTC_DRV_W55FA92)
        // RTC power off mode
        else if (buffer[0] == 'r' && buffer[1] == 'p' && buffer[2] == 'o') {
            w55fa92_poweroff();
        }
    #else
        // power off mode
        else if (buffer[0] == 'p' && buffer[1] == 'o') {
            w55fa92_poweroff();
        }
    #endif
    
        // power reset mode
        else if (buffer[0] == 'p' && buffer[1] == 'r') {
            w55fa92_reboot();
        }
    
        // CPU:PLL clock change
        else {
            u32 pll_clock, sys_clock, cpu_clock, apb_clock, vpost_clock;
            u8 vpost_div_N0, vpost_div_N1;
            char clock_buf[64];
            char *clock1, *clock2, *next;
    
            strncpy(clock_buf, buffer, count);
            next = &clock_buf[0];
            pll_clock = w55fa92_upll_clock;
            clock1 = strsep(&next, ":");
            //printk("clock1 = %s
    ", clock1);
            cpu_clock = simple_strtol(clock1, NULL, 10) * 1000;
            if (cpu_clock == 0) {
                printk("Command "%s" does not support !!
    ", clock1);
                return -1;
            }
            if (next) {
                clock2 = strsep(&next, ":");
                //printk("clock2 = %s
    ", clock2);
                pll_clock = simple_strtol(clock2, NULL, 10) * 1000;
                if (pll_clock == 0) {
                    printk("Command "%s" does not support !!
    ", clock2);
                    return -1;
                }
            }
    
            if (pll_clock % cpu_clock) {
                printk("UPLL clock(%d) is not a multiple of CPU clock(%d) !!
    ", 
                    pll_clock, cpu_clock);
                return -1;
            }
    
    #if defined(CONFIG_FB_W55FA92)
            vpost_div_N0 = (__raw_readl(REG_CLKDIV1) & VPOST_N0) + 1;
            vpost_div_N1 = ((__raw_readl(REG_CLKDIV1) & VPOST_N1) >> 8) + 1;
            vpost_clock = pll_clock / (vpost_div_N0 * vpost_div_N1);
            if (cpu_clock > vpost_clock*2) {
                sys_clock = cpu_clock;
            } else {
                for (i = 1; ; i++) {
                    sys_clock = cpu_clock * i * 2;
                    if ((i > 8) || (sys_clock > pll_clock)) {
                        printk("Cannot get valid System clock !!
    "); 
                        return -1;
                    }
                    if ((sys_clock>(vpost_clock*2)) && ((pll_clock%sys_clock)==0))
                        break;
                }
            }
    #else
            sys_clock = cpu_clock;
    #endif
            apb_clock = (cpu_clock == sys_clock) ? cpu_clock/4 : cpu_clock/2;
    #if CPU_DEBUG
            printk("vpost_clock = %d
    ", vpost_clock);
            printk("pll_clock = %d
    ", pll_clock);
            printk("sys_clock = %d
    ", sys_clock);
            printk("cpu_clock = %d
    ", cpu_clock);
            printk("apb_clock = %d
    ", apb_clock);
    #endif
    
            // PLL:SYS:CPU:AHB:APB = pll_clock:sys_clock:cpu_clock:sys_clock/2:apb_clock
            set_system_clocks(pll_clock, sys_clock, cpu_clock, apb_clock);
        }
    
        return count;
    }
    
    /* Attach the sysfs write method */
    DEVICE_ATTR(clock, 0644, read_clk, write_clk);
    
    /* Attribute Descriptor */
    static struct attribute *clk_attrs[] = {
        &dev_attr_clock.attr,
        NULL
    };
    
    /* Attribute group */
    static struct attribute_group clk_attr_group = {
        .attrs = clk_attrs,
    };
    
    static int __init w55fa92_system_clock_init(void)
    {
        /* Register a platform device */
        printk("register clock device
    ");
    
      ///sys/devices/w55fa92-clk sys_clk
    = platform_device_register_simple("w55fa92-clk", -1, NULL, 0); if (sys_clk == NULL) printk("register failed "); sysfs_create_group(&sys_clk->dev.kobj, &clk_attr_group); sram_vaddr = ioremap(0xFF000000, 4*1024); return 0; } module_init(w55fa92_system_clock_init);
  • 相关阅读:
    全栈必备Linux 基础
    Linux 的 Socket IO 模型
    Vim
    Linux 下使用 Sar 简介
    提高效率,推荐 5 款命令行工具
    Vim小技巧
    剑指Offer 矩形覆盖
    剑指Offer 变态跳台阶
    剑指Offer 跳台阶
    2016 网易校招内推C/C++第二场8.6
  • 原文地址:https://www.cnblogs.com/cslunatic/p/5660663.html
Copyright © 2020-2023  润新知