View | Details | Raw Unified | Return to bug 211979
Collapse All | Expand All

(-)sys/modules/Makefile (+1 lines)
Lines 124-133 Link Here
124
	gem \
124
	gem \
125
	geom \
125
	geom \
126
	${_glxiic} \
126
	${_glxiic} \
127
	${_glxsb} \
127
	${_glxsb} \
128
	gpio \
128
	gpio \
129
	gpioshutdown \
129
	hatm \
130
	hatm \
130
	hifn \
131
	hifn \
131
	hme \
132
	hme \
132
	${_hpt27xx} \
133
	${_hpt27xx} \
133
	${_hptiop} \
134
	${_hptiop} \
(-)sys/modules/gpioshutdown/Makefile (+41 lines)
Added Link Here
1
#
2
# Copyright (c) 2012 Adrian Chadd, Xenion Pty Ltd
3
# All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
7
# are met:
8
# 1. Redistributions of source code must retain the above copyright
9
#    notice, this list of conditions and the following disclaimer,
10
#    without modification.
11
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
12
#    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13
#    redistribution must be conditioned upon including a substantially
14
#    similar Disclaimer requirement for further binary redistribution.
15
#
16
# NO WARRANTY
17
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27
# THE POSSIBILITY OF SUCH DAMAGES.
28
#
29
# $FreeBSD: stable/11/sys/modules/gpio/gpioled/Makefile 300823 2016-05-27 04:34:42Z ian $
30
#
31
32
.PATH:	${.CURDIR}/../../dev/gpioshutdown
33
34
KMOD=	gpioshutdown
35
SRCS=	gpioshutdown.c
36
SRCS+=	device_if.h bus_if.h gpio_if.h gpiobus_if.h opt_platform.h ofw_bus_if.h
37
38
CFLAGS+=  -I. -I${.CURDIR}/../../dev/gpio/
39
40
.include <bsd.kmod.mk>
41
(-)sys/dev/gpioshutdown/gpioshutdown.c (+231 lines)
Added Link Here
1
/*-
2
 * Copyright (c) 2009 Oleksandr Tymoshenko <gonzo@freebsd.org>
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 */
26
27
// gpioshutdown - written by Bob Frazier for S.F.T. Inc. http://mrp3.com/
28
//                contributed to the FreeBSD source as-is, to address 
29
//                bug report 211979
30
//
31
// This module's purpose is to reset all non-reserved GPIO pins to a default
32
// (input) state on shutdown, right before halt.  This way an external device
33
// that relies on GPIO pins being reset this way to identify a 'power off'
34
// condition can THEN detect a shutdown and power off the CPU, once it's safe.
35
//
36
// For more info, see bug 211979.
37
//
38
// This is primarily intended for the Raspberry Pi, but can be
39
// included by [or dynamically loaded into] any other kernel, as needed.
40
41
42
#include <sys/cdefs.h>
43
44
#include "opt_platform.h"
45
46
// NOTE: these headers were copied from other driver sources, and some may not be needed
47
#include <sys/param.h>
48
#include <sys/systm.h>
49
#include <sys/bus.h>
50
#include <sys/gpio.h>
51
#include <sys/kernel.h>
52
#include <sys/lock.h>
53
#include <sys/malloc.h>
54
#include <sys/module.h>
55
#include <sys/mutex.h>
56
#include <sys/conf.h>
57
#include <sys/eventhandler.h>
58
59
#include <dev/gpio/gpiobusvar.h>
60
61
#include "gpio_if.h"
62
#include "gpiobus_if.h"
63
64
//#define USE_MOD_SHUTDOWN /* uncomment to use 'MOD_SHUTDOWN' in lieu of registered event handler */
65
66
//#define DEBUG_VERBOSE /* uncomment this define this to display verbose messages */
67
68
#ifdef DEBUG_VERBOSE
69
#define INTERNAL_DEBUG_PRINT(...) printf(__VA_ARGS__)
70
#else // !DEBUG_VERBOSE
71
#define INTERNAL_DEBUG_PRINT(...)
72
#endif // DEBUG_VERBOSE
73
74
75
static void internal_do_shutdown(device_t);
76
77
// I added a handler proc so I can monitor certain things THAT way...
78
// however, I'm calling this from 'MOD_SHUTDOWN' for now
79
static int gpioshutdown_handler(module_t mod, int /*modeventtype_t*/ what, void *arg);
80
81
82
static void internal_do_shutdown(device_t dev)
83
{
84
int max_pin, res, caps, pin, val;
85
86
  INTERNAL_DEBUG_PRINT("gpioshutdown - internal_do_shutdown\n");
87
88
  // this is where I do all the work.  for now, just assume all non-reserved
89
  // GPIO pins are to be converted to inputs without pull up/down resistors,
90
  // and that reserved pins will fail when I check the caps against the pin
91
92
	res = GPIO_PIN_MAX(dev, &max_pin);
93
94
  for(pin=0; pin < max_pin; pin++)
95
  {
96
    res = GPIO_PIN_GET(dev, pin, &val);
97
98
    if(!(val & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))) // pin is neither input nor output
99
    {
100
      INTERNAL_DEBUG_PRINT("skipping pin %d, neither input nor output\n", pin);
101
      continue;
102
    }
103
104
    // TODO:  find out whether or not this is normally a reserved pin, such as having
105
    //        an 'ALT' designation in the broadcom implementation...
106
    //        (this is to correct the apparent bug caused by all of the I/O pin definitions
107
    //        being assigned to 'input' within the array, but not on the actual pin)
108
109
		res = GPIO_PIN_GETCAPS(dev, pin, &caps);
110
		if (res == 0)
111
		{
112
      res = gpio_check_flags(caps, GPIO_PIN_INPUT);
113
114
      if (res == 0) // assume this excludes reserved GPIO pins
115
      {
116
        res = GPIO_PIN_SETFLAGS(dev, pin, GPIO_PIN_INPUT);
117
118
        if(val == GPIO_PIN_INPUT)
119
        {
120
          INTERNAL_DEBUG_PRINT("set flags on input pin %d, result=%d\n", pin, res);
121
        }
122
        else
123
        {
124
          INTERNAL_DEBUG_PRINT("set flags on output pin %d, result=%d\n", pin, res);
125
        }
126
      }
127
      else
128
      {
129
        INTERNAL_DEBUG_PRINT("skipping pin %d, flags don't match caps (%xH)\n", pin, caps);
130
      }
131
    }
132
    else
133
    {
134
      INTERNAL_DEBUG_PRINT("skipping pin %d, no caps\n", pin);
135
    }
136
  }
137
138
  INTERNAL_DEBUG_PRINT("gpioshutdown - internal_do_shutdown - done, max_pin=%d\n", max_pin);
139
}
140
141
142
#ifndef USE_MOD_SHUTDOWN
143
static eventhandler_tag evt_tag; // uncomment if I register an event handler instead
144
#endif // !USE_MOD_SHUTDOWN
145
146
static int internal_shutdown_final(void *arg1)
147
{
148
devclass_t dc;
149
device_t dev;
150
int nMaxUnit, nUnit;
151
152
153
//  INTERNAL_DEBUG_PRINT("gpioshutdown - internal_shutdown_final\n");
154
  printf("gpioshutdown - I/O pin reset begin ...");
155
156
  // scan for all gpio drivers, call internal_do_shutdown
157
158
  dc = devclass_find("gpio"); // we want all of the GPIO device class drivers
159
160
  if(dc)
161
  {
162
    nMaxUnit = devclass_get_maxunit(dc);
163
164
    for(nUnit=0; nUnit < nMaxUnit; nUnit++)
165
    {
166
      dev = devclass_get_device(dc, nUnit);
167
168
      if(dev)
169
      {
170
        INTERNAL_DEBUG_PRINT("gpioshutdown - internal_shutdown_final - temporary, doing unit %d\n", nUnit);
171
        internal_do_shutdown(dev); // turn all of the IO pins into inputs
172
      }
173
    }
174
  }
175
176
  // for now, always print this message so I know when it completes
177
  printf(" complete\n");
178
179
  return 0;
180
}
181
182
static int gpioshutdown_handler(module_t mod, int what, void *arg)
183
{
184
int err=0;
185
186
  switch(what)
187
  {
188
    case MOD_LOAD:
189
      INTERNAL_DEBUG_PRINT("gpioshutdown_handler - module load\n");
190
191
#ifndef USE_MOD_SHUTDOWN
192
      evt_tag = EVENTHANDLER_REGISTER(shutdown_final, internal_shutdown_final, 0, EVENTHANDLER_PRI_LAST);
193
#endif // !USE_MOD_SHUTDOWN
194
195
      break;
196
    
197
    case MOD_UNLOAD:
198
#ifndef USE_MOD_SHUTDOWN
199
      EVENTHANDLER_DEREGISTER(shutdown_final, evt_tag);
200
#endif // !USE_MOD_SHUTDOWN
201
202
      INTERNAL_DEBUG_PRINT("gpioshutdown_handler - module unload\n");
203
      break;
204
205
    case MOD_SHUTDOWN:
206
#ifdef USE_MOD_SHUTDOWN
207
      internal_shutdown_final(0); // do the GPIO shutdown from the 'MOD_SHUTDOWN' event
208
#endif // !USE_MOD_SHUTDOWN
209
210
      INTERNAL_DEBUG_PRINT("gpioshutdown_handler - module shutdown\n");
211
      break;
212
213
    case MOD_QUIESCE:
214
      INTERNAL_DEBUG_PRINT("gpioshutdown_handler - module quiesce\n");
215
      break;
216
217
    default:
218
      INTERNAL_DEBUG_PRINT("gpioshutdown_handler - module command %d (err)\n", what);
219
      err = EINVAL;
220
      break;
221
  }
222
223
  return err;
224
}
225
226
// this is a simple module, can be dynamically loaded
227
228
DEV_MODULE(gpioshutdown, gpioshutdown_handler, 0);
229
MODULE_VERSION(gpioshutdown, 1);
230
231

Return to bug 211979