summaryrefslogtreecommitdiffstats
path: root/include/linux/apple-gmux.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/apple-gmux.h')
-rw-r--r--include/linux/apple-gmux.h56
1 files changed, 43 insertions, 13 deletions
diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h
index 147dc1c52e08..272f63f8fd7c 100644
--- a/include/linux/apple-gmux.h
+++ b/include/linux/apple-gmux.h
@@ -34,11 +34,18 @@
#define GMUX_PORT_READ 0xd0
#define GMUX_PORT_WRITE 0xd4
+#define GMUX_MMIO_PORT_SELECT 0x0e
+#define GMUX_MMIO_COMMAND_SEND 0x0f
+
+#define GMUX_MMIO_READ 0x00
+#define GMUX_MMIO_WRITE 0x40
+
#define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4)
enum apple_gmux_type {
APPLE_GMUX_TYPE_PIO,
APPLE_GMUX_TYPE_INDEXED,
+ APPLE_GMUX_TYPE_MMIO,
};
#if IS_ENABLED(CONFIG_APPLE_GMUX)
@@ -57,6 +64,24 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart)
return false;
}
+static inline bool apple_gmux_is_mmio(unsigned long iostart)
+{
+ u8 *__iomem iomem_base = ioremap(iostart, 16);
+ u8 val;
+
+ if (!iomem_base)
+ return false;
+
+ /*
+ * If this is 0xff, then gmux must not be present, as the gmux would
+ * reset it to 0x00, or it would be one of 0x1, 0x4, 0x41, 0x44 if a
+ * command is currently being processed.
+ */
+ val = ioread8(iomem_base + GMUX_MMIO_COMMAND_SEND);
+ iounmap(iomem_base);
+ return (val != 0xff);
+}
+
/**
* apple_gmux_detect() - detect if gmux is built into the machine
*
@@ -93,19 +118,24 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_ty
}
res = pnp_get_resource(pnp_dev, IORESOURCE_IO, 0);
- if (!res || resource_size(res) < GMUX_MIN_IO_LEN)
- goto out;
-
- /*
- * Invalid version information may indicate either that the gmux
- * device isn't present or that it's a new one that uses indexed io.
- */
- ver_major = inb(res->start + GMUX_PORT_VERSION_MAJOR);
- ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR);
- ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE);
- if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
- if (apple_gmux_is_indexed(res->start))
- type = APPLE_GMUX_TYPE_INDEXED;
+ if (res && resource_size(res) >= GMUX_MIN_IO_LEN) {
+ /*
+ * Invalid version information may indicate either that the gmux
+ * device isn't present or that it's a new one that uses indexed io.
+ */
+ ver_major = inb(res->start + GMUX_PORT_VERSION_MAJOR);
+ ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR);
+ ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE);
+ if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
+ if (apple_gmux_is_indexed(res->start))
+ type = APPLE_GMUX_TYPE_INDEXED;
+ else
+ goto out;
+ }
+ } else {
+ res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0);
+ if (res && apple_gmux_is_mmio(res->start))
+ type = APPLE_GMUX_TYPE_MMIO;
else
goto out;
}