Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.9-rc2 147 lines 3.9 kB view raw
1/* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License version 2 as 4 * published by the Free Software Foundation. 5 * 6 * This program is distributed in the hope that it will be useful, 7 * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 * GNU General Public License for more details. 10 * 11 * Copyright (C) 2012 ARM Limited 12 */ 13 14#define DRVNAME "vexpress-regulator" 15#define pr_fmt(fmt) DRVNAME ": " fmt 16 17#include <linux/device.h> 18#include <linux/err.h> 19#include <linux/module.h> 20#include <linux/of_device.h> 21#include <linux/regulator/driver.h> 22#include <linux/regulator/machine.h> 23#include <linux/regulator/of_regulator.h> 24#include <linux/vexpress.h> 25 26struct vexpress_regulator { 27 struct regulator_desc desc; 28 struct regulator_dev *regdev; 29 struct vexpress_config_func *func; 30}; 31 32static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) 33{ 34 struct vexpress_regulator *reg = rdev_get_drvdata(regdev); 35 u32 uV; 36 int err = vexpress_config_read(reg->func, 0, &uV); 37 38 return err ? err : uV; 39} 40 41static int vexpress_regulator_set_voltage(struct regulator_dev *regdev, 42 int min_uV, int max_uV, unsigned *selector) 43{ 44 struct vexpress_regulator *reg = rdev_get_drvdata(regdev); 45 46 return vexpress_config_write(reg->func, 0, min_uV); 47} 48 49static struct regulator_ops vexpress_regulator_ops_ro = { 50 .get_voltage = vexpress_regulator_get_voltage, 51}; 52 53static struct regulator_ops vexpress_regulator_ops = { 54 .get_voltage = vexpress_regulator_get_voltage, 55 .set_voltage = vexpress_regulator_set_voltage, 56}; 57 58static int vexpress_regulator_probe(struct platform_device *pdev) 59{ 60 int err; 61 struct vexpress_regulator *reg; 62 struct regulator_init_data *init_data; 63 struct regulator_config config = { }; 64 65 reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL); 66 if (!reg) { 67 err = -ENOMEM; 68 goto error_kzalloc; 69 } 70 71 reg->func = vexpress_config_func_get_by_dev(&pdev->dev); 72 if (!reg->func) { 73 err = -ENXIO; 74 goto error_get_func; 75 } 76 77 reg->desc.name = dev_name(&pdev->dev); 78 reg->desc.type = REGULATOR_VOLTAGE; 79 reg->desc.owner = THIS_MODULE; 80 reg->desc.continuous_voltage_range = true; 81 82 init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); 83 if (!init_data) { 84 err = -EINVAL; 85 goto error_get_regulator_init_data; 86 } 87 88 init_data->constraints.apply_uV = 0; 89 if (init_data->constraints.min_uV && init_data->constraints.max_uV) 90 reg->desc.ops = &vexpress_regulator_ops; 91 else 92 reg->desc.ops = &vexpress_regulator_ops_ro; 93 94 config.dev = &pdev->dev; 95 config.init_data = init_data; 96 config.driver_data = reg; 97 config.of_node = pdev->dev.of_node; 98 99 reg->regdev = regulator_register(&reg->desc, &config); 100 if (IS_ERR(reg->regdev)) { 101 err = PTR_ERR(reg->regdev); 102 goto error_regulator_register; 103 } 104 105 platform_set_drvdata(pdev, reg); 106 107 return 0; 108 109error_regulator_register: 110error_get_regulator_init_data: 111 vexpress_config_func_put(reg->func); 112error_get_func: 113error_kzalloc: 114 return err; 115} 116 117static int vexpress_regulator_remove(struct platform_device *pdev) 118{ 119 struct vexpress_regulator *reg = platform_get_drvdata(pdev); 120 121 vexpress_config_func_put(reg->func); 122 regulator_unregister(reg->regdev); 123 124 return 0; 125} 126 127static struct of_device_id vexpress_regulator_of_match[] = { 128 { .compatible = "arm,vexpress-volt", }, 129 { } 130}; 131 132static struct platform_driver vexpress_regulator_driver = { 133 .probe = vexpress_regulator_probe, 134 .remove = vexpress_regulator_remove, 135 .driver = { 136 .name = DRVNAME, 137 .owner = THIS_MODULE, 138 .of_match_table = vexpress_regulator_of_match, 139 }, 140}; 141 142module_platform_driver(vexpress_regulator_driver); 143 144MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>"); 145MODULE_DESCRIPTION("Versatile Express regulator"); 146MODULE_LICENSE("GPL"); 147MODULE_ALIAS("platform:vexpress-regulator");