Version:  2.6.34 2.6.35 2.6.36 2.6.37 2.6.38 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14

Linux/drivers/power/reset/vexpress-poweroff.c

  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 #include <linux/jiffies.h>
 15 #include <linux/of.h>
 16 #include <linux/of_device.h>
 17 #include <linux/platform_device.h>
 18 #include <linux/stat.h>
 19 #include <linux/vexpress.h>
 20 
 21 #include <asm/system_misc.h>
 22 
 23 static void vexpress_reset_do(struct device *dev, const char *what)
 24 {
 25         int err = -ENOENT;
 26         struct vexpress_config_func *func =
 27                         vexpress_config_func_get_by_dev(dev);
 28 
 29         if (func) {
 30                 unsigned long timeout;
 31 
 32                 err = vexpress_config_write(func, 0, 0);
 33 
 34                 timeout = jiffies + HZ;
 35                 while (time_before(jiffies, timeout))
 36                         cpu_relax();
 37         }
 38 
 39         dev_emerg(dev, "Unable to %s (%d)\n", what, err);
 40 }
 41 
 42 static struct device *vexpress_power_off_device;
 43 
 44 static void vexpress_power_off(void)
 45 {
 46         vexpress_reset_do(vexpress_power_off_device, "power off");
 47 }
 48 
 49 static struct device *vexpress_restart_device;
 50 
 51 static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd)
 52 {
 53         vexpress_reset_do(vexpress_restart_device, "restart");
 54 }
 55 
 56 static ssize_t vexpress_reset_active_show(struct device *dev,
 57                 struct device_attribute *attr, char *buf)
 58 {
 59         return sprintf(buf, "%d\n", vexpress_restart_device == dev);
 60 }
 61 
 62 static ssize_t vexpress_reset_active_store(struct device *dev,
 63                 struct device_attribute *attr, const char *buf, size_t count)
 64 {
 65         long value;
 66         int err = kstrtol(buf, 0, &value);
 67 
 68         if (!err && value)
 69                 vexpress_restart_device = dev;
 70 
 71         return err ? err : count;
 72 }
 73 
 74 DEVICE_ATTR(active, S_IRUGO | S_IWUSR, vexpress_reset_active_show,
 75                 vexpress_reset_active_store);
 76 
 77 
 78 enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT };
 79 
 80 static struct of_device_id vexpress_reset_of_match[] = {
 81         {
 82                 .compatible = "arm,vexpress-reset",
 83                 .data = (void *)FUNC_RESET,
 84         }, {
 85                 .compatible = "arm,vexpress-shutdown",
 86                 .data = (void *)FUNC_SHUTDOWN
 87         }, {
 88                 .compatible = "arm,vexpress-reboot",
 89                 .data = (void *)FUNC_REBOOT
 90         },
 91         {}
 92 };
 93 
 94 static int vexpress_reset_probe(struct platform_device *pdev)
 95 {
 96         enum vexpress_reset_func func;
 97         const struct of_device_id *match =
 98                         of_match_device(vexpress_reset_of_match, &pdev->dev);
 99 
100         if (match)
101                 func = (enum vexpress_reset_func)match->data;
102         else
103                 func = pdev->id_entry->driver_data;
104 
105         switch (func) {
106         case FUNC_SHUTDOWN:
107                 vexpress_power_off_device = &pdev->dev;
108                 pm_power_off = vexpress_power_off;
109                 break;
110         case FUNC_RESET:
111                 if (!vexpress_restart_device)
112                         vexpress_restart_device = &pdev->dev;
113                 arm_pm_restart = vexpress_restart;
114                 device_create_file(&pdev->dev, &dev_attr_active);
115                 break;
116         case FUNC_REBOOT:
117                 vexpress_restart_device = &pdev->dev;
118                 arm_pm_restart = vexpress_restart;
119                 device_create_file(&pdev->dev, &dev_attr_active);
120                 break;
121         };
122 
123         return 0;
124 }
125 
126 static const struct platform_device_id vexpress_reset_id_table[] = {
127         { .name = "vexpress-reset", .driver_data = FUNC_RESET, },
128         { .name = "vexpress-shutdown", .driver_data = FUNC_SHUTDOWN, },
129         { .name = "vexpress-reboot", .driver_data = FUNC_REBOOT, },
130         {}
131 };
132 
133 static struct platform_driver vexpress_reset_driver = {
134         .probe = vexpress_reset_probe,
135         .driver = {
136                 .name = "vexpress-reset",
137                 .of_match_table = vexpress_reset_of_match,
138         },
139         .id_table = vexpress_reset_id_table,
140 };
141 
142 static int __init vexpress_reset_init(void)
143 {
144         return platform_driver_register(&vexpress_reset_driver);
145 }
146 device_initcall(vexpress_reset_init);
147 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us