Commit de4fb5f5 authored by Hans de Goede's avatar Hans de Goede

Merge tag 'ib-pdx86-backlight-6.4' into review-hans

Immutable branch between pdx86 and backlight due for the v6.4 merge window
parents b59018c1 3608a2cd
...@@ -206,7 +206,6 @@ config APPLE_GMUX ...@@ -206,7 +206,6 @@ config APPLE_GMUX
depends on ACPI && PCI depends on ACPI && PCI
depends on PNP depends on PNP
depends on BACKLIGHT_CLASS_DEVICE depends on BACKLIGHT_CLASS_DEVICE
depends on BACKLIGHT_APPLE=n || BACKLIGHT_APPLE
help help
This driver provides support for the gmux device found on many This driver provides support for the gmux device found on many
Apple laptops, which controls the display mux for the hybrid Apple laptops, which controls the display mux for the hybrid
......
This diff is collapsed.
...@@ -285,6 +285,7 @@ config BACKLIGHT_MT6370 ...@@ -285,6 +285,7 @@ config BACKLIGHT_MT6370
config BACKLIGHT_APPLE config BACKLIGHT_APPLE
tristate "Apple Backlight Driver" tristate "Apple Backlight Driver"
depends on X86 && ACPI depends on X86 && ACPI
depends on ACPI_VIDEO=n || ACPI_VIDEO
help help
If you have an Intel-based Apple say Y to enable a driver for its If you have an Intel-based Apple say Y to enable a driver for its
backlight. backlight.
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/apple_bl.h> #include <acpi/video.h>
static struct backlight_device *apple_backlight_device; static struct backlight_device *apple_backlight_device;
...@@ -215,32 +215,21 @@ static struct acpi_driver apple_bl_driver = { ...@@ -215,32 +215,21 @@ static struct acpi_driver apple_bl_driver = {
}, },
}; };
static atomic_t apple_bl_registered = ATOMIC_INIT(0);
int apple_bl_register(void)
{
if (atomic_xchg(&apple_bl_registered, 1) == 0)
return acpi_bus_register_driver(&apple_bl_driver);
return 0;
}
EXPORT_SYMBOL_GPL(apple_bl_register);
void apple_bl_unregister(void)
{
if (atomic_xchg(&apple_bl_registered, 0) == 1)
acpi_bus_unregister_driver(&apple_bl_driver);
}
EXPORT_SYMBOL_GPL(apple_bl_unregister);
static int __init apple_bl_init(void) static int __init apple_bl_init(void)
{ {
return apple_bl_register(); /*
* Use ACPI video detection code to see if this driver should register
* or if another driver, e.g. the apple-gmux driver should be used.
*/
if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
return -ENODEV;
return acpi_bus_register_driver(&apple_bl_driver);
} }
static void __exit apple_bl_exit(void) static void __exit apple_bl_exit(void)
{ {
apple_bl_unregister(); acpi_bus_unregister_driver(&apple_bl_driver);
} }
module_init(apple_bl_init); module_init(apple_bl_init);
......
...@@ -34,8 +34,20 @@ ...@@ -34,8 +34,20 @@
#define GMUX_PORT_READ 0xd0 #define GMUX_PORT_READ 0xd0
#define GMUX_PORT_WRITE 0xd4 #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) #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) #if IS_ENABLED(CONFIG_APPLE_GMUX)
static inline bool apple_gmux_is_indexed(unsigned long iostart) static inline bool apple_gmux_is_indexed(unsigned long iostart)
{ {
...@@ -52,11 +64,29 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart) ...@@ -52,11 +64,29 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart)
return false; 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 * apple_gmux_detect() - detect if gmux is built into the machine
* *
* @pnp_dev: Device to probe or NULL to use the first matching device * @pnp_dev: Device to probe or NULL to use the first matching device
* @indexed_ret: Returns (by reference) if the gmux is indexed or not * @type_ret: Returns (by reference) the apple_gmux_type of the device
* *
* Detect if a supported gmux device is present by actually probing it. * Detect if a supported gmux device is present by actually probing it.
* This avoids the false positives returned on some models by * This avoids the false positives returned on some models by
...@@ -65,13 +95,13 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart) ...@@ -65,13 +95,13 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart)
* Return: %true if a supported gmux ACPI device is detected and the kernel * Return: %true if a supported gmux ACPI device is detected and the kernel
* was configured with CONFIG_APPLE_GMUX, %false otherwise. * was configured with CONFIG_APPLE_GMUX, %false otherwise.
*/ */
static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool *indexed_ret) static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_type *type_ret)
{ {
u8 ver_major, ver_minor, ver_release; u8 ver_major, ver_minor, ver_release;
struct device *dev = NULL; struct device *dev = NULL;
struct acpi_device *adev; struct acpi_device *adev;
struct resource *res; struct resource *res;
bool indexed = false; enum apple_gmux_type type = APPLE_GMUX_TYPE_PIO;
bool ret = false; bool ret = false;
if (!pnp_dev) { if (!pnp_dev) {
...@@ -88,24 +118,30 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool *indexed_ret) ...@@ -88,24 +118,30 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool *indexed_ret)
} }
res = pnp_get_resource(pnp_dev, IORESOURCE_IO, 0); res = pnp_get_resource(pnp_dev, IORESOURCE_IO, 0);
if (!res || resource_size(res) < GMUX_MIN_IO_LEN) 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.
* 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_major = inb(res->start + GMUX_PORT_VERSION_MAJOR); ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE);
ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR); if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE); if (apple_gmux_is_indexed(res->start))
if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { type = APPLE_GMUX_TYPE_INDEXED;
indexed = apple_gmux_is_indexed(res->start); else
if (!indexed) 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; goto out;
} }
if (indexed_ret) if (type_ret)
*indexed_ret = indexed; *type_ret = type;
ret = true; ret = true;
out: out:
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* apple_bl exported symbols
*/
#ifndef _LINUX_APPLE_BL_H
#define _LINUX_APPLE_BL_H
#if defined(CONFIG_BACKLIGHT_APPLE) || defined(CONFIG_BACKLIGHT_APPLE_MODULE)
extern int apple_bl_register(void);
extern void apple_bl_unregister(void);
#else /* !CONFIG_BACKLIGHT_APPLE */
static inline int apple_bl_register(void)
{
return 0;
}
static inline void apple_bl_unregister(void)
{
}
#endif /* !CONFIG_BACKLIGHT_APPLE */
#endif /* _LINUX_APPLE_BL_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment