Skip to content

Commit

Permalink
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/mjg59/platform-drivers-x86

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86:
  platform/x86: move rfkill for Dell Mini 1012 to compal-laptop
  thinkpad-acpi: Add KEY_CAMERA (Fn-F6) for Lenovo keyboards
  thinkpad-acpi: add support for model-specific keymaps
  thinkpad-acpi: lock down size of hotkey keymap
  thinkpad-acpi: untangle ACPI/vendor backlight selection
  thinkpad-acpi: find ACPI video device by synthetic HID
  intel_ips: potential null dereference
  drivers/platform/x86: Adjust confusing if indentation
  x86: intel_ips: do not use PCI resources before pci_enable_device()
  • Loading branch information
Linus Torvalds committed Aug 18, 2010
2 parents 351f13d + c3f755e commit 472db19
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 91 deletions.
4 changes: 4 additions & 0 deletions Documentation/laptops/thinkpad-acpi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,10 @@ ThinkPad-specific interface. The driver will disable its native
backlight brightness control interface if it detects that the standard
ACPI interface is available in the ThinkPad.

If you want to use the thinkpad-acpi backlight brightness control
instead of the generic ACPI video backlight brightness control for some
reason, you should use the acpi_backlight=vendor kernel parameter.

The brightness_enable module parameter can be used to control whether
the LCD brightness control feature will be enabled when available.
brightness_enable=0 forces it to be disabled. brightness_enable=1
Expand Down
6 changes: 4 additions & 2 deletions drivers/platform/x86/asus_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -938,10 +938,11 @@ static int set_brightness(int value)
/* SPLV laptop */
if (hotk->methods->brightness_set) {
if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set,
value, NULL))
value, NULL)) {
printk(KERN_WARNING
"Asus ACPI: Error changing brightness\n");
ret = -EIO;
}
goto out;
}

Expand All @@ -953,10 +954,11 @@ static int set_brightness(int value)
hotk->methods->brightness_down,
NULL, NULL);
(value > 0) ? value-- : value++;
if (ACPI_FAILURE(status))
if (ACPI_FAILURE(status)) {
printk(KERN_WARNING
"Asus ACPI: Error changing brightness\n");
ret = -EIO;
}
}
out:
return ret;
Expand Down
9 changes: 9 additions & 0 deletions drivers/platform/x86/compal-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,14 @@ static struct dmi_system_id __initdata compal_dmi_table[] = {
},
.callback = dmi_check_cb
},
{
.ident = "Dell Mini 1012",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
},
.callback = dmi_check_cb
},
{
.ident = "Dell Inspiron 11z",
.matches = {
Expand Down Expand Up @@ -1092,5 +1100,6 @@ MODULE_ALIAS("dmi:*:rnJHL90:rvrREFERENCE:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1012:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*");
7 changes: 7 additions & 0 deletions drivers/platform/x86/dell-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"),
},
},
{
.ident = "Dell Mini 1012",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
},
},
{
.ident = "Dell Inspiron 11z",
.matches = {
Expand Down
15 changes: 9 additions & 6 deletions drivers/platform/x86/intel_ips.c
Original file line number Diff line number Diff line change
Expand Up @@ -1342,8 +1342,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips)
limits = &ips_lv_limits;
else if (strstr(boot_cpu_data.x86_model_id, "CPU U"))
limits = &ips_ulv_limits;
else
else {
dev_info(&ips->dev->dev, "No CPUID match found.\n");
goto out;
}

rdmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_power);
tdp = turbo_power & TURBO_TDP_MASK;
Expand Down Expand Up @@ -1432,6 +1434,12 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)

spin_lock_init(&ips->turbo_status_lock);

ret = pci_enable_device(dev);
if (ret) {
dev_err(&dev->dev, "can't enable PCI device, aborting\n");
goto error_free;
}

if (!pci_resource_start(dev, 0)) {
dev_err(&dev->dev, "TBAR not assigned, aborting\n");
ret = -ENXIO;
Expand All @@ -1444,11 +1452,6 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto error_free;
}

ret = pci_enable_device(dev);
if (ret) {
dev_err(&dev->dev, "can't enable PCI device, aborting\n");
goto error_free;
}

ips->regmap = ioremap(pci_resource_start(dev, 0),
pci_resource_len(dev, 0));
Expand Down
171 changes: 88 additions & 83 deletions drivers/platform/x86/thinkpad_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,17 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */
TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
TP_ACPI_HOTKEYSCAN_MUTE,
TP_ACPI_HOTKEYSCAN_THINKPAD,
TP_ACPI_HOTKEYSCAN_UNK1,
TP_ACPI_HOTKEYSCAN_UNK2,
TP_ACPI_HOTKEYSCAN_UNK3,
TP_ACPI_HOTKEYSCAN_UNK4,
TP_ACPI_HOTKEYSCAN_UNK5,
TP_ACPI_HOTKEYSCAN_UNK6,
TP_ACPI_HOTKEYSCAN_UNK7,
TP_ACPI_HOTKEYSCAN_UNK8,

/* Hotkey keymap size */
TPACPI_HOTKEY_MAP_LEN
};

enum { /* Keys/events available through NVRAM polling */
Expand Down Expand Up @@ -3082,6 +3093,8 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
};

typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];

static int __init hotkey_init(struct ibm_init_struct *iibm)
{
/* Requirements for changing the default keymaps:
Expand Down Expand Up @@ -3113,9 +3126,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
* If the above is too much to ask, don't change the keymap.
* Ask the thinkpad-acpi maintainer to do it, instead.
*/
static u16 ibm_keycode_map[] __initdata = {

enum keymap_index {
TPACPI_KEYMAP_IBM_GENERIC = 0,
TPACPI_KEYMAP_LENOVO_GENERIC,
};

static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = {
/* Generic keymap for IBM ThinkPads */
[TPACPI_KEYMAP_IBM_GENERIC] = {
/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP,
KEY_FN_F1, KEY_BATTERY, KEY_COFFEE, KEY_SLEEP,
KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,

Expand Down Expand Up @@ -3146,11 +3167,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
};
static u16 lenovo_keycode_map[] __initdata = {
},

/* Generic keymap for Lenovo ThinkPads */
[TPACPI_KEYMAP_LENOVO_GENERIC] = {
/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
KEY_WLAN, KEY_CAMERA, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,

/* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
Expand Down Expand Up @@ -3189,11 +3212,25 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
},
};

static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = {
/* Generic maps (fallback) */
{
.vendor = PCI_VENDOR_ID_IBM,
.bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
.quirks = TPACPI_KEYMAP_IBM_GENERIC,
},
{
.vendor = PCI_VENDOR_ID_LENOVO,
.bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
.quirks = TPACPI_KEYMAP_LENOVO_GENERIC,
},
};

#define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map)
#define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map)
#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0])
#define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t)
#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_t[0])

int res, i;
int status;
Expand All @@ -3202,6 +3239,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
bool tabletsw_state = false;

unsigned long quirks;
unsigned long keymap_id;

vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"initializing hotkey subdriver\n");
Expand Down Expand Up @@ -3342,7 +3380,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
goto err_exit;

/* Set up key map */

hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
GFP_KERNEL);
if (!hotkey_keycode_map) {
Expand All @@ -3352,17 +3389,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
goto err_exit;
}

if (tpacpi_is_lenovo()) {
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using Lenovo default hot key map\n");
memcpy(hotkey_keycode_map, &lenovo_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
} else {
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using IBM default hot key map\n");
memcpy(hotkey_keycode_map, &ibm_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
}
keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
ARRAY_SIZE(tpacpi_keymap_qtable));
BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using keymap number %lu\n", keymap_id);

memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id],
TPACPI_HOTKEY_MAP_SIZE);

input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
Expand Down Expand Up @@ -3469,7 +3503,8 @@ static bool hotkey_notify_hotkey(const u32 hkey,
*send_acpi_ev = true;
*ignore_acpi_ev = false;

if (scancode > 0 && scancode < 0x21) {
/* HKEY event 0x1001 is scancode 0x00 */
if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) {
scancode--;
if (!(hotkey_source_mask & (1 << scancode))) {
tpacpi_input_send_key_masked(scancode);
Expand Down Expand Up @@ -6080,13 +6115,18 @@ static struct backlight_ops ibm_backlight_data = {

/* --------------------------------------------------------------------- */

/*
* Call _BCL method of video device. On some ThinkPads this will
* switch the firmware to the ACPI brightness control mode.
*/

static int __init tpacpi_query_bcl_levels(acpi_handle handle)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
int rc;

if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) {
obj = (union acpi_object *)buffer.pointer;
if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
printk(TPACPI_ERR "Unknown _BCL data, "
Expand All @@ -6103,55 +6143,22 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle)
return rc;
}

static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
u32 lvl, void *context, void **rv)
{
char name[ACPI_PATH_SEGMENT_LENGTH];
struct acpi_buffer buffer = { sizeof(name), &name };

if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
!strncmp("_BCL", name, sizeof(name) - 1)) {
BUG_ON(!rv || !*rv);
**(int **)rv = tpacpi_query_bcl_levels(handle);
return AE_CTRL_TERMINATE;
} else {
return AE_OK;
}
}

/*
* Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
*/
static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
{
int status;
acpi_handle video_device;
int bcl_levels = 0;
void *bcl_ptr = &bcl_levels;

if (!vid_handle)
TPACPI_ACPIHANDLE_INIT(vid);

if (!vid_handle)
return 0;

/*
* Search for a _BCL method, and execute it. This is safe on all
* ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
* BIOS in ACPI backlight control mode. We do NOT have to care
* about calling the _BCL method in an enabled video device, any
* will do for our purposes.
*/

status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
tpacpi_acpi_walk_find_bcl, NULL, NULL,
&bcl_ptr);
tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device);
if (video_device)
bcl_levels = tpacpi_query_bcl_levels(video_device);

if (ACPI_SUCCESS(status) && bcl_levels > 2) {
tp_features.bright_acpimode = 1;
return bcl_levels - 2;
}
tp_features.bright_acpimode = (bcl_levels > 0);

return 0;
return (bcl_levels > 2) ? (bcl_levels - 2) : 0;
}

/*
Expand Down Expand Up @@ -6244,35 +6251,33 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
if (tp_features.bright_unkfw)
return 1;

if (tp_features.bright_acpimode) {
if (acpi_video_backlight_support()) {
if (brightness_enable > 1) {
printk(TPACPI_NOTICE
"Standard ACPI backlight interface "
"available, not loading native one.\n");
return 1;
} else if (brightness_enable == 1) {
printk(TPACPI_NOTICE
"Backlight control force enabled, even if standard "
"ACPI backlight interface is available\n");
}
} else {
if (brightness_enable > 1) {
printk(TPACPI_NOTICE
"Standard ACPI backlight interface not "
"available, thinkpad_acpi native "
"brightness control enabled\n");
}
}
}

if (!brightness_enable) {
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
"brightness support disabled by "
"module parameter\n");
return 1;
}

if (acpi_video_backlight_support()) {
if (brightness_enable > 1) {
printk(TPACPI_INFO
"Standard ACPI backlight interface "
"available, not loading native one.\n");
return 1;
} else if (brightness_enable == 1) {
printk(TPACPI_WARN
"Cannot enable backlight brightness support, "
"ACPI is already handling it. Refer to the "
"acpi_backlight kernel parameter\n");
return 1;
}
} else if (tp_features.bright_acpimode && brightness_enable > 1) {
printk(TPACPI_NOTICE
"Standard ACPI backlight interface not "
"available, thinkpad_acpi native "
"brightness control enabled\n");
}

/*
* Check for module parameter bogosity, note that we
* init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
Expand Down

0 comments on commit 472db19

Please sign in to comment.