~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/platforms/85xx/sgy_cts1000.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Servergy CTS-1000 Setup
  4  *
  5  * Maintained by Ben Collins <ben.c@servergy.com>
  6  *
  7  * Copyright 2012 by Servergy, Inc.
  8  */
  9 
 10 #define pr_fmt(fmt) "gpio-halt: " fmt
 11 
 12 #include <linux/err.h>
 13 #include <linux/platform_device.h>
 14 #include <linux/device.h>
 15 #include <linux/gpio/consumer.h>
 16 #include <linux/module.h>
 17 #include <linux/of_irq.h>
 18 #include <linux/workqueue.h>
 19 #include <linux/reboot.h>
 20 #include <linux/interrupt.h>
 21 
 22 #include <asm/machdep.h>
 23 
 24 static struct gpio_desc *halt_gpio;
 25 static int halt_irq;
 26 
 27 static const struct of_device_id child_match[] = {
 28         {
 29                 .compatible = "sgy,gpio-halt",
 30         },
 31         {},
 32 };
 33 
 34 static void gpio_halt_wfn(struct work_struct *work)
 35 {
 36         /* Likely wont return */
 37         orderly_poweroff(true);
 38 }
 39 static DECLARE_WORK(gpio_halt_wq, gpio_halt_wfn);
 40 
 41 static void __noreturn gpio_halt_cb(void)
 42 {
 43         pr_info("triggering GPIO.\n");
 44 
 45         /* Probably wont return */
 46         gpiod_set_value(halt_gpio, 1);
 47 
 48         panic("Halt failed\n");
 49 }
 50 
 51 /* This IRQ means someone pressed the power button and it is waiting for us
 52  * to handle the shutdown/poweroff. */
 53 static irqreturn_t gpio_halt_irq(int irq, void *__data)
 54 {
 55         struct platform_device *pdev = __data;
 56 
 57         dev_info(&pdev->dev, "scheduling shutdown due to power button IRQ\n");
 58         schedule_work(&gpio_halt_wq);
 59 
 60         return IRQ_HANDLED;
 61 };
 62 
 63 static int __gpio_halt_probe(struct platform_device *pdev,
 64                              struct device_node *halt_node)
 65 {
 66         int err;
 67 
 68         halt_gpio = fwnode_gpiod_get_index(of_fwnode_handle(halt_node),
 69                                            NULL, 0, GPIOD_OUT_LOW, "gpio-halt");
 70         err = PTR_ERR_OR_ZERO(halt_gpio);
 71         if (err) {
 72                 dev_err(&pdev->dev, "failed to request halt GPIO: %d\n", err);
 73                 return err;
 74         }
 75 
 76         /* Now get the IRQ which tells us when the power button is hit */
 77         halt_irq = irq_of_parse_and_map(halt_node, 0);
 78         err = request_irq(halt_irq, gpio_halt_irq,
 79                           IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 80                           "gpio-halt", pdev);
 81         if (err) {
 82                 dev_err(&pdev->dev, "failed to request IRQ %d: %d\n",
 83                         halt_irq, err);
 84                 gpiod_put(halt_gpio);
 85                 halt_gpio = NULL;
 86                 return err;
 87         }
 88 
 89         /* Register our halt function */
 90         ppc_md.halt = gpio_halt_cb;
 91         pm_power_off = gpio_halt_cb;
 92 
 93         dev_info(&pdev->dev, "registered halt GPIO, irq: %d\n", halt_irq);
 94 
 95         return 0;
 96 }
 97 
 98 static int gpio_halt_probe(struct platform_device *pdev)
 99 {
100         struct device_node *halt_node;
101         int ret;
102 
103         if (!pdev->dev.of_node)
104                 return -ENODEV;
105 
106         /* If there's no matching child, this isn't really an error */
107         halt_node = of_find_matching_node(pdev->dev.of_node, child_match);
108         if (!halt_node)
109                 return -ENODEV;
110 
111         ret = __gpio_halt_probe(pdev, halt_node);
112         of_node_put(halt_node);
113 
114         return ret;
115 }
116 
117 static void gpio_halt_remove(struct platform_device *pdev)
118 {
119         free_irq(halt_irq, pdev);
120         cancel_work_sync(&gpio_halt_wq);
121 
122         ppc_md.halt = NULL;
123         pm_power_off = NULL;
124 
125         gpiod_put(halt_gpio);
126         halt_gpio = NULL;
127 }
128 
129 static const struct of_device_id gpio_halt_match[] = {
130         /* We match on the gpio bus itself and scan the children since they
131          * wont be matched against us. We know the bus wont match until it
132          * has been registered too. */
133         {
134                 .compatible = "fsl,qoriq-gpio",
135         },
136         {},
137 };
138 MODULE_DEVICE_TABLE(of, gpio_halt_match);
139 
140 static struct platform_driver gpio_halt_driver = {
141         .driver = {
142                 .name           = "gpio-halt",
143                 .of_match_table = gpio_halt_match,
144         },
145         .probe          = gpio_halt_probe,
146         .remove_new     = gpio_halt_remove,
147 };
148 
149 module_platform_driver(gpio_halt_driver);
150 
151 MODULE_DESCRIPTION("Driver to support GPIO triggered system halt for Servergy CTS-1000 Systems.");
152 MODULE_VERSION("1.0");
153 MODULE_AUTHOR("Ben Collins <ben.c@servergy.com>");
154 MODULE_LICENSE("GPL");
155 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php