| /* |
| * Copyright (C) 2015 Nest Labs |
| * |
| * 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. |
| * |
| * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
| * kind, whether express or implied; without even the implied warranty |
| * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #include <linux/gpio.h> |
| #include <linux/delay.h> |
| #include <linux/of.h> |
| #include <linux/of_gpio.h> |
| #include <linux/cpufreq.h> |
| |
| #ifdef CONFIG_MACH_DIAMOND3_HIGH_CPU_CLK |
| #define D3_MAX_CPU_CORE_CLK 792000 |
| #else |
| #define D3_MAX_CPU_CORE_CLK 396000 |
| #endif |
| |
| extern void (*pm_halt_system)(void); |
| extern void snvs_poweroff(void); |
| |
| static void reset_mcu(void) |
| { |
| int mcu_reset_gpio = -1; |
| struct device_node *np; |
| np = of_find_node_by_name(NULL, "sensor-mcu-gpios"); |
| if(np != NULL) |
| { |
| mcu_reset_gpio = of_get_named_gpio(np, "output-gpios", 0); |
| } |
| |
| if(gpio_is_valid(mcu_reset_gpio)) |
| { |
| /* Drop down reset pin and wait for it to discharge first */ |
| gpio_direction_output(mcu_reset_gpio, 0); |
| msleep(5000); |
| /* Toggle reset pin to reset MCU */ |
| gpio_direction_output(mcu_reset_gpio, 1); |
| msleep(20); |
| gpio_direction_output(mcu_reset_gpio, 0); |
| } |
| } |
| |
| static void diamond_halt(void) |
| { |
| /* Reset MCU first so MCU can hold down VCC main*/ |
| /* do NOT perform pmic shut down, we'll rely on MCU to kill VCC main*/ |
| reset_mcu(); |
| } |
| |
| static void diamond_register_pm_halt(void) |
| { |
| pm_halt_system = diamond_halt; |
| } |
| |
| static void diamond_set_max_core_clk(void) |
| { |
| struct cpufreq_policy *policy = cpufreq_cpu_get(0); |
| if(policy != NULL) |
| { |
| policy->user_policy.max = D3_MAX_CPU_CORE_CLK; |
| cpufreq_update_policy(0); |
| } |
| } |
| |
| void diamond_late_init(void) |
| { |
| diamond_register_pm_halt(); |
| diamond_set_max_core_clk(); |
| } |
| EXPORT_SYMBOL(diamond_register_pm_halt); |
| |
| |