diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/eeprom/at24.c | 43 | ||||
-rw-r--r-- | drivers/misc/ioc4.c | 29 | ||||
-rw-r--r-- | drivers/misc/vmw_balloon.c | 13 |
3 files changed, 54 insertions, 31 deletions
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 559b0b3c16c3..ab1ad41786d1 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/log2.h> | 20 | #include <linux/log2.h> |
21 | #include <linux/bitops.h> | 21 | #include <linux/bitops.h> |
22 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
23 | #include <linux/of.h> | ||
23 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
24 | #include <linux/i2c/at24.h> | 25 | #include <linux/i2c/at24.h> |
25 | 26 | ||
@@ -457,6 +458,27 @@ static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf, | |||
457 | 458 | ||
458 | /*-------------------------------------------------------------------------*/ | 459 | /*-------------------------------------------------------------------------*/ |
459 | 460 | ||
461 | #ifdef CONFIG_OF | ||
462 | static void at24_get_ofdata(struct i2c_client *client, | ||
463 | struct at24_platform_data *chip) | ||
464 | { | ||
465 | const __be32 *val; | ||
466 | struct device_node *node = client->dev.of_node; | ||
467 | |||
468 | if (node) { | ||
469 | if (of_get_property(node, "read-only", NULL)) | ||
470 | chip->flags |= AT24_FLAG_READONLY; | ||
471 | val = of_get_property(node, "pagesize", NULL); | ||
472 | if (val) | ||
473 | chip->page_size = be32_to_cpup(val); | ||
474 | } | ||
475 | } | ||
476 | #else | ||
477 | static void at24_get_ofdata(struct i2c_client *client, | ||
478 | struct at24_platform_data *chip) | ||
479 | { } | ||
480 | #endif /* CONFIG_OF */ | ||
481 | |||
460 | static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) | 482 | static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) |
461 | { | 483 | { |
462 | struct at24_platform_data chip; | 484 | struct at24_platform_data chip; |
@@ -485,6 +507,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
485 | */ | 507 | */ |
486 | chip.page_size = 1; | 508 | chip.page_size = 1; |
487 | 509 | ||
510 | /* update chipdata if OF is present */ | ||
511 | at24_get_ofdata(client, &chip); | ||
512 | |||
488 | chip.setup = NULL; | 513 | chip.setup = NULL; |
489 | chip.context = NULL; | 514 | chip.context = NULL; |
490 | } | 515 | } |
@@ -492,6 +517,11 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
492 | if (!is_power_of_2(chip.byte_len)) | 517 | if (!is_power_of_2(chip.byte_len)) |
493 | dev_warn(&client->dev, | 518 | dev_warn(&client->dev, |
494 | "byte_len looks suspicious (no power of 2)!\n"); | 519 | "byte_len looks suspicious (no power of 2)!\n"); |
520 | if (!chip.page_size) { | ||
521 | dev_err(&client->dev, "page_size must not be 0!\n"); | ||
522 | err = -EINVAL; | ||
523 | goto err_out; | ||
524 | } | ||
495 | if (!is_power_of_2(chip.page_size)) | 525 | if (!is_power_of_2(chip.page_size)) |
496 | dev_warn(&client->dev, | 526 | dev_warn(&client->dev, |
497 | "page_size looks suspicious (no power of 2)!\n"); | 527 | "page_size looks suspicious (no power of 2)!\n"); |
@@ -597,19 +627,15 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
597 | 627 | ||
598 | i2c_set_clientdata(client, at24); | 628 | i2c_set_clientdata(client, at24); |
599 | 629 | ||
600 | dev_info(&client->dev, "%zu byte %s EEPROM %s\n", | 630 | dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n", |
601 | at24->bin.size, client->name, | 631 | at24->bin.size, client->name, |
602 | writable ? "(writable)" : "(read-only)"); | 632 | writable ? "writable" : "read-only", at24->write_max); |
603 | if (use_smbus == I2C_SMBUS_WORD_DATA || | 633 | if (use_smbus == I2C_SMBUS_WORD_DATA || |
604 | use_smbus == I2C_SMBUS_BYTE_DATA) { | 634 | use_smbus == I2C_SMBUS_BYTE_DATA) { |
605 | dev_notice(&client->dev, "Falling back to %s reads, " | 635 | dev_notice(&client->dev, "Falling back to %s reads, " |
606 | "performance will suffer\n", use_smbus == | 636 | "performance will suffer\n", use_smbus == |
607 | I2C_SMBUS_WORD_DATA ? "word" : "byte"); | 637 | I2C_SMBUS_WORD_DATA ? "word" : "byte"); |
608 | } | 638 | } |
609 | dev_dbg(&client->dev, | ||
610 | "page_size %d, num_addresses %d, write_max %d, use_smbus %d\n", | ||
611 | chip.page_size, num_addresses, | ||
612 | at24->write_max, use_smbus); | ||
613 | 639 | ||
614 | /* export data to kernel code */ | 640 | /* export data to kernel code */ |
615 | if (chip.setup) | 641 | if (chip.setup) |
@@ -660,6 +686,11 @@ static struct i2c_driver at24_driver = { | |||
660 | 686 | ||
661 | static int __init at24_init(void) | 687 | static int __init at24_init(void) |
662 | { | 688 | { |
689 | if (!io_limit) { | ||
690 | pr_err("at24: io_limit must not be 0!\n"); | ||
691 | return -EINVAL; | ||
692 | } | ||
693 | |||
663 | io_limit = rounddown_pow_of_two(io_limit); | 694 | io_limit = rounddown_pow_of_two(io_limit); |
664 | return i2c_add_driver(&at24_driver); | 695 | return i2c_add_driver(&at24_driver); |
665 | } | 696 | } |
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 193206602d88..668d41e594a9 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c | |||
@@ -273,13 +273,11 @@ ioc4_variant(struct ioc4_driver_data *idd) | |||
273 | static void __devinit | 273 | static void __devinit |
274 | ioc4_load_modules(struct work_struct *work) | 274 | ioc4_load_modules(struct work_struct *work) |
275 | { | 275 | { |
276 | /* arg just has to be freed */ | ||
277 | |||
278 | request_module("sgiioc4"); | 276 | request_module("sgiioc4"); |
279 | |||
280 | kfree(work); | ||
281 | } | 277 | } |
282 | 278 | ||
279 | static DECLARE_WORK(ioc4_load_modules_work, ioc4_load_modules); | ||
280 | |||
283 | /* Adds a new instance of an IOC4 card */ | 281 | /* Adds a new instance of an IOC4 card */ |
284 | static int __devinit | 282 | static int __devinit |
285 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | 283 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) |
@@ -396,21 +394,12 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
396 | * PCI device. | 394 | * PCI device. |
397 | */ | 395 | */ |
398 | if (idd->idd_variant != IOC4_VARIANT_PCI_RT) { | 396 | if (idd->idd_variant != IOC4_VARIANT_PCI_RT) { |
399 | struct work_struct *work; | 397 | /* Request the module from a work procedure as the modprobe |
400 | work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); | 398 | * goes out to a userland helper and that will hang if done |
401 | if (!work) { | 399 | * directly from ioc4_probe(). |
402 | printk(KERN_WARNING | 400 | */ |
403 | "%s: IOC4 unable to allocate memory for " | 401 | printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n"); |
404 | "load of sub-modules.\n", __func__); | 402 | schedule_work(&ioc4_load_modules_work); |
405 | } else { | ||
406 | /* Request the module from a work procedure as the | ||
407 | * modprobe goes out to a userland helper and that | ||
408 | * will hang if done directly from ioc4_probe(). | ||
409 | */ | ||
410 | printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n"); | ||
411 | INIT_WORK(work, ioc4_load_modules); | ||
412 | schedule_work(work); | ||
413 | } | ||
414 | } | 403 | } |
415 | 404 | ||
416 | return 0; | 405 | return 0; |
@@ -498,7 +487,7 @@ static void __exit | |||
498 | ioc4_exit(void) | 487 | ioc4_exit(void) |
499 | { | 488 | { |
500 | /* Ensure ioc4_load_modules() has completed before exiting */ | 489 | /* Ensure ioc4_load_modules() has completed before exiting */ |
501 | flush_scheduled_work(); | 490 | flush_work_sync(&ioc4_load_modules_work); |
502 | pci_unregister_driver(&ioc4_driver); | 491 | pci_unregister_driver(&ioc4_driver); |
503 | } | 492 | } |
504 | 493 | ||
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 2a1e804a71aa..4d2ea8e80140 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | MODULE_AUTHOR("VMware, Inc."); | 46 | MODULE_AUTHOR("VMware, Inc."); |
47 | MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver"); | 47 | MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver"); |
48 | MODULE_VERSION("1.2.1.1-k"); | 48 | MODULE_VERSION("1.2.1.2-k"); |
49 | MODULE_ALIAS("dmi:*:svnVMware*:*"); | 49 | MODULE_ALIAS("dmi:*:svnVMware*:*"); |
50 | MODULE_ALIAS("vmware_vmmemctl"); | 50 | MODULE_ALIAS("vmware_vmmemctl"); |
51 | MODULE_LICENSE("GPL"); | 51 | MODULE_LICENSE("GPL"); |
@@ -315,7 +315,8 @@ static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target) | |||
315 | * fear that guest will need it. Host may reject some pages, we need to | 315 | * fear that guest will need it. Host may reject some pages, we need to |
316 | * check the return value and maybe submit a different page. | 316 | * check the return value and maybe submit a different page. |
317 | */ | 317 | */ |
318 | static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn) | 318 | static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn, |
319 | unsigned int *hv_status) | ||
319 | { | 320 | { |
320 | unsigned long status, dummy; | 321 | unsigned long status, dummy; |
321 | u32 pfn32; | 322 | u32 pfn32; |
@@ -326,7 +327,7 @@ static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn) | |||
326 | 327 | ||
327 | STATS_INC(b->stats.lock); | 328 | STATS_INC(b->stats.lock); |
328 | 329 | ||
329 | status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy); | 330 | *hv_status = status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy); |
330 | if (vmballoon_check_status(b, status)) | 331 | if (vmballoon_check_status(b, status)) |
331 | return true; | 332 | return true; |
332 | 333 | ||
@@ -410,6 +411,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep) | |||
410 | { | 411 | { |
411 | struct page *page; | 412 | struct page *page; |
412 | gfp_t flags; | 413 | gfp_t flags; |
414 | unsigned int hv_status; | ||
413 | bool locked = false; | 415 | bool locked = false; |
414 | 416 | ||
415 | do { | 417 | do { |
@@ -429,11 +431,12 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep) | |||
429 | } | 431 | } |
430 | 432 | ||
431 | /* inform monitor */ | 433 | /* inform monitor */ |
432 | locked = vmballoon_send_lock_page(b, page_to_pfn(page)); | 434 | locked = vmballoon_send_lock_page(b, page_to_pfn(page), &hv_status); |
433 | if (!locked) { | 435 | if (!locked) { |
434 | STATS_INC(b->stats.refused_alloc); | 436 | STATS_INC(b->stats.refused_alloc); |
435 | 437 | ||
436 | if (b->reset_required) { | 438 | if (hv_status == VMW_BALLOON_ERROR_RESET || |
439 | hv_status == VMW_BALLOON_ERROR_PPN_NOTNEEDED) { | ||
437 | __free_page(page); | 440 | __free_page(page); |
438 | return -EIO; | 441 | return -EIO; |
439 | } | 442 | } |