- 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"
1219 lines
36 KiB
Diff
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
|
|
|