armbian-build/patch/kernel/archive/uefi-x86-6.18/3001-applesmc-convert-static-structures-to-drvdata.patch
Ricardo Pardini 3f909fa645 uefi: x86: current (6.12) and edge (6.18): add Apple T2 patches
- from linux-t2 project: https://github.com/t2linux/linux-t2-patches
  - https://t2linux.org/
- x86: add .config hook `custom_kernel_config__applet2()`
- original patches from t2linux for 6.18 and 6.12
- rewrite patches against v6.18-rc4 and v6.12.57
  - `7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch`
    needed special attention for correct patch attribution (missing From)
  - `1002-Put-apple-bce-in-drivers-staging` needs reordering to the
    top to avoid conflicts with EXTRAWIFI sed-based "patching"
2025-11-17 20:24:53 +01:00

1219 lines
36 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Pawlowski <paul@mrarm.io>
Date: Sun, 17 Nov 2019 23:12:55 +0100
Subject: applesmc: convert static structures to drvdata
All static data structures have been moved to an applesmc_device struct,
which is then associated with the platform device.
This change is intended to ease the migration to an acpi_device, where
static data would preferably be avoided.
Signed-off-by: Aun-Ali Zaidi <admin@kodeit.net>
---
drivers/hwmon/applesmc.c | 540 ++++++----
1 file changed, 319 insertions(+), 221 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -6,6 +6,7 @@
*
* Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
* Copyright (C) 2010 Henrik Rydberg <rydberg@euromail.se>
+ * Copyright (C) 2019 Paul Pawlowski <paul@mrarm.io>
*
* Based on hdaps.c driver:
* Copyright (C) 2005 Robert Love <rml@novell.com>
@@ -119,7 +120,7 @@ struct applesmc_entry {
};
/* Register lookup and registers common to all SMCs */
-static struct applesmc_registers {
+struct applesmc_registers {
struct mutex mutex; /* register read/write mutex */
unsigned int key_count; /* number of SMC registers */
unsigned int fan_count; /* number of fans */
@@ -133,26 +134,32 @@ static struct applesmc_registers {
bool init_complete; /* true when fully initialized */
struct applesmc_entry *cache; /* cached key entries */
const char **index; /* temperature key index */
-} smcreg = {
- .mutex = __MUTEX_INITIALIZER(smcreg.mutex),
};
-static const int debug;
-static struct platform_device *pdev;
-static s16 rest_x;
-static s16 rest_y;
-static u8 backlight_state[2];
+struct applesmc_device {
+ struct platform_device *dev;
+ struct applesmc_registers reg;
-static struct device *hwmon_dev;
-static struct input_dev *applesmc_idev;
+ s16 rest_x;
+ s16 rest_y;
-/*
- * Last index written to key_at_index sysfs file, and value to use for all other
- * key_at_index_* sysfs files.
- */
-static unsigned int key_at_index;
+ u8 backlight_state[2];
+
+ struct device *hwmon_dev;
+ struct input_dev *idev;
+
+ /*
+ * Last index written to key_at_index sysfs file, and value to use for all other
+ * key_at_index_* sysfs files.
+ */
+ unsigned int key_at_index;
+
+ struct workqueue_struct *backlight_wq;
+ struct work_struct backlight_work;
+ struct led_classdev backlight_dev;
+};
-static struct workqueue_struct *applesmc_led_wq;
+static const int debug;
/*
* Wait for specific status bits with a mask on the SMC.
@@ -338,36 +345,37 @@ static int read_register_count(unsigned int *count)
* All functions below are concurrency safe - callers should NOT hold lock.
*/
-static int applesmc_read_entry(const struct applesmc_entry *entry,
- u8 *buf, u8 len)
+static int applesmc_read_entry(struct applesmc_device *smc,
+ const struct applesmc_entry *entry, u8 *buf, u8 len)
{
int ret;
if (entry->len != len)
return -EINVAL;
- mutex_lock(&smcreg.mutex);
+ mutex_lock(&smc->reg.mutex);
ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len);
- mutex_unlock(&smcreg.mutex);
+ mutex_unlock(&smc->reg.mutex);
return ret;
}
-static int applesmc_write_entry(const struct applesmc_entry *entry,
- const u8 *buf, u8 len)
+static int applesmc_write_entry(struct applesmc_device *smc,
+ const struct applesmc_entry *entry, const u8 *buf, u8 len)
{
int ret;
if (entry->len != len)
return -EINVAL;
- mutex_lock(&smcreg.mutex);
+ mutex_lock(&smc->reg.mutex);
ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len);
- mutex_unlock(&smcreg.mutex);
+ mutex_unlock(&smc->reg.mutex);
return ret;
}
-static const struct applesmc_entry *applesmc_get_entry_by_index(int index)
+static const struct applesmc_entry *applesmc_get_entry_by_index(
+ struct applesmc_device *smc, int index)
{
- struct applesmc_entry *cache = &smcreg.cache[index];
+ struct applesmc_entry *cache = &smc->reg.cache[index];
u8 key[4], info[6];
__be32 be;
int ret = 0;
@@ -375,7 +383,7 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index)
if (cache->valid)
return cache;
- mutex_lock(&smcreg.mutex);
+ mutex_lock(&smc->reg.mutex);
if (cache->valid)
goto out;
@@ -394,20 +402,21 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index)
cache->valid = true;
out:
- mutex_unlock(&smcreg.mutex);
+ mutex_unlock(&smc->reg.mutex);
if (ret)
return ERR_PTR(ret);
return cache;
}
-static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
+static int applesmc_get_lower_bound(struct applesmc_device *smc,
+ unsigned int *lo, const char *key)
{
- int begin = 0, end = smcreg.key_count;
+ int begin = 0, end = smc->reg.key_count;
const struct applesmc_entry *entry;
while (begin != end) {
int middle = begin + (end - begin) / 2;
- entry = applesmc_get_entry_by_index(middle);
+ entry = applesmc_get_entry_by_index(smc, middle);
if (IS_ERR(entry)) {
*lo = 0;
return PTR_ERR(entry);
@@ -422,16 +431,17 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
return 0;
}
-static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
+static int applesmc_get_upper_bound(struct applesmc_device *smc,
+ unsigned int *hi, const char *key)
{
- int begin = 0, end = smcreg.key_count;
+ int begin = 0, end = smc->reg.key_count;
const struct applesmc_entry *entry;
while (begin != end) {
int middle = begin + (end - begin) / 2;
- entry = applesmc_get_entry_by_index(middle);
+ entry = applesmc_get_entry_by_index(smc, middle);
if (IS_ERR(entry)) {
- *hi = smcreg.key_count;
+ *hi = smc->reg.key_count;
return PTR_ERR(entry);
}
if (strcmp(key, entry->key) < 0)
@@ -444,50 +454,54 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
return 0;
}
-static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key)
+static const struct applesmc_entry *applesmc_get_entry_by_key(
+ struct applesmc_device *smc, const char *key)
{
int begin, end;
int ret;
- ret = applesmc_get_lower_bound(&begin, key);
+ ret = applesmc_get_lower_bound(smc, &begin, key);
if (ret)
return ERR_PTR(ret);
- ret = applesmc_get_upper_bound(&end, key);
+ ret = applesmc_get_upper_bound(smc, &end, key);
if (ret)
return ERR_PTR(ret);
if (end - begin != 1)
return ERR_PTR(-EINVAL);
- return applesmc_get_entry_by_index(begin);
+ return applesmc_get_entry_by_index(smc, begin);
}
-static int applesmc_read_key(const char *key, u8 *buffer, u8 len)
+static int applesmc_read_key(struct applesmc_device *smc,
+ const char *key, u8 *buffer, u8 len)
{
const struct applesmc_entry *entry;
- entry = applesmc_get_entry_by_key(key);
+ entry = applesmc_get_entry_by_key(smc, key);
if (IS_ERR(entry))
return PTR_ERR(entry);
- return applesmc_read_entry(entry, buffer, len);
+ return applesmc_read_entry(smc, entry, buffer, len);
}
-static int applesmc_write_key(const char *key, const u8 *buffer, u8 len)
+static int applesmc_write_key(struct applesmc_device *smc,
+ const char *key, const u8 *buffer, u8 len)
{
const struct applesmc_entry *entry;
- entry = applesmc_get_entry_by_key(key);
+ entry = applesmc_get_entry_by_key(smc, key);
if (IS_ERR(entry))
return PTR_ERR(entry);
- return applesmc_write_entry(entry, buffer, len);
+ return applesmc_write_entry(smc, entry, buffer, len);
}
-static int applesmc_has_key(const char *key, bool *value)
+static int applesmc_has_key(struct applesmc_device *smc,
+ const char *key, bool *value)
{
const struct applesmc_entry *entry;
- entry = applesmc_get_entry_by_key(key);
+ entry = applesmc_get_entry_by_key(smc, key);
if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL)
return PTR_ERR(entry);
@@ -498,12 +512,13 @@ static int applesmc_has_key(const char *key, bool *value)
/*
* applesmc_read_s16 - Read 16-bit signed big endian register
*/
-static int applesmc_read_s16(const char *key, s16 *value)
+static int applesmc_read_s16(struct applesmc_device *smc,
+ const char *key, s16 *value)
{
u8 buffer[2];
int ret;
- ret = applesmc_read_key(key, buffer, 2);
+ ret = applesmc_read_key(smc, key, buffer, 2);
if (ret)
return ret;
@@ -514,28 +529,29 @@ static int applesmc_read_s16(const char *key, s16 *value)
/*
* applesmc_device_init - initialize the accelerometer. Can sleep.
*/
-static void applesmc_device_init(void)
+static void applesmc_device_init(struct applesmc_device *smc)
{
int total;
u8 buffer[2];
- if (!smcreg.has_accelerometer)
+ if (!smc->reg.has_accelerometer)
return;
for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
- if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
+ if (!applesmc_read_key(smc, MOTION_SENSOR_KEY, buffer, 2) &&
(buffer[0] != 0x00 || buffer[1] != 0x00))
return;
buffer[0] = 0xe0;
buffer[1] = 0x00;
- applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
+ applesmc_write_key(smc, MOTION_SENSOR_KEY, buffer, 2);
msleep(INIT_WAIT_MSECS);
}
pr_warn("failed to init the device\n");
}
-static int applesmc_init_index(struct applesmc_registers *s)
+static int applesmc_init_index(struct applesmc_device *smc,
+ struct applesmc_registers *s)
{
const struct applesmc_entry *entry;
unsigned int i;
@@ -548,7 +564,7 @@ static int applesmc_init_index(struct applesmc_registers *s)
return -ENOMEM;
for (i = s->temp_begin; i < s->temp_end; i++) {
- entry = applesmc_get_entry_by_index(i);
+ entry = applesmc_get_entry_by_index(smc, i);
if (IS_ERR(entry))
continue;
if (strcmp(entry->type, TEMP_SENSOR_TYPE))
@@ -562,9 +578,9 @@ static int applesmc_init_index(struct applesmc_registers *s)
/*
* applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
*/
-static int applesmc_init_smcreg_try(void)
+static int applesmc_init_smcreg_try(struct applesmc_device *smc)
{
- struct applesmc_registers *s = &smcreg;
+ struct applesmc_registers *s = &smc->reg;
bool left_light_sensor = false, right_light_sensor = false;
unsigned int count;
u8 tmp[1];
@@ -590,35 +606,35 @@ static int applesmc_init_smcreg_try(void)
if (!s->cache)
return -ENOMEM;
- ret = applesmc_read_key(FANS_COUNT, tmp, 1);
+ ret = applesmc_read_key(smc, FANS_COUNT, tmp, 1);
if (ret)
return ret;
s->fan_count = tmp[0];
if (s->fan_count > 10)
s->fan_count = 10;
- ret = applesmc_get_lower_bound(&s->temp_begin, "T");
+ ret = applesmc_get_lower_bound(smc, &s->temp_begin, "T");
if (ret)
return ret;
- ret = applesmc_get_lower_bound(&s->temp_end, "U");
+ ret = applesmc_get_lower_bound(smc, &s->temp_end, "U");
if (ret)
return ret;
s->temp_count = s->temp_end - s->temp_begin;
- ret = applesmc_init_index(s);
+ ret = applesmc_init_index(smc, s);
if (ret)
return ret;
- ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor);
+ ret = applesmc_has_key(smc, LIGHT_SENSOR_LEFT_KEY, &left_light_sensor);
if (ret)
return ret;
- ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor);
+ ret = applesmc_has_key(smc, LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor);
if (ret)
return ret;
- ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer);
+ ret = applesmc_has_key(smc, MOTION_SENSOR_KEY, &s->has_accelerometer);
if (ret)
return ret;
- ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight);
+ ret = applesmc_has_key(smc, BACKLIGHT_KEY, &s->has_key_backlight);
if (ret)
return ret;
@@ -634,13 +650,13 @@ static int applesmc_init_smcreg_try(void)
return 0;
}
-static void applesmc_destroy_smcreg(void)
+static void applesmc_destroy_smcreg(struct applesmc_device *smc)
{
- kfree(smcreg.index);
- smcreg.index = NULL;
- kfree(smcreg.cache);
- smcreg.cache = NULL;
- smcreg.init_complete = false;
+ kfree(smc->reg.index);
+ smc->reg.index = NULL;
+ kfree(smc->reg.cache);
+ smc->reg.cache = NULL;
+ smc->reg.init_complete = false;
}
/*
@@ -649,12 +665,12 @@ static void applesmc_destroy_smcreg(void)
* Retries until initialization is successful, or the operation times out.
*
*/
-static int applesmc_init_smcreg(void)
+static int applesmc_init_smcreg(struct applesmc_device *smc)
{
int ms, ret;
for (ms = 0; ms < INIT_TIMEOUT_MSECS; ms += INIT_WAIT_MSECS) {
- ret = applesmc_init_smcreg_try();
+ ret = applesmc_init_smcreg_try(smc);
if (!ret) {
if (ms)
pr_info("init_smcreg() took %d ms\n", ms);
@@ -663,21 +679,58 @@ static int applesmc_init_smcreg(void)
msleep(INIT_WAIT_MSECS);
}
- applesmc_destroy_smcreg();
+ applesmc_destroy_smcreg(smc);
return ret;
}
/* Device model stuff */
+static int applesmc_create_modules(struct applesmc_device *smc);
+static void applesmc_destroy_modules(struct applesmc_device *smc);
static int applesmc_probe(struct platform_device *dev)
{
+ struct applesmc_device *smc;
int ret;
- ret = applesmc_init_smcreg();
+ smc = kzalloc(sizeof(struct applesmc_device), GFP_KERNEL);
+ if (!smc)
+ return -ENOMEM;
+ smc->dev = dev;
+ mutex_init(&smc->reg.mutex);
+
+ platform_set_drvdata(dev, smc);
+
+ ret = applesmc_init_smcreg(smc);
if (ret)
- return ret;
+ goto out_mem;
+
+ applesmc_device_init(smc);
+
+ ret = applesmc_create_modules(smc);
+ if (ret)
+ goto out_reg;
+
+ return 0;
+
+out_reg:
+ applesmc_destroy_smcreg(smc);
+out_mem:
+ platform_set_drvdata(dev, NULL);
+ mutex_destroy(&smc->reg.mutex);
+ kfree(smc);
- applesmc_device_init();
+ return ret;
+}
+
+static int applesmc_remove(struct platform_device *dev)
+{
+ struct applesmc_device *smc = platform_get_drvdata(dev);
+
+ applesmc_destroy_modules(smc);
+ applesmc_destroy_smcreg(smc);
+
+ mutex_destroy(&smc->reg.mutex);
+ kfree(smc);
return 0;
}
@@ -685,15 +738,21 @@ static int applesmc_probe(struct platform_device *dev)
/* Synchronize device with memorized backlight state */
static int applesmc_pm_resume(struct device *dev)
{
- if (smcreg.has_key_backlight)
- applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+
+ if (smc->reg.has_key_backlight)
+ applesmc_write_key(smc, BACKLIGHT_KEY, smc->backlight_state, 2);
+
return 0;
}
/* Reinitialize device on resume from hibernation */
static int applesmc_pm_restore(struct device *dev)
{
- applesmc_device_init();
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+
+ applesmc_device_init(smc);
+
return applesmc_pm_resume(dev);
}
@@ -704,6 +763,7 @@ static const struct dev_pm_ops applesmc_pm_ops = {
static struct platform_driver applesmc_driver = {
.probe = applesmc_probe,
+ .remove = applesmc_remove,
.driver = {
.name = "applesmc",
.pm = &applesmc_pm_ops,
@@ -714,25 +774,26 @@ static struct platform_driver applesmc_driver = {
* applesmc_calibrate - Set our "resting" values. Callers must
* hold applesmc_lock.
*/
-static void applesmc_calibrate(void)
+static void applesmc_calibrate(struct applesmc_device *smc)
{
- applesmc_read_s16(MOTION_SENSOR_X_KEY, &rest_x);
- applesmc_read_s16(MOTION_SENSOR_Y_KEY, &rest_y);
- rest_x = -rest_x;
+ applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &smc->rest_x);
+ applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &smc->rest_y);
+ smc->rest_x = -smc->rest_x;
}
static void applesmc_idev_poll(struct input_dev *idev)
{
+ struct applesmc_device *smc = dev_get_drvdata(&idev->dev);
s16 x, y;
- if (applesmc_read_s16(MOTION_SENSOR_X_KEY, &x))
+ if (applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &x))
return;
- if (applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y))
+ if (applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &y))
return;
x = -x;
- input_report_abs(idev, ABS_X, x - rest_x);
- input_report_abs(idev, ABS_Y, y - rest_y);
+ input_report_abs(idev, ABS_X, x - smc->rest_x);
+ input_report_abs(idev, ABS_Y, y - smc->rest_y);
input_sync(idev);
}
@@ -747,16 +808,17 @@ static ssize_t applesmc_name_show(struct device *dev,
static ssize_t applesmc_position_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
int ret;
s16 x, y, z;
- ret = applesmc_read_s16(MOTION_SENSOR_X_KEY, &x);
+ ret = applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &x);
if (ret)
goto out;
- ret = applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y);
+ ret = applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &y);
if (ret)
goto out;
- ret = applesmc_read_s16(MOTION_SENSOR_Z_KEY, &z);
+ ret = applesmc_read_s16(smc, MOTION_SENSOR_Z_KEY, &z);
if (ret)
goto out;
@@ -770,6 +832,7 @@ static ssize_t applesmc_position_show(struct device *dev,
static ssize_t applesmc_light_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
const struct applesmc_entry *entry;
static int data_length;
int ret;
@@ -777,7 +840,7 @@ static ssize_t applesmc_light_show(struct device *dev,
u8 buffer[10];
if (!data_length) {
- entry = applesmc_get_entry_by_key(LIGHT_SENSOR_LEFT_KEY);
+ entry = applesmc_get_entry_by_key(smc, LIGHT_SENSOR_LEFT_KEY);
if (IS_ERR(entry))
return PTR_ERR(entry);
if (entry->len > 10)
@@ -786,7 +849,7 @@ static ssize_t applesmc_light_show(struct device *dev,
pr_info("light sensor data length set to %d\n", data_length);
}
- ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
+ ret = applesmc_read_key(smc, LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
if (ret)
goto out;
/* newer macbooks report a single 10-bit bigendian value */
@@ -796,7 +859,7 @@ static ssize_t applesmc_light_show(struct device *dev,
}
left = buffer[2];
- ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
+ ret = applesmc_read_key(smc, LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
if (ret)
goto out;
right = buffer[2];
@@ -812,7 +875,8 @@ static ssize_t applesmc_light_show(struct device *dev,
static ssize_t applesmc_show_sensor_label(struct device *dev,
struct device_attribute *devattr, char *sysfsbuf)
{
- const char *key = smcreg.index[to_index(devattr)];
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+ const char *key = smc->reg.index[to_index(devattr)];
return sysfs_emit(sysfsbuf, "%s\n", key);
}
@@ -821,12 +885,13 @@ static ssize_t applesmc_show_sensor_label(struct device *dev,
static ssize_t applesmc_show_temperature(struct device *dev,
struct device_attribute *devattr, char *sysfsbuf)
{
- const char *key = smcreg.index[to_index(devattr)];
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+ const char *key = smc->reg.index[to_index(devattr)];
int ret;
s16 value;
int temp;
- ret = applesmc_read_s16(key, &value);
+ ret = applesmc_read_s16(smc, key, &value);
if (ret)
return ret;
@@ -838,6 +903,7 @@ static ssize_t applesmc_show_temperature(struct device *dev,
static ssize_t applesmc_show_fan_speed(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
int ret;
unsigned int speed = 0;
char newkey[5];
@@ -846,7 +912,7 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)],
to_index(attr));
- ret = applesmc_read_key(newkey, buffer, 2);
+ ret = applesmc_read_key(smc, newkey, buffer, 2);
if (ret)
return ret;
@@ -858,6 +924,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
struct device_attribute *attr,
const char *sysfsbuf, size_t count)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
int ret;
unsigned long speed;
char newkey[5];
@@ -871,7 +938,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
buffer[0] = (speed >> 6) & 0xff;
buffer[1] = (speed << 2) & 0xff;
- ret = applesmc_write_key(newkey, buffer, 2);
+ ret = applesmc_write_key(smc, newkey, buffer, 2);
if (ret)
return ret;
@@ -882,11 +949,12 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
static ssize_t applesmc_show_fan_manual(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
int ret;
u16 manual = 0;
u8 buffer[2];
- ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
+ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2);
if (ret)
return ret;
@@ -898,6 +966,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
struct device_attribute *attr,
const char *sysfsbuf, size_t count)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
int ret;
u8 buffer[2];
unsigned long input;
@@ -906,7 +975,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
if (kstrtoul(sysfsbuf, 10, &input) < 0)
return -EINVAL;
- ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
+ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2);
if (ret)
goto out;
@@ -920,7 +989,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
buffer[0] = (val >> 8) & 0xFF;
buffer[1] = val & 0xFF;
- ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
+ ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2);
out:
if (ret)
@@ -932,13 +1001,14 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
static ssize_t applesmc_show_fan_position(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
int ret;
char newkey[5];
u8 buffer[17];
scnprintf(newkey, sizeof(newkey), FAN_ID_FMT, to_index(attr));
- ret = applesmc_read_key(newkey, buffer, 16);
+ ret = applesmc_read_key(smc, newkey, buffer, 16);
buffer[16] = 0;
if (ret)
@@ -950,30 +1020,36 @@ static ssize_t applesmc_show_fan_position(struct device *dev,
static ssize_t applesmc_calibrate_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
- return sysfs_emit(sysfsbuf, "(%d,%d)\n", rest_x, rest_y);
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+
+ return sysfs_emit(sysfsbuf, "(%d,%d)\n", smc->rest_x, smc->rest_y);
}
static ssize_t applesmc_calibrate_store(struct device *dev,
struct device_attribute *attr, const char *sysfsbuf, size_t count)
{
- applesmc_calibrate();
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+
+ applesmc_calibrate(smc);
return count;
}
static void applesmc_backlight_set(struct work_struct *work)
{
- applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
+ struct applesmc_device *smc = container_of(work, struct applesmc_device, backlight_work);
+
+ applesmc_write_key(smc, BACKLIGHT_KEY, smc->backlight_state, 2);
}
-static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
static void applesmc_brightness_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
+ struct applesmc_device *smc = dev_get_drvdata(led_cdev->dev);
int ret;
- backlight_state[0] = value;
- ret = queue_work(applesmc_led_wq, &backlight_work);
+ smc->backlight_state[0] = value;
+ ret = queue_work(smc->backlight_wq, &smc->backlight_work);
if (debug && (!ret))
dev_dbg(led_cdev->dev, "work was already on the queue.\n");
@@ -982,11 +1058,12 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev,
static ssize_t applesmc_key_count_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
int ret;
u8 buffer[4];
u32 count;
- ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
+ ret = applesmc_read_key(smc, KEY_COUNT_KEY, buffer, 4);
if (ret)
return ret;
@@ -998,13 +1075,14 @@ static ssize_t applesmc_key_count_show(struct device *dev,
static ssize_t applesmc_key_at_index_read_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
const struct applesmc_entry *entry;
int ret;
- entry = applesmc_get_entry_by_index(key_at_index);
+ entry = applesmc_get_entry_by_index(smc, smc->key_at_index);
if (IS_ERR(entry))
return PTR_ERR(entry);
- ret = applesmc_read_entry(entry, sysfsbuf, entry->len);
+ ret = applesmc_read_entry(smc, entry, sysfsbuf, entry->len);
if (ret)
return ret;
@@ -1014,9 +1092,10 @@ static ssize_t applesmc_key_at_index_read_show(struct device *dev,
static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
const struct applesmc_entry *entry;
- entry = applesmc_get_entry_by_index(key_at_index);
+ entry = applesmc_get_entry_by_index(smc, smc->key_at_index);
if (IS_ERR(entry))
return PTR_ERR(entry);
@@ -1026,9 +1105,10 @@ static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
static ssize_t applesmc_key_at_index_type_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
const struct applesmc_entry *entry;
- entry = applesmc_get_entry_by_index(key_at_index);
+ entry = applesmc_get_entry_by_index(smc, smc->key_at_index);
if (IS_ERR(entry))
return PTR_ERR(entry);
@@ -1038,9 +1118,10 @@ static ssize_t applesmc_key_at_index_type_show(struct device *dev,
static ssize_t applesmc_key_at_index_name_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
const struct applesmc_entry *entry;
- entry = applesmc_get_entry_by_index(key_at_index);
+ entry = applesmc_get_entry_by_index(smc, smc->key_at_index);
if (IS_ERR(entry))
return PTR_ERR(entry);
@@ -1050,28 +1131,25 @@ static ssize_t applesmc_key_at_index_name_show(struct device *dev,
static ssize_t applesmc_key_at_index_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
- return sysfs_emit(sysfsbuf, "%d\n", key_at_index);
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+
+ return sysfs_emit(sysfsbuf, "%d\n", smc->key_at_index);
}
static ssize_t applesmc_key_at_index_store(struct device *dev,
struct device_attribute *attr, const char *sysfsbuf, size_t count)
{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
unsigned long newkey;
if (kstrtoul(sysfsbuf, 10, &newkey) < 0
- || newkey >= smcreg.key_count)
+ || newkey >= smc->reg.key_count)
return -EINVAL;
- key_at_index = newkey;
+ smc->key_at_index = newkey;
return count;
}
-static struct led_classdev applesmc_backlight = {
- .name = "smc::kbd_backlight",
- .default_trigger = "nand-disk",
- .brightness_set = applesmc_brightness_set,
-};
-
static struct applesmc_node_group info_group[] = {
{ "name", applesmc_name_show },
{ "key_count", applesmc_key_count_show },
@@ -1116,14 +1194,15 @@ static struct applesmc_node_group temp_group[] = {
/*
* applesmc_destroy_nodes - remove files and free associated memory
*/
-static void applesmc_destroy_nodes(struct applesmc_node_group *groups)
+static void applesmc_destroy_nodes(struct applesmc_device *smc,
+ struct applesmc_node_group *groups)
{
struct applesmc_node_group *grp;
struct applesmc_dev_attr *node;
for (grp = groups; grp->nodes; grp++) {
for (node = grp->nodes; node->sda.dev_attr.attr.name; node++)
- sysfs_remove_file(&pdev->dev.kobj,
+ sysfs_remove_file(&smc->dev->dev.kobj,
&node->sda.dev_attr.attr);
kfree(grp->nodes);
grp->nodes = NULL;
@@ -1133,7 +1212,8 @@ static void applesmc_destroy_nodes(struct applesmc_node_group *groups)
/*
* applesmc_create_nodes - create a two-dimensional group of sysfs files
*/
-static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
+static int applesmc_create_nodes(struct applesmc_device *smc,
+ struct applesmc_node_group *groups, int num)
{
struct applesmc_node_group *grp;
struct applesmc_dev_attr *node;
@@ -1157,7 +1237,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
sysfs_attr_init(attr);
attr->name = node->name;
attr->mode = 0444 | (grp->store ? 0200 : 0);
- ret = sysfs_create_file(&pdev->dev.kobj, attr);
+ ret = sysfs_create_file(&smc->dev->dev.kobj, attr);
if (ret) {
attr->name = NULL;
goto out;
@@ -1167,57 +1247,57 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
return 0;
out:
- applesmc_destroy_nodes(groups);
+ applesmc_destroy_nodes(smc, groups);
return ret;
}
/* Create accelerometer resources */
-static int applesmc_create_accelerometer(void)
+static int applesmc_create_accelerometer(struct applesmc_device *smc)
{
int ret;
- if (!smcreg.has_accelerometer)
+ if (!smc->reg.has_accelerometer)
return 0;
- ret = applesmc_create_nodes(accelerometer_group, 1);
+ ret = applesmc_create_nodes(smc, accelerometer_group, 1);
if (ret)
goto out;
- applesmc_idev = input_allocate_device();
- if (!applesmc_idev) {
+ smc->idev = input_allocate_device();
+ if (!smc->idev) {
ret = -ENOMEM;
goto out_sysfs;
}
/* initial calibrate for the input device */
- applesmc_calibrate();
+ applesmc_calibrate(smc);
/* initialize the input device */
- applesmc_idev->name = "applesmc";
- applesmc_idev->id.bustype = BUS_HOST;
- applesmc_idev->dev.parent = &pdev->dev;
- input_set_abs_params(applesmc_idev, ABS_X,
+ smc->idev->name = "applesmc";
+ smc->idev->id.bustype = BUS_HOST;
+ smc->idev->dev.parent = &smc->dev->dev;
+ input_set_abs_params(smc->idev, ABS_X,
-256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
- input_set_abs_params(applesmc_idev, ABS_Y,
+ input_set_abs_params(smc->idev, ABS_Y,
-256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
- ret = input_setup_polling(applesmc_idev, applesmc_idev_poll);
+ ret = input_setup_polling(smc->idev, applesmc_idev_poll);
if (ret)
goto out_idev;
- input_set_poll_interval(applesmc_idev, APPLESMC_POLL_INTERVAL);
+ input_set_poll_interval(smc->idev, APPLESMC_POLL_INTERVAL);
- ret = input_register_device(applesmc_idev);
+ ret = input_register_device(smc->idev);
if (ret)
goto out_idev;
return 0;
out_idev:
- input_free_device(applesmc_idev);
+ input_free_device(smc->idev);
out_sysfs:
- applesmc_destroy_nodes(accelerometer_group);
+ applesmc_destroy_nodes(smc, accelerometer_group);
out:
pr_warn("driver init failed (ret=%d)!\n", ret);
@@ -1225,44 +1305,55 @@ static int applesmc_create_accelerometer(void)
}
/* Release all resources used by the accelerometer */
-static void applesmc_release_accelerometer(void)
+static void applesmc_release_accelerometer(struct applesmc_device *smc)
{
- if (!smcreg.has_accelerometer)
+ if (!smc->reg.has_accelerometer)
return;
- input_unregister_device(applesmc_idev);
- applesmc_destroy_nodes(accelerometer_group);
+ input_unregister_device(smc->idev);
+ applesmc_destroy_nodes(smc, accelerometer_group);
}
-static int applesmc_create_light_sensor(void)
+static int applesmc_create_light_sensor(struct applesmc_device *smc)
{
- if (!smcreg.num_light_sensors)
+ if (!smc->reg.num_light_sensors)
return 0;
- return applesmc_create_nodes(light_sensor_group, 1);
+ return applesmc_create_nodes(smc, light_sensor_group, 1);
}
-static void applesmc_release_light_sensor(void)
+static void applesmc_release_light_sensor(struct applesmc_device *smc)
{
- if (!smcreg.num_light_sensors)
+ if (!smc->reg.num_light_sensors)
return;
- applesmc_destroy_nodes(light_sensor_group);
+ applesmc_destroy_nodes(smc, light_sensor_group);
}
-static int applesmc_create_key_backlight(void)
+static int applesmc_create_key_backlight(struct applesmc_device *smc)
{
- if (!smcreg.has_key_backlight)
+ int ret;
+
+ if (!smc->reg.has_key_backlight)
return 0;
- applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
- if (!applesmc_led_wq)
+ smc->backlight_wq = create_singlethread_workqueue("applesmc-led");
+ if (!smc->backlight_wq)
return -ENOMEM;
- return led_classdev_register(&pdev->dev, &applesmc_backlight);
+
+ INIT_WORK(&smc->backlight_work, applesmc_backlight_set);
+ smc->backlight_dev.name = "smc::kbd_backlight";
+ smc->backlight_dev.default_trigger = "nand-disk";
+ smc->backlight_dev.brightness_set = applesmc_brightness_set;
+ ret = led_classdev_register(&smc->dev->dev, &smc->backlight_dev);
+ if (ret)
+ destroy_workqueue(smc->backlight_wq);
+
+ return ret;
}
-static void applesmc_release_key_backlight(void)
+static void applesmc_release_key_backlight(struct applesmc_device *smc)
{
- if (!smcreg.has_key_backlight)
+ if (!smc->reg.has_key_backlight)
return;
- led_classdev_unregister(&applesmc_backlight);
- destroy_workqueue(applesmc_led_wq);
+ led_classdev_unregister(&smc->backlight_dev);
+ destroy_workqueue(smc->backlight_wq);
}
static int applesmc_dmi_match(const struct dmi_system_id *id)
@@ -1306,86 +1397,100 @@ static const struct dmi_system_id applesmc_whitelist[] __initconst = {
{ .ident = NULL }
};
-static int __init applesmc_init(void)
+static int applesmc_create_modules(struct applesmc_device *smc)
{
int ret;
- if (!dmi_check_system(applesmc_whitelist)) {
- pr_warn("supported laptop not found!\n");
- ret = -ENODEV;
- goto out;
- }
-
- if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
- "applesmc")) {
- ret = -ENXIO;
- goto out;
- }
-
- ret = platform_driver_register(&applesmc_driver);
- if (ret)
- goto out_region;
-
- pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
- NULL, 0);
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- goto out_driver;
- }
-
- /* create register cache */
- ret = applesmc_init_smcreg();
- if (ret)
- goto out_device;
-
- ret = applesmc_create_nodes(info_group, 1);
+ ret = applesmc_create_nodes(smc, info_group, 1);
if (ret)
- goto out_smcreg;
+ goto out;
- ret = applesmc_create_nodes(fan_group, smcreg.fan_count);
+ ret = applesmc_create_nodes(smc, fan_group, smc->reg.fan_count);
if (ret)
goto out_info;
- ret = applesmc_create_nodes(temp_group, smcreg.index_count);
+ ret = applesmc_create_nodes(smc, temp_group, smc->reg.index_count);
if (ret)
goto out_fans;
- ret = applesmc_create_accelerometer();
+ ret = applesmc_create_accelerometer(smc);
if (ret)
goto out_temperature;
- ret = applesmc_create_light_sensor();
+ ret = applesmc_create_light_sensor(smc);
if (ret)
goto out_accelerometer;
- ret = applesmc_create_key_backlight();
+ ret = applesmc_create_key_backlight(smc);
if (ret)
goto out_light_sysfs;
- hwmon_dev = hwmon_device_register(&pdev->dev);
- if (IS_ERR(hwmon_dev)) {
- ret = PTR_ERR(hwmon_dev);
+ smc->hwmon_dev = hwmon_device_register(&smc->dev->dev);
+ if (IS_ERR(smc->hwmon_dev)) {
+ ret = PTR_ERR(smc->hwmon_dev);
goto out_light_ledclass;
}
return 0;
out_light_ledclass:
- applesmc_release_key_backlight();
+ applesmc_release_key_backlight(smc);
out_light_sysfs:
- applesmc_release_light_sensor();
+ applesmc_release_light_sensor(smc);
out_accelerometer:
- applesmc_release_accelerometer();
+ applesmc_release_accelerometer(smc);
out_temperature:
- applesmc_destroy_nodes(temp_group);
+ applesmc_destroy_nodes(smc, temp_group);
out_fans:
- applesmc_destroy_nodes(fan_group);
+ applesmc_destroy_nodes(smc, fan_group);
out_info:
- applesmc_destroy_nodes(info_group);
-out_smcreg:
- applesmc_destroy_smcreg();
-out_device:
- platform_device_unregister(pdev);
+ applesmc_destroy_nodes(smc, info_group);
+out:
+ return ret;
+}
+
+static void applesmc_destroy_modules(struct applesmc_device *smc)
+{
+ hwmon_device_unregister(smc->hwmon_dev);
+ applesmc_release_key_backlight(smc);
+ applesmc_release_light_sensor(smc);
+ applesmc_release_accelerometer(smc);
+ applesmc_destroy_nodes(smc, temp_group);
+ applesmc_destroy_nodes(smc, fan_group);
+ applesmc_destroy_nodes(smc, info_group);
+}
+
+static struct platform_device *pdev;
+
+static int __init applesmc_init(void)
+{
+ int ret;
+
+ if (!dmi_check_system(applesmc_whitelist)) {
+ pr_warn("supported laptop not found!\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
+ "applesmc")) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ ret = platform_driver_register(&applesmc_driver);
+ if (ret)
+ goto out_region;
+
+ pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
+ NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto out_driver;
+ }
+
+ return 0;
+
out_driver:
platform_driver_unregister(&applesmc_driver);
out_region:
@@ -1397,14 +1502,6 @@ static int __init applesmc_init(void)
static void __exit applesmc_exit(void)
{
- hwmon_device_unregister(hwmon_dev);
- applesmc_release_key_backlight();
- applesmc_release_light_sensor();
- applesmc_release_accelerometer();
- applesmc_destroy_nodes(temp_group);
- applesmc_destroy_nodes(fan_group);
- applesmc_destroy_nodes(info_group);
- applesmc_destroy_smcreg();
platform_device_unregister(pdev);
platform_driver_unregister(&applesmc_driver);
release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
@@ -1414,6 +1511,7 @@ module_init(applesmc_init);
module_exit(applesmc_exit);
MODULE_AUTHOR("Nicolas Boichat");
+MODULE_AUTHOR("Paul Pawlowski");
MODULE_DESCRIPTION("Apple SMC");
MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);
--
Armbian