File arm64-revision.patch of Package wiringpi
Author: Dave Jones <dave.jones@canonical.com>
Description: Prefer /proc/device-tree for revision information
All later kernels provide Pi revision information via /proc/device-tree. Use
this in preference to /proc/cpuinfo, but retain fallback to the latter to
continue support for older kernels.
--- a/wiringPi/wiringPi.c
+++ b/wiringPi/wiringPi.c
@@ -70,6 +70,7 @@
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <asm/ioctl.h>
+#include <arpa/inet.h>
#include "softPwm.h"
#include "softTone.h"
@@ -727,7 +728,8 @@
static void piGpioLayoutOops (const char *why)
{
- fprintf (stderr, "Oops: Unable to determine board revision from /proc/cpuinfo\n") ;
+ fprintf (stderr, "Oops: Unable to determine board revision from /proc/device-tree/system/linux,revision\n");
+ fprintf (stderr, "or from /proc/cpuinfo\n") ;
fprintf (stderr, " -> %s\n", why) ;
fprintf (stderr, " -> You'd best google the error to find out why.\n") ;
//fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
@@ -744,8 +746,30 @@
if (gpioLayout != -1) // No point checking twice
return gpioLayout ;
+// The "/proc/device-tree/compatible" file consists of a sequence of
+// NUL-terminated strings. We expect to find brcm,bcm283[765] on pi platforms
+
+ if ((cpuFd = fopen ("/proc/device-tree/compatible", "r")) != NULL) {
+ size_t linelen;
+ linelen = fread(line, 1, sizeof(line), cpuFd);
+ fclose(cpuFd);
+ cpuFd = NULL;
+ line[linelen] = '\0';
+ c = line;
+ while ((size_t)(c - line) < linelen) {
+ if ((strncmp(c, "brcm,bcm2837", strlen(c)) == 0) ||
+ (strncmp(c, "brcm,bcm2836", strlen(c)) == 0)) {
+ gpioLayout = 2;
+ if (wiringPiDebug)
+ printf ("piGpioLayoutOops: Returning revision: %d\n", gpioLayout) ;
+ return gpioLayout;
+ }
+ c += strlen(c) + 1;
+ }
+ }
+
if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
- piGpioLayoutOops ("Unable to open /proc/cpuinfo") ;
+ piGpioLayoutOops ("Unable to open /proc/device-tree/compatible or /proc/cpuinfo") ;
// Start by looking for the Architecture to make sure we're really running
// on a Pi. I'm getting fed-up with people whinging at me because
@@ -956,47 +980,63 @@
(void)piGpioLayout () ; // Call this first to make sure all's OK. Don't care about the result.
- if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
- piGpioLayoutOops ("Unable to open /proc/cpuinfo") ;
+// The /proc/device-tree/system/linux,revision (on modern versions of Raspbian
+// and a few other distros) stores the revision code as a big-endian 32-bit
+// integer
+
+ if ((cpuFd = fopen ("/proc/device-tree/system/linux,revision", "r")) != NULL) {
+ revision = 0;
+ fread(&revision, sizeof(revision), 1, cpuFd);
+ fclose(cpuFd);
+ if (revision)
+ revision = ntohl(revision);
+ else
+ piGpioLayoutOops ("No revision in /proc/device-tree/system/linux,revision");
+ }
- while (fgets (line, 120, cpuFd) != NULL)
- if (strncmp (line, "Revision", 8) == 0)
- break ;
+ else if ((cpuFd = fopen ("/proc/cpuinfo", "r")) != NULL) {
- fclose (cpuFd) ;
+ while (fgets (line, 120, cpuFd) != NULL)
+ if (strncmp (line, "Revision", 8) == 0)
+ break ;
- if (strncmp (line, "Revision", 8) != 0)
- piGpioLayoutOops ("No \"Revision\" line") ;
+ fclose (cpuFd) ;
+
+ if (strncmp (line, "Revision", 8) != 0)
+ piGpioLayoutOops ("No \"Revision\" line") ;
// Chomp trailing CR/NL
- for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
- *c = 0 ;
-
- if (wiringPiDebug)
- printf ("piBoardId: Revision string: %s\n", line) ;
+ for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
+ *c = 0 ;
+
+ if (wiringPiDebug)
+ printf ("piBoardId: Revision string: %s\n", line) ;
// Need to work out if it's using the new or old encoding scheme:
// Scan to the first character of the revision number
- for (c = line ; *c ; ++c)
- if (*c == ':')
- break ;
+ for (c = line ; *c ; ++c)
+ if (*c == ':')
+ break ;
- if (*c != ':')
- piGpioLayoutOops ("Bogus \"Revision\" line (no colon)") ;
+ if (*c != ':')
+ piGpioLayoutOops ("Bogus \"Revision\" line (no colon)") ;
// Chomp spaces
- ++c ;
- while (isspace (*c))
++c ;
+ while (isspace (*c))
+ ++c ;
- if (!isxdigit (*c))
- piGpioLayoutOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ;
+ if (!isxdigit (*c))
+ piGpioLayoutOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ;
- revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x
+ revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x
+ }
+ else
+ piGpioLayoutOops ("Unable to open /proc/device-tree/system/linux,revision or /proc/cpuinfo") ;
// Check for new way: