13d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij/* 23d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * arch/arm/mach-u300/regulator.c 33d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * 43d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * Copyright (C) 2009 ST-Ericsson AB 53d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * License terms: GNU General Public License (GPL) version 2 63d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * Handle board-bound regulators and board power not related 73d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * to any devices. 83d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * Author: Linus Walleij <linus.walleij@stericsson.com> 93d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij */ 103d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij#include <linux/device.h> 113d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij#include <linux/signal.h> 123d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij#include <linux/err.h> 133d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij#include <linux/regulator/consumer.h> 143d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij/* Those are just for writing in syscon */ 153d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij#include <linux/io.h> 163d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij#include <mach/hardware.h> 173d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij#include <mach/syscon.h> 183d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 193d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij/* 203d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * Regulators that power the board and chip and which are 213d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * not copuled to specific drivers are hogged in these 223d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * instances. 233d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij */ 243d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleijstatic struct regulator *main_power_15; 253d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 263d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij/* 273d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * This function is used from pm.h to shut down the system by 283d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * resetting all regulators in turn and then disable regulator 293d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * LDO D (main power). 303d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij */ 313d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleijvoid u300_pm_poweroff(void) 323d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij{ 333d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij sigset_t old, all; 343d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 353d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij sigfillset(&all); 363d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij if (!sigprocmask(SIG_BLOCK, &all, &old)) { 373d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij /* Disable LDO D to shut down the system */ 383d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij if (main_power_15) 393d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij regulator_disable(main_power_15); 403d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij else 413d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij pr_err("regulator not available to shut down system\n"); 423d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij (void) sigprocmask(SIG_SETMASK, &old, NULL); 433d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij } 443d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij return; 453d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij} 463d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 473d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij/* 483d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * Hog the regulators needed to power up the board. 493d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij */ 503d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleijstatic int __init u300_init_boardpower(void) 513d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij{ 523d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij int err; 533d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij u32 val; 543d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 553d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij pr_info("U300: setting up board power\n"); 563d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij main_power_15 = regulator_get(NULL, "vana15"); 573d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij if (IS_ERR(main_power_15)) { 583d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij pr_err("could not get vana15"); 593d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij return PTR_ERR(main_power_15); 603d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij } 613d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij err = regulator_enable(main_power_15); 623d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij if (err) { 633d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij pr_err("could not enable vana15\n"); 643d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij return err; 653d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij } 663d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 673d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij /* 683d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * On U300 a special system controller register pulls up the DC 693d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * until the vana15 (LDO D) regulator comes up. At this point, all 703d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * regulators are set and we do not need power control via 713d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * DC ON anymore. This function will likely be moved whenever 723d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * the rest of the U300 power management is implemented. 733d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij */ 743d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij pr_info("U300: disable system controller pull-up\n"); 753d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR); 763d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij val &= ~U300_SYSCON_PMCR_DCON_ENABLE; 773d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR); 783d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 793d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij /* Register globally exported PM poweroff hook */ 803d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij pm_power_off = u300_pm_poweroff; 813d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 823d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij return 0; 833d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij} 843d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij 853d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij/* 863d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij * So at module init time we hog the regulator! 873d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleij */ 883d81277b65b5b356d81e54fa71f04868cee739e2Linus Walleijmodule_init(u300_init_boardpower); 89