diff options
Diffstat (limited to 'drivers')
329 files changed, 9431 insertions, 3361 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index 3d93b3a3d63..dd0a5b5e9bf 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
@@ -88,6 +88,8 @@ source "drivers/memstick/Kconfig" | |||
88 | 88 | ||
89 | source "drivers/leds/Kconfig" | 89 | source "drivers/leds/Kconfig" |
90 | 90 | ||
91 | source "drivers/nfc/Kconfig" | ||
92 | |||
91 | source "drivers/accessibility/Kconfig" | 93 | source "drivers/accessibility/Kconfig" |
92 | 94 | ||
93 | source "drivers/infiniband/Kconfig" | 95 | source "drivers/infiniband/Kconfig" |
diff --git a/drivers/Makefile b/drivers/Makefile index bf15ce7493d..ef5132469f5 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -40,7 +40,7 @@ obj-$(CONFIG_FB_INTEL) += video/intelfb/ | |||
40 | 40 | ||
41 | obj-y += serial/ | 41 | obj-y += serial/ |
42 | obj-$(CONFIG_PARPORT) += parport/ | 42 | obj-$(CONFIG_PARPORT) += parport/ |
43 | obj-y += base/ block/ misc/ mfd/ | 43 | obj-y += base/ block/ misc/ mfd/ nfc/ |
44 | obj-$(CONFIG_NUBUS) += nubus/ | 44 | obj-$(CONFIG_NUBUS) += nubus/ |
45 | obj-y += macintosh/ | 45 | obj-y += macintosh/ |
46 | obj-$(CONFIG_IDE) += ide/ | 46 | obj-$(CONFIG_IDE) += ide/ |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index bdbfaf22bd1..962a3ccff6f 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -93,7 +93,7 @@ | |||
93 | 93 | ||
94 | #define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */ | 94 | #define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */ |
95 | #define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */ | 95 | #define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */ |
96 | #define AOPOBJ_DATA_VALID 0x04 /* Object is intialized and data is valid */ | 96 | #define AOPOBJ_DATA_VALID 0x04 /* Object is initialized and data is valid */ |
97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */ | 97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */ |
98 | #define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */ | 98 | #define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */ |
99 | #define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */ | 99 | #define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */ |
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index cf29df69380..096aebfe7f3 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #define EINJ_PFX "EINJ: " | 39 | #define EINJ_PFX "EINJ: " |
40 | 40 | ||
41 | #define SPIN_UNIT 100 /* 100ns */ | 41 | #define SPIN_UNIT 100 /* 100ns */ |
42 | /* Firmware should respond within 1 miliseconds */ | 42 | /* Firmware should respond within 1 milliseconds */ |
43 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) | 43 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) |
44 | 44 | ||
45 | /* | 45 | /* |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 5850d320404..cf6db6b7662 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -53,7 +53,7 @@ | |||
53 | sizeof(struct acpi_table_erst))) | 53 | sizeof(struct acpi_table_erst))) |
54 | 54 | ||
55 | #define SPIN_UNIT 100 /* 100ns */ | 55 | #define SPIN_UNIT 100 /* 100ns */ |
56 | /* Firmware should respond within 1 miliseconds */ | 56 | /* Firmware should respond within 1 milliseconds */ |
57 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) | 57 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) |
58 | #define FIRMWARE_MAX_STALL 50 /* 50us */ | 58 | #define FIRMWARE_MAX_STALL 50 /* 50us */ |
59 | 59 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index febb153b5a6..c423231b952 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -319,7 +319,7 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state) | |||
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
322 | static struct platform_suspend_ops acpi_suspend_ops = { | 322 | static const struct platform_suspend_ops acpi_suspend_ops = { |
323 | .valid = acpi_suspend_state_valid, | 323 | .valid = acpi_suspend_state_valid, |
324 | .begin = acpi_suspend_begin, | 324 | .begin = acpi_suspend_begin, |
325 | .prepare_late = acpi_pm_prepare, | 325 | .prepare_late = acpi_pm_prepare, |
@@ -347,7 +347,7 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) | |||
347 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has | 347 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has |
348 | * been requested. | 348 | * been requested. |
349 | */ | 349 | */ |
350 | static struct platform_suspend_ops acpi_suspend_ops_old = { | 350 | static const struct platform_suspend_ops acpi_suspend_ops_old = { |
351 | .valid = acpi_suspend_state_valid, | 351 | .valid = acpi_suspend_state_valid, |
352 | .begin = acpi_suspend_begin_old, | 352 | .begin = acpi_suspend_begin_old, |
353 | .prepare_late = acpi_pm_pre_suspend, | 353 | .prepare_late = acpi_pm_pre_suspend, |
@@ -506,7 +506,7 @@ static void acpi_pm_thaw(void) | |||
506 | acpi_enable_all_runtime_gpes(); | 506 | acpi_enable_all_runtime_gpes(); |
507 | } | 507 | } |
508 | 508 | ||
509 | static struct platform_hibernation_ops acpi_hibernation_ops = { | 509 | static const struct platform_hibernation_ops acpi_hibernation_ops = { |
510 | .begin = acpi_hibernation_begin, | 510 | .begin = acpi_hibernation_begin, |
511 | .end = acpi_pm_end, | 511 | .end = acpi_pm_end, |
512 | .pre_snapshot = acpi_pm_prepare, | 512 | .pre_snapshot = acpi_pm_prepare, |
@@ -549,7 +549,7 @@ static int acpi_hibernation_begin_old(void) | |||
549 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has | 549 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has |
550 | * been requested. | 550 | * been requested. |
551 | */ | 551 | */ |
552 | static struct platform_hibernation_ops acpi_hibernation_ops_old = { | 552 | static const struct platform_hibernation_ops acpi_hibernation_ops_old = { |
553 | .begin = acpi_hibernation_begin_old, | 553 | .begin = acpi_hibernation_begin_old, |
554 | .end = acpi_pm_end, | 554 | .end = acpi_pm_end, |
555 | .pre_snapshot = acpi_pm_pre_suspend, | 555 | .pre_snapshot = acpi_pm_pre_suspend, |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5cd0228d2da..15a0fde4b32 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -260,7 +260,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd) | |||
260 | vd->brightness->levels[request_level]); | 260 | vd->brightness->levels[request_level]); |
261 | } | 261 | } |
262 | 262 | ||
263 | static struct backlight_ops acpi_backlight_ops = { | 263 | static const struct backlight_ops acpi_backlight_ops = { |
264 | .get_brightness = acpi_video_get_brightness, | 264 | .get_brightness = acpi_video_get_brightness, |
265 | .update_status = acpi_video_set_brightness, | 265 | .update_status = acpi_video_set_brightness, |
266 | }; | 266 | }; |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0a6a943b377..a31fe96f7de 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2240,7 +2240,7 @@ int ata_dev_configure(struct ata_device *dev) | |||
2240 | if (id[ATA_ID_CFA_KEY_MGMT] & 1) | 2240 | if (id[ATA_ID_CFA_KEY_MGMT] & 1) |
2241 | ata_dev_printk(dev, KERN_WARNING, | 2241 | ata_dev_printk(dev, KERN_WARNING, |
2242 | "supports DRM functions and may " | 2242 | "supports DRM functions and may " |
2243 | "not be fully accessable.\n"); | 2243 | "not be fully accessible.\n"); |
2244 | snprintf(revbuf, 7, "CFA"); | 2244 | snprintf(revbuf, 7, "CFA"); |
2245 | } else { | 2245 | } else { |
2246 | snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); | 2246 | snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); |
@@ -2248,7 +2248,7 @@ int ata_dev_configure(struct ata_device *dev) | |||
2248 | if (ata_id_has_tpm(id)) | 2248 | if (ata_id_has_tpm(id)) |
2249 | ata_dev_printk(dev, KERN_WARNING, | 2249 | ata_dev_printk(dev, KERN_WARNING, |
2250 | "supports DRM functions and may " | 2250 | "supports DRM functions and may " |
2251 | "not be fully accessable.\n"); | 2251 | "not be fully accessible.\n"); |
2252 | } | 2252 | } |
2253 | 2253 | ||
2254 | dev->n_sectors = ata_id_n_sectors(id); | 2254 | dev->n_sectors = ata_id_n_sectors(id); |
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index b777176ff49..e079cf29ed5 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c | |||
@@ -370,7 +370,7 @@ static int __devinit vsc_sata_init_one(struct pci_dev *pdev, | |||
370 | if (pci_resource_len(pdev, 0) == 0) | 370 | if (pci_resource_len(pdev, 0) == 0) |
371 | return -ENODEV; | 371 | return -ENODEV; |
372 | 372 | ||
373 | /* map IO regions and intialize host accordingly */ | 373 | /* map IO regions and initialize host accordingly */ |
374 | rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME); | 374 | rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME); |
375 | if (rc == -EBUSY) | 375 | if (rc == -EBUSY) |
376 | pcim_pin_device(pdev); | 376 | pcim_pin_device(pdev); |
diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h index 5042bb2dab1..f53a43ae2bb 100644 --- a/drivers/atm/idt77252.h +++ b/drivers/atm/idt77252.h | |||
@@ -572,7 +572,7 @@ struct idt77252_dev | |||
572 | #define SAR_STAT_TSQF 0x00001000 /* Transmit Status Queue full */ | 572 | #define SAR_STAT_TSQF 0x00001000 /* Transmit Status Queue full */ |
573 | #define SAR_STAT_TMROF 0x00000800 /* Timer overflow */ | 573 | #define SAR_STAT_TMROF 0x00000800 /* Timer overflow */ |
574 | #define SAR_STAT_PHYI 0x00000400 /* PHY device Interrupt flag */ | 574 | #define SAR_STAT_PHYI 0x00000400 /* PHY device Interrupt flag */ |
575 | #define SAR_STAT_CMDBZ 0x00000200 /* ABR SAR Comand Busy Flag */ | 575 | #define SAR_STAT_CMDBZ 0x00000200 /* ABR SAR Command Busy Flag */ |
576 | #define SAR_STAT_FBQ3A 0x00000100 /* Free Buffer Queue 3 Attention */ | 576 | #define SAR_STAT_FBQ3A 0x00000100 /* Free Buffer Queue 3 Attention */ |
577 | #define SAR_STAT_FBQ2A 0x00000080 /* Free Buffer Queue 2 Attention */ | 577 | #define SAR_STAT_FBQ2A 0x00000080 /* Free Buffer Queue 2 Attention */ |
578 | #define SAR_STAT_RSQF 0x00000040 /* Receive Status Queue full */ | 578 | #define SAR_STAT_RSQF 0x00000040 /* Receive Status Queue full */ |
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 72925405375..d80d51b62a1 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c | |||
@@ -2063,7 +2063,7 @@ static int tx_init(struct atm_dev *dev) | |||
2063 | - UBR Table size is 4K | 2063 | - UBR Table size is 4K |
2064 | - UBR wait queue is 4K | 2064 | - UBR wait queue is 4K |
2065 | since the table and wait queues are contiguous, all the bytes | 2065 | since the table and wait queues are contiguous, all the bytes |
2066 | can be initialized by one memeset. | 2066 | can be initialized by one memeset. |
2067 | */ | 2067 | */ |
2068 | 2068 | ||
2069 | vcsize_sel = 0; | 2069 | vcsize_sel = 0; |
@@ -2089,7 +2089,7 @@ static int tx_init(struct atm_dev *dev) | |||
2089 | - ABR Table size is 2K | 2089 | - ABR Table size is 2K |
2090 | - ABR wait queue is 2K | 2090 | - ABR wait queue is 2K |
2091 | since the table and wait queues are contiguous, all the bytes | 2091 | since the table and wait queues are contiguous, all the bytes |
2092 | can be intialized by one memeset. | 2092 | can be initialized by one memeset. |
2093 | */ | 2093 | */ |
2094 | i = ABR_SCHED_TABLE * iadev->memSize; | 2094 | i = ABR_SCHED_TABLE * iadev->memSize; |
2095 | writew((i >> 11) & 0xffff, iadev->seg_reg+ABR_SBPTR_BASE); | 2095 | writew((i >> 11) & 0xffff, iadev->seg_reg+ABR_SBPTR_BASE); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index e243bd49764..000e7b2006f 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -975,7 +975,7 @@ struct klist *bus_get_device_klist(struct bus_type *bus) | |||
975 | EXPORT_SYMBOL_GPL(bus_get_device_klist); | 975 | EXPORT_SYMBOL_GPL(bus_get_device_klist); |
976 | 976 | ||
977 | /* | 977 | /* |
978 | * Yes, this forcably breaks the klist abstraction temporarily. It | 978 | * Yes, this forcibly breaks the klist abstraction temporarily. It |
979 | * just wants to sort the klist, not change reference counts and | 979 | * just wants to sort the klist, not change reference counts and |
980 | * take/drop locks rapidly in the process. It does all this while | 980 | * take/drop locks rapidly in the process. It does all this while |
981 | * holding the lock for the list, so objects can't otherwise be | 981 | * holding the lock for the list, so objects can't otherwise be |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 2a52270aeb3..83404973f97 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * | 9 | * |
10 | * The driver model core calls device_pm_add() when a device is registered. | 10 | * The driver model core calls device_pm_add() when a device is registered. |
11 | * This will intialize the embedded device_pm_info object in the device | 11 | * This will initialize the embedded device_pm_info object in the device |
12 | * and add it to the list of power-controlled devices. sysfs entries for | 12 | * and add it to the list of power-controlled devices. sysfs entries for |
13 | * controlling device power management will also be added. | 13 | * controlling device power management will also be added. |
14 | * | 14 | * |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 4b9359a6f6c..83c32cb7258 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -464,6 +464,7 @@ config XEN_BLKDEV_FRONTEND | |||
464 | tristate "Xen virtual block device support" | 464 | tristate "Xen virtual block device support" |
465 | depends on XEN | 465 | depends on XEN |
466 | default y | 466 | default y |
467 | select XEN_XENBUS_FRONTEND | ||
467 | help | 468 | help |
468 | This driver implements the front-end of the Xen virtual | 469 | This driver implements the front-end of the Xen virtual |
469 | block device driver. It communicates with a back-end driver | 470 | block device driver. It communicates with a back-end driver |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index d4a7776f4b7..0f175a866ef 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -1047,15 +1047,6 @@ config NSC_GPIO | |||
1047 | pc8736x_gpio drivers. If those drivers are built as | 1047 | pc8736x_gpio drivers. If those drivers are built as |
1048 | modules, this one will be too, named nsc_gpio | 1048 | modules, this one will be too, named nsc_gpio |
1049 | 1049 | ||
1050 | config CS5535_GPIO | ||
1051 | tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)" | ||
1052 | depends on X86_32 | ||
1053 | help | ||
1054 | Give userspace access to the GPIO pins on the AMD CS5535 and | ||
1055 | CS5536 Geode companion devices. | ||
1056 | |||
1057 | If compiled as a module, it will be called cs5535_gpio. | ||
1058 | |||
1059 | config RAW_DRIVER | 1050 | config RAW_DRIVER |
1060 | tristate "RAW driver (/dev/raw/rawN)" | 1051 | tristate "RAW driver (/dev/raw/rawN)" |
1061 | depends on BLOCK | 1052 | depends on BLOCK |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index fa0b824b7a6..1e9dffb3377 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -82,7 +82,6 @@ obj-$(CONFIG_NWFLASH) += nwflash.o | |||
82 | obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o | 82 | obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o |
83 | obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o | 83 | obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o |
84 | obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o | 84 | obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o |
85 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o | ||
86 | obj-$(CONFIG_GPIO_TB0219) += tb0219.o | 85 | obj-$(CONFIG_GPIO_TB0219) += tb0219.o |
87 | obj-$(CONFIG_TELCLOCK) += tlclk.o | 86 | obj-$(CONFIG_TELCLOCK) += tlclk.o |
88 | 87 | ||
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 010e3defd6c..c195bfeade1 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -94,6 +94,8 @@ | |||
94 | #define G4x_GMCH_SIZE_VT_1_5M (0xa << 8) | 94 | #define G4x_GMCH_SIZE_VT_1_5M (0xa << 8) |
95 | #define G4x_GMCH_SIZE_VT_2M (0xc << 8) | 95 | #define G4x_GMCH_SIZE_VT_2M (0xc << 8) |
96 | 96 | ||
97 | #define GFX_FLSH_CNTL 0x2170 /* 915+ */ | ||
98 | |||
97 | #define I810_DRAM_CTL 0x3000 | 99 | #define I810_DRAM_CTL 0x3000 |
98 | #define I810_DRAM_ROW_0 0x00000001 | 100 | #define I810_DRAM_ROW_0 0x00000001 |
99 | #define I810_DRAM_ROW_0_SDRAM 0x00000001 | 101 | #define I810_DRAM_ROW_0_SDRAM 0x00000001 |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 356f73e0d17..e921b693412 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -688,14 +688,14 @@ static int intel_gtt_init(void) | |||
688 | 688 | ||
689 | intel_private.base.stolen_size = intel_gtt_stolen_size(); | 689 | intel_private.base.stolen_size = intel_gtt_stolen_size(); |
690 | 690 | ||
691 | intel_private.base.needs_dmar = USE_PCI_DMA_API && INTEL_GTT_GEN > 2; | ||
692 | |||
691 | ret = intel_gtt_setup_scratch_page(); | 693 | ret = intel_gtt_setup_scratch_page(); |
692 | if (ret != 0) { | 694 | if (ret != 0) { |
693 | intel_gtt_cleanup(); | 695 | intel_gtt_cleanup(); |
694 | return ret; | 696 | return ret; |
695 | } | 697 | } |
696 | 698 | ||
697 | intel_private.base.needs_dmar = USE_PCI_DMA_API && INTEL_GTT_GEN > 2; | ||
698 | |||
699 | return 0; | 699 | return 0; |
700 | } | 700 | } |
701 | 701 | ||
@@ -814,6 +814,12 @@ static bool intel_enable_gtt(void) | |||
814 | } | 814 | } |
815 | } | 815 | } |
816 | 816 | ||
817 | /* On the resume path we may be adjusting the PGTBL value, so | ||
818 | * be paranoid and flush all chipset write buffers... | ||
819 | */ | ||
820 | if (INTEL_GTT_GEN >= 3) | ||
821 | writel(0, intel_private.registers+GFX_FLSH_CNTL); | ||
822 | |||
817 | reg = intel_private.registers+I810_PGETBL_CTL; | 823 | reg = intel_private.registers+I810_PGETBL_CTL; |
818 | writel(intel_private.PGETBL_save, reg); | 824 | writel(intel_private.PGETBL_save, reg); |
819 | if (HAS_PGTBL_EN && (readl(reg) & I810_PGETBL_ENABLED) == 0) { | 825 | if (HAS_PGTBL_EN && (readl(reg) & I810_PGETBL_ENABLED) == 0) { |
@@ -823,6 +829,9 @@ static bool intel_enable_gtt(void) | |||
823 | return false; | 829 | return false; |
824 | } | 830 | } |
825 | 831 | ||
832 | if (INTEL_GTT_GEN >= 3) | ||
833 | writel(0, intel_private.registers+GFX_FLSH_CNTL); | ||
834 | |||
826 | return true; | 835 | return true; |
827 | } | 836 | } |
828 | 837 | ||
@@ -991,14 +1000,14 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem, | |||
991 | if (mem->page_count == 0) | 1000 | if (mem->page_count == 0) |
992 | return 0; | 1001 | return 0; |
993 | 1002 | ||
1003 | intel_gtt_clear_range(pg_start, mem->page_count); | ||
1004 | |||
994 | if (intel_private.base.needs_dmar) { | 1005 | if (intel_private.base.needs_dmar) { |
995 | intel_gtt_unmap_memory(mem->sg_list, mem->num_sg); | 1006 | intel_gtt_unmap_memory(mem->sg_list, mem->num_sg); |
996 | mem->sg_list = NULL; | 1007 | mem->sg_list = NULL; |
997 | mem->num_sg = 0; | 1008 | mem->num_sg = 0; |
998 | } | 1009 | } |
999 | 1010 | ||
1000 | intel_gtt_clear_range(pg_start, mem->page_count); | ||
1001 | |||
1002 | return 0; | 1011 | return 0; |
1003 | } | 1012 | } |
1004 | 1013 | ||
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c index d3d63be2cd3..1a9f5f6d6ac 100644 --- a/drivers/char/ramoops.c +++ b/drivers/char/ramoops.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #define RAMOOPS_KERNMSG_HDR "====" | 31 | #define RAMOOPS_KERNMSG_HDR "====" |
32 | 32 | ||
33 | #define RECORD_SIZE 4096 | 33 | #define RECORD_SIZE 4096UL |
34 | 34 | ||
35 | static ulong mem_address; | 35 | static ulong mem_address; |
36 | module_param(mem_address, ulong, 0400); | 36 | module_param(mem_address, ulong, 0400); |
@@ -68,11 +68,16 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
68 | char *buf, *buf_orig; | 68 | char *buf, *buf_orig; |
69 | struct timeval timestamp; | 69 | struct timeval timestamp; |
70 | 70 | ||
71 | if (reason != KMSG_DUMP_OOPS && | ||
72 | reason != KMSG_DUMP_PANIC && | ||
73 | reason != KMSG_DUMP_KEXEC) | ||
74 | return; | ||
75 | |||
71 | /* Only dump oopses if dump_oops is set */ | 76 | /* Only dump oopses if dump_oops is set */ |
72 | if (reason == KMSG_DUMP_OOPS && !dump_oops) | 77 | if (reason == KMSG_DUMP_OOPS && !dump_oops) |
73 | return; | 78 | return; |
74 | 79 | ||
75 | buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE)); | 80 | buf = cxt->virt_addr + (cxt->count * RECORD_SIZE); |
76 | buf_orig = buf; | 81 | buf_orig = buf; |
77 | 82 | ||
78 | memset(buf, '\0', RECORD_SIZE); | 83 | memset(buf, '\0', RECORD_SIZE); |
@@ -83,8 +88,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
83 | buf += res; | 88 | buf += res; |
84 | 89 | ||
85 | hdr_size = buf - buf_orig; | 90 | hdr_size = buf - buf_orig; |
86 | l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - hdr_size)); | 91 | l2_cpy = min(l2, RECORD_SIZE - hdr_size); |
87 | l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - hdr_size) - l2_cpy); | 92 | l1_cpy = min(l1, RECORD_SIZE - hdr_size - l2_cpy); |
88 | 93 | ||
89 | s2_start = l2 - l2_cpy; | 94 | s2_start = l2 - l2_cpy; |
90 | s1_start = l1 - l1_cpy; | 95 | s1_start = l1 - l1_cpy; |
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index b98c67664ae..c461eda6241 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c | |||
@@ -110,8 +110,6 @@ static void unregister_dca_providers(void) | |||
110 | 110 | ||
111 | /* at this point only one domain in the list is expected */ | 111 | /* at this point only one domain in the list is expected */ |
112 | domain = list_first_entry(&dca_domains, struct dca_domain, node); | 112 | domain = list_first_entry(&dca_domains, struct dca_domain, node); |
113 | if (!domain) | ||
114 | return; | ||
115 | 113 | ||
116 | list_for_each_entry_safe(dca, _dca, &domain->dca_providers, node) { | 114 | list_for_each_entry_safe(dca, _dca, &domain->dca_providers, node) { |
117 | list_del(&dca->node); | 115 | list_del(&dca->node); |
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 3109bd94bc4..78266382797 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c | |||
@@ -1060,8 +1060,8 @@ static irqreturn_t intel_mid_dma_interrupt2(int irq, void *data) | |||
1060 | * mid_setup_dma - Setup the DMA controller | 1060 | * mid_setup_dma - Setup the DMA controller |
1061 | * @pdev: Controller PCI device structure | 1061 | * @pdev: Controller PCI device structure |
1062 | * | 1062 | * |
1063 | * Initilize the DMA controller, channels, registers with DMA engine, | 1063 | * Initialize the DMA controller, channels, registers with DMA engine, |
1064 | * ISR. Initilize DMA controller channels. | 1064 | * ISR. Initialize DMA controller channels. |
1065 | */ | 1065 | */ |
1066 | static int mid_setup_dma(struct pci_dev *pdev) | 1066 | static int mid_setup_dma(struct pci_dev *pdev) |
1067 | { | 1067 | { |
@@ -1217,7 +1217,7 @@ static void middma_shutdown(struct pci_dev *pdev) | |||
1217 | * @pdev: Controller PCI device structure | 1217 | * @pdev: Controller PCI device structure |
1218 | * @id: pci device id structure | 1218 | * @id: pci device id structure |
1219 | * | 1219 | * |
1220 | * Initilize the PCI device, map BARs, query driver data. | 1220 | * Initialize the PCI device, map BARs, query driver data. |
1221 | * Call setup_dma to complete contoller and chan initilzation | 1221 | * Call setup_dma to complete contoller and chan initilzation |
1222 | */ | 1222 | */ |
1223 | static int __devinit intel_mid_dma_probe(struct pci_dev *pdev, | 1223 | static int __devinit intel_mid_dma_probe(struct pci_dev *pdev, |
diff --git a/drivers/edac/amd8131_edac.h b/drivers/edac/amd8131_edac.h index 60e0d1c72de..6f8b07131ec 100644 --- a/drivers/edac/amd8131_edac.h +++ b/drivers/edac/amd8131_edac.h | |||
@@ -99,7 +99,7 @@ struct amd8131_dev_info { | |||
99 | 99 | ||
100 | /* | 100 | /* |
101 | * AMD8131 chipset has two pairs of PCIX Bridge and related IOAPIC | 101 | * AMD8131 chipset has two pairs of PCIX Bridge and related IOAPIC |
102 | * Controler, and ATCA-6101 has two AMD8131 chipsets, so there are | 102 | * Controller, and ATCA-6101 has two AMD8131 chipsets, so there are |
103 | * four PCIX Bridges on ATCA-6101 altogether. | 103 | * four PCIX Bridges on ATCA-6101 altogether. |
104 | * | 104 | * |
105 | * These PCIX Bridges share the same PCI Device ID and are all of | 105 | * These PCIX Bridges share the same PCI Device ID and are all of |
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c index c973004c002..db1df59ae2b 100644 --- a/drivers/edac/cell_edac.c +++ b/drivers/edac/cell_edac.c | |||
@@ -47,7 +47,7 @@ static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar) | |||
47 | offset = address & ~PAGE_MASK; | 47 | offset = address & ~PAGE_MASK; |
48 | syndrome = (ar & 0x000000001fe00000ul) >> 21; | 48 | syndrome = (ar & 0x000000001fe00000ul) >> 21; |
49 | 49 | ||
50 | /* TODO: Decoding of the error addresss */ | 50 | /* TODO: Decoding of the error address */ |
51 | edac_mc_handle_ce(mci, csrow->first_page + pfn, offset, | 51 | edac_mc_handle_ce(mci, csrow->first_page + pfn, offset, |
52 | syndrome, 0, chan, ""); | 52 | syndrome, 0, chan, ""); |
53 | } | 53 | } |
@@ -68,7 +68,7 @@ static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar) | |||
68 | pfn = address >> PAGE_SHIFT; | 68 | pfn = address >> PAGE_SHIFT; |
69 | offset = address & ~PAGE_MASK; | 69 | offset = address & ~PAGE_MASK; |
70 | 70 | ||
71 | /* TODO: Decoding of the error addresss */ | 71 | /* TODO: Decoding of the error address */ |
72 | edac_mc_handle_ue(mci, csrow->first_page + pfn, offset, 0, ""); | 72 | edac_mc_handle_ue(mci, csrow->first_page + pfn, offset, 0, ""); |
73 | } | 73 | } |
74 | 74 | ||
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index ff1eb7bb26c..3d965347a67 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h | |||
@@ -259,7 +259,7 @@ enum scrub_type { | |||
259 | * for single channel are 64 bits, for dual channel 128 | 259 | * for single channel are 64 bits, for dual channel 128 |
260 | * bits. | 260 | * bits. |
261 | * | 261 | * |
262 | * Single-Ranked stick: A Single-ranked stick has 1 chip-select row of memmory. | 262 | * Single-Ranked stick: A Single-ranked stick has 1 chip-select row of memory. |
263 | * Motherboards commonly drive two chip-select pins to | 263 | * Motherboards commonly drive two chip-select pins to |
264 | * a memory stick. A single-ranked stick, will occupy | 264 | * a memory stick. A single-ranked stick, will occupy |
265 | * only one of those rows. The other will be unused. | 265 | * only one of those rows. The other will be unused. |
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 362861c1577..81154ab296b 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* Intel i7 core/Nehalem Memory Controller kernel module | 1 | /* Intel i7 core/Nehalem Memory Controller kernel module |
2 | * | 2 | * |
3 | * This driver supports yhe memory controllers found on the Intel | 3 | * This driver supports the memory controllers found on the Intel |
4 | * processor families i7core, i7core 7xx/8xx, i5core, Xeon 35xx, | 4 | * processor families i7core, i7core 7xx/8xx, i5core, Xeon 35xx, |
5 | * Xeon 55xx and Xeon 56xx also known as Nehalem, Nehalem-EP, Lynnfield | 5 | * Xeon 55xx and Xeon 56xx also known as Nehalem, Nehalem-EP, Lynnfield |
6 | * and Westmere-EP. | 6 | * and Westmere-EP. |
@@ -1271,7 +1271,7 @@ static void __init i7core_xeon_pci_fixup(const struct pci_id_table *table) | |||
1271 | int i; | 1271 | int i; |
1272 | 1272 | ||
1273 | /* | 1273 | /* |
1274 | * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses | 1274 | * On Xeon 55xx, the Intel Quick Path Arch Generic Non-core pci buses |
1275 | * aren't announced by acpi. So, we need to use a legacy scan probing | 1275 | * aren't announced by acpi. So, we need to use a legacy scan probing |
1276 | * to detect them | 1276 | * to detect them |
1277 | */ | 1277 | */ |
@@ -1864,7 +1864,7 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) | |||
1864 | if (mce->mcgstatus & 1) | 1864 | if (mce->mcgstatus & 1) |
1865 | i7core_check_error(mci); | 1865 | i7core_check_error(mci); |
1866 | 1866 | ||
1867 | /* Advice mcelog that the error were handled */ | 1867 | /* Advise mcelog that the errors were handled */ |
1868 | return 1; | 1868 | return 1; |
1869 | } | 1869 | } |
1870 | 1870 | ||
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index 070cea41b66..b9f0c20df1a 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c | |||
@@ -873,7 +873,7 @@ ppc4xx_edac_get_mtype(u32 mcopt1) | |||
873 | } | 873 | } |
874 | 874 | ||
875 | /** | 875 | /** |
876 | * ppc4xx_edac_init_csrows - intialize driver instance rows | 876 | * ppc4xx_edac_init_csrows - initialize driver instance rows |
877 | * @mci: A pointer to the EDAC memory controller instance | 877 | * @mci: A pointer to the EDAC memory controller instance |
878 | * associated with the ibm,sdram-4xx-ddr2 controller for which | 878 | * associated with the ibm,sdram-4xx-ddr2 controller for which |
879 | * the csrows (i.e. banks/ranks) are being initialized. | 879 | * the csrows (i.e. banks/ranks) are being initialized. |
@@ -881,7 +881,7 @@ ppc4xx_edac_get_mtype(u32 mcopt1) | |||
881 | * currently set for the controller, from which bank width | 881 | * currently set for the controller, from which bank width |
882 | * and memory typ information is derived. | 882 | * and memory typ information is derived. |
883 | * | 883 | * |
884 | * This routine intializes the virtual "chip select rows" associated | 884 | * This routine initializes the virtual "chip select rows" associated |
885 | * with the EDAC memory controller instance. An ibm,sdram-4xx-ddr2 | 885 | * with the EDAC memory controller instance. An ibm,sdram-4xx-ddr2 |
886 | * controller bank/rank is mapped to a row. | 886 | * controller bank/rank is mapped to a row. |
887 | * | 887 | * |
@@ -992,7 +992,7 @@ ppc4xx_edac_init_csrows(struct mem_ctl_info *mci, u32 mcopt1) | |||
992 | } | 992 | } |
993 | 993 | ||
994 | /** | 994 | /** |
995 | * ppc4xx_edac_mc_init - intialize driver instance | 995 | * ppc4xx_edac_mc_init - initialize driver instance |
996 | * @mci: A pointer to the EDAC memory controller instance being | 996 | * @mci: A pointer to the EDAC memory controller instance being |
997 | * initialized. | 997 | * initialized. |
998 | * @op: A pointer to the OpenFirmware device tree node associated | 998 | * @op: A pointer to the OpenFirmware device tree node associated |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 082495bb08a..664660e5633 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -118,7 +118,7 @@ config GPIO_SCH | |||
118 | 118 | ||
119 | config GPIO_VX855 | 119 | config GPIO_VX855 |
120 | tristate "VIA VX855/VX875 GPIO" | 120 | tristate "VIA VX855/VX875 GPIO" |
121 | depends on GPIOLIB | 121 | depends on GPIOLIB && MFD_SUPPORT && PCI |
122 | select MFD_CORE | 122 | select MFD_CORE |
123 | select MFD_VX855 | 123 | select MFD_VX855 |
124 | help | 124 | help |
@@ -295,7 +295,7 @@ comment "PCI GPIO expanders:" | |||
295 | 295 | ||
296 | config GPIO_CS5535 | 296 | config GPIO_CS5535 |
297 | tristate "AMD CS5535/CS5536 GPIO support" | 297 | tristate "AMD CS5535/CS5536 GPIO support" |
298 | depends on PCI && !CS5535_GPIO | 298 | depends on PCI && X86 && !CS5535_GPIO |
299 | help | 299 | help |
300 | The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that | 300 | The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that |
301 | can be used for quite a number of things. The CS5535/6 is found on | 301 | can be used for quite a number of things. The CS5535/6 is found on |
@@ -333,6 +333,15 @@ config GPIO_PCH | |||
333 | which is an IOH(Input/Output Hub) for x86 embedded processor. | 333 | which is an IOH(Input/Output Hub) for x86 embedded processor. |
334 | This driver can access PCH GPIO device. | 334 | This driver can access PCH GPIO device. |
335 | 335 | ||
336 | config GPIO_ML_IOH | ||
337 | tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" | ||
338 | depends on PCI | ||
339 | help | ||
340 | ML7213 is companion chip for Intel Atom E6xx series. | ||
341 | This driver can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/Output | ||
342 | Hub) which is for IVI(In-Vehicle Infotainment) use. | ||
343 | This driver can access the IOH's GPIO device. | ||
344 | |||
336 | config GPIO_TIMBERDALE | 345 | config GPIO_TIMBERDALE |
337 | bool "Support for timberdale GPIO IP" | 346 | bool "Support for timberdale GPIO IP" |
338 | depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM | 347 | depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM |
@@ -342,6 +351,7 @@ config GPIO_TIMBERDALE | |||
342 | config GPIO_RDC321X | 351 | config GPIO_RDC321X |
343 | tristate "RDC R-321x GPIO support" | 352 | tristate "RDC R-321x GPIO support" |
344 | depends on PCI && GPIOLIB | 353 | depends on PCI && GPIOLIB |
354 | select MFD_SUPPORT | ||
345 | select MFD_CORE | 355 | select MFD_CORE |
346 | select MFD_RDC321X | 356 | select MFD_RDC321X |
347 | help | 357 | help |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 39bfd7a3765..3351cf87b0e 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -41,3 +41,4 @@ obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o | |||
41 | obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o | 41 | obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o |
42 | obj-$(CONFIG_GPIO_SX150X) += sx150x.o | 42 | obj-$(CONFIG_GPIO_SX150X) += sx150x.o |
43 | obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o | 43 | obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o |
44 | obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o | ||
diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/adp5588-gpio.c index 0871f78af59..33fc685cb38 100644 --- a/drivers/gpio/adp5588-gpio.c +++ b/drivers/gpio/adp5588-gpio.c | |||
@@ -146,9 +146,10 @@ static int adp5588_gpio_to_irq(struct gpio_chip *chip, unsigned off) | |||
146 | return dev->irq_base + off; | 146 | return dev->irq_base + off; |
147 | } | 147 | } |
148 | 148 | ||
149 | static void adp5588_irq_bus_lock(unsigned int irq) | 149 | static void adp5588_irq_bus_lock(struct irq_data *d) |
150 | { | 150 | { |
151 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | 151 | struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d); |
152 | |||
152 | mutex_lock(&dev->irq_lock); | 153 | mutex_lock(&dev->irq_lock); |
153 | } | 154 | } |
154 | 155 | ||
@@ -160,9 +161,9 @@ static void adp5588_irq_bus_lock(unsigned int irq) | |||
160 | * and unlocks the bus. | 161 | * and unlocks the bus. |
161 | */ | 162 | */ |
162 | 163 | ||
163 | static void adp5588_irq_bus_sync_unlock(unsigned int irq) | 164 | static void adp5588_irq_bus_sync_unlock(struct irq_data *d) |
164 | { | 165 | { |
165 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | 166 | struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d); |
166 | int i; | 167 | int i; |
167 | 168 | ||
168 | for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) | 169 | for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) |
@@ -175,31 +176,31 @@ static void adp5588_irq_bus_sync_unlock(unsigned int irq) | |||
175 | mutex_unlock(&dev->irq_lock); | 176 | mutex_unlock(&dev->irq_lock); |
176 | } | 177 | } |
177 | 178 | ||
178 | static void adp5588_irq_mask(unsigned int irq) | 179 | static void adp5588_irq_mask(struct irq_data *d) |
179 | { | 180 | { |
180 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | 181 | struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d); |
181 | unsigned gpio = irq - dev->irq_base; | 182 | unsigned gpio = d->irq - dev->irq_base; |
182 | 183 | ||
183 | dev->irq_mask[ADP5588_BANK(gpio)] &= ~ADP5588_BIT(gpio); | 184 | dev->irq_mask[ADP5588_BANK(gpio)] &= ~ADP5588_BIT(gpio); |
184 | } | 185 | } |
185 | 186 | ||
186 | static void adp5588_irq_unmask(unsigned int irq) | 187 | static void adp5588_irq_unmask(struct irq_data *d) |
187 | { | 188 | { |
188 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | 189 | struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d); |
189 | unsigned gpio = irq - dev->irq_base; | 190 | unsigned gpio = d->irq - dev->irq_base; |
190 | 191 | ||
191 | dev->irq_mask[ADP5588_BANK(gpio)] |= ADP5588_BIT(gpio); | 192 | dev->irq_mask[ADP5588_BANK(gpio)] |= ADP5588_BIT(gpio); |
192 | } | 193 | } |
193 | 194 | ||
194 | static int adp5588_irq_set_type(unsigned int irq, unsigned int type) | 195 | static int adp5588_irq_set_type(struct irq_data *d, unsigned int type) |
195 | { | 196 | { |
196 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | 197 | struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d); |
197 | uint16_t gpio = irq - dev->irq_base; | 198 | uint16_t gpio = d->irq - dev->irq_base; |
198 | unsigned bank, bit; | 199 | unsigned bank, bit; |
199 | 200 | ||
200 | if ((type & IRQ_TYPE_EDGE_BOTH)) { | 201 | if ((type & IRQ_TYPE_EDGE_BOTH)) { |
201 | dev_err(&dev->client->dev, "irq %d: unsupported type %d\n", | 202 | dev_err(&dev->client->dev, "irq %d: unsupported type %d\n", |
202 | irq, type); | 203 | d->irq, type); |
203 | return -EINVAL; | 204 | return -EINVAL; |
204 | } | 205 | } |
205 | 206 | ||
@@ -222,11 +223,11 @@ static int adp5588_irq_set_type(unsigned int irq, unsigned int type) | |||
222 | 223 | ||
223 | static struct irq_chip adp5588_irq_chip = { | 224 | static struct irq_chip adp5588_irq_chip = { |
224 | .name = "adp5588", | 225 | .name = "adp5588", |
225 | .mask = adp5588_irq_mask, | 226 | .irq_mask = adp5588_irq_mask, |
226 | .unmask = adp5588_irq_unmask, | 227 | .irq_unmask = adp5588_irq_unmask, |
227 | .bus_lock = adp5588_irq_bus_lock, | 228 | .irq_bus_lock = adp5588_irq_bus_lock, |
228 | .bus_sync_unlock = adp5588_irq_bus_sync_unlock, | 229 | .irq_bus_sync_unlock = adp5588_irq_bus_sync_unlock, |
229 | .set_type = adp5588_irq_set_type, | 230 | .irq_set_type = adp5588_irq_set_type, |
230 | }; | 231 | }; |
231 | 232 | ||
232 | static int adp5588_gpio_read_intstat(struct i2c_client *client, u8 *buf) | 233 | static int adp5588_gpio_read_intstat(struct i2c_client *client, u8 *buf) |
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index d3e55a0ae92..815d98b2c1b 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/cs5535.h> | 17 | #include <linux/cs5535.h> |
18 | #include <asm/msr.h> | ||
18 | 19 | ||
19 | #define DRV_NAME "cs5535-gpio" | 20 | #define DRV_NAME "cs5535-gpio" |
20 | #define GPIO_BAR 1 | 21 | #define GPIO_BAR 1 |
@@ -144,6 +145,57 @@ int cs5535_gpio_isset(unsigned offset, unsigned int reg) | |||
144 | } | 145 | } |
145 | EXPORT_SYMBOL_GPL(cs5535_gpio_isset); | 146 | EXPORT_SYMBOL_GPL(cs5535_gpio_isset); |
146 | 147 | ||
148 | int cs5535_gpio_set_irq(unsigned group, unsigned irq) | ||
149 | { | ||
150 | uint32_t lo, hi; | ||
151 | |||
152 | if (group > 7 || irq > 15) | ||
153 | return -EINVAL; | ||
154 | |||
155 | rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi); | ||
156 | |||
157 | lo &= ~(0xF << (group * 4)); | ||
158 | lo |= (irq & 0xF) << (group * 4); | ||
159 | |||
160 | wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi); | ||
161 | return 0; | ||
162 | } | ||
163 | EXPORT_SYMBOL_GPL(cs5535_gpio_set_irq); | ||
164 | |||
165 | void cs5535_gpio_setup_event(unsigned offset, int pair, int pme) | ||
166 | { | ||
167 | struct cs5535_gpio_chip *chip = &cs5535_gpio_chip; | ||
168 | uint32_t shift = (offset % 8) * 4; | ||
169 | unsigned long flags; | ||
170 | uint32_t val; | ||
171 | |||
172 | if (offset >= 24) | ||
173 | offset = GPIO_MAP_W; | ||
174 | else if (offset >= 16) | ||
175 | offset = GPIO_MAP_Z; | ||
176 | else if (offset >= 8) | ||
177 | offset = GPIO_MAP_Y; | ||
178 | else | ||
179 | offset = GPIO_MAP_X; | ||
180 | |||
181 | spin_lock_irqsave(&chip->lock, flags); | ||
182 | val = inl(chip->base + offset); | ||
183 | |||
184 | /* Clear whatever was there before */ | ||
185 | val &= ~(0xF << shift); | ||
186 | |||
187 | /* Set the new value */ | ||
188 | val |= ((pair & 7) << shift); | ||
189 | |||
190 | /* Set the PME bit if this is a PME event */ | ||
191 | if (pme) | ||
192 | val |= (1 << (shift + 3)); | ||
193 | |||
194 | outl(val, chip->base + offset); | ||
195 | spin_unlock_irqrestore(&chip->lock, flags); | ||
196 | } | ||
197 | EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event); | ||
198 | |||
147 | /* | 199 | /* |
148 | * Generic gpio_chip API support. | 200 | * Generic gpio_chip API support. |
149 | */ | 201 | */ |
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index 64db9dc3a27..d81cc748e77 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c | |||
@@ -134,10 +134,10 @@ static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
134 | return lnw->irq_base + offset; | 134 | return lnw->irq_base + offset; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int lnw_irq_type(unsigned irq, unsigned type) | 137 | static int lnw_irq_type(struct irq_data *d, unsigned type) |
138 | { | 138 | { |
139 | struct lnw_gpio *lnw = get_irq_chip_data(irq); | 139 | struct lnw_gpio *lnw = irq_data_get_irq_chip_data(d); |
140 | u32 gpio = irq - lnw->irq_base; | 140 | u32 gpio = d->irq - lnw->irq_base; |
141 | unsigned long flags; | 141 | unsigned long flags; |
142 | u32 value; | 142 | u32 value; |
143 | void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER); | 143 | void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER); |
@@ -162,19 +162,19 @@ static int lnw_irq_type(unsigned irq, unsigned type) | |||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | static void lnw_irq_unmask(unsigned irq) | 165 | static void lnw_irq_unmask(struct irq_data *d) |
166 | { | 166 | { |
167 | } | 167 | } |
168 | 168 | ||
169 | static void lnw_irq_mask(unsigned irq) | 169 | static void lnw_irq_mask(struct irq_data *d) |
170 | { | 170 | { |
171 | } | 171 | } |
172 | 172 | ||
173 | static struct irq_chip lnw_irqchip = { | 173 | static struct irq_chip lnw_irqchip = { |
174 | .name = "LNW-GPIO", | 174 | .name = "LNW-GPIO", |
175 | .mask = lnw_irq_mask, | 175 | .irq_mask = lnw_irq_mask, |
176 | .unmask = lnw_irq_unmask, | 176 | .irq_unmask = lnw_irq_unmask, |
177 | .set_type = lnw_irq_type, | 177 | .irq_set_type = lnw_irq_type, |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */ | 180 | static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */ |
diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c index 9cad60f9e96..9e1d01f0071 100644 --- a/drivers/gpio/max732x.c +++ b/drivers/gpio/max732x.c | |||
@@ -327,40 +327,40 @@ static int max732x_gpio_to_irq(struct gpio_chip *gc, unsigned off) | |||
327 | return chip->irq_base + off; | 327 | return chip->irq_base + off; |
328 | } | 328 | } |
329 | 329 | ||
330 | static void max732x_irq_mask(unsigned int irq) | 330 | static void max732x_irq_mask(struct irq_data *d) |
331 | { | 331 | { |
332 | struct max732x_chip *chip = get_irq_chip_data(irq); | 332 | struct max732x_chip *chip = irq_data_get_irq_chip_data(d); |
333 | 333 | ||
334 | chip->irq_mask_cur &= ~(1 << (irq - chip->irq_base)); | 334 | chip->irq_mask_cur &= ~(1 << (d->irq - chip->irq_base)); |
335 | } | 335 | } |
336 | 336 | ||
337 | static void max732x_irq_unmask(unsigned int irq) | 337 | static void max732x_irq_unmask(struct irq_data *d) |
338 | { | 338 | { |
339 | struct max732x_chip *chip = get_irq_chip_data(irq); | 339 | struct max732x_chip *chip = irq_data_get_irq_chip_data(d); |
340 | 340 | ||
341 | chip->irq_mask_cur |= 1 << (irq - chip->irq_base); | 341 | chip->irq_mask_cur |= 1 << (d->irq - chip->irq_base); |
342 | } | 342 | } |
343 | 343 | ||
344 | static void max732x_irq_bus_lock(unsigned int irq) | 344 | static void max732x_irq_bus_lock(struct irq_data *d) |
345 | { | 345 | { |
346 | struct max732x_chip *chip = get_irq_chip_data(irq); | 346 | struct max732x_chip *chip = irq_data_get_irq_chip_data(d); |
347 | 347 | ||
348 | mutex_lock(&chip->irq_lock); | 348 | mutex_lock(&chip->irq_lock); |
349 | chip->irq_mask_cur = chip->irq_mask; | 349 | chip->irq_mask_cur = chip->irq_mask; |
350 | } | 350 | } |
351 | 351 | ||
352 | static void max732x_irq_bus_sync_unlock(unsigned int irq) | 352 | static void max732x_irq_bus_sync_unlock(struct irq_data *d) |
353 | { | 353 | { |
354 | struct max732x_chip *chip = get_irq_chip_data(irq); | 354 | struct max732x_chip *chip = irq_data_get_irq_chip_data(d); |
355 | 355 | ||
356 | max732x_irq_update_mask(chip); | 356 | max732x_irq_update_mask(chip); |
357 | mutex_unlock(&chip->irq_lock); | 357 | mutex_unlock(&chip->irq_lock); |
358 | } | 358 | } |
359 | 359 | ||
360 | static int max732x_irq_set_type(unsigned int irq, unsigned int type) | 360 | static int max732x_irq_set_type(struct irq_data *d, unsigned int type) |
361 | { | 361 | { |
362 | struct max732x_chip *chip = get_irq_chip_data(irq); | 362 | struct max732x_chip *chip = irq_data_get_irq_chip_data(d); |
363 | uint16_t off = irq - chip->irq_base; | 363 | uint16_t off = d->irq - chip->irq_base; |
364 | uint16_t mask = 1 << off; | 364 | uint16_t mask = 1 << off; |
365 | 365 | ||
366 | if (!(mask & chip->dir_input)) { | 366 | if (!(mask & chip->dir_input)) { |
@@ -371,7 +371,7 @@ static int max732x_irq_set_type(unsigned int irq, unsigned int type) | |||
371 | 371 | ||
372 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 372 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
373 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 373 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
374 | irq, type); | 374 | d->irq, type); |
375 | return -EINVAL; | 375 | return -EINVAL; |
376 | } | 376 | } |
377 | 377 | ||
@@ -390,11 +390,11 @@ static int max732x_irq_set_type(unsigned int irq, unsigned int type) | |||
390 | 390 | ||
391 | static struct irq_chip max732x_irq_chip = { | 391 | static struct irq_chip max732x_irq_chip = { |
392 | .name = "max732x", | 392 | .name = "max732x", |
393 | .mask = max732x_irq_mask, | 393 | .irq_mask = max732x_irq_mask, |
394 | .unmask = max732x_irq_unmask, | 394 | .irq_unmask = max732x_irq_unmask, |
395 | .bus_lock = max732x_irq_bus_lock, | 395 | .irq_bus_lock = max732x_irq_bus_lock, |
396 | .bus_sync_unlock = max732x_irq_bus_sync_unlock, | 396 | .irq_bus_sync_unlock = max732x_irq_bus_sync_unlock, |
397 | .set_type = max732x_irq_set_type, | 397 | .irq_set_type = max732x_irq_set_type, |
398 | }; | 398 | }; |
399 | 399 | ||
400 | static uint8_t max732x_irq_pending(struct max732x_chip *chip) | 400 | static uint8_t max732x_irq_pending(struct max732x_chip *chip) |
diff --git a/drivers/gpio/ml_ioh_gpio.c b/drivers/gpio/ml_ioh_gpio.c new file mode 100644 index 00000000000..cead8e6ff34 --- /dev/null +++ b/drivers/gpio/ml_ioh_gpio.c | |||
@@ -0,0 +1,352 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; version 2 of the License. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
16 | */ | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/gpio.h> | ||
20 | |||
21 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
22 | |||
23 | struct ioh_reg_comn { | ||
24 | u32 ien; | ||
25 | u32 istatus; | ||
26 | u32 idisp; | ||
27 | u32 iclr; | ||
28 | u32 imask; | ||
29 | u32 imaskclr; | ||
30 | u32 po; | ||
31 | u32 pi; | ||
32 | u32 pm; | ||
33 | u32 im_0; | ||
34 | u32 im_1; | ||
35 | u32 reserved; | ||
36 | }; | ||
37 | |||
38 | struct ioh_regs { | ||
39 | struct ioh_reg_comn regs[8]; | ||
40 | u32 reserve1[16]; | ||
41 | u32 ioh_sel_reg[4]; | ||
42 | u32 reserve2[11]; | ||
43 | u32 srst; | ||
44 | }; | ||
45 | |||
46 | /** | ||
47 | * struct ioh_gpio_reg_data - The register store data. | ||
48 | * @po_reg: To store contents of PO register. | ||
49 | * @pm_reg: To store contents of PM register. | ||
50 | */ | ||
51 | struct ioh_gpio_reg_data { | ||
52 | u32 po_reg; | ||
53 | u32 pm_reg; | ||
54 | }; | ||
55 | |||
56 | /** | ||
57 | * struct ioh_gpio - GPIO private data structure. | ||
58 | * @base: PCI base address of Memory mapped I/O register. | ||
59 | * @reg: Memory mapped IOH GPIO register list. | ||
60 | * @dev: Pointer to device structure. | ||
61 | * @gpio: Data for GPIO infrastructure. | ||
62 | * @ioh_gpio_reg: Memory mapped Register data is saved here | ||
63 | * when suspend. | ||
64 | * @ch: Indicate GPIO channel | ||
65 | */ | ||
66 | struct ioh_gpio { | ||
67 | void __iomem *base; | ||
68 | struct ioh_regs __iomem *reg; | ||
69 | struct device *dev; | ||
70 | struct gpio_chip gpio; | ||
71 | struct ioh_gpio_reg_data ioh_gpio_reg; | ||
72 | struct mutex lock; | ||
73 | int ch; | ||
74 | }; | ||
75 | |||
76 | static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12}; | ||
77 | |||
78 | static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) | ||
79 | { | ||
80 | u32 reg_val; | ||
81 | struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); | ||
82 | |||
83 | mutex_lock(&chip->lock); | ||
84 | reg_val = ioread32(&chip->reg->regs[chip->ch].po); | ||
85 | if (val) | ||
86 | reg_val |= (1 << nr); | ||
87 | else | ||
88 | reg_val &= ~(1 << nr); | ||
89 | |||
90 | iowrite32(reg_val, &chip->reg->regs[chip->ch].po); | ||
91 | mutex_unlock(&chip->lock); | ||
92 | } | ||
93 | |||
94 | static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr) | ||
95 | { | ||
96 | struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); | ||
97 | |||
98 | return ioread32(&chip->reg->regs[chip->ch].pi) & (1 << nr); | ||
99 | } | ||
100 | |||
101 | static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | ||
102 | int val) | ||
103 | { | ||
104 | struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); | ||
105 | u32 pm; | ||
106 | u32 reg_val; | ||
107 | |||
108 | mutex_lock(&chip->lock); | ||
109 | pm = ioread32(&chip->reg->regs[chip->ch].pm) & | ||
110 | ((1 << num_ports[chip->ch]) - 1); | ||
111 | pm |= (1 << nr); | ||
112 | iowrite32(pm, &chip->reg->regs[chip->ch].pm); | ||
113 | |||
114 | reg_val = ioread32(&chip->reg->regs[chip->ch].po); | ||
115 | if (val) | ||
116 | reg_val |= (1 << nr); | ||
117 | else | ||
118 | reg_val &= ~(1 << nr); | ||
119 | |||
120 | mutex_unlock(&chip->lock); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | ||
126 | { | ||
127 | struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); | ||
128 | u32 pm; | ||
129 | |||
130 | mutex_lock(&chip->lock); | ||
131 | pm = ioread32(&chip->reg->regs[chip->ch].pm) & | ||
132 | ((1 << num_ports[chip->ch]) - 1); | ||
133 | pm &= ~(1 << nr); | ||
134 | iowrite32(pm, &chip->reg->regs[chip->ch].pm); | ||
135 | mutex_unlock(&chip->lock); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Save register configuration and disable interrupts. | ||
142 | */ | ||
143 | static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) | ||
144 | { | ||
145 | chip->ioh_gpio_reg.po_reg = ioread32(&chip->reg->regs[chip->ch].po); | ||
146 | chip->ioh_gpio_reg.pm_reg = ioread32(&chip->reg->regs[chip->ch].pm); | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * This function restores the register configuration of the GPIO device. | ||
151 | */ | ||
152 | static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) | ||
153 | { | ||
154 | /* to store contents of PO register */ | ||
155 | iowrite32(chip->ioh_gpio_reg.po_reg, &chip->reg->regs[chip->ch].po); | ||
156 | /* to store contents of PM register */ | ||
157 | iowrite32(chip->ioh_gpio_reg.pm_reg, &chip->reg->regs[chip->ch].pm); | ||
158 | } | ||
159 | |||
160 | static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port) | ||
161 | { | ||
162 | struct gpio_chip *gpio = &chip->gpio; | ||
163 | |||
164 | gpio->label = dev_name(chip->dev); | ||
165 | gpio->owner = THIS_MODULE; | ||
166 | gpio->direction_input = ioh_gpio_direction_input; | ||
167 | gpio->get = ioh_gpio_get; | ||
168 | gpio->direction_output = ioh_gpio_direction_output; | ||
169 | gpio->set = ioh_gpio_set; | ||
170 | gpio->dbg_show = NULL; | ||
171 | gpio->base = -1; | ||
172 | gpio->ngpio = num_port; | ||
173 | gpio->can_sleep = 0; | ||
174 | } | ||
175 | |||
176 | static int __devinit ioh_gpio_probe(struct pci_dev *pdev, | ||
177 | const struct pci_device_id *id) | ||
178 | { | ||
179 | int ret; | ||
180 | int i; | ||
181 | struct ioh_gpio *chip; | ||
182 | void __iomem *base; | ||
183 | void __iomem *chip_save; | ||
184 | |||
185 | ret = pci_enable_device(pdev); | ||
186 | if (ret) { | ||
187 | dev_err(&pdev->dev, "%s : pci_enable_device failed", __func__); | ||
188 | goto err_pci_enable; | ||
189 | } | ||
190 | |||
191 | ret = pci_request_regions(pdev, KBUILD_MODNAME); | ||
192 | if (ret) { | ||
193 | dev_err(&pdev->dev, "pci_request_regions failed-%d", ret); | ||
194 | goto err_request_regions; | ||
195 | } | ||
196 | |||
197 | base = pci_iomap(pdev, 1, 0); | ||
198 | if (base == 0) { | ||
199 | dev_err(&pdev->dev, "%s : pci_iomap failed", __func__); | ||
200 | ret = -ENOMEM; | ||
201 | goto err_iomap; | ||
202 | } | ||
203 | |||
204 | chip_save = kzalloc(sizeof(*chip) * 8, GFP_KERNEL); | ||
205 | if (chip_save == NULL) { | ||
206 | dev_err(&pdev->dev, "%s : kzalloc failed", __func__); | ||
207 | ret = -ENOMEM; | ||
208 | goto err_kzalloc; | ||
209 | } | ||
210 | |||
211 | chip = chip_save; | ||
212 | for (i = 0; i < 8; i++, chip++) { | ||
213 | chip->dev = &pdev->dev; | ||
214 | chip->base = base; | ||
215 | chip->reg = chip->base; | ||
216 | chip->ch = i; | ||
217 | mutex_init(&chip->lock); | ||
218 | ioh_gpio_setup(chip, num_ports[i]); | ||
219 | ret = gpiochip_add(&chip->gpio); | ||
220 | if (ret) { | ||
221 | dev_err(&pdev->dev, "IOH gpio: Failed to register GPIO\n"); | ||
222 | goto err_gpiochip_add; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | chip = chip_save; | ||
227 | pci_set_drvdata(pdev, chip); | ||
228 | |||
229 | return 0; | ||
230 | |||
231 | err_gpiochip_add: | ||
232 | for (; i != 0; i--) { | ||
233 | chip--; | ||
234 | ret = gpiochip_remove(&chip->gpio); | ||
235 | if (ret) | ||
236 | dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); | ||
237 | } | ||
238 | kfree(chip_save); | ||
239 | |||
240 | err_kzalloc: | ||
241 | pci_iounmap(pdev, base); | ||
242 | |||
243 | err_iomap: | ||
244 | pci_release_regions(pdev); | ||
245 | |||
246 | err_request_regions: | ||
247 | pci_disable_device(pdev); | ||
248 | |||
249 | err_pci_enable: | ||
250 | |||
251 | dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); | ||
252 | return ret; | ||
253 | } | ||
254 | |||
255 | static void __devexit ioh_gpio_remove(struct pci_dev *pdev) | ||
256 | { | ||
257 | int err; | ||
258 | int i; | ||
259 | struct ioh_gpio *chip = pci_get_drvdata(pdev); | ||
260 | void __iomem *chip_save; | ||
261 | |||
262 | chip_save = chip; | ||
263 | for (i = 0; i < 8; i++, chip++) { | ||
264 | err = gpiochip_remove(&chip->gpio); | ||
265 | if (err) | ||
266 | dev_err(&pdev->dev, "Failed gpiochip_remove\n"); | ||
267 | } | ||
268 | |||
269 | chip = chip_save; | ||
270 | pci_iounmap(pdev, chip->base); | ||
271 | pci_release_regions(pdev); | ||
272 | pci_disable_device(pdev); | ||
273 | kfree(chip); | ||
274 | } | ||
275 | |||
276 | #ifdef CONFIG_PM | ||
277 | static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state) | ||
278 | { | ||
279 | s32 ret; | ||
280 | struct ioh_gpio *chip = pci_get_drvdata(pdev); | ||
281 | |||
282 | ioh_gpio_save_reg_conf(chip); | ||
283 | ioh_gpio_restore_reg_conf(chip); | ||
284 | |||
285 | ret = pci_save_state(pdev); | ||
286 | if (ret) { | ||
287 | dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret); | ||
288 | return ret; | ||
289 | } | ||
290 | pci_disable_device(pdev); | ||
291 | pci_set_power_state(pdev, PCI_D0); | ||
292 | ret = pci_enable_wake(pdev, PCI_D0, 1); | ||
293 | if (ret) | ||
294 | dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret); | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int ioh_gpio_resume(struct pci_dev *pdev) | ||
300 | { | ||
301 | s32 ret; | ||
302 | struct ioh_gpio *chip = pci_get_drvdata(pdev); | ||
303 | |||
304 | ret = pci_enable_wake(pdev, PCI_D0, 0); | ||
305 | |||
306 | pci_set_power_state(pdev, PCI_D0); | ||
307 | ret = pci_enable_device(pdev); | ||
308 | if (ret) { | ||
309 | dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret); | ||
310 | return ret; | ||
311 | } | ||
312 | pci_restore_state(pdev); | ||
313 | |||
314 | iowrite32(0x01, &chip->reg->srst); | ||
315 | iowrite32(0x00, &chip->reg->srst); | ||
316 | ioh_gpio_restore_reg_conf(chip); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | #else | ||
321 | #define ioh_gpio_suspend NULL | ||
322 | #define ioh_gpio_resume NULL | ||
323 | #endif | ||
324 | |||
325 | static DEFINE_PCI_DEVICE_TABLE(ioh_gpio_pcidev_id) = { | ||
326 | { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) }, | ||
327 | { 0, } | ||
328 | }; | ||
329 | |||
330 | static struct pci_driver ioh_gpio_driver = { | ||
331 | .name = "ml_ioh_gpio", | ||
332 | .id_table = ioh_gpio_pcidev_id, | ||
333 | .probe = ioh_gpio_probe, | ||
334 | .remove = __devexit_p(ioh_gpio_remove), | ||
335 | .suspend = ioh_gpio_suspend, | ||
336 | .resume = ioh_gpio_resume | ||
337 | }; | ||
338 | |||
339 | static int __init ioh_gpio_pci_init(void) | ||
340 | { | ||
341 | return pci_register_driver(&ioh_gpio_driver); | ||
342 | } | ||
343 | module_init(ioh_gpio_pci_init); | ||
344 | |||
345 | static void __exit ioh_gpio_pci_exit(void) | ||
346 | { | ||
347 | pci_unregister_driver(&ioh_gpio_driver); | ||
348 | } | ||
349 | module_exit(ioh_gpio_pci_exit); | ||
350 | |||
351 | MODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver"); | ||
352 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 501866662e0..a261972f603 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -228,30 +228,30 @@ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off) | |||
228 | return chip->irq_base + off; | 228 | return chip->irq_base + off; |
229 | } | 229 | } |
230 | 230 | ||
231 | static void pca953x_irq_mask(unsigned int irq) | 231 | static void pca953x_irq_mask(struct irq_data *d) |
232 | { | 232 | { |
233 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 233 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
234 | 234 | ||
235 | chip->irq_mask &= ~(1 << (irq - chip->irq_base)); | 235 | chip->irq_mask &= ~(1 << (d->irq - chip->irq_base)); |
236 | } | 236 | } |
237 | 237 | ||
238 | static void pca953x_irq_unmask(unsigned int irq) | 238 | static void pca953x_irq_unmask(struct irq_data *d) |
239 | { | 239 | { |
240 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 240 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
241 | 241 | ||
242 | chip->irq_mask |= 1 << (irq - chip->irq_base); | 242 | chip->irq_mask |= 1 << (d->irq - chip->irq_base); |
243 | } | 243 | } |
244 | 244 | ||
245 | static void pca953x_irq_bus_lock(unsigned int irq) | 245 | static void pca953x_irq_bus_lock(struct irq_data *d) |
246 | { | 246 | { |
247 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 247 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
248 | 248 | ||
249 | mutex_lock(&chip->irq_lock); | 249 | mutex_lock(&chip->irq_lock); |
250 | } | 250 | } |
251 | 251 | ||
252 | static void pca953x_irq_bus_sync_unlock(unsigned int irq) | 252 | static void pca953x_irq_bus_sync_unlock(struct irq_data *d) |
253 | { | 253 | { |
254 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 254 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
255 | uint16_t new_irqs; | 255 | uint16_t new_irqs; |
256 | uint16_t level; | 256 | uint16_t level; |
257 | 257 | ||
@@ -268,15 +268,15 @@ static void pca953x_irq_bus_sync_unlock(unsigned int irq) | |||
268 | mutex_unlock(&chip->irq_lock); | 268 | mutex_unlock(&chip->irq_lock); |
269 | } | 269 | } |
270 | 270 | ||
271 | static int pca953x_irq_set_type(unsigned int irq, unsigned int type) | 271 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) |
272 | { | 272 | { |
273 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 273 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
274 | uint16_t level = irq - chip->irq_base; | 274 | uint16_t level = d->irq - chip->irq_base; |
275 | uint16_t mask = 1 << level; | 275 | uint16_t mask = 1 << level; |
276 | 276 | ||
277 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 277 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
278 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 278 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
279 | irq, type); | 279 | d->irq, type); |
280 | return -EINVAL; | 280 | return -EINVAL; |
281 | } | 281 | } |
282 | 282 | ||
@@ -295,11 +295,11 @@ static int pca953x_irq_set_type(unsigned int irq, unsigned int type) | |||
295 | 295 | ||
296 | static struct irq_chip pca953x_irq_chip = { | 296 | static struct irq_chip pca953x_irq_chip = { |
297 | .name = "pca953x", | 297 | .name = "pca953x", |
298 | .mask = pca953x_irq_mask, | 298 | .irq_mask = pca953x_irq_mask, |
299 | .unmask = pca953x_irq_unmask, | 299 | .irq_unmask = pca953x_irq_unmask, |
300 | .bus_lock = pca953x_irq_bus_lock, | 300 | .irq_bus_lock = pca953x_irq_bus_lock, |
301 | .bus_sync_unlock = pca953x_irq_bus_sync_unlock, | 301 | .irq_bus_sync_unlock = pca953x_irq_bus_sync_unlock, |
302 | .set_type = pca953x_irq_set_type, | 302 | .irq_set_type = pca953x_irq_set_type, |
303 | }; | 303 | }; |
304 | 304 | ||
305 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | 305 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) |
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c index 5005990f751..2975d22daff 100644 --- a/drivers/gpio/pl061.c +++ b/drivers/gpio/pl061.c | |||
@@ -129,10 +129,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) | |||
129 | /* | 129 | /* |
130 | * PL061 GPIO IRQ | 130 | * PL061 GPIO IRQ |
131 | */ | 131 | */ |
132 | static void pl061_irq_disable(unsigned irq) | 132 | static void pl061_irq_disable(struct irq_data *d) |
133 | { | 133 | { |
134 | struct pl061_gpio *chip = get_irq_chip_data(irq); | 134 | struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); |
135 | int offset = irq - chip->irq_base; | 135 | int offset = d->irq - chip->irq_base; |
136 | unsigned long flags; | 136 | unsigned long flags; |
137 | u8 gpioie; | 137 | u8 gpioie; |
138 | 138 | ||
@@ -143,10 +143,10 @@ static void pl061_irq_disable(unsigned irq) | |||
143 | spin_unlock_irqrestore(&chip->irq_lock, flags); | 143 | spin_unlock_irqrestore(&chip->irq_lock, flags); |
144 | } | 144 | } |
145 | 145 | ||
146 | static void pl061_irq_enable(unsigned irq) | 146 | static void pl061_irq_enable(struct irq_data *d) |
147 | { | 147 | { |
148 | struct pl061_gpio *chip = get_irq_chip_data(irq); | 148 | struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); |
149 | int offset = irq - chip->irq_base; | 149 | int offset = d->irq - chip->irq_base; |
150 | unsigned long flags; | 150 | unsigned long flags; |
151 | u8 gpioie; | 151 | u8 gpioie; |
152 | 152 | ||
@@ -157,10 +157,10 @@ static void pl061_irq_enable(unsigned irq) | |||
157 | spin_unlock_irqrestore(&chip->irq_lock, flags); | 157 | spin_unlock_irqrestore(&chip->irq_lock, flags); |
158 | } | 158 | } |
159 | 159 | ||
160 | static int pl061_irq_type(unsigned irq, unsigned trigger) | 160 | static int pl061_irq_type(struct irq_data *d, unsigned trigger) |
161 | { | 161 | { |
162 | struct pl061_gpio *chip = get_irq_chip_data(irq); | 162 | struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); |
163 | int offset = irq - chip->irq_base; | 163 | int offset = d->irq - chip->irq_base; |
164 | unsigned long flags; | 164 | unsigned long flags; |
165 | u8 gpiois, gpioibe, gpioiev; | 165 | u8 gpiois, gpioibe, gpioiev; |
166 | 166 | ||
@@ -203,9 +203,9 @@ static int pl061_irq_type(unsigned irq, unsigned trigger) | |||
203 | 203 | ||
204 | static struct irq_chip pl061_irqchip = { | 204 | static struct irq_chip pl061_irqchip = { |
205 | .name = "GPIO", | 205 | .name = "GPIO", |
206 | .enable = pl061_irq_enable, | 206 | .irq_enable = pl061_irq_enable, |
207 | .disable = pl061_irq_disable, | 207 | .irq_disable = pl061_irq_disable, |
208 | .set_type = pl061_irq_type, | 208 | .irq_set_type = pl061_irq_type, |
209 | }; | 209 | }; |
210 | 210 | ||
211 | static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) | 211 | static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) |
@@ -214,7 +214,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) | |||
214 | struct list_head *ptr; | 214 | struct list_head *ptr; |
215 | struct pl061_gpio *chip; | 215 | struct pl061_gpio *chip; |
216 | 216 | ||
217 | desc->chip->ack(irq); | 217 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
218 | list_for_each(ptr, chip_list) { | 218 | list_for_each(ptr, chip_list) { |
219 | unsigned long pending; | 219 | unsigned long pending; |
220 | int offset; | 220 | int offset; |
@@ -229,7 +229,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) | |||
229 | for_each_set_bit(offset, &pending, PL061_GPIO_NR) | 229 | for_each_set_bit(offset, &pending, PL061_GPIO_NR) |
230 | generic_handle_irq(pl061_to_irq(&chip->gc, offset)); | 230 | generic_handle_irq(pl061_to_irq(&chip->gc, offset)); |
231 | } | 231 | } |
232 | desc->chip->unmask(irq); | 232 | desc->irq_data.chip->irq_unmask(&desc->irq_data); |
233 | } | 233 | } |
234 | 234 | ||
235 | static int pl061_probe(struct amba_device *dev, struct amba_id *id) | 235 | static int pl061_probe(struct amba_device *dev, struct amba_id *id) |
diff --git a/drivers/gpio/stmpe-gpio.c b/drivers/gpio/stmpe-gpio.c index 7c9e6a052c4..eb2901f8ab5 100644 --- a/drivers/gpio/stmpe-gpio.c +++ b/drivers/gpio/stmpe-gpio.c | |||
@@ -122,10 +122,10 @@ static struct gpio_chip template_chip = { | |||
122 | .can_sleep = 1, | 122 | .can_sleep = 1, |
123 | }; | 123 | }; |
124 | 124 | ||
125 | static int stmpe_gpio_irq_set_type(unsigned int irq, unsigned int type) | 125 | static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
126 | { | 126 | { |
127 | struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); | 127 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); |
128 | int offset = irq - stmpe_gpio->irq_base; | 128 | int offset = d->irq - stmpe_gpio->irq_base; |
129 | int regoffset = offset / 8; | 129 | int regoffset = offset / 8; |
130 | int mask = 1 << (offset % 8); | 130 | int mask = 1 << (offset % 8); |
131 | 131 | ||
@@ -145,16 +145,16 @@ static int stmpe_gpio_irq_set_type(unsigned int irq, unsigned int type) | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static void stmpe_gpio_irq_lock(unsigned int irq) | 148 | static void stmpe_gpio_irq_lock(struct irq_data *d) |
149 | { | 149 | { |
150 | struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); | 150 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); |
151 | 151 | ||
152 | mutex_lock(&stmpe_gpio->irq_lock); | 152 | mutex_lock(&stmpe_gpio->irq_lock); |
153 | } | 153 | } |
154 | 154 | ||
155 | static void stmpe_gpio_irq_sync_unlock(unsigned int irq) | 155 | static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) |
156 | { | 156 | { |
157 | struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); | 157 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); |
158 | struct stmpe *stmpe = stmpe_gpio->stmpe; | 158 | struct stmpe *stmpe = stmpe_gpio->stmpe; |
159 | int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); | 159 | int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); |
160 | static const u8 regmap[] = { | 160 | static const u8 regmap[] = { |
@@ -180,20 +180,20 @@ static void stmpe_gpio_irq_sync_unlock(unsigned int irq) | |||
180 | mutex_unlock(&stmpe_gpio->irq_lock); | 180 | mutex_unlock(&stmpe_gpio->irq_lock); |
181 | } | 181 | } |
182 | 182 | ||
183 | static void stmpe_gpio_irq_mask(unsigned int irq) | 183 | static void stmpe_gpio_irq_mask(struct irq_data *d) |
184 | { | 184 | { |
185 | struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); | 185 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); |
186 | int offset = irq - stmpe_gpio->irq_base; | 186 | int offset = d->irq - stmpe_gpio->irq_base; |
187 | int regoffset = offset / 8; | 187 | int regoffset = offset / 8; |
188 | int mask = 1 << (offset % 8); | 188 | int mask = 1 << (offset % 8); |
189 | 189 | ||
190 | stmpe_gpio->regs[REG_IE][regoffset] &= ~mask; | 190 | stmpe_gpio->regs[REG_IE][regoffset] &= ~mask; |
191 | } | 191 | } |
192 | 192 | ||
193 | static void stmpe_gpio_irq_unmask(unsigned int irq) | 193 | static void stmpe_gpio_irq_unmask(struct irq_data *d) |
194 | { | 194 | { |
195 | struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); | 195 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); |
196 | int offset = irq - stmpe_gpio->irq_base; | 196 | int offset = d->irq - stmpe_gpio->irq_base; |
197 | int regoffset = offset / 8; | 197 | int regoffset = offset / 8; |
198 | int mask = 1 << (offset % 8); | 198 | int mask = 1 << (offset % 8); |
199 | 199 | ||
@@ -202,11 +202,11 @@ static void stmpe_gpio_irq_unmask(unsigned int irq) | |||
202 | 202 | ||
203 | static struct irq_chip stmpe_gpio_irq_chip = { | 203 | static struct irq_chip stmpe_gpio_irq_chip = { |
204 | .name = "stmpe-gpio", | 204 | .name = "stmpe-gpio", |
205 | .bus_lock = stmpe_gpio_irq_lock, | 205 | .irq_bus_lock = stmpe_gpio_irq_lock, |
206 | .bus_sync_unlock = stmpe_gpio_irq_sync_unlock, | 206 | .irq_bus_sync_unlock = stmpe_gpio_irq_sync_unlock, |
207 | .mask = stmpe_gpio_irq_mask, | 207 | .irq_mask = stmpe_gpio_irq_mask, |
208 | .unmask = stmpe_gpio_irq_unmask, | 208 | .irq_unmask = stmpe_gpio_irq_unmask, |
209 | .set_type = stmpe_gpio_irq_set_type, | 209 | .irq_set_type = stmpe_gpio_irq_set_type, |
210 | }; | 210 | }; |
211 | 211 | ||
212 | static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | 212 | static irqreturn_t stmpe_gpio_irq(int irq, void *dev) |
diff --git a/drivers/gpio/sx150x.c b/drivers/gpio/sx150x.c index 823559ab0e2..e60be0015c9 100644 --- a/drivers/gpio/sx150x.c +++ b/drivers/gpio/sx150x.c | |||
@@ -304,36 +304,36 @@ static int sx150x_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | |||
304 | return chip->irq_base + offset; | 304 | return chip->irq_base + offset; |
305 | } | 305 | } |
306 | 306 | ||
307 | static void sx150x_irq_mask(unsigned int irq) | 307 | static void sx150x_irq_mask(struct irq_data *d) |
308 | { | 308 | { |
309 | struct irq_chip *ic = get_irq_chip(irq); | 309 | struct irq_chip *ic = irq_data_get_irq_chip(d); |
310 | struct sx150x_chip *chip; | 310 | struct sx150x_chip *chip; |
311 | unsigned n; | 311 | unsigned n; |
312 | 312 | ||
313 | chip = container_of(ic, struct sx150x_chip, irq_chip); | 313 | chip = container_of(ic, struct sx150x_chip, irq_chip); |
314 | n = irq - chip->irq_base; | 314 | n = d->irq - chip->irq_base; |
315 | 315 | ||
316 | sx150x_write_cfg(chip, n, 1, chip->dev_cfg->reg_irq_mask, 1); | 316 | sx150x_write_cfg(chip, n, 1, chip->dev_cfg->reg_irq_mask, 1); |
317 | sx150x_write_cfg(chip, n, 2, chip->dev_cfg->reg_sense, 0); | 317 | sx150x_write_cfg(chip, n, 2, chip->dev_cfg->reg_sense, 0); |
318 | } | 318 | } |
319 | 319 | ||
320 | static void sx150x_irq_unmask(unsigned int irq) | 320 | static void sx150x_irq_unmask(struct irq_data *d) |
321 | { | 321 | { |
322 | struct irq_chip *ic = get_irq_chip(irq); | 322 | struct irq_chip *ic = irq_data_get_irq_chip(d); |
323 | struct sx150x_chip *chip; | 323 | struct sx150x_chip *chip; |
324 | unsigned n; | 324 | unsigned n; |
325 | 325 | ||
326 | chip = container_of(ic, struct sx150x_chip, irq_chip); | 326 | chip = container_of(ic, struct sx150x_chip, irq_chip); |
327 | n = irq - chip->irq_base; | 327 | n = d->irq - chip->irq_base; |
328 | 328 | ||
329 | sx150x_write_cfg(chip, n, 1, chip->dev_cfg->reg_irq_mask, 0); | 329 | sx150x_write_cfg(chip, n, 1, chip->dev_cfg->reg_irq_mask, 0); |
330 | sx150x_write_cfg(chip, n, 2, chip->dev_cfg->reg_sense, | 330 | sx150x_write_cfg(chip, n, 2, chip->dev_cfg->reg_sense, |
331 | chip->irq_sense >> (n * 2)); | 331 | chip->irq_sense >> (n * 2)); |
332 | } | 332 | } |
333 | 333 | ||
334 | static int sx150x_irq_set_type(unsigned int irq, unsigned int flow_type) | 334 | static int sx150x_irq_set_type(struct irq_data *d, unsigned int flow_type) |
335 | { | 335 | { |
336 | struct irq_chip *ic = get_irq_chip(irq); | 336 | struct irq_chip *ic = irq_data_get_irq_chip(d); |
337 | struct sx150x_chip *chip; | 337 | struct sx150x_chip *chip; |
338 | unsigned n, val = 0; | 338 | unsigned n, val = 0; |
339 | 339 | ||
@@ -341,7 +341,7 @@ static int sx150x_irq_set_type(unsigned int irq, unsigned int flow_type) | |||
341 | return -EINVAL; | 341 | return -EINVAL; |
342 | 342 | ||
343 | chip = container_of(ic, struct sx150x_chip, irq_chip); | 343 | chip = container_of(ic, struct sx150x_chip, irq_chip); |
344 | n = irq - chip->irq_base; | 344 | n = d->irq - chip->irq_base; |
345 | 345 | ||
346 | if (flow_type & IRQ_TYPE_EDGE_RISING) | 346 | if (flow_type & IRQ_TYPE_EDGE_RISING) |
347 | val |= 0x1; | 347 | val |= 0x1; |
@@ -386,9 +386,9 @@ static irqreturn_t sx150x_irq_thread_fn(int irq, void *dev_id) | |||
386 | return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); | 386 | return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); |
387 | } | 387 | } |
388 | 388 | ||
389 | static void sx150x_irq_bus_lock(unsigned int irq) | 389 | static void sx150x_irq_bus_lock(struct irq_data *d) |
390 | { | 390 | { |
391 | struct irq_chip *ic = get_irq_chip(irq); | 391 | struct irq_chip *ic = irq_data_get_irq_chip(d); |
392 | struct sx150x_chip *chip; | 392 | struct sx150x_chip *chip; |
393 | 393 | ||
394 | chip = container_of(ic, struct sx150x_chip, irq_chip); | 394 | chip = container_of(ic, struct sx150x_chip, irq_chip); |
@@ -396,9 +396,9 @@ static void sx150x_irq_bus_lock(unsigned int irq) | |||
396 | mutex_lock(&chip->lock); | 396 | mutex_lock(&chip->lock); |
397 | } | 397 | } |
398 | 398 | ||
399 | static void sx150x_irq_bus_sync_unlock(unsigned int irq) | 399 | static void sx150x_irq_bus_sync_unlock(struct irq_data *d) |
400 | { | 400 | { |
401 | struct irq_chip *ic = get_irq_chip(irq); | 401 | struct irq_chip *ic = irq_data_get_irq_chip(d); |
402 | struct sx150x_chip *chip; | 402 | struct sx150x_chip *chip; |
403 | unsigned n; | 403 | unsigned n; |
404 | 404 | ||
@@ -437,16 +437,16 @@ static void sx150x_init_chip(struct sx150x_chip *chip, | |||
437 | if (pdata->oscio_is_gpo) | 437 | if (pdata->oscio_is_gpo) |
438 | ++chip->gpio_chip.ngpio; | 438 | ++chip->gpio_chip.ngpio; |
439 | 439 | ||
440 | chip->irq_chip.name = client->name; | 440 | chip->irq_chip.name = client->name; |
441 | chip->irq_chip.mask = sx150x_irq_mask; | 441 | chip->irq_chip.irq_mask = sx150x_irq_mask; |
442 | chip->irq_chip.unmask = sx150x_irq_unmask; | 442 | chip->irq_chip.irq_unmask = sx150x_irq_unmask; |
443 | chip->irq_chip.set_type = sx150x_irq_set_type; | 443 | chip->irq_chip.irq_set_type = sx150x_irq_set_type; |
444 | chip->irq_chip.bus_lock = sx150x_irq_bus_lock; | 444 | chip->irq_chip.irq_bus_lock = sx150x_irq_bus_lock; |
445 | chip->irq_chip.bus_sync_unlock = sx150x_irq_bus_sync_unlock; | 445 | chip->irq_chip.irq_bus_sync_unlock = sx150x_irq_bus_sync_unlock; |
446 | chip->irq_summary = -1; | 446 | chip->irq_summary = -1; |
447 | chip->irq_base = -1; | 447 | chip->irq_base = -1; |
448 | chip->irq_sense = 0; | 448 | chip->irq_sense = 0; |
449 | chip->irq_set_type_pending = 0; | 449 | chip->irq_set_type_pending = 0; |
450 | } | 450 | } |
451 | 451 | ||
452 | static int sx150x_init_io(struct sx150x_chip *chip, u8 base, u16 cfg) | 452 | static int sx150x_init_io(struct sx150x_chip *chip, u8 base, u16 cfg) |
diff --git a/drivers/gpio/tc3589x-gpio.c b/drivers/gpio/tc3589x-gpio.c index 180d584454f..27200af1a59 100644 --- a/drivers/gpio/tc3589x-gpio.c +++ b/drivers/gpio/tc3589x-gpio.c | |||
@@ -110,10 +110,10 @@ static struct gpio_chip template_chip = { | |||
110 | .can_sleep = 1, | 110 | .can_sleep = 1, |
111 | }; | 111 | }; |
112 | 112 | ||
113 | static int tc3589x_gpio_irq_set_type(unsigned int irq, unsigned int type) | 113 | static int tc3589x_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
114 | { | 114 | { |
115 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | 115 | struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); |
116 | int offset = irq - tc3589x_gpio->irq_base; | 116 | int offset = d->irq - tc3589x_gpio->irq_base; |
117 | int regoffset = offset / 8; | 117 | int regoffset = offset / 8; |
118 | int mask = 1 << (offset % 8); | 118 | int mask = 1 << (offset % 8); |
119 | 119 | ||
@@ -137,16 +137,16 @@ static int tc3589x_gpio_irq_set_type(unsigned int irq, unsigned int type) | |||
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
139 | 139 | ||
140 | static void tc3589x_gpio_irq_lock(unsigned int irq) | 140 | static void tc3589x_gpio_irq_lock(struct irq_data *d) |
141 | { | 141 | { |
142 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | 142 | struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); |
143 | 143 | ||
144 | mutex_lock(&tc3589x_gpio->irq_lock); | 144 | mutex_lock(&tc3589x_gpio->irq_lock); |
145 | } | 145 | } |
146 | 146 | ||
147 | static void tc3589x_gpio_irq_sync_unlock(unsigned int irq) | 147 | static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d) |
148 | { | 148 | { |
149 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | 149 | struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); |
150 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; | 150 | struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; |
151 | static const u8 regmap[] = { | 151 | static const u8 regmap[] = { |
152 | [REG_IBE] = TC3589x_GPIOIBE0, | 152 | [REG_IBE] = TC3589x_GPIOIBE0, |
@@ -172,20 +172,20 @@ static void tc3589x_gpio_irq_sync_unlock(unsigned int irq) | |||
172 | mutex_unlock(&tc3589x_gpio->irq_lock); | 172 | mutex_unlock(&tc3589x_gpio->irq_lock); |
173 | } | 173 | } |
174 | 174 | ||
175 | static void tc3589x_gpio_irq_mask(unsigned int irq) | 175 | static void tc3589x_gpio_irq_mask(struct irq_data *d) |
176 | { | 176 | { |
177 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | 177 | struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); |
178 | int offset = irq - tc3589x_gpio->irq_base; | 178 | int offset = d->irq - tc3589x_gpio->irq_base; |
179 | int regoffset = offset / 8; | 179 | int regoffset = offset / 8; |
180 | int mask = 1 << (offset % 8); | 180 | int mask = 1 << (offset % 8); |
181 | 181 | ||
182 | tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask; | 182 | tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask; |
183 | } | 183 | } |
184 | 184 | ||
185 | static void tc3589x_gpio_irq_unmask(unsigned int irq) | 185 | static void tc3589x_gpio_irq_unmask(struct irq_data *d) |
186 | { | 186 | { |
187 | struct tc3589x_gpio *tc3589x_gpio = get_irq_chip_data(irq); | 187 | struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); |
188 | int offset = irq - tc3589x_gpio->irq_base; | 188 | int offset = d->irq - tc3589x_gpio->irq_base; |
189 | int regoffset = offset / 8; | 189 | int regoffset = offset / 8; |
190 | int mask = 1 << (offset % 8); | 190 | int mask = 1 << (offset % 8); |
191 | 191 | ||
@@ -194,11 +194,11 @@ static void tc3589x_gpio_irq_unmask(unsigned int irq) | |||
194 | 194 | ||
195 | static struct irq_chip tc3589x_gpio_irq_chip = { | 195 | static struct irq_chip tc3589x_gpio_irq_chip = { |
196 | .name = "tc3589x-gpio", | 196 | .name = "tc3589x-gpio", |
197 | .bus_lock = tc3589x_gpio_irq_lock, | 197 | .irq_bus_lock = tc3589x_gpio_irq_lock, |
198 | .bus_sync_unlock = tc3589x_gpio_irq_sync_unlock, | 198 | .irq_bus_sync_unlock = tc3589x_gpio_irq_sync_unlock, |
199 | .mask = tc3589x_gpio_irq_mask, | 199 | .irq_mask = tc3589x_gpio_irq_mask, |
200 | .unmask = tc3589x_gpio_irq_unmask, | 200 | .irq_unmask = tc3589x_gpio_irq_unmask, |
201 | .set_type = tc3589x_gpio_irq_set_type, | 201 | .irq_set_type = tc3589x_gpio_irq_set_type, |
202 | }; | 202 | }; |
203 | 203 | ||
204 | static irqreturn_t tc3589x_gpio_irq(int irq, void *dev) | 204 | static irqreturn_t tc3589x_gpio_irq(int irq, void *dev) |
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c index 45293662e95..349131eb1ce 100644 --- a/drivers/gpio/timbgpio.c +++ b/drivers/gpio/timbgpio.c | |||
@@ -109,10 +109,10 @@ static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset) | |||
109 | /* | 109 | /* |
110 | * GPIO IRQ | 110 | * GPIO IRQ |
111 | */ | 111 | */ |
112 | static void timbgpio_irq_disable(unsigned irq) | 112 | static void timbgpio_irq_disable(struct irq_data *d) |
113 | { | 113 | { |
114 | struct timbgpio *tgpio = get_irq_chip_data(irq); | 114 | struct timbgpio *tgpio = irq_data_get_irq_chip_data(d); |
115 | int offset = irq - tgpio->irq_base; | 115 | int offset = d->irq - tgpio->irq_base; |
116 | unsigned long flags; | 116 | unsigned long flags; |
117 | 117 | ||
118 | spin_lock_irqsave(&tgpio->lock, flags); | 118 | spin_lock_irqsave(&tgpio->lock, flags); |
@@ -121,10 +121,10 @@ static void timbgpio_irq_disable(unsigned irq) | |||
121 | spin_unlock_irqrestore(&tgpio->lock, flags); | 121 | spin_unlock_irqrestore(&tgpio->lock, flags); |
122 | } | 122 | } |
123 | 123 | ||
124 | static void timbgpio_irq_enable(unsigned irq) | 124 | static void timbgpio_irq_enable(struct irq_data *d) |
125 | { | 125 | { |
126 | struct timbgpio *tgpio = get_irq_chip_data(irq); | 126 | struct timbgpio *tgpio = irq_data_get_irq_chip_data(d); |
127 | int offset = irq - tgpio->irq_base; | 127 | int offset = d->irq - tgpio->irq_base; |
128 | unsigned long flags; | 128 | unsigned long flags; |
129 | 129 | ||
130 | spin_lock_irqsave(&tgpio->lock, flags); | 130 | spin_lock_irqsave(&tgpio->lock, flags); |
@@ -133,10 +133,10 @@ static void timbgpio_irq_enable(unsigned irq) | |||
133 | spin_unlock_irqrestore(&tgpio->lock, flags); | 133 | spin_unlock_irqrestore(&tgpio->lock, flags); |
134 | } | 134 | } |
135 | 135 | ||
136 | static int timbgpio_irq_type(unsigned irq, unsigned trigger) | 136 | static int timbgpio_irq_type(struct irq_data *d, unsigned trigger) |
137 | { | 137 | { |
138 | struct timbgpio *tgpio = get_irq_chip_data(irq); | 138 | struct timbgpio *tgpio = irq_data_get_irq_chip_data(d); |
139 | int offset = irq - tgpio->irq_base; | 139 | int offset = d->irq - tgpio->irq_base; |
140 | unsigned long flags; | 140 | unsigned long flags; |
141 | u32 lvr, flr, bflr = 0; | 141 | u32 lvr, flr, bflr = 0; |
142 | u32 ver; | 142 | u32 ver; |
@@ -193,13 +193,13 @@ out: | |||
193 | return ret; | 193 | return ret; |
194 | } | 194 | } |
195 | 195 | ||
196 | static void timbgpio_irq(unsigned int irq, struct irq_desc *desc) | 196 | static void timbgpio_irq(struct irq_data *d, struct irq_desc *desc) |
197 | { | 197 | { |
198 | struct timbgpio *tgpio = get_irq_data(irq); | 198 | struct timbgpio *tgpio = irq_data_get_irq_data(d); |
199 | unsigned long ipr; | 199 | unsigned long ipr; |
200 | int offset; | 200 | int offset; |
201 | 201 | ||
202 | desc->chip->ack(irq); | 202 | desc->irq_data.chip->ack(irq_get_irq_data(d)); |
203 | ipr = ioread32(tgpio->membase + TGPIO_IPR); | 203 | ipr = ioread32(tgpio->membase + TGPIO_IPR); |
204 | iowrite32(ipr, tgpio->membase + TGPIO_ICR); | 204 | iowrite32(ipr, tgpio->membase + TGPIO_ICR); |
205 | 205 | ||
@@ -217,9 +217,9 @@ static void timbgpio_irq(unsigned int irq, struct irq_desc *desc) | |||
217 | 217 | ||
218 | static struct irq_chip timbgpio_irqchip = { | 218 | static struct irq_chip timbgpio_irqchip = { |
219 | .name = "GPIO", | 219 | .name = "GPIO", |
220 | .enable = timbgpio_irq_enable, | 220 | .irq_enable = timbgpio_irq_enable, |
221 | .disable = timbgpio_irq_disable, | 221 | .irq_disable = timbgpio_irq_disable, |
222 | .set_type = timbgpio_irq_type, | 222 | .irq_set_type = timbgpio_irq_type, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static int __devinit timbgpio_probe(struct platform_device *pdev) | 225 | static int __devinit timbgpio_probe(struct platform_device *pdev) |
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/vr41xx_giu.c index b16c9a8c03f..cffa3bd7ad3 100644 --- a/drivers/gpio/vr41xx_giu.c +++ b/drivers/gpio/vr41xx_giu.c | |||
@@ -111,69 +111,69 @@ static inline u16 giu_clear(u16 offset, u16 clear) | |||
111 | return data; | 111 | return data; |
112 | } | 112 | } |
113 | 113 | ||
114 | static void ack_giuint_low(unsigned int irq) | 114 | static void ack_giuint_low(struct irq_data *d) |
115 | { | 115 | { |
116 | giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); | 116 | giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(d->irq)); |
117 | } | 117 | } |
118 | 118 | ||
119 | static void mask_giuint_low(unsigned int irq) | 119 | static void mask_giuint_low(struct irq_data *d) |
120 | { | 120 | { |
121 | giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); | 121 | giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq)); |
122 | } | 122 | } |
123 | 123 | ||
124 | static void mask_ack_giuint_low(unsigned int irq) | 124 | static void mask_ack_giuint_low(struct irq_data *d) |
125 | { | 125 | { |
126 | unsigned int pin; | 126 | unsigned int pin; |
127 | 127 | ||
128 | pin = GPIO_PIN_OF_IRQ(irq); | 128 | pin = GPIO_PIN_OF_IRQ(d->irq); |
129 | giu_clear(GIUINTENL, 1 << pin); | 129 | giu_clear(GIUINTENL, 1 << pin); |
130 | giu_write(GIUINTSTATL, 1 << pin); | 130 | giu_write(GIUINTSTATL, 1 << pin); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void unmask_giuint_low(unsigned int irq) | 133 | static void unmask_giuint_low(struct irq_data *d) |
134 | { | 134 | { |
135 | giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); | 135 | giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq)); |
136 | } | 136 | } |
137 | 137 | ||
138 | static struct irq_chip giuint_low_irq_chip = { | 138 | static struct irq_chip giuint_low_irq_chip = { |
139 | .name = "GIUINTL", | 139 | .name = "GIUINTL", |
140 | .ack = ack_giuint_low, | 140 | .irq_ack = ack_giuint_low, |
141 | .mask = mask_giuint_low, | 141 | .irq_mask = mask_giuint_low, |
142 | .mask_ack = mask_ack_giuint_low, | 142 | .irq_mask_ack = mask_ack_giuint_low, |
143 | .unmask = unmask_giuint_low, | 143 | .irq_unmask = unmask_giuint_low, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | static void ack_giuint_high(unsigned int irq) | 146 | static void ack_giuint_high(struct irq_data *d) |
147 | { | 147 | { |
148 | giu_write(GIUINTSTATH, | 148 | giu_write(GIUINTSTATH, |
149 | 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | 149 | 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET)); |
150 | } | 150 | } |
151 | 151 | ||
152 | static void mask_giuint_high(unsigned int irq) | 152 | static void mask_giuint_high(struct irq_data *d) |
153 | { | 153 | { |
154 | giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | 154 | giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET)); |
155 | } | 155 | } |
156 | 156 | ||
157 | static void mask_ack_giuint_high(unsigned int irq) | 157 | static void mask_ack_giuint_high(struct irq_data *d) |
158 | { | 158 | { |
159 | unsigned int pin; | 159 | unsigned int pin; |
160 | 160 | ||
161 | pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; | 161 | pin = GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET; |
162 | giu_clear(GIUINTENH, 1 << pin); | 162 | giu_clear(GIUINTENH, 1 << pin); |
163 | giu_write(GIUINTSTATH, 1 << pin); | 163 | giu_write(GIUINTSTATH, 1 << pin); |
164 | } | 164 | } |
165 | 165 | ||
166 | static void unmask_giuint_high(unsigned int irq) | 166 | static void unmask_giuint_high(struct irq_data *d) |
167 | { | 167 | { |
168 | giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); | 168 | giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET)); |
169 | } | 169 | } |
170 | 170 | ||
171 | static struct irq_chip giuint_high_irq_chip = { | 171 | static struct irq_chip giuint_high_irq_chip = { |
172 | .name = "GIUINTH", | 172 | .name = "GIUINTH", |
173 | .ack = ack_giuint_high, | 173 | .irq_ack = ack_giuint_high, |
174 | .mask = mask_giuint_high, | 174 | .irq_mask = mask_giuint_high, |
175 | .mask_ack = mask_ack_giuint_high, | 175 | .irq_mask_ack = mask_ack_giuint_high, |
176 | .unmask = unmask_giuint_high, | 176 | .irq_unmask = unmask_giuint_high, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | static int giu_get_irq(unsigned int irq) | 179 | static int giu_get_irq(unsigned int irq) |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 92f75782c33..19a3d58044d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -106,10 +106,19 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj) | |||
106 | } | 106 | } |
107 | } | 107 | } |
108 | 108 | ||
109 | static const char *agp_type_str(int type) | ||
110 | { | ||
111 | switch (type) { | ||
112 | case 0: return " uncached"; | ||
113 | case 1: return " snooped"; | ||
114 | default: return ""; | ||
115 | } | ||
116 | } | ||
117 | |||
109 | static void | 118 | static void |
110 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | 119 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) |
111 | { | 120 | { |
112 | seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s", | 121 | seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s", |
113 | &obj->base, | 122 | &obj->base, |
114 | get_pin_flag(obj), | 123 | get_pin_flag(obj), |
115 | get_tiling_flag(obj), | 124 | get_tiling_flag(obj), |
@@ -118,6 +127,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
118 | obj->base.write_domain, | 127 | obj->base.write_domain, |
119 | obj->last_rendering_seqno, | 128 | obj->last_rendering_seqno, |
120 | obj->last_fenced_seqno, | 129 | obj->last_fenced_seqno, |
130 | agp_type_str(obj->agp_type == AGP_USER_CACHED_MEMORY), | ||
121 | obj->dirty ? " dirty" : "", | 131 | obj->dirty ? " dirty" : "", |
122 | obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | 132 | obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); |
123 | if (obj->base.name) | 133 | if (obj->base.name) |
@@ -276,6 +286,37 @@ static int i915_gem_object_info(struct seq_file *m, void* data) | |||
276 | return 0; | 286 | return 0; |
277 | } | 287 | } |
278 | 288 | ||
289 | static int i915_gem_gtt_info(struct seq_file *m, void* data) | ||
290 | { | ||
291 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
292 | struct drm_device *dev = node->minor->dev; | ||
293 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
294 | struct drm_i915_gem_object *obj; | ||
295 | size_t total_obj_size, total_gtt_size; | ||
296 | int count, ret; | ||
297 | |||
298 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
299 | if (ret) | ||
300 | return ret; | ||
301 | |||
302 | total_obj_size = total_gtt_size = count = 0; | ||
303 | list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { | ||
304 | seq_printf(m, " "); | ||
305 | describe_obj(m, obj); | ||
306 | seq_printf(m, "\n"); | ||
307 | total_obj_size += obj->base.size; | ||
308 | total_gtt_size += obj->gtt_space->size; | ||
309 | count++; | ||
310 | } | ||
311 | |||
312 | mutex_unlock(&dev->struct_mutex); | ||
313 | |||
314 | seq_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n", | ||
315 | count, total_obj_size, total_gtt_size); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
279 | 320 | ||
280 | static int i915_gem_pageflip_info(struct seq_file *m, void *data) | 321 | static int i915_gem_pageflip_info(struct seq_file *m, void *data) |
281 | { | 322 | { |
@@ -456,8 +497,14 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
456 | } | 497 | } |
457 | seq_printf(m, "Interrupts received: %d\n", | 498 | seq_printf(m, "Interrupts received: %d\n", |
458 | atomic_read(&dev_priv->irq_received)); | 499 | atomic_read(&dev_priv->irq_received)); |
459 | for (i = 0; i < I915_NUM_RINGS; i++) | 500 | for (i = 0; i < I915_NUM_RINGS; i++) { |
501 | if (IS_GEN6(dev)) { | ||
502 | seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", | ||
503 | dev_priv->ring[i].name, | ||
504 | I915_READ_IMR(&dev_priv->ring[i])); | ||
505 | } | ||
460 | i915_ring_seqno_info(m, &dev_priv->ring[i]); | 506 | i915_ring_seqno_info(m, &dev_priv->ring[i]); |
507 | } | ||
461 | mutex_unlock(&dev->struct_mutex); | 508 | mutex_unlock(&dev->struct_mutex); |
462 | 509 | ||
463 | return 0; | 510 | return 0; |
@@ -656,7 +703,7 @@ static void print_error_buffers(struct seq_file *m, | |||
656 | seq_printf(m, "%s [%d]:\n", name, count); | 703 | seq_printf(m, "%s [%d]:\n", name, count); |
657 | 704 | ||
658 | while (count--) { | 705 | while (count--) { |
659 | seq_printf(m, " %08x %8zd %04x %04x %08x%s%s%s%s%s", | 706 | seq_printf(m, " %08x %8zd %04x %04x %08x%s%s%s%s%s%s", |
660 | err->gtt_offset, | 707 | err->gtt_offset, |
661 | err->size, | 708 | err->size, |
662 | err->read_domains, | 709 | err->read_domains, |
@@ -666,7 +713,8 @@ static void print_error_buffers(struct seq_file *m, | |||
666 | tiling_flag(err->tiling), | 713 | tiling_flag(err->tiling), |
667 | dirty_flag(err->dirty), | 714 | dirty_flag(err->dirty), |
668 | purgeable_flag(err->purgeable), | 715 | purgeable_flag(err->purgeable), |
669 | ring_str(err->ring)); | 716 | ring_str(err->ring), |
717 | agp_type_str(err->agp_type)); | ||
670 | 718 | ||
671 | if (err->name) | 719 | if (err->name) |
672 | seq_printf(m, " (name: %d)", err->name); | 720 | seq_printf(m, " (name: %d)", err->name); |
@@ -744,7 +792,9 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
744 | if (error->batchbuffer[i]) { | 792 | if (error->batchbuffer[i]) { |
745 | struct drm_i915_error_object *obj = error->batchbuffer[i]; | 793 | struct drm_i915_error_object *obj = error->batchbuffer[i]; |
746 | 794 | ||
747 | seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset); | 795 | seq_printf(m, "%s --- gtt_offset = 0x%08x\n", |
796 | dev_priv->ring[i].name, | ||
797 | obj->gtt_offset); | ||
748 | offset = 0; | 798 | offset = 0; |
749 | for (page = 0; page < obj->page_count; page++) { | 799 | for (page = 0; page < obj->page_count; page++) { |
750 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { | 800 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { |
@@ -890,7 +940,7 @@ static int i915_drpc_info(struct seq_file *m, void *unused) | |||
890 | struct drm_device *dev = node->minor->dev; | 940 | struct drm_device *dev = node->minor->dev; |
891 | drm_i915_private_t *dev_priv = dev->dev_private; | 941 | drm_i915_private_t *dev_priv = dev->dev_private; |
892 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 942 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
893 | u32 rstdbyctl = I915_READ(MCHBAR_RENDER_STANDBY); | 943 | u32 rstdbyctl = I915_READ(RSTDBYCTL); |
894 | u16 crstandvid = I915_READ16(CRSTANDVID); | 944 | u16 crstandvid = I915_READ16(CRSTANDVID); |
895 | 945 | ||
896 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? | 946 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? |
@@ -913,6 +963,30 @@ static int i915_drpc_info(struct seq_file *m, void *unused) | |||
913 | seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); | 963 | seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); |
914 | seq_printf(m, "Render standby enabled: %s\n", | 964 | seq_printf(m, "Render standby enabled: %s\n", |
915 | (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); | 965 | (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); |
966 | seq_printf(m, "Current RS state: "); | ||
967 | switch (rstdbyctl & RSX_STATUS_MASK) { | ||
968 | case RSX_STATUS_ON: | ||
969 | seq_printf(m, "on\n"); | ||
970 | break; | ||
971 | case RSX_STATUS_RC1: | ||
972 | seq_printf(m, "RC1\n"); | ||
973 | break; | ||
974 | case RSX_STATUS_RC1E: | ||
975 | seq_printf(m, "RC1E\n"); | ||
976 | break; | ||
977 | case RSX_STATUS_RS1: | ||
978 | seq_printf(m, "RS1\n"); | ||
979 | break; | ||
980 | case RSX_STATUS_RS2: | ||
981 | seq_printf(m, "RS2 (RC6)\n"); | ||
982 | break; | ||
983 | case RSX_STATUS_RS3: | ||
984 | seq_printf(m, "RC3 (RC6+)\n"); | ||
985 | break; | ||
986 | default: | ||
987 | seq_printf(m, "unknown\n"); | ||
988 | break; | ||
989 | } | ||
916 | 990 | ||
917 | return 0; | 991 | return 0; |
918 | } | 992 | } |
@@ -1187,6 +1261,7 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) | |||
1187 | static struct drm_info_list i915_debugfs_list[] = { | 1261 | static struct drm_info_list i915_debugfs_list[] = { |
1188 | {"i915_capabilities", i915_capabilities, 0, 0}, | 1262 | {"i915_capabilities", i915_capabilities, 0, 0}, |
1189 | {"i915_gem_objects", i915_gem_object_info, 0}, | 1263 | {"i915_gem_objects", i915_gem_object_info, 0}, |
1264 | {"i915_gem_gtt", i915_gem_gtt_info, 0}, | ||
1190 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 1265 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
1191 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 1266 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
1192 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, | 1267 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 0568dbdc10e..844f3c972b0 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1962,13 +1962,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1962 | /* enable GEM by default */ | 1962 | /* enable GEM by default */ |
1963 | dev_priv->has_gem = 1; | 1963 | dev_priv->has_gem = 1; |
1964 | 1964 | ||
1965 | if (dev_priv->has_gem == 0 && | ||
1966 | drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
1967 | DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); | ||
1968 | ret = -ENODEV; | ||
1969 | goto out_workqueue_free; | ||
1970 | } | ||
1971 | |||
1972 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1965 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
1973 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 1966 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
1974 | if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev)) { | 1967 | if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev)) { |
@@ -2055,7 +2048,6 @@ out_gem_unload: | |||
2055 | 2048 | ||
2056 | intel_teardown_gmbus(dev); | 2049 | intel_teardown_gmbus(dev); |
2057 | intel_teardown_mchbar(dev); | 2050 | intel_teardown_mchbar(dev); |
2058 | out_workqueue_free: | ||
2059 | destroy_workqueue(dev_priv->wq); | 2051 | destroy_workqueue(dev_priv->wq); |
2060 | out_iomapfree: | 2052 | out_iomapfree: |
2061 | io_mapping_free(dev_priv->mm.gtt_mapping); | 2053 | io_mapping_free(dev_priv->mm.gtt_mapping); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 87249333198..0de75a23f8e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -49,6 +49,9 @@ module_param_named(powersave, i915_powersave, int, 0600); | |||
49 | unsigned int i915_lvds_downclock = 0; | 49 | unsigned int i915_lvds_downclock = 0; |
50 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); | 50 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); |
51 | 51 | ||
52 | bool i915_try_reset = true; | ||
53 | module_param_named(reset, i915_try_reset, bool, 0600); | ||
54 | |||
52 | static struct drm_driver driver; | 55 | static struct drm_driver driver; |
53 | extern int intel_agp_enabled; | 56 | extern int intel_agp_enabled; |
54 | 57 | ||
@@ -352,6 +355,9 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
352 | 355 | ||
353 | /* Resume the modeset for every activated CRTC */ | 356 | /* Resume the modeset for every activated CRTC */ |
354 | drm_helper_resume_force_mode(dev); | 357 | drm_helper_resume_force_mode(dev); |
358 | |||
359 | if (dev_priv->renderctx && dev_priv->pwrctx) | ||
360 | ironlake_enable_rc6(dev); | ||
355 | } | 361 | } |
356 | 362 | ||
357 | intel_opregion_init(dev); | 363 | intel_opregion_init(dev); |
@@ -475,6 +481,9 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
475 | bool need_display = true; | 481 | bool need_display = true; |
476 | int ret; | 482 | int ret; |
477 | 483 | ||
484 | if (!i915_try_reset) | ||
485 | return 0; | ||
486 | |||
478 | if (!mutex_trylock(&dev->struct_mutex)) | 487 | if (!mutex_trylock(&dev->struct_mutex)) |
479 | return -EBUSY; | 488 | return -EBUSY; |
480 | 489 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aac1bf332f7..385fc7ec39d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -172,20 +172,21 @@ struct drm_i915_error_state { | |||
172 | int page_count; | 172 | int page_count; |
173 | u32 gtt_offset; | 173 | u32 gtt_offset; |
174 | u32 *pages[0]; | 174 | u32 *pages[0]; |
175 | } *ringbuffer, *batchbuffer[2]; | 175 | } *ringbuffer, *batchbuffer[I915_NUM_RINGS]; |
176 | struct drm_i915_error_buffer { | 176 | struct drm_i915_error_buffer { |
177 | size_t size; | 177 | u32 size; |
178 | u32 name; | 178 | u32 name; |
179 | u32 seqno; | 179 | u32 seqno; |
180 | u32 gtt_offset; | 180 | u32 gtt_offset; |
181 | u32 read_domains; | 181 | u32 read_domains; |
182 | u32 write_domain; | 182 | u32 write_domain; |
183 | u32 fence_reg; | 183 | s32 fence_reg:5; |
184 | s32 pinned:2; | 184 | s32 pinned:2; |
185 | u32 tiling:2; | 185 | u32 tiling:2; |
186 | u32 dirty:1; | 186 | u32 dirty:1; |
187 | u32 purgeable:1; | 187 | u32 purgeable:1; |
188 | u32 ring:4; | 188 | u32 ring:4; |
189 | u32 agp_type:1; | ||
189 | } *active_bo, *pinned_bo; | 190 | } *active_bo, *pinned_bo; |
190 | u32 active_bo_count, pinned_bo_count; | 191 | u32 active_bo_count, pinned_bo_count; |
191 | struct intel_overlay_error_state *overlay; | 192 | struct intel_overlay_error_state *overlay; |
@@ -332,6 +333,7 @@ typedef struct drm_i915_private { | |||
332 | 333 | ||
333 | /* LVDS info */ | 334 | /* LVDS info */ |
334 | int backlight_level; /* restore backlight to this value */ | 335 | int backlight_level; /* restore backlight to this value */ |
336 | bool backlight_enabled; | ||
335 | struct drm_display_mode *panel_fixed_mode; | 337 | struct drm_display_mode *panel_fixed_mode; |
336 | struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ | 338 | struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ |
337 | struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ | 339 | struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ |
@@ -794,6 +796,7 @@ struct drm_i915_gem_object { | |||
794 | */ | 796 | */ |
795 | struct hlist_node exec_node; | 797 | struct hlist_node exec_node; |
796 | unsigned long exec_handle; | 798 | unsigned long exec_handle; |
799 | struct drm_i915_gem_exec_object2 *exec_entry; | ||
797 | 800 | ||
798 | /** | 801 | /** |
799 | * Current offset of the object in GTT space. | 802 | * Current offset of the object in GTT space. |
@@ -1006,12 +1009,6 @@ extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); | |||
1006 | extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); | 1009 | extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); |
1007 | extern int i915_vblank_swap(struct drm_device *dev, void *data, | 1010 | extern int i915_vblank_swap(struct drm_device *dev, void *data, |
1008 | struct drm_file *file_priv); | 1011 | struct drm_file *file_priv); |
1009 | extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); | ||
1010 | extern void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask); | ||
1011 | extern void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, | ||
1012 | u32 mask); | ||
1013 | extern void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, | ||
1014 | u32 mask); | ||
1015 | 1012 | ||
1016 | void | 1013 | void |
1017 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); | 1014 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); |
@@ -1091,10 +1088,10 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | |||
1091 | struct drm_file *file_priv); | 1088 | struct drm_file *file_priv); |
1092 | void i915_gem_load(struct drm_device *dev); | 1089 | void i915_gem_load(struct drm_device *dev); |
1093 | int i915_gem_init_object(struct drm_gem_object *obj); | 1090 | int i915_gem_init_object(struct drm_gem_object *obj); |
1094 | void i915_gem_flush_ring(struct drm_device *dev, | 1091 | int __must_check i915_gem_flush_ring(struct drm_device *dev, |
1095 | struct intel_ring_buffer *ring, | 1092 | struct intel_ring_buffer *ring, |
1096 | uint32_t invalidate_domains, | 1093 | uint32_t invalidate_domains, |
1097 | uint32_t flush_domains); | 1094 | uint32_t flush_domains); |
1098 | struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, | 1095 | struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, |
1099 | size_t size); | 1096 | size_t size); |
1100 | void i915_gem_free_object(struct drm_gem_object *obj); | 1097 | void i915_gem_free_object(struct drm_gem_object *obj); |
@@ -1265,6 +1262,7 @@ extern void intel_disable_fbc(struct drm_device *dev); | |||
1265 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); | 1262 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); |
1266 | extern bool intel_fbc_enabled(struct drm_device *dev); | 1263 | extern bool intel_fbc_enabled(struct drm_device *dev); |
1267 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | 1264 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); |
1265 | extern void ironlake_enable_rc6(struct drm_device *dev); | ||
1268 | extern void gen6_set_rps(struct drm_device *dev, u8 val); | 1266 | extern void gen6_set_rps(struct drm_device *dev, u8 val); |
1269 | extern void intel_detect_pch (struct drm_device *dev); | 1267 | extern void intel_detect_pch (struct drm_device *dev); |
1270 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1268 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c79c0b62ef6..3dfc848ff75 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -35,18 +35,18 @@ | |||
35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | 37 | ||
38 | static void i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj); | 38 | static __must_check int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj); |
39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); | 39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); |
40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); | 40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); |
41 | static int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, | 41 | static __must_check int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, |
42 | bool write); | 42 | bool write); |
43 | static int i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, | 43 | static __must_check int i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, |
44 | uint64_t offset, | 44 | uint64_t offset, |
45 | uint64_t size); | 45 | uint64_t size); |
46 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj); | 46 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj); |
47 | static int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | 47 | static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, |
48 | unsigned alignment, | 48 | unsigned alignment, |
49 | bool map_and_fenceable); | 49 | bool map_and_fenceable); |
50 | static void i915_gem_clear_fence_reg(struct drm_device *dev, | 50 | static void i915_gem_clear_fence_reg(struct drm_device *dev, |
51 | struct drm_i915_fence_reg *reg); | 51 | struct drm_i915_fence_reg *reg); |
52 | static int i915_gem_phys_pwrite(struct drm_device *dev, | 52 | static int i915_gem_phys_pwrite(struct drm_device *dev, |
@@ -1935,6 +1935,8 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1935 | { | 1935 | { |
1936 | drm_i915_private_t *dev_priv; | 1936 | drm_i915_private_t *dev_priv; |
1937 | struct drm_device *dev; | 1937 | struct drm_device *dev; |
1938 | bool idle; | ||
1939 | int i; | ||
1938 | 1940 | ||
1939 | dev_priv = container_of(work, drm_i915_private_t, | 1941 | dev_priv = container_of(work, drm_i915_private_t, |
1940 | mm.retire_work.work); | 1942 | mm.retire_work.work); |
@@ -1948,11 +1950,31 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1948 | 1950 | ||
1949 | i915_gem_retire_requests(dev); | 1951 | i915_gem_retire_requests(dev); |
1950 | 1952 | ||
1951 | if (!dev_priv->mm.suspended && | 1953 | /* Send a periodic flush down the ring so we don't hold onto GEM |
1952 | (!list_empty(&dev_priv->ring[RCS].request_list) || | 1954 | * objects indefinitely. |
1953 | !list_empty(&dev_priv->ring[VCS].request_list) || | 1955 | */ |
1954 | !list_empty(&dev_priv->ring[BCS].request_list))) | 1956 | idle = true; |
1957 | for (i = 0; i < I915_NUM_RINGS; i++) { | ||
1958 | struct intel_ring_buffer *ring = &dev_priv->ring[i]; | ||
1959 | |||
1960 | if (!list_empty(&ring->gpu_write_list)) { | ||
1961 | struct drm_i915_gem_request *request; | ||
1962 | int ret; | ||
1963 | |||
1964 | ret = i915_gem_flush_ring(dev, ring, 0, | ||
1965 | I915_GEM_GPU_DOMAINS); | ||
1966 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
1967 | if (ret || request == NULL || | ||
1968 | i915_add_request(dev, NULL, request, ring)) | ||
1969 | kfree(request); | ||
1970 | } | ||
1971 | |||
1972 | idle &= list_empty(&ring->request_list); | ||
1973 | } | ||
1974 | |||
1975 | if (!dev_priv->mm.suspended && !idle) | ||
1955 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); | 1976 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); |
1977 | |||
1956 | mutex_unlock(&dev->struct_mutex); | 1978 | mutex_unlock(&dev->struct_mutex); |
1957 | } | 1979 | } |
1958 | 1980 | ||
@@ -2142,25 +2164,37 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) | |||
2142 | return ret; | 2164 | return ret; |
2143 | } | 2165 | } |
2144 | 2166 | ||
2145 | void | 2167 | int |
2146 | i915_gem_flush_ring(struct drm_device *dev, | 2168 | i915_gem_flush_ring(struct drm_device *dev, |
2147 | struct intel_ring_buffer *ring, | 2169 | struct intel_ring_buffer *ring, |
2148 | uint32_t invalidate_domains, | 2170 | uint32_t invalidate_domains, |
2149 | uint32_t flush_domains) | 2171 | uint32_t flush_domains) |
2150 | { | 2172 | { |
2151 | ring->flush(ring, invalidate_domains, flush_domains); | 2173 | int ret; |
2174 | |||
2175 | ret = ring->flush(ring, invalidate_domains, flush_domains); | ||
2176 | if (ret) | ||
2177 | return ret; | ||
2178 | |||
2152 | i915_gem_process_flushing_list(dev, flush_domains, ring); | 2179 | i915_gem_process_flushing_list(dev, flush_domains, ring); |
2180 | return 0; | ||
2153 | } | 2181 | } |
2154 | 2182 | ||
2155 | static int i915_ring_idle(struct drm_device *dev, | 2183 | static int i915_ring_idle(struct drm_device *dev, |
2156 | struct intel_ring_buffer *ring) | 2184 | struct intel_ring_buffer *ring) |
2157 | { | 2185 | { |
2186 | int ret; | ||
2187 | |||
2158 | if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) | 2188 | if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) |
2159 | return 0; | 2189 | return 0; |
2160 | 2190 | ||
2161 | if (!list_empty(&ring->gpu_write_list)) | 2191 | if (!list_empty(&ring->gpu_write_list)) { |
2162 | i915_gem_flush_ring(dev, ring, | 2192 | ret = i915_gem_flush_ring(dev, ring, |
2163 | I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); | 2193 | I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); |
2194 | if (ret) | ||
2195 | return ret; | ||
2196 | } | ||
2197 | |||
2164 | return i915_wait_request(dev, | 2198 | return i915_wait_request(dev, |
2165 | i915_gem_next_request_seqno(dev, ring), | 2199 | i915_gem_next_request_seqno(dev, ring), |
2166 | ring); | 2200 | ring); |
@@ -2370,10 +2404,13 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, | |||
2370 | int ret; | 2404 | int ret; |
2371 | 2405 | ||
2372 | if (obj->fenced_gpu_access) { | 2406 | if (obj->fenced_gpu_access) { |
2373 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) | 2407 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { |
2374 | i915_gem_flush_ring(obj->base.dev, | 2408 | ret = i915_gem_flush_ring(obj->base.dev, |
2375 | obj->last_fenced_ring, | 2409 | obj->last_fenced_ring, |
2376 | 0, obj->base.write_domain); | 2410 | 0, obj->base.write_domain); |
2411 | if (ret) | ||
2412 | return ret; | ||
2413 | } | ||
2377 | 2414 | ||
2378 | obj->fenced_gpu_access = false; | 2415 | obj->fenced_gpu_access = false; |
2379 | } | 2416 | } |
@@ -2393,6 +2430,12 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, | |||
2393 | obj->last_fenced_ring = NULL; | 2430 | obj->last_fenced_ring = NULL; |
2394 | } | 2431 | } |
2395 | 2432 | ||
2433 | /* Ensure that all CPU reads are completed before installing a fence | ||
2434 | * and all writes before removing the fence. | ||
2435 | */ | ||
2436 | if (obj->base.read_domains & I915_GEM_DOMAIN_GTT) | ||
2437 | mb(); | ||
2438 | |||
2396 | return 0; | 2439 | return 0; |
2397 | } | 2440 | } |
2398 | 2441 | ||
@@ -2523,9 +2566,12 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, | |||
2523 | return ret; | 2566 | return ret; |
2524 | } else if (obj->tiling_changed) { | 2567 | } else if (obj->tiling_changed) { |
2525 | if (obj->fenced_gpu_access) { | 2568 | if (obj->fenced_gpu_access) { |
2526 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) | 2569 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { |
2527 | i915_gem_flush_ring(obj->base.dev, obj->ring, | 2570 | ret = i915_gem_flush_ring(obj->base.dev, obj->ring, |
2528 | 0, obj->base.write_domain); | 2571 | 0, obj->base.write_domain); |
2572 | if (ret) | ||
2573 | return ret; | ||
2574 | } | ||
2529 | 2575 | ||
2530 | obj->fenced_gpu_access = false; | 2576 | obj->fenced_gpu_access = false; |
2531 | } | 2577 | } |
@@ -2736,10 +2782,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2736 | obj->gtt_space = NULL; | 2782 | obj->gtt_space = NULL; |
2737 | 2783 | ||
2738 | if (ret == -ENOMEM) { | 2784 | if (ret == -ENOMEM) { |
2739 | /* first try to clear up some space from the GTT */ | 2785 | /* first try to reclaim some memory by clearing the GTT */ |
2740 | ret = i915_gem_evict_something(dev, size, | 2786 | ret = i915_gem_evict_everything(dev, false); |
2741 | alignment, | ||
2742 | map_and_fenceable); | ||
2743 | if (ret) { | 2787 | if (ret) { |
2744 | /* now try to shrink everyone else */ | 2788 | /* now try to shrink everyone else */ |
2745 | if (gfpmask) { | 2789 | if (gfpmask) { |
@@ -2747,7 +2791,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2747 | goto search_free; | 2791 | goto search_free; |
2748 | } | 2792 | } |
2749 | 2793 | ||
2750 | return ret; | 2794 | return -ENOMEM; |
2751 | } | 2795 | } |
2752 | 2796 | ||
2753 | goto search_free; | 2797 | goto search_free; |
@@ -2762,9 +2806,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2762 | drm_mm_put_block(obj->gtt_space); | 2806 | drm_mm_put_block(obj->gtt_space); |
2763 | obj->gtt_space = NULL; | 2807 | obj->gtt_space = NULL; |
2764 | 2808 | ||
2765 | ret = i915_gem_evict_something(dev, size, | 2809 | if (i915_gem_evict_everything(dev, false)) |
2766 | alignment, map_and_fenceable); | ||
2767 | if (ret) | ||
2768 | return ret; | 2810 | return ret; |
2769 | 2811 | ||
2770 | goto search_free; | 2812 | goto search_free; |
@@ -2811,17 +2853,16 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj) | |||
2811 | } | 2853 | } |
2812 | 2854 | ||
2813 | /** Flushes any GPU write domain for the object if it's dirty. */ | 2855 | /** Flushes any GPU write domain for the object if it's dirty. */ |
2814 | static void | 2856 | static int |
2815 | i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj) | 2857 | i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj) |
2816 | { | 2858 | { |
2817 | struct drm_device *dev = obj->base.dev; | 2859 | struct drm_device *dev = obj->base.dev; |
2818 | 2860 | ||
2819 | if ((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0) | 2861 | if ((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0) |
2820 | return; | 2862 | return 0; |
2821 | 2863 | ||
2822 | /* Queue the GPU write cache flushing we need. */ | 2864 | /* Queue the GPU write cache flushing we need. */ |
2823 | i915_gem_flush_ring(dev, obj->ring, 0, obj->base.write_domain); | 2865 | return i915_gem_flush_ring(dev, obj->ring, 0, obj->base.write_domain); |
2824 | BUG_ON(obj->base.write_domain); | ||
2825 | } | 2866 | } |
2826 | 2867 | ||
2827 | /** Flushes the GTT write domain for the object if it's dirty. */ | 2868 | /** Flushes the GTT write domain for the object if it's dirty. */ |
@@ -2833,10 +2874,16 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) | |||
2833 | if (obj->base.write_domain != I915_GEM_DOMAIN_GTT) | 2874 | if (obj->base.write_domain != I915_GEM_DOMAIN_GTT) |
2834 | return; | 2875 | return; |
2835 | 2876 | ||
2836 | /* No actual flushing is required for the GTT write domain. Writes | 2877 | /* No actual flushing is required for the GTT write domain. Writes |
2837 | * to it immediately go to main memory as far as we know, so there's | 2878 | * to it immediately go to main memory as far as we know, so there's |
2838 | * no chipset flush. It also doesn't land in render cache. | 2879 | * no chipset flush. It also doesn't land in render cache. |
2880 | * | ||
2881 | * However, we do have to enforce the order so that all writes through | ||
2882 | * the GTT land before any writes to the device, such as updates to | ||
2883 | * the GATT itself. | ||
2839 | */ | 2884 | */ |
2885 | wmb(); | ||
2886 | |||
2840 | i915_gem_release_mmap(obj); | 2887 | i915_gem_release_mmap(obj); |
2841 | 2888 | ||
2842 | old_write_domain = obj->base.write_domain; | 2889 | old_write_domain = obj->base.write_domain; |
@@ -2882,7 +2929,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | |||
2882 | if (obj->gtt_space == NULL) | 2929 | if (obj->gtt_space == NULL) |
2883 | return -EINVAL; | 2930 | return -EINVAL; |
2884 | 2931 | ||
2885 | i915_gem_object_flush_gpu_write_domain(obj); | 2932 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
2933 | if (ret) | ||
2934 | return ret; | ||
2935 | |||
2886 | if (obj->pending_gpu_write || write) { | 2936 | if (obj->pending_gpu_write || write) { |
2887 | ret = i915_gem_object_wait_rendering(obj, true); | 2937 | ret = i915_gem_object_wait_rendering(obj, true); |
2888 | if (ret) | 2938 | if (ret) |
@@ -2927,7 +2977,10 @@ i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, | |||
2927 | if (obj->gtt_space == NULL) | 2977 | if (obj->gtt_space == NULL) |
2928 | return -EINVAL; | 2978 | return -EINVAL; |
2929 | 2979 | ||
2930 | i915_gem_object_flush_gpu_write_domain(obj); | 2980 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
2981 | if (ret) | ||
2982 | return ret; | ||
2983 | |||
2931 | 2984 | ||
2932 | /* Currently, we are always called from an non-interruptible context. */ | 2985 | /* Currently, we are always called from an non-interruptible context. */ |
2933 | if (pipelined != obj->ring) { | 2986 | if (pipelined != obj->ring) { |
@@ -2952,12 +3005,17 @@ int | |||
2952 | i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, | 3005 | i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, |
2953 | bool interruptible) | 3006 | bool interruptible) |
2954 | { | 3007 | { |
3008 | int ret; | ||
3009 | |||
2955 | if (!obj->active) | 3010 | if (!obj->active) |
2956 | return 0; | 3011 | return 0; |
2957 | 3012 | ||
2958 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) | 3013 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { |
2959 | i915_gem_flush_ring(obj->base.dev, obj->ring, | 3014 | ret = i915_gem_flush_ring(obj->base.dev, obj->ring, |
2960 | 0, obj->base.write_domain); | 3015 | 0, obj->base.write_domain); |
3016 | if (ret) | ||
3017 | return ret; | ||
3018 | } | ||
2961 | 3019 | ||
2962 | return i915_gem_object_wait_rendering(obj, interruptible); | 3020 | return i915_gem_object_wait_rendering(obj, interruptible); |
2963 | } | 3021 | } |
@@ -2974,7 +3032,10 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) | |||
2974 | uint32_t old_write_domain, old_read_domains; | 3032 | uint32_t old_write_domain, old_read_domains; |
2975 | int ret; | 3033 | int ret; |
2976 | 3034 | ||
2977 | i915_gem_object_flush_gpu_write_domain(obj); | 3035 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
3036 | if (ret) | ||
3037 | return ret; | ||
3038 | |||
2978 | ret = i915_gem_object_wait_rendering(obj, true); | 3039 | ret = i915_gem_object_wait_rendering(obj, true); |
2979 | if (ret) | 3040 | if (ret) |
2980 | return ret; | 3041 | return ret; |
@@ -3069,7 +3130,10 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, | |||
3069 | if (offset == 0 && size == obj->base.size) | 3130 | if (offset == 0 && size == obj->base.size) |
3070 | return i915_gem_object_set_to_cpu_domain(obj, 0); | 3131 | return i915_gem_object_set_to_cpu_domain(obj, 0); |
3071 | 3132 | ||
3072 | i915_gem_object_flush_gpu_write_domain(obj); | 3133 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
3134 | if (ret) | ||
3135 | return ret; | ||
3136 | |||
3073 | ret = i915_gem_object_wait_rendering(obj, true); | 3137 | ret = i915_gem_object_wait_rendering(obj, true); |
3074 | if (ret) | 3138 | if (ret) |
3075 | return ret; | 3139 | return ret; |
@@ -3362,8 +3426,8 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
3362 | * flush earlier is beneficial. | 3426 | * flush earlier is beneficial. |
3363 | */ | 3427 | */ |
3364 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { | 3428 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { |
3365 | i915_gem_flush_ring(dev, obj->ring, | 3429 | ret = i915_gem_flush_ring(dev, obj->ring, |
3366 | 0, obj->base.write_domain); | 3430 | 0, obj->base.write_domain); |
3367 | } else if (obj->ring->outstanding_lazy_request == | 3431 | } else if (obj->ring->outstanding_lazy_request == |
3368 | obj->last_rendering_seqno) { | 3432 | obj->last_rendering_seqno) { |
3369 | struct drm_i915_gem_request *request; | 3433 | struct drm_i915_gem_request *request; |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 78b8cf90c92..3d39005540a 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -127,9 +127,15 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, | |||
127 | } | 127 | } |
128 | 128 | ||
129 | /* Nothing found, clean up and bail out! */ | 129 | /* Nothing found, clean up and bail out! */ |
130 | list_for_each_entry(obj, &unwind_list, exec_list) { | 130 | while (!list_empty(&unwind_list)) { |
131 | obj = list_first_entry(&unwind_list, | ||
132 | struct drm_i915_gem_object, | ||
133 | exec_list); | ||
134 | |||
131 | ret = drm_mm_scan_remove_block(obj->gtt_space); | 135 | ret = drm_mm_scan_remove_block(obj->gtt_space); |
132 | BUG_ON(ret); | 136 | BUG_ON(ret); |
137 | |||
138 | list_del_init(&obj->exec_list); | ||
133 | drm_gem_object_unreference(&obj->base); | 139 | drm_gem_object_unreference(&obj->base); |
134 | } | 140 | } |
135 | 141 | ||
@@ -162,6 +168,7 @@ found: | |||
162 | exec_list); | 168 | exec_list); |
163 | if (ret == 0) | 169 | if (ret == 0) |
164 | ret = i915_gem_object_unbind(obj); | 170 | ret = i915_gem_object_unbind(obj); |
171 | |||
165 | list_del_init(&obj->exec_list); | 172 | list_del_init(&obj->exec_list); |
166 | drm_gem_object_unreference(&obj->base); | 173 | drm_gem_object_unreference(&obj->base); |
167 | } | 174 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 61129e6759e..e69834341ef 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -268,7 +268,6 @@ eb_destroy(struct eb_objects *eb) | |||
268 | static int | 268 | static int |
269 | i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | 269 | i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, |
270 | struct eb_objects *eb, | 270 | struct eb_objects *eb, |
271 | struct drm_i915_gem_exec_object2 *entry, | ||
272 | struct drm_i915_gem_relocation_entry *reloc) | 271 | struct drm_i915_gem_relocation_entry *reloc) |
273 | { | 272 | { |
274 | struct drm_device *dev = obj->base.dev; | 273 | struct drm_device *dev = obj->base.dev; |
@@ -411,10 +410,10 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
411 | 410 | ||
412 | static int | 411 | static int |
413 | i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, | 412 | i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, |
414 | struct eb_objects *eb, | 413 | struct eb_objects *eb) |
415 | struct drm_i915_gem_exec_object2 *entry) | ||
416 | { | 414 | { |
417 | struct drm_i915_gem_relocation_entry __user *user_relocs; | 415 | struct drm_i915_gem_relocation_entry __user *user_relocs; |
416 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | ||
418 | int i, ret; | 417 | int i, ret; |
419 | 418 | ||
420 | user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; | 419 | user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; |
@@ -426,7 +425,7 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, | |||
426 | sizeof(reloc))) | 425 | sizeof(reloc))) |
427 | return -EFAULT; | 426 | return -EFAULT; |
428 | 427 | ||
429 | ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &reloc); | 428 | ret = i915_gem_execbuffer_relocate_entry(obj, eb, &reloc); |
430 | if (ret) | 429 | if (ret) |
431 | return ret; | 430 | return ret; |
432 | 431 | ||
@@ -442,13 +441,13 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, | |||
442 | static int | 441 | static int |
443 | i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, | 442 | i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, |
444 | struct eb_objects *eb, | 443 | struct eb_objects *eb, |
445 | struct drm_i915_gem_exec_object2 *entry, | ||
446 | struct drm_i915_gem_relocation_entry *relocs) | 444 | struct drm_i915_gem_relocation_entry *relocs) |
447 | { | 445 | { |
446 | const struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | ||
448 | int i, ret; | 447 | int i, ret; |
449 | 448 | ||
450 | for (i = 0; i < entry->relocation_count; i++) { | 449 | for (i = 0; i < entry->relocation_count; i++) { |
451 | ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &relocs[i]); | 450 | ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i]); |
452 | if (ret) | 451 | if (ret) |
453 | return ret; | 452 | return ret; |
454 | } | 453 | } |
@@ -459,8 +458,7 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, | |||
459 | static int | 458 | static int |
460 | i915_gem_execbuffer_relocate(struct drm_device *dev, | 459 | i915_gem_execbuffer_relocate(struct drm_device *dev, |
461 | struct eb_objects *eb, | 460 | struct eb_objects *eb, |
462 | struct list_head *objects, | 461 | struct list_head *objects) |
463 | struct drm_i915_gem_exec_object2 *exec) | ||
464 | { | 462 | { |
465 | struct drm_i915_gem_object *obj; | 463 | struct drm_i915_gem_object *obj; |
466 | int ret; | 464 | int ret; |
@@ -468,7 +466,7 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, | |||
468 | list_for_each_entry(obj, objects, exec_list) { | 466 | list_for_each_entry(obj, objects, exec_list) { |
469 | obj->base.pending_read_domains = 0; | 467 | obj->base.pending_read_domains = 0; |
470 | obj->base.pending_write_domain = 0; | 468 | obj->base.pending_write_domain = 0; |
471 | ret = i915_gem_execbuffer_relocate_object(obj, eb, exec++); | 469 | ret = i915_gem_execbuffer_relocate_object(obj, eb); |
472 | if (ret) | 470 | if (ret) |
473 | return ret; | 471 | return ret; |
474 | } | 472 | } |
@@ -479,13 +477,36 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, | |||
479 | static int | 477 | static int |
480 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | 478 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, |
481 | struct drm_file *file, | 479 | struct drm_file *file, |
482 | struct list_head *objects, | 480 | struct list_head *objects) |
483 | struct drm_i915_gem_exec_object2 *exec) | ||
484 | { | 481 | { |
485 | struct drm_i915_gem_object *obj; | 482 | struct drm_i915_gem_object *obj; |
486 | struct drm_i915_gem_exec_object2 *entry; | ||
487 | int ret, retry; | 483 | int ret, retry; |
488 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; | 484 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; |
485 | struct list_head ordered_objects; | ||
486 | |||
487 | INIT_LIST_HEAD(&ordered_objects); | ||
488 | while (!list_empty(objects)) { | ||
489 | struct drm_i915_gem_exec_object2 *entry; | ||
490 | bool need_fence, need_mappable; | ||
491 | |||
492 | obj = list_first_entry(objects, | ||
493 | struct drm_i915_gem_object, | ||
494 | exec_list); | ||
495 | entry = obj->exec_entry; | ||
496 | |||
497 | need_fence = | ||
498 | has_fenced_gpu_access && | ||
499 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | ||
500 | obj->tiling_mode != I915_TILING_NONE; | ||
501 | need_mappable = | ||
502 | entry->relocation_count ? true : need_fence; | ||
503 | |||
504 | if (need_mappable) | ||
505 | list_move(&obj->exec_list, &ordered_objects); | ||
506 | else | ||
507 | list_move_tail(&obj->exec_list, &ordered_objects); | ||
508 | } | ||
509 | list_splice(&ordered_objects, objects); | ||
489 | 510 | ||
490 | /* Attempt to pin all of the buffers into the GTT. | 511 | /* Attempt to pin all of the buffers into the GTT. |
491 | * This is done in 3 phases: | 512 | * This is done in 3 phases: |
@@ -504,14 +525,11 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
504 | ret = 0; | 525 | ret = 0; |
505 | 526 | ||
506 | /* Unbind any ill-fitting objects or pin. */ | 527 | /* Unbind any ill-fitting objects or pin. */ |
507 | entry = exec; | ||
508 | list_for_each_entry(obj, objects, exec_list) { | 528 | list_for_each_entry(obj, objects, exec_list) { |
529 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | ||
509 | bool need_fence, need_mappable; | 530 | bool need_fence, need_mappable; |
510 | 531 | if (!obj->gtt_space) | |
511 | if (!obj->gtt_space) { | ||
512 | entry++; | ||
513 | continue; | 532 | continue; |
514 | } | ||
515 | 533 | ||
516 | need_fence = | 534 | need_fence = |
517 | has_fenced_gpu_access && | 535 | has_fenced_gpu_access && |
@@ -534,8 +552,8 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
534 | } | 552 | } |
535 | 553 | ||
536 | /* Bind fresh objects */ | 554 | /* Bind fresh objects */ |
537 | entry = exec; | ||
538 | list_for_each_entry(obj, objects, exec_list) { | 555 | list_for_each_entry(obj, objects, exec_list) { |
556 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | ||
539 | bool need_fence; | 557 | bool need_fence; |
540 | 558 | ||
541 | need_fence = | 559 | need_fence = |
@@ -570,7 +588,6 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
570 | } | 588 | } |
571 | 589 | ||
572 | entry->offset = obj->gtt_offset; | 590 | entry->offset = obj->gtt_offset; |
573 | entry++; | ||
574 | } | 591 | } |
575 | 592 | ||
576 | /* Decrement pin count for bound objects */ | 593 | /* Decrement pin count for bound objects */ |
@@ -622,7 +639,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
622 | int i, total, ret; | 639 | int i, total, ret; |
623 | 640 | ||
624 | /* We may process another execbuffer during the unlock... */ | 641 | /* We may process another execbuffer during the unlock... */ |
625 | while (list_empty(objects)) { | 642 | while (!list_empty(objects)) { |
626 | obj = list_first_entry(objects, | 643 | obj = list_first_entry(objects, |
627 | struct drm_i915_gem_object, | 644 | struct drm_i915_gem_object, |
628 | exec_list); | 645 | exec_list); |
@@ -665,7 +682,6 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
665 | } | 682 | } |
666 | 683 | ||
667 | /* reacquire the objects */ | 684 | /* reacquire the objects */ |
668 | INIT_LIST_HEAD(objects); | ||
669 | eb_reset(eb); | 685 | eb_reset(eb); |
670 | for (i = 0; i < count; i++) { | 686 | for (i = 0; i < count; i++) { |
671 | struct drm_i915_gem_object *obj; | 687 | struct drm_i915_gem_object *obj; |
@@ -681,10 +697,11 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
681 | 697 | ||
682 | list_add_tail(&obj->exec_list, objects); | 698 | list_add_tail(&obj->exec_list, objects); |
683 | obj->exec_handle = exec[i].handle; | 699 | obj->exec_handle = exec[i].handle; |
700 | obj->exec_entry = &exec[i]; | ||
684 | eb_add_object(eb, obj); | 701 | eb_add_object(eb, obj); |
685 | } | 702 | } |
686 | 703 | ||
687 | ret = i915_gem_execbuffer_reserve(ring, file, objects, exec); | 704 | ret = i915_gem_execbuffer_reserve(ring, file, objects); |
688 | if (ret) | 705 | if (ret) |
689 | goto err; | 706 | goto err; |
690 | 707 | ||
@@ -693,7 +710,6 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
693 | obj->base.pending_read_domains = 0; | 710 | obj->base.pending_read_domains = 0; |
694 | obj->base.pending_write_domain = 0; | 711 | obj->base.pending_write_domain = 0; |
695 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, | 712 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, |
696 | exec, | ||
697 | reloc + total); | 713 | reloc + total); |
698 | if (ret) | 714 | if (ret) |
699 | goto err; | 715 | goto err; |
@@ -713,25 +729,34 @@ err: | |||
713 | return ret; | 729 | return ret; |
714 | } | 730 | } |
715 | 731 | ||
716 | static void | 732 | static int |
717 | i915_gem_execbuffer_flush(struct drm_device *dev, | 733 | i915_gem_execbuffer_flush(struct drm_device *dev, |
718 | uint32_t invalidate_domains, | 734 | uint32_t invalidate_domains, |
719 | uint32_t flush_domains, | 735 | uint32_t flush_domains, |
720 | uint32_t flush_rings) | 736 | uint32_t flush_rings) |
721 | { | 737 | { |
722 | drm_i915_private_t *dev_priv = dev->dev_private; | 738 | drm_i915_private_t *dev_priv = dev->dev_private; |
723 | int i; | 739 | int i, ret; |
724 | 740 | ||
725 | if (flush_domains & I915_GEM_DOMAIN_CPU) | 741 | if (flush_domains & I915_GEM_DOMAIN_CPU) |
726 | intel_gtt_chipset_flush(); | 742 | intel_gtt_chipset_flush(); |
727 | 743 | ||
744 | if (flush_domains & I915_GEM_DOMAIN_GTT) | ||
745 | wmb(); | ||
746 | |||
728 | if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { | 747 | if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { |
729 | for (i = 0; i < I915_NUM_RINGS; i++) | 748 | for (i = 0; i < I915_NUM_RINGS; i++) |
730 | if (flush_rings & (1 << i)) | 749 | if (flush_rings & (1 << i)) { |
731 | i915_gem_flush_ring(dev, &dev_priv->ring[i], | 750 | ret = i915_gem_flush_ring(dev, |
732 | invalidate_domains, | 751 | &dev_priv->ring[i], |
733 | flush_domains); | 752 | invalidate_domains, |
753 | flush_domains); | ||
754 | if (ret) | ||
755 | return ret; | ||
756 | } | ||
734 | } | 757 | } |
758 | |||
759 | return 0; | ||
735 | } | 760 | } |
736 | 761 | ||
737 | static int | 762 | static int |
@@ -795,10 +820,12 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, | |||
795 | cd.invalidate_domains, | 820 | cd.invalidate_domains, |
796 | cd.flush_domains); | 821 | cd.flush_domains); |
797 | #endif | 822 | #endif |
798 | i915_gem_execbuffer_flush(ring->dev, | 823 | ret = i915_gem_execbuffer_flush(ring->dev, |
799 | cd.invalidate_domains, | 824 | cd.invalidate_domains, |
800 | cd.flush_domains, | 825 | cd.flush_domains, |
801 | cd.flush_rings); | 826 | cd.flush_rings); |
827 | if (ret) | ||
828 | return ret; | ||
802 | } | 829 | } |
803 | 830 | ||
804 | list_for_each_entry(obj, objects, exec_list) { | 831 | list_for_each_entry(obj, objects, exec_list) { |
@@ -921,7 +948,7 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev, | |||
921 | struct intel_ring_buffer *ring) | 948 | struct intel_ring_buffer *ring) |
922 | { | 949 | { |
923 | struct drm_i915_gem_request *request; | 950 | struct drm_i915_gem_request *request; |
924 | u32 flush_domains; | 951 | u32 invalidate; |
925 | 952 | ||
926 | /* | 953 | /* |
927 | * Ensure that the commands in the batch buffer are | 954 | * Ensure that the commands in the batch buffer are |
@@ -929,11 +956,13 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev, | |||
929 | * | 956 | * |
930 | * The sampler always gets flushed on i965 (sigh). | 957 | * The sampler always gets flushed on i965 (sigh). |
931 | */ | 958 | */ |
932 | flush_domains = 0; | 959 | invalidate = I915_GEM_DOMAIN_COMMAND; |
933 | if (INTEL_INFO(dev)->gen >= 4) | 960 | if (INTEL_INFO(dev)->gen >= 4) |
934 | flush_domains |= I915_GEM_DOMAIN_SAMPLER; | 961 | invalidate |= I915_GEM_DOMAIN_SAMPLER; |
935 | 962 | if (ring->flush(ring, invalidate, 0)) { | |
936 | ring->flush(ring, I915_GEM_DOMAIN_COMMAND, flush_domains); | 963 | i915_gem_next_request_seqno(dev, ring); |
964 | return; | ||
965 | } | ||
937 | 966 | ||
938 | /* Add a breadcrumb for the completion of the batch buffer */ | 967 | /* Add a breadcrumb for the completion of the batch buffer */ |
939 | request = kzalloc(sizeof(*request), GFP_KERNEL); | 968 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
@@ -1098,16 +1127,22 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1098 | 1127 | ||
1099 | list_add_tail(&obj->exec_list, &objects); | 1128 | list_add_tail(&obj->exec_list, &objects); |
1100 | obj->exec_handle = exec[i].handle; | 1129 | obj->exec_handle = exec[i].handle; |
1130 | obj->exec_entry = &exec[i]; | ||
1101 | eb_add_object(eb, obj); | 1131 | eb_add_object(eb, obj); |
1102 | } | 1132 | } |
1103 | 1133 | ||
1134 | /* take note of the batch buffer before we might reorder the lists */ | ||
1135 | batch_obj = list_entry(objects.prev, | ||
1136 | struct drm_i915_gem_object, | ||
1137 | exec_list); | ||
1138 | |||
1104 | /* Move the objects en-masse into the GTT, evicting if necessary. */ | 1139 | /* Move the objects en-masse into the GTT, evicting if necessary. */ |
1105 | ret = i915_gem_execbuffer_reserve(ring, file, &objects, exec); | 1140 | ret = i915_gem_execbuffer_reserve(ring, file, &objects); |
1106 | if (ret) | 1141 | if (ret) |
1107 | goto err; | 1142 | goto err; |
1108 | 1143 | ||
1109 | /* The objects are in their final locations, apply the relocations. */ | 1144 | /* The objects are in their final locations, apply the relocations. */ |
1110 | ret = i915_gem_execbuffer_relocate(dev, eb, &objects, exec); | 1145 | ret = i915_gem_execbuffer_relocate(dev, eb, &objects); |
1111 | if (ret) { | 1146 | if (ret) { |
1112 | if (ret == -EFAULT) { | 1147 | if (ret == -EFAULT) { |
1113 | ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, | 1148 | ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, |
@@ -1121,9 +1156,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1121 | } | 1156 | } |
1122 | 1157 | ||
1123 | /* Set the pending read domains for the batch buffer to COMMAND */ | 1158 | /* Set the pending read domains for the batch buffer to COMMAND */ |
1124 | batch_obj = list_entry(objects.prev, | ||
1125 | struct drm_i915_gem_object, | ||
1126 | exec_list); | ||
1127 | if (batch_obj->base.pending_write_domain) { | 1159 | if (batch_obj->base.pending_write_domain) { |
1128 | DRM_ERROR("Attempting to use self-modifying batch buffer\n"); | 1160 | DRM_ERROR("Attempting to use self-modifying batch buffer\n"); |
1129 | ret = -EINVAL; | 1161 | ret = -EINVAL; |
@@ -1340,4 +1372,3 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | |||
1340 | drm_free_large(exec2_list); | 1372 | drm_free_large(exec2_list); |
1341 | return ret; | 1373 | return ret; |
1342 | } | 1374 | } |
1343 | |||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 86673e77d7c..70433ae50ac 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -85,15 +85,11 @@ int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj) | |||
85 | 85 | ||
86 | void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) | 86 | void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) |
87 | { | 87 | { |
88 | struct drm_device *dev = obj->base.dev; | 88 | intel_gtt_clear_range(obj->gtt_space->start >> PAGE_SHIFT, |
89 | struct drm_i915_private *dev_priv = dev->dev_private; | 89 | obj->base.size >> PAGE_SHIFT); |
90 | 90 | ||
91 | if (dev_priv->mm.gtt->needs_dmar) { | 91 | if (obj->sg_list) { |
92 | intel_gtt_unmap_memory(obj->sg_list, obj->num_sg); | 92 | intel_gtt_unmap_memory(obj->sg_list, obj->num_sg); |
93 | obj->sg_list = NULL; | 93 | obj->sg_list = NULL; |
94 | obj->num_sg = 0; | ||
95 | } | 94 | } |
96 | |||
97 | intel_gtt_clear_range(obj->gtt_space->start >> PAGE_SHIFT, | ||
98 | obj->base.size >> PAGE_SHIFT); | ||
99 | } | 95 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0dadc025b77..e418e8bb61e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -64,26 +64,6 @@ | |||
64 | #define DRM_I915_VBLANK_PIPE_ALL (DRM_I915_VBLANK_PIPE_A | \ | 64 | #define DRM_I915_VBLANK_PIPE_ALL (DRM_I915_VBLANK_PIPE_A | \ |
65 | DRM_I915_VBLANK_PIPE_B) | 65 | DRM_I915_VBLANK_PIPE_B) |
66 | 66 | ||
67 | void | ||
68 | ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
69 | { | ||
70 | if ((dev_priv->gt_irq_mask & mask) != 0) { | ||
71 | dev_priv->gt_irq_mask &= ~mask; | ||
72 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
73 | POSTING_READ(GTIMR); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | void | ||
78 | ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
79 | { | ||
80 | if ((dev_priv->gt_irq_mask & mask) != mask) { | ||
81 | dev_priv->gt_irq_mask |= mask; | ||
82 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
83 | POSTING_READ(GTIMR); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | /* For display hotplug interrupt */ | 67 | /* For display hotplug interrupt */ |
88 | static void | 68 | static void |
89 | ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) | 69 | ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
@@ -105,26 +85,6 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) | |||
105 | } | 85 | } |
106 | } | 86 | } |
107 | 87 | ||
108 | void | ||
109 | i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
110 | { | ||
111 | if ((dev_priv->irq_mask & mask) != 0) { | ||
112 | dev_priv->irq_mask &= ~mask; | ||
113 | I915_WRITE(IMR, dev_priv->irq_mask); | ||
114 | POSTING_READ(IMR); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | void | ||
119 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
120 | { | ||
121 | if ((dev_priv->irq_mask & mask) != mask) { | ||
122 | dev_priv->irq_mask |= mask; | ||
123 | I915_WRITE(IMR, dev_priv->irq_mask); | ||
124 | POSTING_READ(IMR); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static inline u32 | 88 | static inline u32 |
129 | i915_pipestat(int pipe) | 89 | i915_pipestat(int pipe) |
130 | { | 90 | { |
@@ -389,9 +349,12 @@ static void notify_ring(struct drm_device *dev, | |||
389 | { | 349 | { |
390 | struct drm_i915_private *dev_priv = dev->dev_private; | 350 | struct drm_i915_private *dev_priv = dev->dev_private; |
391 | u32 seqno = ring->get_seqno(ring); | 351 | u32 seqno = ring->get_seqno(ring); |
392 | ring->irq_seqno = seqno; | 352 | |
393 | trace_i915_gem_request_complete(dev, seqno); | 353 | trace_i915_gem_request_complete(dev, seqno); |
354 | |||
355 | ring->irq_seqno = seqno; | ||
394 | wake_up_all(&ring->irq_queue); | 356 | wake_up_all(&ring->irq_queue); |
357 | |||
395 | dev_priv->hangcheck_count = 0; | 358 | dev_priv->hangcheck_count = 0; |
396 | mod_timer(&dev_priv->hangcheck_timer, | 359 | mod_timer(&dev_priv->hangcheck_timer, |
397 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); | 360 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); |
@@ -435,6 +398,50 @@ static void gen6_pm_irq_handler(struct drm_device *dev) | |||
435 | I915_WRITE(GEN6_PMIIR, pm_iir); | 398 | I915_WRITE(GEN6_PMIIR, pm_iir); |
436 | } | 399 | } |
437 | 400 | ||
401 | static void pch_irq_handler(struct drm_device *dev) | ||
402 | { | ||
403 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
404 | u32 pch_iir; | ||
405 | |||
406 | pch_iir = I915_READ(SDEIIR); | ||
407 | |||
408 | if (pch_iir & SDE_AUDIO_POWER_MASK) | ||
409 | DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", | ||
410 | (pch_iir & SDE_AUDIO_POWER_MASK) >> | ||
411 | SDE_AUDIO_POWER_SHIFT); | ||
412 | |||
413 | if (pch_iir & SDE_GMBUS) | ||
414 | DRM_DEBUG_DRIVER("PCH GMBUS interrupt\n"); | ||
415 | |||
416 | if (pch_iir & SDE_AUDIO_HDCP_MASK) | ||
417 | DRM_DEBUG_DRIVER("PCH HDCP audio interrupt\n"); | ||
418 | |||
419 | if (pch_iir & SDE_AUDIO_TRANS_MASK) | ||
420 | DRM_DEBUG_DRIVER("PCH transcoder audio interrupt\n"); | ||
421 | |||
422 | if (pch_iir & SDE_POISON) | ||
423 | DRM_ERROR("PCH poison interrupt\n"); | ||
424 | |||
425 | if (pch_iir & SDE_FDI_MASK) { | ||
426 | u32 fdia, fdib; | ||
427 | |||
428 | fdia = I915_READ(FDI_RXA_IIR); | ||
429 | fdib = I915_READ(FDI_RXB_IIR); | ||
430 | DRM_DEBUG_DRIVER("PCH FDI RX interrupt; FDI RXA IIR: 0x%08x, FDI RXB IIR: 0x%08x\n", fdia, fdib); | ||
431 | } | ||
432 | |||
433 | if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) | ||
434 | DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n"); | ||
435 | |||
436 | if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR)) | ||
437 | DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n"); | ||
438 | |||
439 | if (pch_iir & SDE_TRANSB_FIFO_UNDER) | ||
440 | DRM_DEBUG_DRIVER("PCH transcoder B underrun interrupt\n"); | ||
441 | if (pch_iir & SDE_TRANSA_FIFO_UNDER) | ||
442 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); | ||
443 | } | ||
444 | |||
438 | static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | 445 | static irqreturn_t ironlake_irq_handler(struct drm_device *dev) |
439 | { | 446 | { |
440 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 447 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -502,8 +509,11 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
502 | drm_handle_vblank(dev, 1); | 509 | drm_handle_vblank(dev, 1); |
503 | 510 | ||
504 | /* check event from PCH */ | 511 | /* check event from PCH */ |
505 | if ((de_iir & DE_PCH_EVENT) && (pch_iir & hotplug_mask)) | 512 | if (de_iir & DE_PCH_EVENT) { |
506 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | 513 | if (pch_iir & hotplug_mask) |
514 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | ||
515 | pch_irq_handler(dev); | ||
516 | } | ||
507 | 517 | ||
508 | if (de_iir & DE_PCU_EVENT) { | 518 | if (de_iir & DE_PCU_EVENT) { |
509 | I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); | 519 | I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); |
@@ -556,10 +566,9 @@ static void i915_error_work_func(struct work_struct *work) | |||
556 | 566 | ||
557 | #ifdef CONFIG_DEBUG_FS | 567 | #ifdef CONFIG_DEBUG_FS |
558 | static struct drm_i915_error_object * | 568 | static struct drm_i915_error_object * |
559 | i915_error_object_create(struct drm_device *dev, | 569 | i915_error_object_create(struct drm_i915_private *dev_priv, |
560 | struct drm_i915_gem_object *src) | 570 | struct drm_i915_gem_object *src) |
561 | { | 571 | { |
562 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
563 | struct drm_i915_error_object *dst; | 572 | struct drm_i915_error_object *dst; |
564 | int page, page_count; | 573 | int page, page_count; |
565 | u32 reloc_offset; | 574 | u32 reloc_offset; |
@@ -632,52 +641,6 @@ i915_error_state_free(struct drm_device *dev, | |||
632 | kfree(error); | 641 | kfree(error); |
633 | } | 642 | } |
634 | 643 | ||
635 | static u32 | ||
636 | i915_get_bbaddr(struct drm_device *dev, u32 *ring) | ||
637 | { | ||
638 | u32 cmd; | ||
639 | |||
640 | if (IS_I830(dev) || IS_845G(dev)) | ||
641 | cmd = MI_BATCH_BUFFER; | ||
642 | else if (INTEL_INFO(dev)->gen >= 4) | ||
643 | cmd = (MI_BATCH_BUFFER_START | (2 << 6) | | ||
644 | MI_BATCH_NON_SECURE_I965); | ||
645 | else | ||
646 | cmd = (MI_BATCH_BUFFER_START | (2 << 6)); | ||
647 | |||
648 | return ring[0] == cmd ? ring[1] : 0; | ||
649 | } | ||
650 | |||
651 | static u32 | ||
652 | i915_ringbuffer_last_batch(struct drm_device *dev, | ||
653 | struct intel_ring_buffer *ring) | ||
654 | { | ||
655 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
656 | u32 head, bbaddr; | ||
657 | u32 *val; | ||
658 | |||
659 | /* Locate the current position in the ringbuffer and walk back | ||
660 | * to find the most recently dispatched batch buffer. | ||
661 | */ | ||
662 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | ||
663 | |||
664 | val = (u32 *)(ring->virtual_start + head); | ||
665 | while (--val >= (u32 *)ring->virtual_start) { | ||
666 | bbaddr = i915_get_bbaddr(dev, val); | ||
667 | if (bbaddr) | ||
668 | return bbaddr; | ||
669 | } | ||
670 | |||
671 | val = (u32 *)(ring->virtual_start + ring->size); | ||
672 | while (--val >= (u32 *)ring->virtual_start) { | ||
673 | bbaddr = i915_get_bbaddr(dev, val); | ||
674 | if (bbaddr) | ||
675 | return bbaddr; | ||
676 | } | ||
677 | |||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | static u32 capture_bo_list(struct drm_i915_error_buffer *err, | 644 | static u32 capture_bo_list(struct drm_i915_error_buffer *err, |
682 | int count, | 645 | int count, |
683 | struct list_head *head) | 646 | struct list_head *head) |
@@ -702,6 +665,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, | |||
702 | err->dirty = obj->dirty; | 665 | err->dirty = obj->dirty; |
703 | err->purgeable = obj->madv != I915_MADV_WILLNEED; | 666 | err->purgeable = obj->madv != I915_MADV_WILLNEED; |
704 | err->ring = obj->ring ? obj->ring->id : 0; | 667 | err->ring = obj->ring ? obj->ring->id : 0; |
668 | err->agp_type = obj->agp_type == AGP_USER_CACHED_MEMORY; | ||
705 | 669 | ||
706 | if (++i == count) | 670 | if (++i == count) |
707 | break; | 671 | break; |
@@ -741,6 +705,36 @@ static void i915_gem_record_fences(struct drm_device *dev, | |||
741 | } | 705 | } |
742 | } | 706 | } |
743 | 707 | ||
708 | static struct drm_i915_error_object * | ||
709 | i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, | ||
710 | struct intel_ring_buffer *ring) | ||
711 | { | ||
712 | struct drm_i915_gem_object *obj; | ||
713 | u32 seqno; | ||
714 | |||
715 | if (!ring->get_seqno) | ||
716 | return NULL; | ||
717 | |||
718 | seqno = ring->get_seqno(ring); | ||
719 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { | ||
720 | if (obj->ring != ring) | ||
721 | continue; | ||
722 | |||
723 | if (!i915_seqno_passed(obj->last_rendering_seqno, seqno)) | ||
724 | continue; | ||
725 | |||
726 | if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) | ||
727 | continue; | ||
728 | |||
729 | /* We need to copy these to an anonymous buffer as the simplest | ||
730 | * method to avoid being overwritten by userspace. | ||
731 | */ | ||
732 | return i915_error_object_create(dev_priv, obj); | ||
733 | } | ||
734 | |||
735 | return NULL; | ||
736 | } | ||
737 | |||
744 | /** | 738 | /** |
745 | * i915_capture_error_state - capture an error record for later analysis | 739 | * i915_capture_error_state - capture an error record for later analysis |
746 | * @dev: drm device | 740 | * @dev: drm device |
@@ -755,10 +749,8 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
755 | struct drm_i915_private *dev_priv = dev->dev_private; | 749 | struct drm_i915_private *dev_priv = dev->dev_private; |
756 | struct drm_i915_gem_object *obj; | 750 | struct drm_i915_gem_object *obj; |
757 | struct drm_i915_error_state *error; | 751 | struct drm_i915_error_state *error; |
758 | struct drm_i915_gem_object *batchbuffer[2]; | ||
759 | unsigned long flags; | 752 | unsigned long flags; |
760 | u32 bbaddr; | 753 | int i; |
761 | int count; | ||
762 | 754 | ||
763 | spin_lock_irqsave(&dev_priv->error_lock, flags); | 755 | spin_lock_irqsave(&dev_priv->error_lock, flags); |
764 | error = dev_priv->first_error; | 756 | error = dev_priv->first_error; |
@@ -817,83 +809,30 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
817 | } | 809 | } |
818 | i915_gem_record_fences(dev, error); | 810 | i915_gem_record_fences(dev, error); |
819 | 811 | ||
820 | bbaddr = i915_ringbuffer_last_batch(dev, &dev_priv->ring[RCS]); | 812 | /* Record the active batchbuffers */ |
821 | 813 | for (i = 0; i < I915_NUM_RINGS; i++) | |
822 | /* Grab the current batchbuffer, most likely to have crashed. */ | 814 | error->batchbuffer[i] = |
823 | batchbuffer[0] = NULL; | 815 | i915_error_first_batchbuffer(dev_priv, |
824 | batchbuffer[1] = NULL; | 816 | &dev_priv->ring[i]); |
825 | count = 0; | ||
826 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { | ||
827 | if (batchbuffer[0] == NULL && | ||
828 | bbaddr >= obj->gtt_offset && | ||
829 | bbaddr < obj->gtt_offset + obj->base.size) | ||
830 | batchbuffer[0] = obj; | ||
831 | |||
832 | if (batchbuffer[1] == NULL && | ||
833 | error->acthd >= obj->gtt_offset && | ||
834 | error->acthd < obj->gtt_offset + obj->base.size) | ||
835 | batchbuffer[1] = obj; | ||
836 | |||
837 | count++; | ||
838 | } | ||
839 | /* Scan the other lists for completeness for those bizarre errors. */ | ||
840 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
841 | list_for_each_entry(obj, &dev_priv->mm.flushing_list, mm_list) { | ||
842 | if (batchbuffer[0] == NULL && | ||
843 | bbaddr >= obj->gtt_offset && | ||
844 | bbaddr < obj->gtt_offset + obj->base.size) | ||
845 | batchbuffer[0] = obj; | ||
846 | |||
847 | if (batchbuffer[1] == NULL && | ||
848 | error->acthd >= obj->gtt_offset && | ||
849 | error->acthd < obj->gtt_offset + obj->base.size) | ||
850 | batchbuffer[1] = obj; | ||
851 | |||
852 | if (batchbuffer[0] && batchbuffer[1]) | ||
853 | break; | ||
854 | } | ||
855 | } | ||
856 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
857 | list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { | ||
858 | if (batchbuffer[0] == NULL && | ||
859 | bbaddr >= obj->gtt_offset && | ||
860 | bbaddr < obj->gtt_offset + obj->base.size) | ||
861 | batchbuffer[0] = obj; | ||
862 | |||
863 | if (batchbuffer[1] == NULL && | ||
864 | error->acthd >= obj->gtt_offset && | ||
865 | error->acthd < obj->gtt_offset + obj->base.size) | ||
866 | batchbuffer[1] = obj; | ||
867 | |||
868 | if (batchbuffer[0] && batchbuffer[1]) | ||
869 | break; | ||
870 | } | ||
871 | } | ||
872 | |||
873 | /* We need to copy these to an anonymous buffer as the simplest | ||
874 | * method to avoid being overwritten by userspace. | ||
875 | */ | ||
876 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); | ||
877 | if (batchbuffer[1] != batchbuffer[0]) | ||
878 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | ||
879 | else | ||
880 | error->batchbuffer[1] = NULL; | ||
881 | 817 | ||
882 | /* Record the ringbuffer */ | 818 | /* Record the ringbuffer */ |
883 | error->ringbuffer = i915_error_object_create(dev, | 819 | error->ringbuffer = i915_error_object_create(dev_priv, |
884 | dev_priv->ring[RCS].obj); | 820 | dev_priv->ring[RCS].obj); |
885 | 821 | ||
886 | /* Record buffers on the active and pinned lists. */ | 822 | /* Record buffers on the active and pinned lists. */ |
887 | error->active_bo = NULL; | 823 | error->active_bo = NULL; |
888 | error->pinned_bo = NULL; | 824 | error->pinned_bo = NULL; |
889 | 825 | ||
890 | error->active_bo_count = count; | 826 | i = 0; |
827 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) | ||
828 | i++; | ||
829 | error->active_bo_count = i; | ||
891 | list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) | 830 | list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) |
892 | count++; | 831 | i++; |
893 | error->pinned_bo_count = count - error->active_bo_count; | 832 | error->pinned_bo_count = i - error->active_bo_count; |
894 | 833 | ||
895 | if (count) { | 834 | if (i) { |
896 | error->active_bo = kmalloc(sizeof(*error->active_bo)*count, | 835 | error->active_bo = kmalloc(sizeof(*error->active_bo)*i, |
897 | GFP_ATOMIC); | 836 | GFP_ATOMIC); |
898 | if (error->active_bo) | 837 | if (error->active_bo) |
899 | error->pinned_bo = | 838 | error->pinned_bo = |
@@ -1673,11 +1612,6 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1673 | 1612 | ||
1674 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1613 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
1675 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | 1614 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
1676 | if (IS_GEN6(dev)) { | ||
1677 | I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_USER_INTERRUPT); | ||
1678 | I915_WRITE(GEN6_BSD_IMR, ~GEN6_BSD_USER_INTERRUPT); | ||
1679 | I915_WRITE(GEN6_BLITTER_IMR, ~GEN6_BLITTER_USER_INTERRUPT); | ||
1680 | } | ||
1681 | 1615 | ||
1682 | if (IS_GEN6(dev)) | 1616 | if (IS_GEN6(dev)) |
1683 | render_irqs = | 1617 | render_irqs = |
@@ -1698,6 +1632,9 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1698 | } else { | 1632 | } else { |
1699 | hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | | 1633 | hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | |
1700 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; | 1634 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; |
1635 | hotplug_mask |= SDE_AUX_MASK | SDE_FDI_MASK | SDE_TRANS_MASK; | ||
1636 | I915_WRITE(FDI_RXA_IMR, 0); | ||
1637 | I915_WRITE(FDI_RXB_IMR, 0); | ||
1701 | } | 1638 | } |
1702 | 1639 | ||
1703 | dev_priv->pch_irq_mask = ~hotplug_mask; | 1640 | dev_priv->pch_irq_mask = ~hotplug_mask; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8f948a6fbc1..40a407f41f6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -145,6 +145,8 @@ | |||
145 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ | 145 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ |
146 | #define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ | 146 | #define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ |
147 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) | 147 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) |
148 | #define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0) | ||
149 | #define MI_SUSPEND_FLUSH_EN (1<<0) | ||
148 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) | 150 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) |
149 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) | 151 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) |
150 | #define MI_OVERLAY_CONTINUE (0x0<<21) | 152 | #define MI_OVERLAY_CONTINUE (0x0<<21) |
@@ -159,6 +161,7 @@ | |||
159 | #define MI_MM_SPACE_PHYSICAL (0<<8) | 161 | #define MI_MM_SPACE_PHYSICAL (0<<8) |
160 | #define MI_SAVE_EXT_STATE_EN (1<<3) | 162 | #define MI_SAVE_EXT_STATE_EN (1<<3) |
161 | #define MI_RESTORE_EXT_STATE_EN (1<<2) | 163 | #define MI_RESTORE_EXT_STATE_EN (1<<2) |
164 | #define MI_FORCE_RESTORE (1<<1) | ||
162 | #define MI_RESTORE_INHIBIT (1<<0) | 165 | #define MI_RESTORE_INHIBIT (1<<0) |
163 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) | 166 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) |
164 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ | 167 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ |
@@ -288,6 +291,7 @@ | |||
288 | #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) | 291 | #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) |
289 | #define RING_ACTHD(base) ((base)+0x74) | 292 | #define RING_ACTHD(base) ((base)+0x74) |
290 | #define RING_NOPID(base) ((base)+0x94) | 293 | #define RING_NOPID(base) ((base)+0x94) |
294 | #define RING_IMR(base) ((base)+0xa8) | ||
291 | #define TAIL_ADDR 0x001FFFF8 | 295 | #define TAIL_ADDR 0x001FFFF8 |
292 | #define HEAD_WRAP_COUNT 0xFFE00000 | 296 | #define HEAD_WRAP_COUNT 0xFFE00000 |
293 | #define HEAD_WRAP_ONE 0x00200000 | 297 | #define HEAD_WRAP_ONE 0x00200000 |
@@ -1130,9 +1134,50 @@ | |||
1130 | #define RCBMINAVG 0x111a0 | 1134 | #define RCBMINAVG 0x111a0 |
1131 | #define RCUPEI 0x111b0 | 1135 | #define RCUPEI 0x111b0 |
1132 | #define RCDNEI 0x111b4 | 1136 | #define RCDNEI 0x111b4 |
1133 | #define MCHBAR_RENDER_STANDBY 0x111b8 | 1137 | #define RSTDBYCTL 0x111b8 |
1134 | #define RCX_SW_EXIT (1<<23) | 1138 | #define RS1EN (1<<31) |
1135 | #define RSX_STATUS_MASK 0x00700000 | 1139 | #define RS2EN (1<<30) |
1140 | #define RS3EN (1<<29) | ||
1141 | #define D3RS3EN (1<<28) /* Display D3 imlies RS3 */ | ||
1142 | #define SWPROMORSX (1<<27) /* RSx promotion timers ignored */ | ||
1143 | #define RCWAKERW (1<<26) /* Resetwarn from PCH causes wakeup */ | ||
1144 | #define DPRSLPVREN (1<<25) /* Fast voltage ramp enable */ | ||
1145 | #define GFXTGHYST (1<<24) /* Hysteresis to allow trunk gating */ | ||
1146 | #define RCX_SW_EXIT (1<<23) /* Leave RSx and prevent re-entry */ | ||
1147 | #define RSX_STATUS_MASK (7<<20) | ||
1148 | #define RSX_STATUS_ON (0<<20) | ||
1149 | #define RSX_STATUS_RC1 (1<<20) | ||
1150 | #define RSX_STATUS_RC1E (2<<20) | ||
1151 | #define RSX_STATUS_RS1 (3<<20) | ||
1152 | #define RSX_STATUS_RS2 (4<<20) /* aka rc6 */ | ||
1153 | #define RSX_STATUS_RSVD (5<<20) /* deep rc6 unsupported on ilk */ | ||
1154 | #define RSX_STATUS_RS3 (6<<20) /* rs3 unsupported on ilk */ | ||
1155 | #define RSX_STATUS_RSVD2 (7<<20) | ||
1156 | #define UWRCRSXE (1<<19) /* wake counter limit prevents rsx */ | ||
1157 | #define RSCRP (1<<18) /* rs requests control on rs1/2 reqs */ | ||
1158 | #define JRSC (1<<17) /* rsx coupled to cpu c-state */ | ||
1159 | #define RS2INC0 (1<<16) /* allow rs2 in cpu c0 */ | ||
1160 | #define RS1CONTSAV_MASK (3<<14) | ||
1161 | #define RS1CONTSAV_NO_RS1 (0<<14) /* rs1 doesn't save/restore context */ | ||
1162 | #define RS1CONTSAV_RSVD (1<<14) | ||
1163 | #define RS1CONTSAV_SAVE_RS1 (2<<14) /* rs1 saves context */ | ||
1164 | #define RS1CONTSAV_FULL_RS1 (3<<14) /* rs1 saves and restores context */ | ||
1165 | #define NORMSLEXLAT_MASK (3<<12) | ||
1166 | #define SLOW_RS123 (0<<12) | ||
1167 | #define SLOW_RS23 (1<<12) | ||
1168 | #define SLOW_RS3 (2<<12) | ||
1169 | #define NORMAL_RS123 (3<<12) | ||
1170 | #define RCMODE_TIMEOUT (1<<11) /* 0 is eval interval method */ | ||
1171 | #define IMPROMOEN (1<<10) /* promo is immediate or delayed until next idle interval (only for timeout method above) */ | ||
1172 | #define RCENTSYNC (1<<9) /* rs coupled to cpu c-state (3/6/7) */ | ||
1173 | #define STATELOCK (1<<7) /* locked to rs_cstate if 0 */ | ||
1174 | #define RS_CSTATE_MASK (3<<4) | ||
1175 | #define RS_CSTATE_C367_RS1 (0<<4) | ||
1176 | #define RS_CSTATE_C36_RS1_C7_RS2 (1<<4) | ||
1177 | #define RS_CSTATE_RSVD (2<<4) | ||
1178 | #define RS_CSTATE_C367_RS2 (3<<4) | ||
1179 | #define REDSAVES (1<<3) /* no context save if was idle during rs0 */ | ||
1180 | #define REDRESTORES (1<<2) /* no restore if was idle during rs0 */ | ||
1136 | #define VIDCTL 0x111c0 | 1181 | #define VIDCTL 0x111c0 |
1137 | #define VIDSTS 0x111c8 | 1182 | #define VIDSTS 0x111c8 |
1138 | #define VIDSTART 0x111cc /* 8 bits */ | 1183 | #define VIDSTART 0x111cc /* 8 bits */ |
@@ -2345,8 +2390,13 @@ | |||
2345 | 2390 | ||
2346 | /* Memory latency timer register */ | 2391 | /* Memory latency timer register */ |
2347 | #define MLTR_ILK 0x11222 | 2392 | #define MLTR_ILK 0x11222 |
2393 | #define MLTR_WM1_SHIFT 0 | ||
2394 | #define MLTR_WM2_SHIFT 8 | ||
2348 | /* the unit of memory self-refresh latency time is 0.5us */ | 2395 | /* the unit of memory self-refresh latency time is 0.5us */ |
2349 | #define ILK_SRLT_MASK 0x3f | 2396 | #define ILK_SRLT_MASK 0x3f |
2397 | #define ILK_LATENCY(shift) (I915_READ(MLTR_ILK) >> (shift) & ILK_SRLT_MASK) | ||
2398 | #define ILK_READ_WM1_LATENCY() ILK_LATENCY(MLTR_WM1_SHIFT) | ||
2399 | #define ILK_READ_WM2_LATENCY() ILK_LATENCY(MLTR_WM2_SHIFT) | ||
2350 | 2400 | ||
2351 | /* define the fifo size on Ironlake */ | 2401 | /* define the fifo size on Ironlake */ |
2352 | #define ILK_DISPLAY_FIFO 128 | 2402 | #define ILK_DISPLAY_FIFO 128 |
@@ -2728,12 +2778,41 @@ | |||
2728 | /* PCH */ | 2778 | /* PCH */ |
2729 | 2779 | ||
2730 | /* south display engine interrupt */ | 2780 | /* south display engine interrupt */ |
2781 | #define SDE_AUDIO_POWER_D (1 << 27) | ||
2782 | #define SDE_AUDIO_POWER_C (1 << 26) | ||
2783 | #define SDE_AUDIO_POWER_B (1 << 25) | ||
2784 | #define SDE_AUDIO_POWER_SHIFT (25) | ||
2785 | #define SDE_AUDIO_POWER_MASK (7 << SDE_AUDIO_POWER_SHIFT) | ||
2786 | #define SDE_GMBUS (1 << 24) | ||
2787 | #define SDE_AUDIO_HDCP_TRANSB (1 << 23) | ||
2788 | #define SDE_AUDIO_HDCP_TRANSA (1 << 22) | ||
2789 | #define SDE_AUDIO_HDCP_MASK (3 << 22) | ||
2790 | #define SDE_AUDIO_TRANSB (1 << 21) | ||
2791 | #define SDE_AUDIO_TRANSA (1 << 20) | ||
2792 | #define SDE_AUDIO_TRANS_MASK (3 << 20) | ||
2793 | #define SDE_POISON (1 << 19) | ||
2794 | /* 18 reserved */ | ||
2795 | #define SDE_FDI_RXB (1 << 17) | ||
2796 | #define SDE_FDI_RXA (1 << 16) | ||
2797 | #define SDE_FDI_MASK (3 << 16) | ||
2798 | #define SDE_AUXD (1 << 15) | ||
2799 | #define SDE_AUXC (1 << 14) | ||
2800 | #define SDE_AUXB (1 << 13) | ||
2801 | #define SDE_AUX_MASK (7 << 13) | ||
2802 | /* 12 reserved */ | ||
2731 | #define SDE_CRT_HOTPLUG (1 << 11) | 2803 | #define SDE_CRT_HOTPLUG (1 << 11) |
2732 | #define SDE_PORTD_HOTPLUG (1 << 10) | 2804 | #define SDE_PORTD_HOTPLUG (1 << 10) |
2733 | #define SDE_PORTC_HOTPLUG (1 << 9) | 2805 | #define SDE_PORTC_HOTPLUG (1 << 9) |
2734 | #define SDE_PORTB_HOTPLUG (1 << 8) | 2806 | #define SDE_PORTB_HOTPLUG (1 << 8) |
2735 | #define SDE_SDVOB_HOTPLUG (1 << 6) | 2807 | #define SDE_SDVOB_HOTPLUG (1 << 6) |
2736 | #define SDE_HOTPLUG_MASK (0xf << 8) | 2808 | #define SDE_HOTPLUG_MASK (0xf << 8) |
2809 | #define SDE_TRANSB_CRC_DONE (1 << 5) | ||
2810 | #define SDE_TRANSB_CRC_ERR (1 << 4) | ||
2811 | #define SDE_TRANSB_FIFO_UNDER (1 << 3) | ||
2812 | #define SDE_TRANSA_CRC_DONE (1 << 2) | ||
2813 | #define SDE_TRANSA_CRC_ERR (1 << 1) | ||
2814 | #define SDE_TRANSA_FIFO_UNDER (1 << 0) | ||
2815 | #define SDE_TRANS_MASK (0x3f) | ||
2737 | /* CPT */ | 2816 | /* CPT */ |
2738 | #define SDE_CRT_HOTPLUG_CPT (1 << 19) | 2817 | #define SDE_CRT_HOTPLUG_CPT (1 << 19) |
2739 | #define SDE_PORTD_HOTPLUG_CPT (1 << 23) | 2818 | #define SDE_PORTD_HOTPLUG_CPT (1 << 23) |
@@ -3174,10 +3253,11 @@ | |||
3174 | #define EDP_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01<<22) | 3253 | #define EDP_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01<<22) |
3175 | #define EDP_LINK_TRAIN_800MV_0DB_SNB_A (0x0<<22) | 3254 | #define EDP_LINK_TRAIN_800MV_0DB_SNB_A (0x0<<22) |
3176 | /* SNB B-stepping */ | 3255 | /* SNB B-stepping */ |
3177 | #define EDP_LINK_TRAIN_400MV_0DB_SNB_B (0x0<<22) | 3256 | #define EDP_LINK_TRAIN_400_600MV_0DB_SNB_B (0x0<<22) |
3178 | #define EDP_LINK_TRAIN_400MV_6DB_SNB_B (0x3a<<22) | 3257 | #define EDP_LINK_TRAIN_400MV_3_5DB_SNB_B (0x1<<22) |
3179 | #define EDP_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39<<22) | 3258 | #define EDP_LINK_TRAIN_400_600MV_6DB_SNB_B (0x3a<<22) |
3180 | #define EDP_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) | 3259 | #define EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B (0x39<<22) |
3260 | #define EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B (0x38<<22) | ||
3181 | #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) | 3261 | #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) |
3182 | 3262 | ||
3183 | #define FORCEWAKE 0xA18C | 3263 | #define FORCEWAKE 0xA18C |
@@ -3239,6 +3319,7 @@ | |||
3239 | 3319 | ||
3240 | #define GEN6_PCODE_MAILBOX 0x138124 | 3320 | #define GEN6_PCODE_MAILBOX 0x138124 |
3241 | #define GEN6_PCODE_READY (1<<31) | 3321 | #define GEN6_PCODE_READY (1<<31) |
3322 | #define GEN6_READ_OC_PARAMS 0xc | ||
3242 | #define GEN6_PCODE_WRITE_MIN_FREQ_TABLE 0x9 | 3323 | #define GEN6_PCODE_WRITE_MIN_FREQ_TABLE 0x9 |
3243 | #define GEN6_PCODE_DATA 0x138128 | 3324 | #define GEN6_PCODE_DATA 0x138128 |
3244 | 3325 | ||
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 410772466fa..0521ecf2601 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -740,7 +740,7 @@ void i915_restore_display(struct drm_device *dev) | |||
740 | I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); | 740 | I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); |
741 | I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); | 741 | I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); |
742 | I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL); | 742 | I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL); |
743 | I915_WRITE(MCHBAR_RENDER_STANDBY, | 743 | I915_WRITE(RSTDBYCTL, |
744 | dev_priv->saveMCHBAR_RENDER_STANDBY); | 744 | dev_priv->saveMCHBAR_RENDER_STANDBY); |
745 | } else { | 745 | } else { |
746 | I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); | 746 | I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); |
@@ -811,7 +811,7 @@ int i915_save_state(struct drm_device *dev) | |||
811 | dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR); | 811 | dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR); |
812 | dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR); | 812 | dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR); |
813 | dev_priv->saveMCHBAR_RENDER_STANDBY = | 813 | dev_priv->saveMCHBAR_RENDER_STANDBY = |
814 | I915_READ(MCHBAR_RENDER_STANDBY); | 814 | I915_READ(RSTDBYCTL); |
815 | } else { | 815 | } else { |
816 | dev_priv->saveIER = I915_READ(IER); | 816 | dev_priv->saveIER = I915_READ(IER); |
817 | dev_priv->saveIMR = I915_READ(IMR); | 817 | dev_priv->saveIMR = I915_READ(IMR); |
@@ -822,10 +822,6 @@ int i915_save_state(struct drm_device *dev) | |||
822 | if (IS_GEN6(dev)) | 822 | if (IS_GEN6(dev)) |
823 | gen6_disable_rps(dev); | 823 | gen6_disable_rps(dev); |
824 | 824 | ||
825 | /* XXX disabling the clock gating breaks suspend on gm45 | ||
826 | intel_disable_clock_gating(dev); | ||
827 | */ | ||
828 | |||
829 | /* Cache mode state */ | 825 | /* Cache mode state */ |
830 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | 826 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); |
831 | 827 | ||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 8df57431606..17035b87ee4 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "drm.h" | 30 | #include "drm.h" |
31 | #include "drm_crtc.h" | 31 | #include "drm_crtc.h" |
32 | #include "drm_crtc_helper.h" | 32 | #include "drm_crtc_helper.h" |
33 | #include "drm_edid.h" | ||
33 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
@@ -287,8 +288,9 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus) | |||
287 | return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; | 288 | return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; |
288 | } | 289 | } |
289 | 290 | ||
290 | static bool intel_crt_detect_ddc(struct intel_crt *crt) | 291 | static bool intel_crt_detect_ddc(struct drm_connector *connector) |
291 | { | 292 | { |
293 | struct intel_crt *crt = intel_attached_crt(connector); | ||
292 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; | 294 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; |
293 | 295 | ||
294 | /* CRT should always be at 0, but check anyway */ | 296 | /* CRT should always be at 0, but check anyway */ |
@@ -301,8 +303,26 @@ static bool intel_crt_detect_ddc(struct intel_crt *crt) | |||
301 | } | 303 | } |
302 | 304 | ||
303 | if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { | 305 | if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { |
304 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); | 306 | struct edid *edid; |
305 | return true; | 307 | bool is_digital = false; |
308 | |||
309 | edid = drm_get_edid(connector, | ||
310 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); | ||
311 | /* | ||
312 | * This may be a DVI-I connector with a shared DDC | ||
313 | * link between analog and digital outputs, so we | ||
314 | * have to check the EDID input spec of the attached device. | ||
315 | */ | ||
316 | if (edid != NULL) { | ||
317 | is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; | ||
318 | connector->display_info.raw_edid = NULL; | ||
319 | kfree(edid); | ||
320 | } | ||
321 | |||
322 | if (!is_digital) { | ||
323 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); | ||
324 | return true; | ||
325 | } | ||
306 | } | 326 | } |
307 | 327 | ||
308 | return false; | 328 | return false; |
@@ -458,7 +478,7 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
458 | } | 478 | } |
459 | } | 479 | } |
460 | 480 | ||
461 | if (intel_crt_detect_ddc(crt)) | 481 | if (intel_crt_detect_ddc(connector)) |
462 | return connector_status_connected; | 482 | return connector_status_connected; |
463 | 483 | ||
464 | if (!force) | 484 | if (!force) |
@@ -472,7 +492,7 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
472 | crtc = intel_get_load_detect_pipe(&crt->base, connector, | 492 | crtc = intel_get_load_detect_pipe(&crt->base, connector, |
473 | NULL, &dpms_mode); | 493 | NULL, &dpms_mode); |
474 | if (crtc) { | 494 | if (crtc) { |
475 | if (intel_crt_detect_ddc(crt)) | 495 | if (intel_crt_detect_ddc(connector)) |
476 | status = connector_status_connected; | 496 | status = connector_status_connected; |
477 | else | 497 | else |
478 | status = intel_crt_load_detect(crtc, crt); | 498 | status = intel_crt_load_detect(crtc, crt); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0abe79fb638..25d96889d7d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3418,15 +3418,16 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, | |||
3418 | static bool ironlake_compute_wm0(struct drm_device *dev, | 3418 | static bool ironlake_compute_wm0(struct drm_device *dev, |
3419 | int pipe, | 3419 | int pipe, |
3420 | const struct intel_watermark_params *display, | 3420 | const struct intel_watermark_params *display, |
3421 | int display_latency, | 3421 | int display_latency_ns, |
3422 | const struct intel_watermark_params *cursor, | 3422 | const struct intel_watermark_params *cursor, |
3423 | int cursor_latency, | 3423 | int cursor_latency_ns, |
3424 | int *plane_wm, | 3424 | int *plane_wm, |
3425 | int *cursor_wm) | 3425 | int *cursor_wm) |
3426 | { | 3426 | { |
3427 | struct drm_crtc *crtc; | 3427 | struct drm_crtc *crtc; |
3428 | int htotal, hdisplay, clock, pixel_size = 0; | 3428 | int htotal, hdisplay, clock, pixel_size; |
3429 | int line_time_us, line_count, entries; | 3429 | int line_time_us, line_count; |
3430 | int entries, tlb_miss; | ||
3430 | 3431 | ||
3431 | crtc = intel_get_crtc_for_pipe(dev, pipe); | 3432 | crtc = intel_get_crtc_for_pipe(dev, pipe); |
3432 | if (crtc->fb == NULL || !crtc->enabled) | 3433 | if (crtc->fb == NULL || !crtc->enabled) |
@@ -3438,7 +3439,10 @@ static bool ironlake_compute_wm0(struct drm_device *dev, | |||
3438 | pixel_size = crtc->fb->bits_per_pixel / 8; | 3439 | pixel_size = crtc->fb->bits_per_pixel / 8; |
3439 | 3440 | ||
3440 | /* Use the small buffer method to calculate plane watermark */ | 3441 | /* Use the small buffer method to calculate plane watermark */ |
3441 | entries = ((clock * pixel_size / 1000) * display_latency * 100) / 1000; | 3442 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; |
3443 | tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8; | ||
3444 | if (tlb_miss > 0) | ||
3445 | entries += tlb_miss; | ||
3442 | entries = DIV_ROUND_UP(entries, display->cacheline_size); | 3446 | entries = DIV_ROUND_UP(entries, display->cacheline_size); |
3443 | *plane_wm = entries + display->guard_size; | 3447 | *plane_wm = entries + display->guard_size; |
3444 | if (*plane_wm > (int)display->max_wm) | 3448 | if (*plane_wm > (int)display->max_wm) |
@@ -3446,8 +3450,11 @@ static bool ironlake_compute_wm0(struct drm_device *dev, | |||
3446 | 3450 | ||
3447 | /* Use the large buffer method to calculate cursor watermark */ | 3451 | /* Use the large buffer method to calculate cursor watermark */ |
3448 | line_time_us = ((htotal * 1000) / clock); | 3452 | line_time_us = ((htotal * 1000) / clock); |
3449 | line_count = (cursor_latency * 100 / line_time_us + 1000) / 1000; | 3453 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; |
3450 | entries = line_count * 64 * pixel_size; | 3454 | entries = line_count * 64 * pixel_size; |
3455 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; | ||
3456 | if (tlb_miss > 0) | ||
3457 | entries += tlb_miss; | ||
3451 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); | 3458 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
3452 | *cursor_wm = entries + cursor->guard_size; | 3459 | *cursor_wm = entries + cursor->guard_size; |
3453 | if (*cursor_wm > (int)cursor->max_wm) | 3460 | if (*cursor_wm > (int)cursor->max_wm) |
@@ -3456,113 +3463,17 @@ static bool ironlake_compute_wm0(struct drm_device *dev, | |||
3456 | return true; | 3463 | return true; |
3457 | } | 3464 | } |
3458 | 3465 | ||
3459 | static void ironlake_update_wm(struct drm_device *dev, | ||
3460 | int planea_clock, int planeb_clock, | ||
3461 | int sr_hdisplay, int sr_htotal, | ||
3462 | int pixel_size) | ||
3463 | { | ||
3464 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3465 | int plane_wm, cursor_wm, enabled; | ||
3466 | int tmp; | ||
3467 | |||
3468 | enabled = 0; | ||
3469 | if (ironlake_compute_wm0(dev, 0, | ||
3470 | &ironlake_display_wm_info, | ||
3471 | ILK_LP0_PLANE_LATENCY, | ||
3472 | &ironlake_cursor_wm_info, | ||
3473 | ILK_LP0_CURSOR_LATENCY, | ||
3474 | &plane_wm, &cursor_wm)) { | ||
3475 | I915_WRITE(WM0_PIPEA_ILK, | ||
3476 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3477 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
3478 | " plane %d, " "cursor: %d\n", | ||
3479 | plane_wm, cursor_wm); | ||
3480 | enabled++; | ||
3481 | } | ||
3482 | |||
3483 | if (ironlake_compute_wm0(dev, 1, | ||
3484 | &ironlake_display_wm_info, | ||
3485 | ILK_LP0_PLANE_LATENCY, | ||
3486 | &ironlake_cursor_wm_info, | ||
3487 | ILK_LP0_CURSOR_LATENCY, | ||
3488 | &plane_wm, &cursor_wm)) { | ||
3489 | I915_WRITE(WM0_PIPEB_ILK, | ||
3490 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3491 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
3492 | " plane %d, cursor: %d\n", | ||
3493 | plane_wm, cursor_wm); | ||
3494 | enabled++; | ||
3495 | } | ||
3496 | |||
3497 | /* | ||
3498 | * Calculate and update the self-refresh watermark only when one | ||
3499 | * display plane is used. | ||
3500 | */ | ||
3501 | tmp = 0; | ||
3502 | if (enabled == 1) { | ||
3503 | unsigned long line_time_us; | ||
3504 | int small, large, plane_fbc; | ||
3505 | int sr_clock, entries; | ||
3506 | int line_count, line_size; | ||
3507 | /* Read the self-refresh latency. The unit is 0.5us */ | ||
3508 | int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK; | ||
3509 | |||
3510 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
3511 | line_time_us = (sr_htotal * 1000) / sr_clock; | ||
3512 | |||
3513 | /* Use ns/us then divide to preserve precision */ | ||
3514 | line_count = ((ilk_sr_latency * 500) / line_time_us + 1000) | ||
3515 | / 1000; | ||
3516 | line_size = sr_hdisplay * pixel_size; | ||
3517 | |||
3518 | /* Use the minimum of the small and large buffer method for primary */ | ||
3519 | small = ((sr_clock * pixel_size / 1000) * (ilk_sr_latency * 500)) / 1000; | ||
3520 | large = line_count * line_size; | ||
3521 | |||
3522 | entries = DIV_ROUND_UP(min(small, large), | ||
3523 | ironlake_display_srwm_info.cacheline_size); | ||
3524 | |||
3525 | plane_fbc = entries * 64; | ||
3526 | plane_fbc = DIV_ROUND_UP(plane_fbc, line_size); | ||
3527 | |||
3528 | plane_wm = entries + ironlake_display_srwm_info.guard_size; | ||
3529 | if (plane_wm > (int)ironlake_display_srwm_info.max_wm) | ||
3530 | plane_wm = ironlake_display_srwm_info.max_wm; | ||
3531 | |||
3532 | /* calculate the self-refresh watermark for display cursor */ | ||
3533 | entries = line_count * pixel_size * 64; | ||
3534 | entries = DIV_ROUND_UP(entries, | ||
3535 | ironlake_cursor_srwm_info.cacheline_size); | ||
3536 | |||
3537 | cursor_wm = entries + ironlake_cursor_srwm_info.guard_size; | ||
3538 | if (cursor_wm > (int)ironlake_cursor_srwm_info.max_wm) | ||
3539 | cursor_wm = ironlake_cursor_srwm_info.max_wm; | ||
3540 | |||
3541 | /* configure watermark and enable self-refresh */ | ||
3542 | tmp = (WM1_LP_SR_EN | | ||
3543 | (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) | | ||
3544 | (plane_fbc << WM1_LP_FBC_SHIFT) | | ||
3545 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3546 | cursor_wm); | ||
3547 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d, fbc lines %d," | ||
3548 | " cursor %d\n", plane_wm, plane_fbc, cursor_wm); | ||
3549 | } | ||
3550 | I915_WRITE(WM1_LP_ILK, tmp); | ||
3551 | /* XXX setup WM2 and WM3 */ | ||
3552 | } | ||
3553 | |||
3554 | /* | 3466 | /* |
3555 | * Check the wm result. | 3467 | * Check the wm result. |
3556 | * | 3468 | * |
3557 | * If any calculated watermark values is larger than the maximum value that | 3469 | * If any calculated watermark values is larger than the maximum value that |
3558 | * can be programmed into the associated watermark register, that watermark | 3470 | * can be programmed into the associated watermark register, that watermark |
3559 | * must be disabled. | 3471 | * must be disabled. |
3560 | * | ||
3561 | * Also return true if all of those watermark values is 0, which is set by | ||
3562 | * sandybridge_compute_srwm, to indicate the latency is ZERO. | ||
3563 | */ | 3472 | */ |
3564 | static bool sandybridge_check_srwm(struct drm_device *dev, int level, | 3473 | static bool ironlake_check_srwm(struct drm_device *dev, int level, |
3565 | int fbc_wm, int display_wm, int cursor_wm) | 3474 | int fbc_wm, int display_wm, int cursor_wm, |
3475 | const struct intel_watermark_params *display, | ||
3476 | const struct intel_watermark_params *cursor) | ||
3566 | { | 3477 | { |
3567 | struct drm_i915_private *dev_priv = dev->dev_private; | 3478 | struct drm_i915_private *dev_priv = dev->dev_private; |
3568 | 3479 | ||
@@ -3571,7 +3482,7 @@ static bool sandybridge_check_srwm(struct drm_device *dev, int level, | |||
3571 | 3482 | ||
3572 | if (fbc_wm > SNB_FBC_MAX_SRWM) { | 3483 | if (fbc_wm > SNB_FBC_MAX_SRWM) { |
3573 | DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", | 3484 | DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", |
3574 | fbc_wm, SNB_FBC_MAX_SRWM, level); | 3485 | fbc_wm, SNB_FBC_MAX_SRWM, level); |
3575 | 3486 | ||
3576 | /* fbc has it's own way to disable FBC WM */ | 3487 | /* fbc has it's own way to disable FBC WM */ |
3577 | I915_WRITE(DISP_ARB_CTL, | 3488 | I915_WRITE(DISP_ARB_CTL, |
@@ -3579,15 +3490,15 @@ static bool sandybridge_check_srwm(struct drm_device *dev, int level, | |||
3579 | return false; | 3490 | return false; |
3580 | } | 3491 | } |
3581 | 3492 | ||
3582 | if (display_wm > SNB_DISPLAY_MAX_SRWM) { | 3493 | if (display_wm > display->max_wm) { |
3583 | DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", | 3494 | DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", |
3584 | display_wm, SNB_DISPLAY_MAX_SRWM, level); | 3495 | display_wm, SNB_DISPLAY_MAX_SRWM, level); |
3585 | return false; | 3496 | return false; |
3586 | } | 3497 | } |
3587 | 3498 | ||
3588 | if (cursor_wm > SNB_CURSOR_MAX_SRWM) { | 3499 | if (cursor_wm > cursor->max_wm) { |
3589 | DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", | 3500 | DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", |
3590 | cursor_wm, SNB_CURSOR_MAX_SRWM, level); | 3501 | cursor_wm, SNB_CURSOR_MAX_SRWM, level); |
3591 | return false; | 3502 | return false; |
3592 | } | 3503 | } |
3593 | 3504 | ||
@@ -3602,16 +3513,18 @@ static bool sandybridge_check_srwm(struct drm_device *dev, int level, | |||
3602 | /* | 3513 | /* |
3603 | * Compute watermark values of WM[1-3], | 3514 | * Compute watermark values of WM[1-3], |
3604 | */ | 3515 | */ |
3605 | static bool sandybridge_compute_srwm(struct drm_device *dev, int level, | 3516 | static bool ironlake_compute_srwm(struct drm_device *dev, int level, |
3606 | int hdisplay, int htotal, int pixel_size, | 3517 | int hdisplay, int htotal, |
3607 | int clock, int latency_ns, int *fbc_wm, | 3518 | int pixel_size, int clock, int latency_ns, |
3608 | int *display_wm, int *cursor_wm) | 3519 | const struct intel_watermark_params *display, |
3520 | const struct intel_watermark_params *cursor, | ||
3521 | int *fbc_wm, int *display_wm, int *cursor_wm) | ||
3609 | { | 3522 | { |
3610 | 3523 | ||
3611 | unsigned long line_time_us; | 3524 | unsigned long line_time_us; |
3525 | int line_count, line_size; | ||
3612 | int small, large; | 3526 | int small, large; |
3613 | int entries; | 3527 | int entries; |
3614 | int line_count, line_size; | ||
3615 | 3528 | ||
3616 | if (!latency_ns) { | 3529 | if (!latency_ns) { |
3617 | *fbc_wm = *display_wm = *cursor_wm = 0; | 3530 | *fbc_wm = *display_wm = *cursor_wm = 0; |
@@ -3626,24 +3539,110 @@ static bool sandybridge_compute_srwm(struct drm_device *dev, int level, | |||
3626 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | 3539 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; |
3627 | large = line_count * line_size; | 3540 | large = line_count * line_size; |
3628 | 3541 | ||
3629 | entries = DIV_ROUND_UP(min(small, large), | 3542 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); |
3630 | sandybridge_display_srwm_info.cacheline_size); | 3543 | *display_wm = entries + display->guard_size; |
3631 | *display_wm = entries + sandybridge_display_srwm_info.guard_size; | ||
3632 | 3544 | ||
3633 | /* | 3545 | /* |
3634 | * Spec said: | 3546 | * Spec says: |
3635 | * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 | 3547 | * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 |
3636 | */ | 3548 | */ |
3637 | *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; | 3549 | *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; |
3638 | 3550 | ||
3639 | /* calculate the self-refresh watermark for display cursor */ | 3551 | /* calculate the self-refresh watermark for display cursor */ |
3640 | entries = line_count * pixel_size * 64; | 3552 | entries = line_count * pixel_size * 64; |
3641 | entries = DIV_ROUND_UP(entries, | 3553 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
3642 | sandybridge_cursor_srwm_info.cacheline_size); | 3554 | *cursor_wm = entries + cursor->guard_size; |
3643 | *cursor_wm = entries + sandybridge_cursor_srwm_info.guard_size; | ||
3644 | 3555 | ||
3645 | return sandybridge_check_srwm(dev, level, | 3556 | return ironlake_check_srwm(dev, level, |
3646 | *fbc_wm, *display_wm, *cursor_wm); | 3557 | *fbc_wm, *display_wm, *cursor_wm, |
3558 | display, cursor); | ||
3559 | } | ||
3560 | |||
3561 | static void ironlake_update_wm(struct drm_device *dev, | ||
3562 | int planea_clock, int planeb_clock, | ||
3563 | int hdisplay, int htotal, | ||
3564 | int pixel_size) | ||
3565 | { | ||
3566 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3567 | int fbc_wm, plane_wm, cursor_wm, enabled; | ||
3568 | int clock; | ||
3569 | |||
3570 | enabled = 0; | ||
3571 | if (ironlake_compute_wm0(dev, 0, | ||
3572 | &ironlake_display_wm_info, | ||
3573 | ILK_LP0_PLANE_LATENCY, | ||
3574 | &ironlake_cursor_wm_info, | ||
3575 | ILK_LP0_CURSOR_LATENCY, | ||
3576 | &plane_wm, &cursor_wm)) { | ||
3577 | I915_WRITE(WM0_PIPEA_ILK, | ||
3578 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3579 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
3580 | " plane %d, " "cursor: %d\n", | ||
3581 | plane_wm, cursor_wm); | ||
3582 | enabled++; | ||
3583 | } | ||
3584 | |||
3585 | if (ironlake_compute_wm0(dev, 1, | ||
3586 | &ironlake_display_wm_info, | ||
3587 | ILK_LP0_PLANE_LATENCY, | ||
3588 | &ironlake_cursor_wm_info, | ||
3589 | ILK_LP0_CURSOR_LATENCY, | ||
3590 | &plane_wm, &cursor_wm)) { | ||
3591 | I915_WRITE(WM0_PIPEB_ILK, | ||
3592 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3593 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
3594 | " plane %d, cursor: %d\n", | ||
3595 | plane_wm, cursor_wm); | ||
3596 | enabled++; | ||
3597 | } | ||
3598 | |||
3599 | /* | ||
3600 | * Calculate and update the self-refresh watermark only when one | ||
3601 | * display plane is used. | ||
3602 | */ | ||
3603 | I915_WRITE(WM3_LP_ILK, 0); | ||
3604 | I915_WRITE(WM2_LP_ILK, 0); | ||
3605 | I915_WRITE(WM1_LP_ILK, 0); | ||
3606 | |||
3607 | if (enabled != 1) | ||
3608 | return; | ||
3609 | |||
3610 | clock = planea_clock ? planea_clock : planeb_clock; | ||
3611 | |||
3612 | /* WM1 */ | ||
3613 | if (!ironlake_compute_srwm(dev, 1, hdisplay, htotal, pixel_size, | ||
3614 | clock, ILK_READ_WM1_LATENCY() * 500, | ||
3615 | &ironlake_display_srwm_info, | ||
3616 | &ironlake_cursor_srwm_info, | ||
3617 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3618 | return; | ||
3619 | |||
3620 | I915_WRITE(WM1_LP_ILK, | ||
3621 | WM1_LP_SR_EN | | ||
3622 | (ILK_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
3623 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
3624 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3625 | cursor_wm); | ||
3626 | |||
3627 | /* WM2 */ | ||
3628 | if (!ironlake_compute_srwm(dev, 2, hdisplay, htotal, pixel_size, | ||
3629 | clock, ILK_READ_WM2_LATENCY() * 500, | ||
3630 | &ironlake_display_srwm_info, | ||
3631 | &ironlake_cursor_srwm_info, | ||
3632 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3633 | return; | ||
3634 | |||
3635 | I915_WRITE(WM2_LP_ILK, | ||
3636 | WM2_LP_EN | | ||
3637 | (ILK_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
3638 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
3639 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3640 | cursor_wm); | ||
3641 | |||
3642 | /* | ||
3643 | * WM3 is unsupported on ILK, probably because we don't have latency | ||
3644 | * data for that power state | ||
3645 | */ | ||
3647 | } | 3646 | } |
3648 | 3647 | ||
3649 | static void sandybridge_update_wm(struct drm_device *dev, | 3648 | static void sandybridge_update_wm(struct drm_device *dev, |
@@ -3652,7 +3651,7 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
3652 | int pixel_size) | 3651 | int pixel_size) |
3653 | { | 3652 | { |
3654 | struct drm_i915_private *dev_priv = dev->dev_private; | 3653 | struct drm_i915_private *dev_priv = dev->dev_private; |
3655 | int latency = SNB_READ_WM0_LATENCY(); | 3654 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ |
3656 | int fbc_wm, plane_wm, cursor_wm, enabled; | 3655 | int fbc_wm, plane_wm, cursor_wm, enabled; |
3657 | int clock; | 3656 | int clock; |
3658 | 3657 | ||
@@ -3701,9 +3700,11 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
3701 | clock = planea_clock ? planea_clock : planeb_clock; | 3700 | clock = planea_clock ? planea_clock : planeb_clock; |
3702 | 3701 | ||
3703 | /* WM1 */ | 3702 | /* WM1 */ |
3704 | if (!sandybridge_compute_srwm(dev, 1, hdisplay, htotal, pixel_size, | 3703 | if (!ironlake_compute_srwm(dev, 1, hdisplay, htotal, pixel_size, |
3705 | clock, SNB_READ_WM1_LATENCY() * 500, | 3704 | clock, SNB_READ_WM1_LATENCY() * 500, |
3706 | &fbc_wm, &plane_wm, &cursor_wm)) | 3705 | &sandybridge_display_srwm_info, |
3706 | &sandybridge_cursor_srwm_info, | ||
3707 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3707 | return; | 3708 | return; |
3708 | 3709 | ||
3709 | I915_WRITE(WM1_LP_ILK, | 3710 | I915_WRITE(WM1_LP_ILK, |
@@ -3714,10 +3715,12 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
3714 | cursor_wm); | 3715 | cursor_wm); |
3715 | 3716 | ||
3716 | /* WM2 */ | 3717 | /* WM2 */ |
3717 | if (!sandybridge_compute_srwm(dev, 2, | 3718 | if (!ironlake_compute_srwm(dev, 2, |
3718 | hdisplay, htotal, pixel_size, | 3719 | hdisplay, htotal, pixel_size, |
3719 | clock, SNB_READ_WM2_LATENCY() * 500, | 3720 | clock, SNB_READ_WM2_LATENCY() * 500, |
3720 | &fbc_wm, &plane_wm, &cursor_wm)) | 3721 | &sandybridge_display_srwm_info, |
3722 | &sandybridge_cursor_srwm_info, | ||
3723 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3721 | return; | 3724 | return; |
3722 | 3725 | ||
3723 | I915_WRITE(WM2_LP_ILK, | 3726 | I915_WRITE(WM2_LP_ILK, |
@@ -3728,10 +3731,12 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
3728 | cursor_wm); | 3731 | cursor_wm); |
3729 | 3732 | ||
3730 | /* WM3 */ | 3733 | /* WM3 */ |
3731 | if (!sandybridge_compute_srwm(dev, 3, | 3734 | if (!ironlake_compute_srwm(dev, 3, |
3732 | hdisplay, htotal, pixel_size, | 3735 | hdisplay, htotal, pixel_size, |
3733 | clock, SNB_READ_WM3_LATENCY() * 500, | 3736 | clock, SNB_READ_WM3_LATENCY() * 500, |
3734 | &fbc_wm, &plane_wm, &cursor_wm)) | 3737 | &sandybridge_display_srwm_info, |
3738 | &sandybridge_cursor_srwm_info, | ||
3739 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3735 | return; | 3740 | return; |
3736 | 3741 | ||
3737 | I915_WRITE(WM3_LP_ILK, | 3742 | I915_WRITE(WM3_LP_ILK, |
@@ -3951,7 +3956,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3951 | int lane = 0, link_bw, bpp; | 3956 | int lane = 0, link_bw, bpp; |
3952 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 3957 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
3953 | according to current link config */ | 3958 | according to current link config */ |
3954 | if (has_edp_encoder && !intel_encoder_is_pch_edp(&encoder->base)) { | 3959 | if (has_edp_encoder && !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
3955 | target_clock = mode->clock; | 3960 | target_clock = mode->clock; |
3956 | intel_edp_link_config(has_edp_encoder, | 3961 | intel_edp_link_config(has_edp_encoder, |
3957 | &lane, &link_bw); | 3962 | &lane, &link_bw); |
@@ -5038,8 +5043,8 @@ static void intel_increase_pllclock(struct drm_crtc *crtc) | |||
5038 | drm_i915_private_t *dev_priv = dev->dev_private; | 5043 | drm_i915_private_t *dev_priv = dev->dev_private; |
5039 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 5044 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5040 | int pipe = intel_crtc->pipe; | 5045 | int pipe = intel_crtc->pipe; |
5041 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 5046 | int dpll_reg = DPLL(pipe); |
5042 | int dpll = I915_READ(dpll_reg); | 5047 | int dpll; |
5043 | 5048 | ||
5044 | if (HAS_PCH_SPLIT(dev)) | 5049 | if (HAS_PCH_SPLIT(dev)) |
5045 | return; | 5050 | return; |
@@ -5047,17 +5052,19 @@ static void intel_increase_pllclock(struct drm_crtc *crtc) | |||
5047 | if (!dev_priv->lvds_downclock_avail) | 5052 | if (!dev_priv->lvds_downclock_avail) |
5048 | return; | 5053 | return; |
5049 | 5054 | ||
5055 | dpll = I915_READ(dpll_reg); | ||
5050 | if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { | 5056 | if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { |
5051 | DRM_DEBUG_DRIVER("upclocking LVDS\n"); | 5057 | DRM_DEBUG_DRIVER("upclocking LVDS\n"); |
5052 | 5058 | ||
5053 | /* Unlock panel regs */ | 5059 | /* Unlock panel regs */ |
5054 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | | 5060 | I915_WRITE(PP_CONTROL, |
5055 | PANEL_UNLOCK_REGS); | 5061 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); |
5056 | 5062 | ||
5057 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; | 5063 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
5058 | I915_WRITE(dpll_reg, dpll); | 5064 | I915_WRITE(dpll_reg, dpll); |
5059 | dpll = I915_READ(dpll_reg); | 5065 | POSTING_READ(dpll_reg); |
5060 | intel_wait_for_vblank(dev, pipe); | 5066 | intel_wait_for_vblank(dev, pipe); |
5067 | |||
5061 | dpll = I915_READ(dpll_reg); | 5068 | dpll = I915_READ(dpll_reg); |
5062 | if (dpll & DISPLAY_RATE_SELECT_FPA1) | 5069 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
5063 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); | 5070 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
@@ -5802,6 +5809,8 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
5802 | encoder->base.possible_clones = | 5809 | encoder->base.possible_clones = |
5803 | intel_encoder_clones(dev, encoder->clone_mask); | 5810 | intel_encoder_clones(dev, encoder->clone_mask); |
5804 | } | 5811 | } |
5812 | |||
5813 | intel_panel_setup_backlight(dev); | ||
5805 | } | 5814 | } |
5806 | 5815 | ||
5807 | static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) | 5816 | static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) |
@@ -6145,6 +6154,10 @@ void intel_init_emon(struct drm_device *dev) | |||
6145 | 6154 | ||
6146 | void gen6_enable_rps(struct drm_i915_private *dev_priv) | 6155 | void gen6_enable_rps(struct drm_i915_private *dev_priv) |
6147 | { | 6156 | { |
6157 | u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | ||
6158 | u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); | ||
6159 | u32 pcu_mbox; | ||
6160 | int cur_freq, min_freq, max_freq; | ||
6148 | int i; | 6161 | int i; |
6149 | 6162 | ||
6150 | /* Here begins a magic sequence of register writes to enable | 6163 | /* Here begins a magic sequence of register writes to enable |
@@ -6216,6 +6229,29 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
6216 | 500)) | 6229 | 500)) |
6217 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); | 6230 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); |
6218 | 6231 | ||
6232 | min_freq = (rp_state_cap & 0xff0000) >> 16; | ||
6233 | max_freq = rp_state_cap & 0xff; | ||
6234 | cur_freq = (gt_perf_status & 0xff00) >> 8; | ||
6235 | |||
6236 | /* Check for overclock support */ | ||
6237 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
6238 | 500)) | ||
6239 | DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); | ||
6240 | I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_READ_OC_PARAMS); | ||
6241 | pcu_mbox = I915_READ(GEN6_PCODE_DATA); | ||
6242 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
6243 | 500)) | ||
6244 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); | ||
6245 | if (pcu_mbox & (1<<31)) { /* OC supported */ | ||
6246 | max_freq = pcu_mbox & 0xff; | ||
6247 | DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 100); | ||
6248 | } | ||
6249 | |||
6250 | /* In units of 100MHz */ | ||
6251 | dev_priv->max_delay = max_freq; | ||
6252 | dev_priv->min_delay = min_freq; | ||
6253 | dev_priv->cur_delay = cur_freq; | ||
6254 | |||
6219 | /* requires MSI enabled */ | 6255 | /* requires MSI enabled */ |
6220 | I915_WRITE(GEN6_PMIER, | 6256 | I915_WRITE(GEN6_PMIER, |
6221 | GEN6_PM_MBOX_EVENT | | 6257 | GEN6_PM_MBOX_EVENT | |
@@ -6386,42 +6422,6 @@ void intel_enable_clock_gating(struct drm_device *dev) | |||
6386 | } else if (IS_I830(dev)) { | 6422 | } else if (IS_I830(dev)) { |
6387 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); | 6423 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); |
6388 | } | 6424 | } |
6389 | |||
6390 | /* | ||
6391 | * GPU can automatically power down the render unit if given a page | ||
6392 | * to save state. | ||
6393 | */ | ||
6394 | if (IS_IRONLAKE_M(dev) && 0) { /* XXX causes a failure during suspend */ | ||
6395 | if (dev_priv->renderctx == NULL) | ||
6396 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
6397 | if (dev_priv->renderctx) { | ||
6398 | struct drm_i915_gem_object *obj = dev_priv->renderctx; | ||
6399 | if (BEGIN_LP_RING(4) == 0) { | ||
6400 | OUT_RING(MI_SET_CONTEXT); | ||
6401 | OUT_RING(obj->gtt_offset | | ||
6402 | MI_MM_SPACE_GTT | | ||
6403 | MI_SAVE_EXT_STATE_EN | | ||
6404 | MI_RESTORE_EXT_STATE_EN | | ||
6405 | MI_RESTORE_INHIBIT); | ||
6406 | OUT_RING(MI_NOOP); | ||
6407 | OUT_RING(MI_FLUSH); | ||
6408 | ADVANCE_LP_RING(); | ||
6409 | } | ||
6410 | } else | ||
6411 | DRM_DEBUG_KMS("Failed to allocate render context." | ||
6412 | "Disable RC6\n"); | ||
6413 | } | ||
6414 | |||
6415 | if (IS_GEN4(dev) && IS_MOBILE(dev)) { | ||
6416 | if (dev_priv->pwrctx == NULL) | ||
6417 | dev_priv->pwrctx = intel_alloc_context_page(dev); | ||
6418 | if (dev_priv->pwrctx) { | ||
6419 | struct drm_i915_gem_object *obj = dev_priv->pwrctx; | ||
6420 | I915_WRITE(PWRCTXA, obj->gtt_offset | PWRCTX_EN); | ||
6421 | I915_WRITE(MCHBAR_RENDER_STANDBY, | ||
6422 | I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); | ||
6423 | } | ||
6424 | } | ||
6425 | } | 6425 | } |
6426 | 6426 | ||
6427 | void intel_disable_clock_gating(struct drm_device *dev) | 6427 | void intel_disable_clock_gating(struct drm_device *dev) |
@@ -6451,6 +6451,57 @@ void intel_disable_clock_gating(struct drm_device *dev) | |||
6451 | } | 6451 | } |
6452 | } | 6452 | } |
6453 | 6453 | ||
6454 | static void ironlake_disable_rc6(struct drm_device *dev) | ||
6455 | { | ||
6456 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6457 | |||
6458 | /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ | ||
6459 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); | ||
6460 | wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), | ||
6461 | 10); | ||
6462 | POSTING_READ(CCID); | ||
6463 | I915_WRITE(PWRCTXA, 0); | ||
6464 | POSTING_READ(PWRCTXA); | ||
6465 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | ||
6466 | POSTING_READ(RSTDBYCTL); | ||
6467 | i915_gem_object_unpin(dev_priv->renderctx); | ||
6468 | drm_gem_object_unreference(&dev_priv->renderctx->base); | ||
6469 | dev_priv->renderctx = NULL; | ||
6470 | i915_gem_object_unpin(dev_priv->pwrctx); | ||
6471 | drm_gem_object_unreference(&dev_priv->pwrctx->base); | ||
6472 | dev_priv->pwrctx = NULL; | ||
6473 | } | ||
6474 | |||
6475 | void ironlake_enable_rc6(struct drm_device *dev) | ||
6476 | { | ||
6477 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6478 | int ret; | ||
6479 | |||
6480 | /* | ||
6481 | * GPU can automatically power down the render unit if given a page | ||
6482 | * to save state. | ||
6483 | */ | ||
6484 | ret = BEGIN_LP_RING(6); | ||
6485 | if (ret) { | ||
6486 | ironlake_disable_rc6(dev); | ||
6487 | return; | ||
6488 | } | ||
6489 | OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); | ||
6490 | OUT_RING(MI_SET_CONTEXT); | ||
6491 | OUT_RING(dev_priv->renderctx->gtt_offset | | ||
6492 | MI_MM_SPACE_GTT | | ||
6493 | MI_SAVE_EXT_STATE_EN | | ||
6494 | MI_RESTORE_EXT_STATE_EN | | ||
6495 | MI_RESTORE_INHIBIT); | ||
6496 | OUT_RING(MI_SUSPEND_FLUSH); | ||
6497 | OUT_RING(MI_NOOP); | ||
6498 | OUT_RING(MI_FLUSH); | ||
6499 | ADVANCE_LP_RING(); | ||
6500 | |||
6501 | I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); | ||
6502 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | ||
6503 | } | ||
6504 | |||
6454 | /* Set up chip specific display functions */ | 6505 | /* Set up chip specific display functions */ |
6455 | static void intel_init_display(struct drm_device *dev) | 6506 | static void intel_init_display(struct drm_device *dev) |
6456 | { | 6507 | { |
@@ -6665,12 +6716,7 @@ void intel_modeset_init(struct drm_device *dev) | |||
6665 | dev->mode_config.max_width = 8192; | 6716 | dev->mode_config.max_width = 8192; |
6666 | dev->mode_config.max_height = 8192; | 6717 | dev->mode_config.max_height = 8192; |
6667 | } | 6718 | } |
6668 | 6719 | dev->mode_config.fb_base = dev->agp->base; | |
6669 | /* set memory base */ | ||
6670 | if (IS_GEN2(dev)) | ||
6671 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0); | ||
6672 | else | ||
6673 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, 2); | ||
6674 | 6720 | ||
6675 | if (IS_MOBILE(dev) || !IS_GEN2(dev)) | 6721 | if (IS_MOBILE(dev) || !IS_GEN2(dev)) |
6676 | dev_priv->num_pipe = 2; | 6722 | dev_priv->num_pipe = 2; |
@@ -6698,6 +6744,21 @@ void intel_modeset_init(struct drm_device *dev) | |||
6698 | if (IS_GEN6(dev)) | 6744 | if (IS_GEN6(dev)) |
6699 | gen6_enable_rps(dev_priv); | 6745 | gen6_enable_rps(dev_priv); |
6700 | 6746 | ||
6747 | if (IS_IRONLAKE_M(dev)) { | ||
6748 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
6749 | if (!dev_priv->renderctx) | ||
6750 | goto skip_rc6; | ||
6751 | dev_priv->pwrctx = intel_alloc_context_page(dev); | ||
6752 | if (!dev_priv->pwrctx) { | ||
6753 | i915_gem_object_unpin(dev_priv->renderctx); | ||
6754 | drm_gem_object_unreference(&dev_priv->renderctx->base); | ||
6755 | dev_priv->renderctx = NULL; | ||
6756 | goto skip_rc6; | ||
6757 | } | ||
6758 | ironlake_enable_rc6(dev); | ||
6759 | } | ||
6760 | |||
6761 | skip_rc6: | ||
6701 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | 6762 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
6702 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | 6763 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |
6703 | (unsigned long)dev); | 6764 | (unsigned long)dev); |
@@ -6734,7 +6795,8 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
6734 | if (IS_GEN6(dev)) | 6795 | if (IS_GEN6(dev)) |
6735 | gen6_disable_rps(dev); | 6796 | gen6_disable_rps(dev); |
6736 | 6797 | ||
6737 | intel_disable_clock_gating(dev); | 6798 | if (IS_IRONLAKE_M(dev)) |
6799 | ironlake_disable_rc6(dev); | ||
6738 | 6800 | ||
6739 | mutex_unlock(&dev->struct_mutex); | 6801 | mutex_unlock(&dev->struct_mutex); |
6740 | 6802 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1dc60408d5b..1f4242b682c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1153,18 +1153,27 @@ intel_dp_signal_levels(uint8_t train_set, int lane_count) | |||
1153 | static uint32_t | 1153 | static uint32_t |
1154 | intel_gen6_edp_signal_levels(uint8_t train_set) | 1154 | intel_gen6_edp_signal_levels(uint8_t train_set) |
1155 | { | 1155 | { |
1156 | switch (train_set & (DP_TRAIN_VOLTAGE_SWING_MASK|DP_TRAIN_PRE_EMPHASIS_MASK)) { | 1156 | int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | |
1157 | DP_TRAIN_PRE_EMPHASIS_MASK); | ||
1158 | switch (signal_levels) { | ||
1157 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0: | 1159 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0: |
1158 | return EDP_LINK_TRAIN_400MV_0DB_SNB_B; | 1160 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0: |
1161 | return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B; | ||
1162 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5: | ||
1163 | return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B; | ||
1159 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6: | 1164 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6: |
1160 | return EDP_LINK_TRAIN_400MV_6DB_SNB_B; | 1165 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6: |
1166 | return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B; | ||
1161 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5: | 1167 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5: |
1162 | return EDP_LINK_TRAIN_600MV_3_5DB_SNB_B; | 1168 | case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5: |
1169 | return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B; | ||
1163 | case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0: | 1170 | case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0: |
1164 | return EDP_LINK_TRAIN_800MV_0DB_SNB_B; | 1171 | case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0: |
1172 | return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B; | ||
1165 | default: | 1173 | default: |
1166 | DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level\n"); | 1174 | DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:" |
1167 | return EDP_LINK_TRAIN_400MV_0DB_SNB_B; | 1175 | "0x%x\n", signal_levels); |
1176 | return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B; | ||
1168 | } | 1177 | } |
1169 | } | 1178 | } |
1170 | 1179 | ||
@@ -1334,17 +1343,24 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1334 | struct drm_device *dev = intel_dp->base.base.dev; | 1343 | struct drm_device *dev = intel_dp->base.base.dev; |
1335 | struct drm_i915_private *dev_priv = dev->dev_private; | 1344 | struct drm_i915_private *dev_priv = dev->dev_private; |
1336 | bool channel_eq = false; | 1345 | bool channel_eq = false; |
1337 | int tries; | 1346 | int tries, cr_tries; |
1338 | u32 reg; | 1347 | u32 reg; |
1339 | uint32_t DP = intel_dp->DP; | 1348 | uint32_t DP = intel_dp->DP; |
1340 | 1349 | ||
1341 | /* channel equalization */ | 1350 | /* channel equalization */ |
1342 | tries = 0; | 1351 | tries = 0; |
1352 | cr_tries = 0; | ||
1343 | channel_eq = false; | 1353 | channel_eq = false; |
1344 | for (;;) { | 1354 | for (;;) { |
1345 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | 1355 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1346 | uint32_t signal_levels; | 1356 | uint32_t signal_levels; |
1347 | 1357 | ||
1358 | if (cr_tries > 5) { | ||
1359 | DRM_ERROR("failed to train DP, aborting\n"); | ||
1360 | intel_dp_link_down(intel_dp); | ||
1361 | break; | ||
1362 | } | ||
1363 | |||
1348 | if (IS_GEN6(dev) && is_edp(intel_dp)) { | 1364 | if (IS_GEN6(dev) && is_edp(intel_dp)) { |
1349 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1365 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1350 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1366 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
@@ -1367,14 +1383,26 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1367 | if (!intel_dp_get_link_status(intel_dp)) | 1383 | if (!intel_dp_get_link_status(intel_dp)) |
1368 | break; | 1384 | break; |
1369 | 1385 | ||
1386 | /* Make sure clock is still ok */ | ||
1387 | if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | ||
1388 | intel_dp_start_link_train(intel_dp); | ||
1389 | cr_tries++; | ||
1390 | continue; | ||
1391 | } | ||
1392 | |||
1370 | if (intel_channel_eq_ok(intel_dp)) { | 1393 | if (intel_channel_eq_ok(intel_dp)) { |
1371 | channel_eq = true; | 1394 | channel_eq = true; |
1372 | break; | 1395 | break; |
1373 | } | 1396 | } |
1374 | 1397 | ||
1375 | /* Try 5 times */ | 1398 | /* Try 5 times, then try clock recovery if that fails */ |
1376 | if (tries > 5) | 1399 | if (tries > 5) { |
1377 | break; | 1400 | intel_dp_link_down(intel_dp); |
1401 | intel_dp_start_link_train(intel_dp); | ||
1402 | tries = 0; | ||
1403 | cr_tries++; | ||
1404 | continue; | ||
1405 | } | ||
1378 | 1406 | ||
1379 | /* Compute new intel_dp->train_set as requested by target */ | 1407 | /* Compute new intel_dp->train_set as requested by target */ |
1380 | intel_get_adjust_train(intel_dp); | 1408 | intel_get_adjust_train(intel_dp); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d782ad9fd6d..74db2557d64 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -257,6 +257,9 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, | |||
257 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | 257 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); |
258 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | 258 | extern u32 intel_panel_get_backlight(struct drm_device *dev); |
259 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); | 259 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); |
260 | extern void intel_panel_setup_backlight(struct drm_device *dev); | ||
261 | extern void intel_panel_enable_backlight(struct drm_device *dev); | ||
262 | extern void intel_panel_disable_backlight(struct drm_device *dev); | ||
260 | 263 | ||
261 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 264 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
262 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 265 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 701e830d001..ee145a25728 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -62,6 +62,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
62 | struct drm_fb_helper_surface_size *sizes) | 62 | struct drm_fb_helper_surface_size *sizes) |
63 | { | 63 | { |
64 | struct drm_device *dev = ifbdev->helper.dev; | 64 | struct drm_device *dev = ifbdev->helper.dev; |
65 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
65 | struct fb_info *info; | 66 | struct fb_info *info; |
66 | struct drm_framebuffer *fb; | 67 | struct drm_framebuffer *fb; |
67 | struct drm_mode_fb_cmd mode_cmd; | 68 | struct drm_mode_fb_cmd mode_cmd; |
@@ -77,7 +78,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
77 | mode_cmd.height = sizes->surface_height; | 78 | mode_cmd.height = sizes->surface_height; |
78 | 79 | ||
79 | mode_cmd.bpp = sizes->surface_bpp; | 80 | mode_cmd.bpp = sizes->surface_bpp; |
80 | mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); | 81 | mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64); |
81 | mode_cmd.depth = sizes->surface_depth; | 82 | mode_cmd.depth = sizes->surface_depth; |
82 | 83 | ||
83 | size = mode_cmd.pitch * mode_cmd.height; | 84 | size = mode_cmd.pitch * mode_cmd.height; |
@@ -120,6 +121,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
120 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; | 121 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; |
121 | info->fbops = &intelfb_ops; | 122 | info->fbops = &intelfb_ops; |
122 | 123 | ||
124 | ret = fb_alloc_cmap(&info->cmap, 256, 0); | ||
125 | if (ret) { | ||
126 | ret = -ENOMEM; | ||
127 | goto out_unpin; | ||
128 | } | ||
123 | /* setup aperture base/size for vesafb takeover */ | 129 | /* setup aperture base/size for vesafb takeover */ |
124 | info->apertures = alloc_apertures(1); | 130 | info->apertures = alloc_apertures(1); |
125 | if (!info->apertures) { | 131 | if (!info->apertures) { |
@@ -127,10 +133,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
127 | goto out_unpin; | 133 | goto out_unpin; |
128 | } | 134 | } |
129 | info->apertures->ranges[0].base = dev->mode_config.fb_base; | 135 | info->apertures->ranges[0].base = dev->mode_config.fb_base; |
130 | if (!IS_GEN2(dev)) | 136 | info->apertures->ranges[0].size = |
131 | info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 2); | 137 | dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; |
132 | else | ||
133 | info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); | ||
134 | 138 | ||
135 | info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; | 139 | info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; |
136 | info->fix.smem_len = size; | 140 | info->fix.smem_len = size; |
@@ -140,12 +144,6 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
140 | ret = -ENOSPC; | 144 | ret = -ENOSPC; |
141 | goto out_unpin; | 145 | goto out_unpin; |
142 | } | 146 | } |
143 | |||
144 | ret = fb_alloc_cmap(&info->cmap, 256, 0); | ||
145 | if (ret) { | ||
146 | ret = -ENOMEM; | ||
147 | goto out_unpin; | ||
148 | } | ||
149 | info->screen_size = size; | 147 | info->screen_size = size; |
150 | 148 | ||
151 | // memset(info->screen_base, 0, size); | 149 | // memset(info->screen_base, 0, size); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index aa2307080be..8f4f6bd33ee 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -106,7 +106,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) | |||
106 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | 106 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); |
107 | POSTING_READ(lvds_reg); | 107 | POSTING_READ(lvds_reg); |
108 | 108 | ||
109 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | 109 | intel_panel_enable_backlight(dev); |
110 | } | 110 | } |
111 | 111 | ||
112 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) | 112 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) |
@@ -123,8 +123,7 @@ static void intel_lvds_disable(struct intel_lvds *intel_lvds) | |||
123 | lvds_reg = LVDS; | 123 | lvds_reg = LVDS; |
124 | } | 124 | } |
125 | 125 | ||
126 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | 126 | intel_panel_disable_backlight(dev); |
127 | intel_panel_set_backlight(dev, 0); | ||
128 | 127 | ||
129 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | 128 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); |
130 | 129 | ||
@@ -375,6 +374,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
375 | } | 374 | } |
376 | 375 | ||
377 | out: | 376 | out: |
377 | if ((pfit_control & PFIT_ENABLE) == 0) { | ||
378 | pfit_control = 0; | ||
379 | pfit_pgm_ratios = 0; | ||
380 | } | ||
378 | if (pfit_control != intel_lvds->pfit_control || | 381 | if (pfit_control != intel_lvds->pfit_control || |
379 | pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { | 382 | pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { |
380 | intel_lvds->pfit_control = pfit_control; | 383 | intel_lvds->pfit_control = pfit_control; |
@@ -398,8 +401,6 @@ static void intel_lvds_prepare(struct drm_encoder *encoder) | |||
398 | struct drm_i915_private *dev_priv = dev->dev_private; | 401 | struct drm_i915_private *dev_priv = dev->dev_private; |
399 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 402 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
400 | 403 | ||
401 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
402 | |||
403 | /* We try to do the minimum that is necessary in order to unlock | 404 | /* We try to do the minimum that is necessary in order to unlock |
404 | * the registers for mode setting. | 405 | * the registers for mode setting. |
405 | * | 406 | * |
@@ -430,9 +431,6 @@ static void intel_lvds_commit(struct drm_encoder *encoder) | |||
430 | struct drm_i915_private *dev_priv = dev->dev_private; | 431 | struct drm_i915_private *dev_priv = dev->dev_private; |
431 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 432 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
432 | 433 | ||
433 | if (dev_priv->backlight_level == 0) | ||
434 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); | ||
435 | |||
436 | /* Undo any unlocking done in prepare to prevent accidental | 434 | /* Undo any unlocking done in prepare to prevent accidental |
437 | * adjustment of the registers. | 435 | * adjustment of the registers. |
438 | */ | 436 | */ |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 7350ec2515c..e00d200df3d 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -250,3 +250,34 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level) | |||
250 | tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; | 250 | tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; |
251 | I915_WRITE(BLC_PWM_CTL, tmp | level); | 251 | I915_WRITE(BLC_PWM_CTL, tmp | level); |
252 | } | 252 | } |
253 | |||
254 | void intel_panel_disable_backlight(struct drm_device *dev) | ||
255 | { | ||
256 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
257 | |||
258 | if (dev_priv->backlight_enabled) { | ||
259 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
260 | dev_priv->backlight_enabled = false; | ||
261 | } | ||
262 | |||
263 | intel_panel_set_backlight(dev, 0); | ||
264 | } | ||
265 | |||
266 | void intel_panel_enable_backlight(struct drm_device *dev) | ||
267 | { | ||
268 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
269 | |||
270 | if (dev_priv->backlight_level == 0) | ||
271 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); | ||
272 | |||
273 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | ||
274 | dev_priv->backlight_enabled = true; | ||
275 | } | ||
276 | |||
277 | void intel_panel_setup_backlight(struct drm_device *dev) | ||
278 | { | ||
279 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
280 | |||
281 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); | ||
282 | dev_priv->backlight_enabled = dev_priv->backlight_level != 0; | ||
283 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 56bc95c056d..03e33707251 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -48,7 +48,7 @@ static u32 i915_gem_get_seqno(struct drm_device *dev) | |||
48 | return seqno; | 48 | return seqno; |
49 | } | 49 | } |
50 | 50 | ||
51 | static void | 51 | static int |
52 | render_ring_flush(struct intel_ring_buffer *ring, | 52 | render_ring_flush(struct intel_ring_buffer *ring, |
53 | u32 invalidate_domains, | 53 | u32 invalidate_domains, |
54 | u32 flush_domains) | 54 | u32 flush_domains) |
@@ -56,6 +56,7 @@ render_ring_flush(struct intel_ring_buffer *ring, | |||
56 | struct drm_device *dev = ring->dev; | 56 | struct drm_device *dev = ring->dev; |
57 | drm_i915_private_t *dev_priv = dev->dev_private; | 57 | drm_i915_private_t *dev_priv = dev->dev_private; |
58 | u32 cmd; | 58 | u32 cmd; |
59 | int ret; | ||
59 | 60 | ||
60 | #if WATCH_EXEC | 61 | #if WATCH_EXEC |
61 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | 62 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, |
@@ -116,12 +117,16 @@ render_ring_flush(struct intel_ring_buffer *ring, | |||
116 | #if WATCH_EXEC | 117 | #if WATCH_EXEC |
117 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); | 118 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); |
118 | #endif | 119 | #endif |
119 | if (intel_ring_begin(ring, 2) == 0) { | 120 | ret = intel_ring_begin(ring, 2); |
120 | intel_ring_emit(ring, cmd); | 121 | if (ret) |
121 | intel_ring_emit(ring, MI_NOOP); | 122 | return ret; |
122 | intel_ring_advance(ring); | 123 | |
123 | } | 124 | intel_ring_emit(ring, cmd); |
125 | intel_ring_emit(ring, MI_NOOP); | ||
126 | intel_ring_advance(ring); | ||
124 | } | 127 | } |
128 | |||
129 | return 0; | ||
125 | } | 130 | } |
126 | 131 | ||
127 | static void ring_write_tail(struct intel_ring_buffer *ring, | 132 | static void ring_write_tail(struct intel_ring_buffer *ring, |
@@ -480,26 +485,56 @@ pc_render_get_seqno(struct intel_ring_buffer *ring) | |||
480 | return pc->cpu_page[0]; | 485 | return pc->cpu_page[0]; |
481 | } | 486 | } |
482 | 487 | ||
488 | static void | ||
489 | ironlake_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
490 | { | ||
491 | dev_priv->gt_irq_mask &= ~mask; | ||
492 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
493 | POSTING_READ(GTIMR); | ||
494 | } | ||
495 | |||
496 | static void | ||
497 | ironlake_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
498 | { | ||
499 | dev_priv->gt_irq_mask |= mask; | ||
500 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
501 | POSTING_READ(GTIMR); | ||
502 | } | ||
503 | |||
504 | static void | ||
505 | i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
506 | { | ||
507 | dev_priv->irq_mask &= ~mask; | ||
508 | I915_WRITE(IMR, dev_priv->irq_mask); | ||
509 | POSTING_READ(IMR); | ||
510 | } | ||
511 | |||
512 | static void | ||
513 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | ||
514 | { | ||
515 | dev_priv->irq_mask |= mask; | ||
516 | I915_WRITE(IMR, dev_priv->irq_mask); | ||
517 | POSTING_READ(IMR); | ||
518 | } | ||
519 | |||
483 | static bool | 520 | static bool |
484 | render_ring_get_irq(struct intel_ring_buffer *ring) | 521 | render_ring_get_irq(struct intel_ring_buffer *ring) |
485 | { | 522 | { |
486 | struct drm_device *dev = ring->dev; | 523 | struct drm_device *dev = ring->dev; |
524 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
487 | 525 | ||
488 | if (!dev->irq_enabled) | 526 | if (!dev->irq_enabled) |
489 | return false; | 527 | return false; |
490 | 528 | ||
491 | if (atomic_inc_return(&ring->irq_refcount) == 1) { | 529 | spin_lock(&ring->irq_lock); |
492 | drm_i915_private_t *dev_priv = dev->dev_private; | 530 | if (ring->irq_refcount++ == 0) { |
493 | unsigned long irqflags; | ||
494 | |||
495 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
496 | if (HAS_PCH_SPLIT(dev)) | 531 | if (HAS_PCH_SPLIT(dev)) |
497 | ironlake_enable_graphics_irq(dev_priv, | 532 | ironlake_enable_irq(dev_priv, |
498 | GT_PIPE_NOTIFY | GT_USER_INTERRUPT); | 533 | GT_PIPE_NOTIFY | GT_USER_INTERRUPT); |
499 | else | 534 | else |
500 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | 535 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); |
501 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
502 | } | 536 | } |
537 | spin_unlock(&ring->irq_lock); | ||
503 | 538 | ||
504 | return true; | 539 | return true; |
505 | } | 540 | } |
@@ -508,20 +543,18 @@ static void | |||
508 | render_ring_put_irq(struct intel_ring_buffer *ring) | 543 | render_ring_put_irq(struct intel_ring_buffer *ring) |
509 | { | 544 | { |
510 | struct drm_device *dev = ring->dev; | 545 | struct drm_device *dev = ring->dev; |
546 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
511 | 547 | ||
512 | if (atomic_dec_and_test(&ring->irq_refcount)) { | 548 | spin_lock(&ring->irq_lock); |
513 | drm_i915_private_t *dev_priv = dev->dev_private; | 549 | if (--ring->irq_refcount == 0) { |
514 | unsigned long irqflags; | ||
515 | |||
516 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
517 | if (HAS_PCH_SPLIT(dev)) | 550 | if (HAS_PCH_SPLIT(dev)) |
518 | ironlake_disable_graphics_irq(dev_priv, | 551 | ironlake_disable_irq(dev_priv, |
519 | GT_USER_INTERRUPT | | 552 | GT_USER_INTERRUPT | |
520 | GT_PIPE_NOTIFY); | 553 | GT_PIPE_NOTIFY); |
521 | else | 554 | else |
522 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | 555 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); |
523 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
524 | } | 556 | } |
557 | spin_unlock(&ring->irq_lock); | ||
525 | } | 558 | } |
526 | 559 | ||
527 | void intel_ring_setup_status_page(struct intel_ring_buffer *ring) | 560 | void intel_ring_setup_status_page(struct intel_ring_buffer *ring) |
@@ -534,19 +567,24 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) | |||
534 | POSTING_READ(mmio); | 567 | POSTING_READ(mmio); |
535 | } | 568 | } |
536 | 569 | ||
537 | static void | 570 | static int |
538 | bsd_ring_flush(struct intel_ring_buffer *ring, | 571 | bsd_ring_flush(struct intel_ring_buffer *ring, |
539 | u32 invalidate_domains, | 572 | u32 invalidate_domains, |
540 | u32 flush_domains) | 573 | u32 flush_domains) |
541 | { | 574 | { |
575 | int ret; | ||
576 | |||
542 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) | 577 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) |
543 | return; | 578 | return 0; |
544 | 579 | ||
545 | if (intel_ring_begin(ring, 2) == 0) { | 580 | ret = intel_ring_begin(ring, 2); |
546 | intel_ring_emit(ring, MI_FLUSH); | 581 | if (ret) |
547 | intel_ring_emit(ring, MI_NOOP); | 582 | return ret; |
548 | intel_ring_advance(ring); | 583 | |
549 | } | 584 | intel_ring_emit(ring, MI_FLUSH); |
585 | intel_ring_emit(ring, MI_NOOP); | ||
586 | intel_ring_advance(ring); | ||
587 | return 0; | ||
550 | } | 588 | } |
551 | 589 | ||
552 | static int | 590 | static int |
@@ -577,18 +615,15 @@ static bool | |||
577 | ring_get_irq(struct intel_ring_buffer *ring, u32 flag) | 615 | ring_get_irq(struct intel_ring_buffer *ring, u32 flag) |
578 | { | 616 | { |
579 | struct drm_device *dev = ring->dev; | 617 | struct drm_device *dev = ring->dev; |
618 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
580 | 619 | ||
581 | if (!dev->irq_enabled) | 620 | if (!dev->irq_enabled) |
582 | return false; | 621 | return false; |
583 | 622 | ||
584 | if (atomic_inc_return(&ring->irq_refcount) == 1) { | 623 | spin_lock(&ring->irq_lock); |
585 | drm_i915_private_t *dev_priv = dev->dev_private; | 624 | if (ring->irq_refcount++ == 0) |
586 | unsigned long irqflags; | 625 | ironlake_enable_irq(dev_priv, flag); |
587 | 626 | spin_unlock(&ring->irq_lock); | |
588 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
589 | ironlake_enable_graphics_irq(dev_priv, flag); | ||
590 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
591 | } | ||
592 | 627 | ||
593 | return true; | 628 | return true; |
594 | } | 629 | } |
@@ -597,15 +632,47 @@ static void | |||
597 | ring_put_irq(struct intel_ring_buffer *ring, u32 flag) | 632 | ring_put_irq(struct intel_ring_buffer *ring, u32 flag) |
598 | { | 633 | { |
599 | struct drm_device *dev = ring->dev; | 634 | struct drm_device *dev = ring->dev; |
635 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
600 | 636 | ||
601 | if (atomic_dec_and_test(&ring->irq_refcount)) { | 637 | spin_lock(&ring->irq_lock); |
602 | drm_i915_private_t *dev_priv = dev->dev_private; | 638 | if (--ring->irq_refcount == 0) |
603 | unsigned long irqflags; | 639 | ironlake_disable_irq(dev_priv, flag); |
640 | spin_unlock(&ring->irq_lock); | ||
641 | } | ||
604 | 642 | ||
605 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 643 | static bool |
606 | ironlake_disable_graphics_irq(dev_priv, flag); | 644 | gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) |
607 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 645 | { |
646 | struct drm_device *dev = ring->dev; | ||
647 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
648 | |||
649 | if (!dev->irq_enabled) | ||
650 | return false; | ||
651 | |||
652 | spin_lock(&ring->irq_lock); | ||
653 | if (ring->irq_refcount++ == 0) { | ||
654 | ring->irq_mask &= ~rflag; | ||
655 | I915_WRITE_IMR(ring, ring->irq_mask); | ||
656 | ironlake_enable_irq(dev_priv, gflag); | ||
608 | } | 657 | } |
658 | spin_unlock(&ring->irq_lock); | ||
659 | |||
660 | return true; | ||
661 | } | ||
662 | |||
663 | static void | ||
664 | gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) | ||
665 | { | ||
666 | struct drm_device *dev = ring->dev; | ||
667 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
668 | |||
669 | spin_lock(&ring->irq_lock); | ||
670 | if (--ring->irq_refcount == 0) { | ||
671 | ring->irq_mask |= rflag; | ||
672 | I915_WRITE_IMR(ring, ring->irq_mask); | ||
673 | ironlake_disable_irq(dev_priv, gflag); | ||
674 | } | ||
675 | spin_unlock(&ring->irq_lock); | ||
609 | } | 676 | } |
610 | 677 | ||
611 | static bool | 678 | static bool |
@@ -748,6 +815,9 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
748 | INIT_LIST_HEAD(&ring->request_list); | 815 | INIT_LIST_HEAD(&ring->request_list); |
749 | INIT_LIST_HEAD(&ring->gpu_write_list); | 816 | INIT_LIST_HEAD(&ring->gpu_write_list); |
750 | 817 | ||
818 | spin_lock_init(&ring->irq_lock); | ||
819 | ring->irq_mask = ~0; | ||
820 | |||
751 | if (I915_NEED_GFX_HWS(dev)) { | 821 | if (I915_NEED_GFX_HWS(dev)) { |
752 | ret = init_status_page(ring); | 822 | ret = init_status_page(ring); |
753 | if (ret) | 823 | if (ret) |
@@ -785,6 +855,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
785 | if (ret) | 855 | if (ret) |
786 | goto err_unmap; | 856 | goto err_unmap; |
787 | 857 | ||
858 | /* Workaround an erratum on the i830 which causes a hang if | ||
859 | * the TAIL pointer points to within the last 2 cachelines | ||
860 | * of the buffer. | ||
861 | */ | ||
862 | ring->effective_size = ring->size; | ||
863 | if (IS_I830(ring->dev)) | ||
864 | ring->effective_size -= 128; | ||
865 | |||
788 | return 0; | 866 | return 0; |
789 | 867 | ||
790 | err_unmap: | 868 | err_unmap: |
@@ -827,8 +905,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) | |||
827 | static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) | 905 | static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) |
828 | { | 906 | { |
829 | unsigned int *virt; | 907 | unsigned int *virt; |
830 | int rem; | 908 | int rem = ring->size - ring->tail; |
831 | rem = ring->size - ring->tail; | ||
832 | 909 | ||
833 | if (ring->space < rem) { | 910 | if (ring->space < rem) { |
834 | int ret = intel_wait_ring_buffer(ring, rem); | 911 | int ret = intel_wait_ring_buffer(ring, rem); |
@@ -895,7 +972,7 @@ int intel_ring_begin(struct intel_ring_buffer *ring, | |||
895 | int n = 4*num_dwords; | 972 | int n = 4*num_dwords; |
896 | int ret; | 973 | int ret; |
897 | 974 | ||
898 | if (unlikely(ring->tail + n > ring->size)) { | 975 | if (unlikely(ring->tail + n > ring->effective_size)) { |
899 | ret = intel_wrap_ring_buffer(ring); | 976 | ret = intel_wrap_ring_buffer(ring); |
900 | if (unlikely(ret)) | 977 | if (unlikely(ret)) |
901 | return ret; | 978 | return ret; |
@@ -973,20 +1050,25 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, | |||
973 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); | 1050 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); |
974 | } | 1051 | } |
975 | 1052 | ||
976 | static void gen6_ring_flush(struct intel_ring_buffer *ring, | 1053 | static int gen6_ring_flush(struct intel_ring_buffer *ring, |
977 | u32 invalidate_domains, | 1054 | u32 invalidate_domains, |
978 | u32 flush_domains) | 1055 | u32 flush_domains) |
979 | { | 1056 | { |
1057 | int ret; | ||
1058 | |||
980 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) | 1059 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) |
981 | return; | 1060 | return 0; |
982 | 1061 | ||
983 | if (intel_ring_begin(ring, 4) == 0) { | 1062 | ret = intel_ring_begin(ring, 4); |
984 | intel_ring_emit(ring, MI_FLUSH_DW); | 1063 | if (ret) |
985 | intel_ring_emit(ring, 0); | 1064 | return ret; |
986 | intel_ring_emit(ring, 0); | 1065 | |
987 | intel_ring_emit(ring, 0); | 1066 | intel_ring_emit(ring, MI_FLUSH_DW); |
988 | intel_ring_advance(ring); | 1067 | intel_ring_emit(ring, 0); |
989 | } | 1068 | intel_ring_emit(ring, 0); |
1069 | intel_ring_emit(ring, 0); | ||
1070 | intel_ring_advance(ring); | ||
1071 | return 0; | ||
990 | } | 1072 | } |
991 | 1073 | ||
992 | static int | 1074 | static int |
@@ -1008,15 +1090,35 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
1008 | } | 1090 | } |
1009 | 1091 | ||
1010 | static bool | 1092 | static bool |
1093 | gen6_render_ring_get_irq(struct intel_ring_buffer *ring) | ||
1094 | { | ||
1095 | return gen6_ring_get_irq(ring, | ||
1096 | GT_USER_INTERRUPT, | ||
1097 | GEN6_RENDER_USER_INTERRUPT); | ||
1098 | } | ||
1099 | |||
1100 | static void | ||
1101 | gen6_render_ring_put_irq(struct intel_ring_buffer *ring) | ||
1102 | { | ||
1103 | return gen6_ring_put_irq(ring, | ||
1104 | GT_USER_INTERRUPT, | ||
1105 | GEN6_RENDER_USER_INTERRUPT); | ||
1106 | } | ||
1107 | |||
1108 | static bool | ||
1011 | gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring) | 1109 | gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring) |
1012 | { | 1110 | { |
1013 | return ring_get_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); | 1111 | return gen6_ring_get_irq(ring, |
1112 | GT_GEN6_BSD_USER_INTERRUPT, | ||
1113 | GEN6_BSD_USER_INTERRUPT); | ||
1014 | } | 1114 | } |
1015 | 1115 | ||
1016 | static void | 1116 | static void |
1017 | gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) | 1117 | gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) |
1018 | { | 1118 | { |
1019 | ring_put_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); | 1119 | return gen6_ring_put_irq(ring, |
1120 | GT_GEN6_BSD_USER_INTERRUPT, | ||
1121 | GEN6_BSD_USER_INTERRUPT); | ||
1020 | } | 1122 | } |
1021 | 1123 | ||
1022 | /* ring buffer for Video Codec for Gen6+ */ | 1124 | /* ring buffer for Video Codec for Gen6+ */ |
@@ -1040,13 +1142,17 @@ static const struct intel_ring_buffer gen6_bsd_ring = { | |||
1040 | static bool | 1142 | static bool |
1041 | blt_ring_get_irq(struct intel_ring_buffer *ring) | 1143 | blt_ring_get_irq(struct intel_ring_buffer *ring) |
1042 | { | 1144 | { |
1043 | return ring_get_irq(ring, GT_BLT_USER_INTERRUPT); | 1145 | return gen6_ring_get_irq(ring, |
1146 | GT_BLT_USER_INTERRUPT, | ||
1147 | GEN6_BLITTER_USER_INTERRUPT); | ||
1044 | } | 1148 | } |
1045 | 1149 | ||
1046 | static void | 1150 | static void |
1047 | blt_ring_put_irq(struct intel_ring_buffer *ring) | 1151 | blt_ring_put_irq(struct intel_ring_buffer *ring) |
1048 | { | 1152 | { |
1049 | ring_put_irq(ring, GT_BLT_USER_INTERRUPT); | 1153 | gen6_ring_put_irq(ring, |
1154 | GT_BLT_USER_INTERRUPT, | ||
1155 | GEN6_BLITTER_USER_INTERRUPT); | ||
1050 | } | 1156 | } |
1051 | 1157 | ||
1052 | 1158 | ||
@@ -1115,20 +1221,25 @@ static int blt_ring_begin(struct intel_ring_buffer *ring, | |||
1115 | return intel_ring_begin(ring, 4); | 1221 | return intel_ring_begin(ring, 4); |
1116 | } | 1222 | } |
1117 | 1223 | ||
1118 | static void blt_ring_flush(struct intel_ring_buffer *ring, | 1224 | static int blt_ring_flush(struct intel_ring_buffer *ring, |
1119 | u32 invalidate_domains, | 1225 | u32 invalidate_domains, |
1120 | u32 flush_domains) | 1226 | u32 flush_domains) |
1121 | { | 1227 | { |
1228 | int ret; | ||
1229 | |||
1122 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) | 1230 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) |
1123 | return; | 1231 | return 0; |
1124 | 1232 | ||
1125 | if (blt_ring_begin(ring, 4) == 0) { | 1233 | ret = blt_ring_begin(ring, 4); |
1126 | intel_ring_emit(ring, MI_FLUSH_DW); | 1234 | if (ret) |
1127 | intel_ring_emit(ring, 0); | 1235 | return ret; |
1128 | intel_ring_emit(ring, 0); | 1236 | |
1129 | intel_ring_emit(ring, 0); | 1237 | intel_ring_emit(ring, MI_FLUSH_DW); |
1130 | intel_ring_advance(ring); | 1238 | intel_ring_emit(ring, 0); |
1131 | } | 1239 | intel_ring_emit(ring, 0); |
1240 | intel_ring_emit(ring, 0); | ||
1241 | intel_ring_advance(ring); | ||
1242 | return 0; | ||
1132 | } | 1243 | } |
1133 | 1244 | ||
1134 | static void blt_ring_cleanup(struct intel_ring_buffer *ring) | 1245 | static void blt_ring_cleanup(struct intel_ring_buffer *ring) |
@@ -1165,6 +1276,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1165 | *ring = render_ring; | 1276 | *ring = render_ring; |
1166 | if (INTEL_INFO(dev)->gen >= 6) { | 1277 | if (INTEL_INFO(dev)->gen >= 6) { |
1167 | ring->add_request = gen6_add_request; | 1278 | ring->add_request = gen6_add_request; |
1279 | ring->irq_get = gen6_render_ring_get_irq; | ||
1280 | ring->irq_put = gen6_render_ring_put_irq; | ||
1168 | } else if (IS_GEN5(dev)) { | 1281 | } else if (IS_GEN5(dev)) { |
1169 | ring->add_request = pc_render_add_request; | 1282 | ring->add_request = pc_render_add_request; |
1170 | ring->get_seqno = pc_render_get_seqno; | 1283 | ring->get_seqno = pc_render_get_seqno; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 8e2e357ad6e..be9087e4c9b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -16,21 +16,24 @@ struct intel_hw_status_page { | |||
16 | 16 | ||
17 | #define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) | 17 | #define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) |
18 | 18 | ||
19 | #define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL(ring->mmio_base)) | 19 | #define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL((ring)->mmio_base)) |
20 | #define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL(ring->mmio_base), val) | 20 | #define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val) |
21 | 21 | ||
22 | #define I915_READ_START(ring) I915_RING_READ(RING_START(ring->mmio_base)) | 22 | #define I915_READ_START(ring) I915_RING_READ(RING_START((ring)->mmio_base)) |
23 | #define I915_WRITE_START(ring, val) I915_WRITE(RING_START(ring->mmio_base), val) | 23 | #define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val) |
24 | 24 | ||
25 | #define I915_READ_HEAD(ring) I915_RING_READ(RING_HEAD(ring->mmio_base)) | 25 | #define I915_READ_HEAD(ring) I915_RING_READ(RING_HEAD((ring)->mmio_base)) |
26 | #define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD(ring->mmio_base), val) | 26 | #define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val) |
27 | 27 | ||
28 | #define I915_READ_CTL(ring) I915_RING_READ(RING_CTL(ring->mmio_base)) | 28 | #define I915_READ_CTL(ring) I915_RING_READ(RING_CTL((ring)->mmio_base)) |
29 | #define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL(ring->mmio_base), val) | 29 | #define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val) |
30 | 30 | ||
31 | #define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID(ring->mmio_base)) | 31 | #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) |
32 | #define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0(ring->mmio_base)) | 32 | #define I915_READ_IMR(ring) I915_RING_READ(RING_IMR((ring)->mmio_base)) |
33 | #define I915_READ_SYNC_1(ring) I915_RING_READ(RING_SYNC_1(ring->mmio_base)) | 33 | |
34 | #define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID((ring)->mmio_base)) | ||
35 | #define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0((ring)->mmio_base)) | ||
36 | #define I915_READ_SYNC_1(ring) I915_RING_READ(RING_SYNC_1((ring)->mmio_base)) | ||
34 | 37 | ||
35 | struct intel_ring_buffer { | 38 | struct intel_ring_buffer { |
36 | const char *name; | 39 | const char *name; |
@@ -49,12 +52,15 @@ struct intel_ring_buffer { | |||
49 | u32 tail; | 52 | u32 tail; |
50 | int space; | 53 | int space; |
51 | int size; | 54 | int size; |
55 | int effective_size; | ||
52 | struct intel_hw_status_page status_page; | 56 | struct intel_hw_status_page status_page; |
53 | 57 | ||
58 | spinlock_t irq_lock; | ||
59 | u32 irq_refcount; | ||
60 | u32 irq_mask; | ||
54 | u32 irq_seqno; /* last seq seem at irq time */ | 61 | u32 irq_seqno; /* last seq seem at irq time */ |
55 | u32 waiting_seqno; | 62 | u32 waiting_seqno; |
56 | u32 sync_seqno[I915_NUM_RINGS-1]; | 63 | u32 sync_seqno[I915_NUM_RINGS-1]; |
57 | atomic_t irq_refcount; | ||
58 | bool __must_check (*irq_get)(struct intel_ring_buffer *ring); | 64 | bool __must_check (*irq_get)(struct intel_ring_buffer *ring); |
59 | void (*irq_put)(struct intel_ring_buffer *ring); | 65 | void (*irq_put)(struct intel_ring_buffer *ring); |
60 | 66 | ||
@@ -62,9 +68,9 @@ struct intel_ring_buffer { | |||
62 | 68 | ||
63 | void (*write_tail)(struct intel_ring_buffer *ring, | 69 | void (*write_tail)(struct intel_ring_buffer *ring, |
64 | u32 value); | 70 | u32 value); |
65 | void (*flush)(struct intel_ring_buffer *ring, | 71 | int __must_check (*flush)(struct intel_ring_buffer *ring, |
66 | u32 invalidate_domains, | 72 | u32 invalidate_domains, |
67 | u32 flush_domains); | 73 | u32 flush_domains); |
68 | int (*add_request)(struct intel_ring_buffer *ring, | 74 | int (*add_request)(struct intel_ring_buffer *ring, |
69 | u32 *seqno); | 75 | u32 *seqno); |
70 | u32 (*get_seqno)(struct intel_ring_buffer *ring); | 76 | u32 (*get_seqno)(struct intel_ring_buffer *ring); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9d0af36a13e..45cd37652a3 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1024,9 +1024,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1024 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1024 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1025 | return; | 1025 | return; |
1026 | 1026 | ||
1027 | if (intel_sdvo->has_hdmi_monitor && | 1027 | if (intel_sdvo->has_hdmi_monitor) { |
1028 | !intel_sdvo_set_avi_infoframe(intel_sdvo)) | 1028 | intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); |
1029 | return; | 1029 | intel_sdvo_set_colorimetry(intel_sdvo, |
1030 | SDVO_COLORIMETRY_RGB256); | ||
1031 | intel_sdvo_set_avi_infoframe(intel_sdvo); | ||
1032 | } else | ||
1033 | intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI); | ||
1030 | 1034 | ||
1031 | if (intel_sdvo->is_tv && | 1035 | if (intel_sdvo->is_tv && |
1032 | !intel_sdvo_set_tv_format(intel_sdvo)) | 1036 | !intel_sdvo_set_tv_format(intel_sdvo)) |
@@ -1398,6 +1402,9 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1398 | 1402 | ||
1399 | intel_sdvo->attached_output = response; | 1403 | intel_sdvo->attached_output = response; |
1400 | 1404 | ||
1405 | intel_sdvo->has_hdmi_monitor = false; | ||
1406 | intel_sdvo->has_hdmi_audio = false; | ||
1407 | |||
1401 | if ((intel_sdvo_connector->output_flag & response) == 0) | 1408 | if ((intel_sdvo_connector->output_flag & response) == 0) |
1402 | ret = connector_status_disconnected; | 1409 | ret = connector_status_disconnected; |
1403 | else if (response & SDVO_TMDS_MASK) | 1410 | else if (response & SDVO_TMDS_MASK) |
@@ -1922,20 +1929,7 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, | |||
1922 | static bool | 1929 | static bool |
1923 | intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device) | 1930 | intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device) |
1924 | { | 1931 | { |
1925 | int is_hdmi; | 1932 | return intel_sdvo_check_supp_encode(intel_sdvo); |
1926 | |||
1927 | if (!intel_sdvo_check_supp_encode(intel_sdvo)) | ||
1928 | return false; | ||
1929 | |||
1930 | if (!intel_sdvo_set_target_output(intel_sdvo, | ||
1931 | device == 0 ? SDVO_OUTPUT_TMDS0 : SDVO_OUTPUT_TMDS1)) | ||
1932 | return false; | ||
1933 | |||
1934 | is_hdmi = 0; | ||
1935 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, &is_hdmi, 1)) | ||
1936 | return false; | ||
1937 | |||
1938 | return !!is_hdmi; | ||
1939 | } | 1933 | } |
1940 | 1934 | ||
1941 | static u8 | 1935 | static u8 |
@@ -2037,12 +2031,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2037 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | 2031 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; |
2038 | 2032 | ||
2039 | if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { | 2033 | if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { |
2040 | /* enable hdmi encoding mode if supported */ | ||
2041 | intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); | ||
2042 | intel_sdvo_set_colorimetry(intel_sdvo, | ||
2043 | SDVO_COLORIMETRY_RGB256); | ||
2044 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2034 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2045 | |||
2046 | intel_sdvo->is_hdmi = true; | 2035 | intel_sdvo->is_hdmi = true; |
2047 | } | 2036 | } |
2048 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2037 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index b14c8111057..d3a9c6e0247 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c | |||
@@ -59,7 +59,7 @@ static int nv40_set_intensity(struct backlight_device *bd) | |||
59 | return 0; | 59 | return 0; |
60 | } | 60 | } |
61 | 61 | ||
62 | static struct backlight_ops nv40_bl_ops = { | 62 | static const struct backlight_ops nv40_bl_ops = { |
63 | .options = BL_CORE_SUSPENDRESUME, | 63 | .options = BL_CORE_SUSPENDRESUME, |
64 | .get_brightness = nv40_get_intensity, | 64 | .get_brightness = nv40_get_intensity, |
65 | .update_status = nv40_set_intensity, | 65 | .update_status = nv40_set_intensity, |
@@ -82,7 +82,7 @@ static int nv50_set_intensity(struct backlight_device *bd) | |||
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | static struct backlight_ops nv50_bl_ops = { | 85 | static const struct backlight_ops nv50_bl_ops = { |
86 | .options = BL_CORE_SUSPENDRESUME, | 86 | .options = BL_CORE_SUSPENDRESUME, |
87 | .get_brightness = nv50_get_intensity, | 87 | .get_brightness = nv50_get_intensity, |
88 | .update_status = nv50_set_intensity, | 88 | .update_status = nv50_set_intensity, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index d3046559bf0..2aef5cd3acf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -1927,7 +1927,7 @@ init_ltime(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1927 | * offset (8 bit): opcode | 1927 | * offset (8 bit): opcode |
1928 | * offset + 1 (16 bit): time | 1928 | * offset + 1 (16 bit): time |
1929 | * | 1929 | * |
1930 | * Sleep for "time" miliseconds. | 1930 | * Sleep for "time" milliseconds. |
1931 | */ | 1931 | */ |
1932 | 1932 | ||
1933 | unsigned time = ROM16(bios->data[offset + 1]); | 1933 | unsigned time = ROM16(bios->data[offset + 1]); |
@@ -1935,7 +1935,7 @@ init_ltime(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1935 | if (!iexec->execute) | 1935 | if (!iexec->execute) |
1936 | return 3; | 1936 | return 3; |
1937 | 1937 | ||
1938 | BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X miliseconds\n", | 1938 | BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X milliseconds\n", |
1939 | offset, time); | 1939 | offset, time); |
1940 | 1940 | ||
1941 | msleep(time); | 1941 | msleep(time); |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 58a0cd02c0a..04b269d14a5 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
@@ -1629,7 +1629,7 @@ typedef struct _GET_ENGINE_CLOCK_PARAMETERS | |||
1629 | typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS | 1629 | typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS |
1630 | { | 1630 | { |
1631 | USHORT usPrescale; //Ratio between Engine clock and I2C clock | 1631 | USHORT usPrescale; //Ratio between Engine clock and I2C clock |
1632 | USHORT usVRAMAddress; //Adress in Frame Buffer where to pace raw EDID | 1632 | USHORT usVRAMAddress; //Address in Frame Buffer where to pace raw EDID |
1633 | USHORT usStatus; //When use output: lower byte EDID checksum, high byte hardware status | 1633 | USHORT usStatus; //When use output: lower byte EDID checksum, high byte hardware status |
1634 | //WHen use input: lower byte as 'byte to read':currently limited to 128byte or 1byte | 1634 | //WHen use input: lower byte as 'byte to read':currently limited to 128byte or 1byte |
1635 | UCHAR ucSlaveAddr; //Read from which slave | 1635 | UCHAR ucSlaveAddr; //Read from which slave |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index ffbc278647b..24cca2f69df 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -295,6 +295,23 @@ config HID_MONTEREY | |||
295 | ---help--- | 295 | ---help--- |
296 | Support for Monterey Genius KB29E. | 296 | Support for Monterey Genius KB29E. |
297 | 297 | ||
298 | config HID_MULTITOUCH | ||
299 | tristate "HID Multitouch panels" | ||
300 | depends on USB_HID | ||
301 | ---help--- | ||
302 | Generic support for HID multitouch panels. | ||
303 | |||
304 | Say Y here if you have one of the following devices: | ||
305 | - Cypress TrueTouch panels | ||
306 | - Hanvon dual touch panels | ||
307 | - Pixcir dual touch panels | ||
308 | - 'Sensing Win7-TwoFinger' panel by GeneralTouch | ||
309 | |||
310 | If unsure, say N. | ||
311 | |||
312 | To compile this driver as a module, choose M here: the | ||
313 | module will be called hid-multitouch. | ||
314 | |||
298 | config HID_NTRIG | 315 | config HID_NTRIG |
299 | tristate "N-Trig touch screen" | 316 | tristate "N-Trig touch screen" |
300 | depends on USB_HID | 317 | depends on USB_HID |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 6eae9a90b8d..6efc2a0370a 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -47,6 +47,7 @@ obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o | |||
47 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o | 47 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o |
48 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o | 48 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o |
49 | obj-$(CONFIG_HID_MOSART) += hid-mosart.o | 49 | obj-$(CONFIG_HID_MOSART) += hid-mosart.o |
50 | obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o | ||
50 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o | 51 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o |
51 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o | 52 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o |
52 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o | 53 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o |
diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c index 375b50929a5..1ea066c5520 100644 --- a/drivers/hid/hid-cando.c +++ b/drivers/hid/hid-cando.c | |||
@@ -236,6 +236,8 @@ static const struct hid_device_id cando_devices[] = { | |||
236 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 236 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, |
237 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | 237 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, |
238 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 238 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, |
239 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, | ||
240 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
239 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | 241 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, |
240 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 242 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, |
241 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | 243 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 261168607c9..d678cf3d33d 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1312,7 +1312,9 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1312 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1312 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
1313 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 1313 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
1314 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | 1314 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, |
1315 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, | ||
1315 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | 1316 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, |
1317 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, | ||
1316 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | 1318 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, |
1317 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | 1319 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, |
1318 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1320 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
@@ -1324,6 +1326,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1324 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, | 1326 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, |
1325 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, | 1327 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, |
1326 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, | 1328 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, |
1329 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, | ||
1327 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1330 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1328 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 1331 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
1329 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | 1332 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, |
@@ -1335,11 +1338,13 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1335 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1338 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1336 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1339 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
1337 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, | 1340 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, |
1341 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, | ||
1338 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, | 1342 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, |
1339 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, | 1343 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, |
1340 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1344 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
1341 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 1345 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
1342 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, | 1346 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, |
1347 | { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, | ||
1343 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1348 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
1344 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 1349 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
1345 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1350 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
@@ -1422,6 +1427,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1422 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 1427 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
1423 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, | 1428 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, |
1424 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, | 1429 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, |
1430 | { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | ||
1425 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) }, | 1431 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) }, |
1426 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, | 1432 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, |
1427 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, | 1433 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, |
@@ -1640,7 +1646,6 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
1640 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, | 1646 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, |
1641 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, | 1647 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, |
1642 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, | 1648 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, |
1643 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, | ||
1644 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, | 1649 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, |
1645 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, | 1650 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, |
1646 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, | 1651 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f65cace7772..92a0d61a737 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -140,7 +140,9 @@ | |||
140 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 | 140 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 |
141 | 141 | ||
142 | #define USB_VENDOR_ID_CANDO 0x2087 | 142 | #define USB_VENDOR_ID_CANDO 0x2087 |
143 | #define USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH 0x0703 | ||
143 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 | 144 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 |
145 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1 0x0a02 | ||
144 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 | 146 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 |
145 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01 | 147 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01 |
146 | 148 | ||
@@ -186,6 +188,7 @@ | |||
186 | #define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 | 188 | #define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 |
187 | #define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 | 189 | #define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 |
188 | #define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1 | 190 | #define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1 |
191 | #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 | ||
189 | 192 | ||
190 | #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 | 193 | #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 |
191 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a | 194 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a |
@@ -236,6 +239,7 @@ | |||
236 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 | 239 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 |
237 | 240 | ||
238 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc | 241 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc |
242 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0001 | ||
239 | 243 | ||
240 | #define USB_VENDOR_ID_GLAB 0x06c2 | 244 | #define USB_VENDOR_ID_GLAB 0x06c2 |
241 | #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 | 245 | #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 |
@@ -318,6 +322,9 @@ | |||
318 | #define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000 | 322 | #define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000 |
319 | #define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff | 323 | #define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff |
320 | 324 | ||
325 | #define USB_VENDOR_ID_HANVON 0x20b3 | ||
326 | #define USB_DEVICE_ID_HANVON_MULTITOUCH 0x0a18 | ||
327 | |||
321 | #define USB_VENDOR_ID_HAPP 0x078b | 328 | #define USB_VENDOR_ID_HAPP 0x078b |
322 | #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 | 329 | #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 |
323 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 | 330 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index e60fdb88101..7f552bfad32 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -290,6 +290,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
290 | goto ignore; | 290 | goto ignore; |
291 | } | 291 | } |
292 | 292 | ||
293 | if (field->report_type == HID_FEATURE_REPORT) { | ||
294 | if (device->driver->feature_mapping) { | ||
295 | device->driver->feature_mapping(device, hidinput, field, | ||
296 | usage); | ||
297 | } | ||
298 | goto ignore; | ||
299 | } | ||
300 | |||
293 | if (device->driver->input_mapping) { | 301 | if (device->driver->input_mapping) { |
294 | int ret = device->driver->input_mapping(device, hidinput, field, | 302 | int ret = device->driver->input_mapping(device, hidinput, field, |
295 | usage, &bit, &max); | 303 | usage, &bit, &max); |
@@ -839,7 +847,6 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
839 | struct hid_input *hidinput = NULL; | 847 | struct hid_input *hidinput = NULL; |
840 | struct input_dev *input_dev; | 848 | struct input_dev *input_dev; |
841 | int i, j, k; | 849 | int i, j, k; |
842 | int max_report_type = HID_OUTPUT_REPORT; | ||
843 | 850 | ||
844 | INIT_LIST_HEAD(&hid->inputs); | 851 | INIT_LIST_HEAD(&hid->inputs); |
845 | 852 | ||
@@ -856,10 +863,11 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
856 | return -1; | 863 | return -1; |
857 | } | 864 | } |
858 | 865 | ||
859 | if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) | 866 | for (k = HID_INPUT_REPORT; k <= HID_FEATURE_REPORT; k++) { |
860 | max_report_type = HID_INPUT_REPORT; | 867 | if (k == HID_OUTPUT_REPORT && |
868 | hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) | ||
869 | continue; | ||
861 | 870 | ||
862 | for (k = HID_INPUT_REPORT; k <= max_report_type; k++) | ||
863 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { | 871 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { |
864 | 872 | ||
865 | if (!report->maxfield) | 873 | if (!report->maxfield) |
@@ -912,6 +920,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
912 | hidinput = NULL; | 920 | hidinput = NULL; |
913 | } | 921 | } |
914 | } | 922 | } |
923 | } | ||
915 | 924 | ||
916 | if (hidinput && input_register_device(hidinput->input)) | 925 | if (hidinput && input_register_device(hidinput->input)) |
917 | goto out_cleanup; | 926 | goto out_cleanup; |
diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c index 9fb050ce6f0..aed7ffe3628 100644 --- a/drivers/hid/hid-mosart.c +++ b/drivers/hid/hid-mosart.c | |||
@@ -257,6 +257,7 @@ static void mosart_remove(struct hid_device *hdev) | |||
257 | static const struct hid_device_id mosart_devices[] = { | 257 | static const struct hid_device_id mosart_devices[] = { |
258 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, | 258 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, |
259 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | 259 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, |
260 | { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | ||
260 | { } | 261 | { } |
261 | }; | 262 | }; |
262 | MODULE_DEVICE_TABLE(hid, mosart_devices); | 263 | MODULE_DEVICE_TABLE(hid, mosart_devices); |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c new file mode 100644 index 00000000000..07d3183fdde --- /dev/null +++ b/drivers/hid/hid-multitouch.c | |||
@@ -0,0 +1,516 @@ | |||
1 | /* | ||
2 | * HID driver for multitouch panels | ||
3 | * | ||
4 | * Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr> | ||
5 | * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
6 | * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the Free | ||
13 | * Software Foundation; either version 2 of the License, or (at your option) | ||
14 | * any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/device.h> | ||
18 | #include <linux/hid.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/usb.h> | ||
22 | #include <linux/input/mt.h> | ||
23 | #include "usbhid/usbhid.h" | ||
24 | |||
25 | |||
26 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | ||
27 | MODULE_DESCRIPTION("HID multitouch panels"); | ||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | #include "hid-ids.h" | ||
31 | |||
32 | /* quirks to control the device */ | ||
33 | #define MT_QUIRK_NOT_SEEN_MEANS_UP (1 << 0) | ||
34 | #define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1) | ||
35 | #define MT_QUIRK_CYPRESS (1 << 2) | ||
36 | #define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3) | ||
37 | #define MT_QUIRK_VALID_IS_INRANGE (1 << 4) | ||
38 | #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) | ||
39 | |||
40 | struct mt_slot { | ||
41 | __s32 x, y, p, w, h; | ||
42 | __s32 contactid; /* the device ContactID assigned to this slot */ | ||
43 | bool touch_state; /* is the touch valid? */ | ||
44 | bool seen_in_this_frame;/* has this slot been updated */ | ||
45 | }; | ||
46 | |||
47 | struct mt_device { | ||
48 | struct mt_slot curdata; /* placeholder of incoming data */ | ||
49 | struct mt_class *mtclass; /* our mt device class */ | ||
50 | unsigned last_field_index; /* last field index of the report */ | ||
51 | unsigned last_slot_field; /* the last field of a slot */ | ||
52 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | ||
53 | __u8 num_received; /* how many contacts we received */ | ||
54 | __u8 num_expected; /* expected last contact index */ | ||
55 | bool curvalid; /* is the current contact valid? */ | ||
56 | struct mt_slot slots[0]; /* first slot */ | ||
57 | }; | ||
58 | |||
59 | struct mt_class { | ||
60 | __s32 name; /* MT_CLS */ | ||
61 | __s32 quirks; | ||
62 | __s32 sn_move; /* Signal/noise ratio for move events */ | ||
63 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ | ||
64 | __u8 maxcontacts; | ||
65 | }; | ||
66 | |||
67 | /* classes of device behavior */ | ||
68 | #define MT_CLS_DEFAULT 1 | ||
69 | #define MT_CLS_DUAL1 2 | ||
70 | #define MT_CLS_DUAL2 3 | ||
71 | #define MT_CLS_CYPRESS 4 | ||
72 | |||
73 | /* | ||
74 | * these device-dependent functions determine what slot corresponds | ||
75 | * to a valid contact that was just read. | ||
76 | */ | ||
77 | |||
78 | static int cypress_compute_slot(struct mt_device *td) | ||
79 | { | ||
80 | if (td->curdata.contactid != 0 || td->num_received == 0) | ||
81 | return td->curdata.contactid; | ||
82 | else | ||
83 | return -1; | ||
84 | } | ||
85 | |||
86 | static int find_slot_from_contactid(struct mt_device *td) | ||
87 | { | ||
88 | int i; | ||
89 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | ||
90 | if (td->slots[i].contactid == td->curdata.contactid && | ||
91 | td->slots[i].touch_state) | ||
92 | return i; | ||
93 | } | ||
94 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | ||
95 | if (!td->slots[i].seen_in_this_frame && | ||
96 | !td->slots[i].touch_state) | ||
97 | return i; | ||
98 | } | ||
99 | /* should not occurs. If this happens that means | ||
100 | * that the device sent more touches that it says | ||
101 | * in the report descriptor. It is ignored then. */ | ||
102 | return -1; | ||
103 | } | ||
104 | |||
105 | struct mt_class mt_classes[] = { | ||
106 | { .name = MT_CLS_DEFAULT, | ||
107 | .quirks = MT_QUIRK_VALID_IS_INRANGE, | ||
108 | .maxcontacts = 10 }, | ||
109 | { .name = MT_CLS_DUAL1, | ||
110 | .quirks = MT_QUIRK_VALID_IS_INRANGE | | ||
111 | MT_QUIRK_SLOT_IS_CONTACTID, | ||
112 | .maxcontacts = 2 }, | ||
113 | { .name = MT_CLS_DUAL2, | ||
114 | .quirks = MT_QUIRK_VALID_IS_INRANGE | | ||
115 | MT_QUIRK_SLOT_IS_CONTACTNUMBER, | ||
116 | .maxcontacts = 2 }, | ||
117 | { .name = MT_CLS_CYPRESS, | ||
118 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | | ||
119 | MT_QUIRK_CYPRESS, | ||
120 | .maxcontacts = 10 }, | ||
121 | |||
122 | { } | ||
123 | }; | ||
124 | |||
125 | static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
126 | struct hid_field *field, struct hid_usage *usage) | ||
127 | { | ||
128 | if (usage->hid == HID_DG_INPUTMODE) { | ||
129 | struct mt_device *td = hid_get_drvdata(hdev); | ||
130 | td->inputmode = field->report->id; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void set_abs(struct input_dev *input, unsigned int code, | ||
135 | struct hid_field *field, int snratio) | ||
136 | { | ||
137 | int fmin = field->logical_minimum; | ||
138 | int fmax = field->logical_maximum; | ||
139 | int fuzz = snratio ? (fmax - fmin) / snratio : 0; | ||
140 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); | ||
141 | } | ||
142 | |||
143 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
144 | struct hid_field *field, struct hid_usage *usage, | ||
145 | unsigned long **bit, int *max) | ||
146 | { | ||
147 | struct mt_device *td = hid_get_drvdata(hdev); | ||
148 | struct mt_class *cls = td->mtclass; | ||
149 | switch (usage->hid & HID_USAGE_PAGE) { | ||
150 | |||
151 | case HID_UP_GENDESK: | ||
152 | switch (usage->hid) { | ||
153 | case HID_GD_X: | ||
154 | hid_map_usage(hi, usage, bit, max, | ||
155 | EV_ABS, ABS_MT_POSITION_X); | ||
156 | set_abs(hi->input, ABS_MT_POSITION_X, field, | ||
157 | cls->sn_move); | ||
158 | /* touchscreen emulation */ | ||
159 | set_abs(hi->input, ABS_X, field, cls->sn_move); | ||
160 | td->last_slot_field = usage->hid; | ||
161 | return 1; | ||
162 | case HID_GD_Y: | ||
163 | hid_map_usage(hi, usage, bit, max, | ||
164 | EV_ABS, ABS_MT_POSITION_Y); | ||
165 | set_abs(hi->input, ABS_MT_POSITION_Y, field, | ||
166 | cls->sn_move); | ||
167 | /* touchscreen emulation */ | ||
168 | set_abs(hi->input, ABS_Y, field, cls->sn_move); | ||
169 | td->last_slot_field = usage->hid; | ||
170 | return 1; | ||
171 | } | ||
172 | return 0; | ||
173 | |||
174 | case HID_UP_DIGITIZER: | ||
175 | switch (usage->hid) { | ||
176 | case HID_DG_INRANGE: | ||
177 | td->last_slot_field = usage->hid; | ||
178 | return 1; | ||
179 | case HID_DG_CONFIDENCE: | ||
180 | td->last_slot_field = usage->hid; | ||
181 | return 1; | ||
182 | case HID_DG_TIPSWITCH: | ||
183 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | ||
184 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | ||
185 | td->last_slot_field = usage->hid; | ||
186 | return 1; | ||
187 | case HID_DG_CONTACTID: | ||
188 | input_mt_init_slots(hi->input, | ||
189 | td->mtclass->maxcontacts); | ||
190 | td->last_slot_field = usage->hid; | ||
191 | return 1; | ||
192 | case HID_DG_WIDTH: | ||
193 | hid_map_usage(hi, usage, bit, max, | ||
194 | EV_ABS, ABS_MT_TOUCH_MAJOR); | ||
195 | td->last_slot_field = usage->hid; | ||
196 | return 1; | ||
197 | case HID_DG_HEIGHT: | ||
198 | hid_map_usage(hi, usage, bit, max, | ||
199 | EV_ABS, ABS_MT_TOUCH_MINOR); | ||
200 | field->logical_maximum = 1; | ||
201 | field->logical_minimum = 0; | ||
202 | set_abs(hi->input, ABS_MT_ORIENTATION, field, 0); | ||
203 | td->last_slot_field = usage->hid; | ||
204 | return 1; | ||
205 | case HID_DG_TIPPRESSURE: | ||
206 | hid_map_usage(hi, usage, bit, max, | ||
207 | EV_ABS, ABS_MT_PRESSURE); | ||
208 | set_abs(hi->input, ABS_MT_PRESSURE, field, | ||
209 | cls->sn_pressure); | ||
210 | /* touchscreen emulation */ | ||
211 | set_abs(hi->input, ABS_PRESSURE, field, | ||
212 | cls->sn_pressure); | ||
213 | td->last_slot_field = usage->hid; | ||
214 | return 1; | ||
215 | case HID_DG_CONTACTCOUNT: | ||
216 | td->last_field_index = field->report->maxfield - 1; | ||
217 | return 1; | ||
218 | case HID_DG_CONTACTMAX: | ||
219 | /* we don't set td->last_slot_field as contactcount and | ||
220 | * contact max are global to the report */ | ||
221 | return -1; | ||
222 | } | ||
223 | /* let hid-input decide for the others */ | ||
224 | return 0; | ||
225 | |||
226 | case 0xff000000: | ||
227 | /* we do not want to map these: no input-oriented meaning */ | ||
228 | return -1; | ||
229 | } | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
235 | struct hid_field *field, struct hid_usage *usage, | ||
236 | unsigned long **bit, int *max) | ||
237 | { | ||
238 | if (usage->type == EV_KEY || usage->type == EV_ABS) | ||
239 | set_bit(usage->type, hi->input->evbit); | ||
240 | |||
241 | return -1; | ||
242 | } | ||
243 | |||
244 | static int mt_compute_slot(struct mt_device *td) | ||
245 | { | ||
246 | __s32 quirks = td->mtclass->quirks; | ||
247 | |||
248 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTID) | ||
249 | return td->curdata.contactid; | ||
250 | |||
251 | if (quirks & MT_QUIRK_CYPRESS) | ||
252 | return cypress_compute_slot(td); | ||
253 | |||
254 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) | ||
255 | return td->num_received; | ||
256 | |||
257 | return find_slot_from_contactid(td); | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * this function is called when a whole contact has been processed, | ||
262 | * so that it can assign it to a slot and store the data there | ||
263 | */ | ||
264 | static void mt_complete_slot(struct mt_device *td) | ||
265 | { | ||
266 | td->curdata.seen_in_this_frame = true; | ||
267 | if (td->curvalid) { | ||
268 | int slotnum = mt_compute_slot(td); | ||
269 | |||
270 | if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts) | ||
271 | td->slots[slotnum] = td->curdata; | ||
272 | } | ||
273 | td->num_received++; | ||
274 | } | ||
275 | |||
276 | |||
277 | /* | ||
278 | * this function is called when a whole packet has been received and processed, | ||
279 | * so that it can decide what to send to the input layer. | ||
280 | */ | ||
281 | static void mt_emit_event(struct mt_device *td, struct input_dev *input) | ||
282 | { | ||
283 | int i; | ||
284 | |||
285 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | ||
286 | struct mt_slot *s = &(td->slots[i]); | ||
287 | if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && | ||
288 | !s->seen_in_this_frame) { | ||
289 | s->touch_state = false; | ||
290 | } | ||
291 | |||
292 | input_mt_slot(input, i); | ||
293 | input_mt_report_slot_state(input, MT_TOOL_FINGER, | ||
294 | s->touch_state); | ||
295 | if (s->touch_state) { | ||
296 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); | ||
297 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); | ||
298 | input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); | ||
299 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w); | ||
300 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h); | ||
301 | } | ||
302 | s->seen_in_this_frame = false; | ||
303 | |||
304 | } | ||
305 | |||
306 | input_mt_report_pointer_emulation(input, true); | ||
307 | input_sync(input); | ||
308 | td->num_received = 0; | ||
309 | } | ||
310 | |||
311 | |||
312 | |||
313 | static int mt_event(struct hid_device *hid, struct hid_field *field, | ||
314 | struct hid_usage *usage, __s32 value) | ||
315 | { | ||
316 | struct mt_device *td = hid_get_drvdata(hid); | ||
317 | __s32 quirks = td->mtclass->quirks; | ||
318 | |||
319 | if (hid->claimed & HID_CLAIMED_INPUT) { | ||
320 | switch (usage->hid) { | ||
321 | case HID_DG_INRANGE: | ||
322 | if (quirks & MT_QUIRK_VALID_IS_INRANGE) | ||
323 | td->curvalid = value; | ||
324 | break; | ||
325 | case HID_DG_TIPSWITCH: | ||
326 | if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) | ||
327 | td->curvalid = value; | ||
328 | td->curdata.touch_state = value; | ||
329 | break; | ||
330 | case HID_DG_CONFIDENCE: | ||
331 | if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) | ||
332 | td->curvalid = value; | ||
333 | break; | ||
334 | case HID_DG_CONTACTID: | ||
335 | td->curdata.contactid = value; | ||
336 | break; | ||
337 | case HID_DG_TIPPRESSURE: | ||
338 | td->curdata.p = value; | ||
339 | break; | ||
340 | case HID_GD_X: | ||
341 | td->curdata.x = value; | ||
342 | break; | ||
343 | case HID_GD_Y: | ||
344 | td->curdata.y = value; | ||
345 | break; | ||
346 | case HID_DG_WIDTH: | ||
347 | td->curdata.w = value; | ||
348 | break; | ||
349 | case HID_DG_HEIGHT: | ||
350 | td->curdata.h = value; | ||
351 | break; | ||
352 | case HID_DG_CONTACTCOUNT: | ||
353 | /* | ||
354 | * Includes multi-packet support where subsequent | ||
355 | * packets are sent with zero contactcount. | ||
356 | */ | ||
357 | if (value) | ||
358 | td->num_expected = value; | ||
359 | break; | ||
360 | |||
361 | default: | ||
362 | /* fallback to the generic hidinput handling */ | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | if (usage->hid == td->last_slot_field) | ||
367 | mt_complete_slot(td); | ||
368 | |||
369 | if (field->index == td->last_field_index | ||
370 | && td->num_received >= td->num_expected) | ||
371 | mt_emit_event(td, field->hidinput->input); | ||
372 | |||
373 | } | ||
374 | |||
375 | /* we have handled the hidinput part, now remains hiddev */ | ||
376 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | ||
377 | hid->hiddev_hid_event(hid, field, usage, value); | ||
378 | |||
379 | return 1; | ||
380 | } | ||
381 | |||
382 | static void mt_set_input_mode(struct hid_device *hdev) | ||
383 | { | ||
384 | struct mt_device *td = hid_get_drvdata(hdev); | ||
385 | struct hid_report *r; | ||
386 | struct hid_report_enum *re; | ||
387 | |||
388 | if (td->inputmode < 0) | ||
389 | return; | ||
390 | |||
391 | re = &(hdev->report_enum[HID_FEATURE_REPORT]); | ||
392 | r = re->report_id_hash[td->inputmode]; | ||
393 | if (r) { | ||
394 | r->field[0]->value[0] = 0x02; | ||
395 | usbhid_submit_report(hdev, r, USB_DIR_OUT); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
400 | { | ||
401 | int ret, i; | ||
402 | struct mt_device *td; | ||
403 | struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ | ||
404 | |||
405 | for (i = 0; mt_classes[i].name ; i++) { | ||
406 | if (id->driver_data == mt_classes[i].name) { | ||
407 | mtclass = &(mt_classes[i]); | ||
408 | break; | ||
409 | } | ||
410 | } | ||
411 | |||
412 | /* This allows the driver to correctly support devices | ||
413 | * that emit events over several HID messages. | ||
414 | */ | ||
415 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | ||
416 | |||
417 | td = kzalloc(sizeof(struct mt_device) + | ||
418 | mtclass->maxcontacts * sizeof(struct mt_slot), | ||
419 | GFP_KERNEL); | ||
420 | if (!td) { | ||
421 | dev_err(&hdev->dev, "cannot allocate multitouch data\n"); | ||
422 | return -ENOMEM; | ||
423 | } | ||
424 | td->mtclass = mtclass; | ||
425 | td->inputmode = -1; | ||
426 | hid_set_drvdata(hdev, td); | ||
427 | |||
428 | ret = hid_parse(hdev); | ||
429 | if (ret != 0) | ||
430 | goto fail; | ||
431 | |||
432 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
433 | if (ret) | ||
434 | goto fail; | ||
435 | |||
436 | mt_set_input_mode(hdev); | ||
437 | |||
438 | return 0; | ||
439 | |||
440 | fail: | ||
441 | kfree(td); | ||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | #ifdef CONFIG_PM | ||
446 | static int mt_reset_resume(struct hid_device *hdev) | ||
447 | { | ||
448 | mt_set_input_mode(hdev); | ||
449 | return 0; | ||
450 | } | ||
451 | #endif | ||
452 | |||
453 | static void mt_remove(struct hid_device *hdev) | ||
454 | { | ||
455 | struct mt_device *td = hid_get_drvdata(hdev); | ||
456 | hid_hw_stop(hdev); | ||
457 | kfree(td); | ||
458 | hid_set_drvdata(hdev, NULL); | ||
459 | } | ||
460 | |||
461 | static const struct hid_device_id mt_devices[] = { | ||
462 | |||
463 | /* Cypress panel */ | ||
464 | { .driver_data = MT_CLS_CYPRESS, | ||
465 | HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, | ||
466 | USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, | ||
467 | |||
468 | /* GeneralTouch panel */ | ||
469 | { .driver_data = MT_CLS_DUAL2, | ||
470 | HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, | ||
471 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, | ||
472 | |||
473 | /* PixCir-based panels */ | ||
474 | { .driver_data = MT_CLS_DUAL1, | ||
475 | HID_USB_DEVICE(USB_VENDOR_ID_HANVON, | ||
476 | USB_DEVICE_ID_HANVON_MULTITOUCH) }, | ||
477 | { .driver_data = MT_CLS_DUAL1, | ||
478 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
479 | USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, | ||
480 | |||
481 | { } | ||
482 | }; | ||
483 | MODULE_DEVICE_TABLE(hid, mt_devices); | ||
484 | |||
485 | static const struct hid_usage_id mt_grabbed_usages[] = { | ||
486 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | ||
487 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | ||
488 | }; | ||
489 | |||
490 | static struct hid_driver mt_driver = { | ||
491 | .name = "hid-multitouch", | ||
492 | .id_table = mt_devices, | ||
493 | .probe = mt_probe, | ||
494 | .remove = mt_remove, | ||
495 | .input_mapping = mt_input_mapping, | ||
496 | .input_mapped = mt_input_mapped, | ||
497 | .feature_mapping = mt_feature_mapping, | ||
498 | .usage_table = mt_grabbed_usages, | ||
499 | .event = mt_event, | ||
500 | #ifdef CONFIG_PM | ||
501 | .reset_resume = mt_reset_resume, | ||
502 | #endif | ||
503 | }; | ||
504 | |||
505 | static int __init mt_init(void) | ||
506 | { | ||
507 | return hid_register_driver(&mt_driver); | ||
508 | } | ||
509 | |||
510 | static void __exit mt_exit(void) | ||
511 | { | ||
512 | hid_unregister_driver(&mt_driver); | ||
513 | } | ||
514 | |||
515 | module_init(mt_init); | ||
516 | module_exit(mt_exit); | ||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 76b9a149c7d..9a94b643ccd 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -35,7 +35,6 @@ static const struct hid_blacklist { | |||
35 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, | 35 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, |
36 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, | 36 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, |
37 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, | 37 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, |
38 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, | ||
39 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 38 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
40 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 39 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
41 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 40 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index bdc13d28b1e..35f00dae367 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -809,10 +809,10 @@ config SENSORS_DME1737 | |||
809 | will be called dme1737. | 809 | will be called dme1737. |
810 | 810 | ||
811 | config SENSORS_EMC1403 | 811 | config SENSORS_EMC1403 |
812 | tristate "SMSC EMC1403 thermal sensor" | 812 | tristate "SMSC EMC1403/23 thermal sensor" |
813 | depends on I2C | 813 | depends on I2C |
814 | help | 814 | help |
815 | If you say yes here you get support for the SMSC EMC1403 | 815 | If you say yes here you get support for the SMSC EMC1403/23 |
816 | temperature monitoring chip. | 816 | temperature monitoring chip. |
817 | 817 | ||
818 | Threshold values can be configured using sysfs. | 818 | Threshold values can be configured using sysfs. |
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 0727ad25079..9e234b981b8 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -20,7 +20,7 @@ | |||
20 | * Alarms 16-bit map of active alarms | 20 | * Alarms 16-bit map of active alarms |
21 | * Analog Out 0..1250 mV output | 21 | * Analog Out 0..1250 mV output |
22 | * | 22 | * |
23 | * Chassis Intrusion: clear CI latch with 'echo 1 > chassis_clear' | 23 | * Chassis Intrusion: clear CI latch with 'echo 0 > intrusion0_alarm' |
24 | * | 24 | * |
25 | * Test hardware: Intel SE440BX-2 desktop motherboard --Grant | 25 | * Test hardware: Intel SE440BX-2 desktop motherboard --Grant |
26 | * | 26 | * |
@@ -476,13 +476,16 @@ static ssize_t set_aout(struct device *dev, | |||
476 | static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); | 476 | static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); |
477 | 477 | ||
478 | /* chassis_clear */ | 478 | /* chassis_clear */ |
479 | static ssize_t chassis_clear(struct device *dev, | 479 | static ssize_t chassis_clear_legacy(struct device *dev, |
480 | struct device_attribute *attr, | 480 | struct device_attribute *attr, |
481 | const char *buf, size_t count) | 481 | const char *buf, size_t count) |
482 | { | 482 | { |
483 | struct i2c_client *client = to_i2c_client(dev); | 483 | struct i2c_client *client = to_i2c_client(dev); |
484 | unsigned long val = simple_strtol(buf, NULL, 10); | 484 | unsigned long val = simple_strtol(buf, NULL, 10); |
485 | 485 | ||
486 | dev_warn(dev, "Attribute chassis_clear is deprecated, " | ||
487 | "use intrusion0_alarm instead\n"); | ||
488 | |||
486 | if (val == 1) { | 489 | if (val == 1) { |
487 | i2c_smbus_write_byte_data(client, | 490 | i2c_smbus_write_byte_data(client, |
488 | ADM9240_REG_CHASSIS_CLEAR, 0x80); | 491 | ADM9240_REG_CHASSIS_CLEAR, 0x80); |
@@ -490,7 +493,29 @@ static ssize_t chassis_clear(struct device *dev, | |||
490 | } | 493 | } |
491 | return count; | 494 | return count; |
492 | } | 495 | } |
493 | static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear); | 496 | static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear_legacy); |
497 | |||
498 | static ssize_t chassis_clear(struct device *dev, | ||
499 | struct device_attribute *attr, | ||
500 | const char *buf, size_t count) | ||
501 | { | ||
502 | struct i2c_client *client = to_i2c_client(dev); | ||
503 | struct adm9240_data *data = i2c_get_clientdata(client); | ||
504 | unsigned long val; | ||
505 | |||
506 | if (strict_strtoul(buf, 10, &val) || val != 0) | ||
507 | return -EINVAL; | ||
508 | |||
509 | mutex_lock(&data->update_lock); | ||
510 | i2c_smbus_write_byte_data(client, ADM9240_REG_CHASSIS_CLEAR, 0x80); | ||
511 | data->valid = 0; /* Force cache refresh */ | ||
512 | mutex_unlock(&data->update_lock); | ||
513 | dev_dbg(&client->dev, "chassis intrusion latch cleared\n"); | ||
514 | |||
515 | return count; | ||
516 | } | ||
517 | static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, show_alarm, | ||
518 | chassis_clear, 12); | ||
494 | 519 | ||
495 | static struct attribute *adm9240_attributes[] = { | 520 | static struct attribute *adm9240_attributes[] = { |
496 | &sensor_dev_attr_in0_input.dev_attr.attr, | 521 | &sensor_dev_attr_in0_input.dev_attr.attr, |
@@ -532,6 +557,7 @@ static struct attribute *adm9240_attributes[] = { | |||
532 | &dev_attr_alarms.attr, | 557 | &dev_attr_alarms.attr, |
533 | &dev_attr_aout_output.attr, | 558 | &dev_attr_aout_output.attr, |
534 | &dev_attr_chassis_clear.attr, | 559 | &dev_attr_chassis_clear.attr, |
560 | &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, | ||
535 | &dev_attr_cpu0_vid.attr, | 561 | &dev_attr_cpu0_vid.attr, |
536 | NULL | 562 | NULL |
537 | }; | 563 | }; |
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index aac85f3aed5..c42c5a69a66 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | This driver is based on the lm75 and other lm_sensors/hwmon drivers | 5 | This driver is based on the lm75 and other lm_sensors/hwmon drivers |
6 | 6 | ||
7 | Written by Steve Hardy <steve@linuxrealtime.co.uk> | 7 | Written by Steve Hardy <shardy@redhat.com> |
8 | 8 | ||
9 | Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf | 9 | Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf |
10 | 10 | ||
@@ -271,7 +271,7 @@ static void __exit sensors_ads7828_exit(void) | |||
271 | i2c_del_driver(&ads7828_driver); | 271 | i2c_del_driver(&ads7828_driver); |
272 | } | 272 | } |
273 | 273 | ||
274 | MODULE_AUTHOR("Steve Hardy <steve@linuxrealtime.co.uk>"); | 274 | MODULE_AUTHOR("Steve Hardy <shardy@redhat.com>"); |
275 | MODULE_DESCRIPTION("ADS7828 driver"); | 275 | MODULE_DESCRIPTION("ADS7828 driver"); |
276 | MODULE_LICENSE("GPL"); | 276 | MODULE_LICENSE("GPL"); |
277 | 277 | ||
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index e9a610bfd0c..d9c59271391 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
@@ -77,12 +77,14 @@ enum chips { dme1737, sch5027, sch311x, sch5127 }; | |||
77 | * in4 +12V | 77 | * in4 +12V |
78 | * in5 VTR (+3.3V stby) | 78 | * in5 VTR (+3.3V stby) |
79 | * in6 Vbat | 79 | * in6 Vbat |
80 | * in7 Vtrip (sch5127 only) | ||
80 | * | 81 | * |
81 | * --------------------------------------------------------------------- */ | 82 | * --------------------------------------------------------------------- */ |
82 | 83 | ||
83 | /* Voltages (in) numbered 0-6 (ix) */ | 84 | /* Voltages (in) numbered 0-7 (ix) */ |
84 | #define DME1737_REG_IN(ix) ((ix) < 5 ? 0x20 + (ix) \ | 85 | #define DME1737_REG_IN(ix) ((ix) < 5 ? 0x20 + (ix) : \ |
85 | : 0x94 + (ix)) | 86 | (ix) < 7 ? 0x94 + (ix) : \ |
87 | 0x1f) | ||
86 | #define DME1737_REG_IN_MIN(ix) ((ix) < 5 ? 0x44 + (ix) * 2 \ | 88 | #define DME1737_REG_IN_MIN(ix) ((ix) < 5 ? 0x44 + (ix) * 2 \ |
87 | : 0x91 + (ix) * 2) | 89 | : 0x91 + (ix) * 2) |
88 | #define DME1737_REG_IN_MAX(ix) ((ix) < 5 ? 0x45 + (ix) * 2 \ | 90 | #define DME1737_REG_IN_MAX(ix) ((ix) < 5 ? 0x45 + (ix) * 2 \ |
@@ -101,10 +103,11 @@ enum chips { dme1737, sch5027, sch311x, sch5127 }; | |||
101 | * IN_TEMP_LSB(1) = [temp3, temp1] | 103 | * IN_TEMP_LSB(1) = [temp3, temp1] |
102 | * IN_TEMP_LSB(2) = [in4, temp2] | 104 | * IN_TEMP_LSB(2) = [in4, temp2] |
103 | * IN_TEMP_LSB(3) = [in3, in0] | 105 | * IN_TEMP_LSB(3) = [in3, in0] |
104 | * IN_TEMP_LSB(4) = [in2, in1] */ | 106 | * IN_TEMP_LSB(4) = [in2, in1] |
107 | * IN_TEMP_LSB(5) = [res, in7] */ | ||
105 | #define DME1737_REG_IN_TEMP_LSB(ix) (0x84 + (ix)) | 108 | #define DME1737_REG_IN_TEMP_LSB(ix) (0x84 + (ix)) |
106 | static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0}; | 109 | static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0, 5}; |
107 | static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4}; | 110 | static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4, 4}; |
108 | static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1}; | 111 | static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1}; |
109 | static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0}; | 112 | static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0}; |
110 | 113 | ||
@@ -145,7 +148,7 @@ static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0}; | |||
145 | #define DME1737_REG_ALARM1 0x41 | 148 | #define DME1737_REG_ALARM1 0x41 |
146 | #define DME1737_REG_ALARM2 0x42 | 149 | #define DME1737_REG_ALARM2 0x42 |
147 | #define DME1737_REG_ALARM3 0x83 | 150 | #define DME1737_REG_ALARM3 0x83 |
148 | static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17}; | 151 | static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17, 18}; |
149 | static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6}; | 152 | static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6}; |
150 | static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | 153 | static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; |
151 | 154 | ||
@@ -190,6 +193,7 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
190 | #define HAS_PWM_MIN (1 << 4) /* bit 4 */ | 193 | #define HAS_PWM_MIN (1 << 4) /* bit 4 */ |
191 | #define HAS_FAN(ix) (1 << ((ix) + 5)) /* bits 5-10 */ | 194 | #define HAS_FAN(ix) (1 << ((ix) + 5)) /* bits 5-10 */ |
192 | #define HAS_PWM(ix) (1 << ((ix) + 11)) /* bits 11-16 */ | 195 | #define HAS_PWM(ix) (1 << ((ix) + 11)) /* bits 11-16 */ |
196 | #define HAS_IN7 (1 << 17) /* bit 17 */ | ||
193 | 197 | ||
194 | /* --------------------------------------------------------------------- | 198 | /* --------------------------------------------------------------------- |
195 | * Data structures and manipulation thereof | 199 | * Data structures and manipulation thereof |
@@ -213,9 +217,9 @@ struct dme1737_data { | |||
213 | u32 has_features; | 217 | u32 has_features; |
214 | 218 | ||
215 | /* Register values */ | 219 | /* Register values */ |
216 | u16 in[7]; | 220 | u16 in[8]; |
217 | u8 in_min[7]; | 221 | u8 in_min[8]; |
218 | u8 in_max[7]; | 222 | u8 in_max[8]; |
219 | s16 temp[3]; | 223 | s16 temp[3]; |
220 | s8 temp_min[3]; | 224 | s8 temp_min[3]; |
221 | s8 temp_max[3]; | 225 | s8 temp_max[3]; |
@@ -247,7 +251,7 @@ static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, | |||
247 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, | 251 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, |
248 | 3300}; | 252 | 3300}; |
249 | static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300, | 253 | static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300, |
250 | 3300}; | 254 | 3300, 1500}; |
251 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ | 255 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ |
252 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ | 256 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ |
253 | (type) == sch5127 ? IN_NOMINAL_SCH5127 : \ | 257 | (type) == sch5127 ? IN_NOMINAL_SCH5127 : \ |
@@ -580,7 +584,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
580 | { | 584 | { |
581 | struct dme1737_data *data = dev_get_drvdata(dev); | 585 | struct dme1737_data *data = dev_get_drvdata(dev); |
582 | int ix; | 586 | int ix; |
583 | u8 lsb[5]; | 587 | u8 lsb[6]; |
584 | 588 | ||
585 | mutex_lock(&data->update_lock); | 589 | mutex_lock(&data->update_lock); |
586 | 590 | ||
@@ -603,6 +607,9 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
603 | /* Voltage inputs are stored as 16 bit values even | 607 | /* Voltage inputs are stored as 16 bit values even |
604 | * though they have only 12 bits resolution. This is | 608 | * though they have only 12 bits resolution. This is |
605 | * to make it consistent with the temp inputs. */ | 609 | * to make it consistent with the temp inputs. */ |
610 | if (ix == 7 && !(data->has_features & HAS_IN7)) { | ||
611 | continue; | ||
612 | } | ||
606 | data->in[ix] = dme1737_read(data, | 613 | data->in[ix] = dme1737_read(data, |
607 | DME1737_REG_IN(ix)) << 8; | 614 | DME1737_REG_IN(ix)) << 8; |
608 | data->in_min[ix] = dme1737_read(data, | 615 | data->in_min[ix] = dme1737_read(data, |
@@ -635,10 +642,16 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
635 | * which the registers are read (MSB first, then LSB) is | 642 | * which the registers are read (MSB first, then LSB) is |
636 | * important! */ | 643 | * important! */ |
637 | for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { | 644 | for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { |
645 | if (ix == 5 && !(data->has_features & HAS_IN7)) { | ||
646 | continue; | ||
647 | } | ||
638 | lsb[ix] = dme1737_read(data, | 648 | lsb[ix] = dme1737_read(data, |
639 | DME1737_REG_IN_TEMP_LSB(ix)); | 649 | DME1737_REG_IN_TEMP_LSB(ix)); |
640 | } | 650 | } |
641 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { | 651 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { |
652 | if (ix == 7 && !(data->has_features & HAS_IN7)) { | ||
653 | continue; | ||
654 | } | ||
642 | data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] << | 655 | data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] << |
643 | DME1737_REG_IN_LSB_SHL[ix]) & 0xf0; | 656 | DME1737_REG_IN_LSB_SHL[ix]) & 0xf0; |
644 | } | 657 | } |
@@ -762,7 +775,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
762 | 775 | ||
763 | /* --------------------------------------------------------------------- | 776 | /* --------------------------------------------------------------------- |
764 | * Voltage sysfs attributes | 777 | * Voltage sysfs attributes |
765 | * ix = [0-5] | 778 | * ix = [0-7] |
766 | * --------------------------------------------------------------------- */ | 779 | * --------------------------------------------------------------------- */ |
767 | 780 | ||
768 | #define SYS_IN_INPUT 0 | 781 | #define SYS_IN_INPUT 0 |
@@ -1439,7 +1452,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr, | |||
1439 | * Sysfs device attribute defines and structs | 1452 | * Sysfs device attribute defines and structs |
1440 | * --------------------------------------------------------------------- */ | 1453 | * --------------------------------------------------------------------- */ |
1441 | 1454 | ||
1442 | /* Voltages 0-6 */ | 1455 | /* Voltages 0-7 */ |
1443 | 1456 | ||
1444 | #define SENSOR_DEVICE_ATTR_IN(ix) \ | 1457 | #define SENSOR_DEVICE_ATTR_IN(ix) \ |
1445 | static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \ | 1458 | static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \ |
@@ -1458,6 +1471,7 @@ SENSOR_DEVICE_ATTR_IN(3); | |||
1458 | SENSOR_DEVICE_ATTR_IN(4); | 1471 | SENSOR_DEVICE_ATTR_IN(4); |
1459 | SENSOR_DEVICE_ATTR_IN(5); | 1472 | SENSOR_DEVICE_ATTR_IN(5); |
1460 | SENSOR_DEVICE_ATTR_IN(6); | 1473 | SENSOR_DEVICE_ATTR_IN(6); |
1474 | SENSOR_DEVICE_ATTR_IN(7); | ||
1461 | 1475 | ||
1462 | /* Temperatures 1-3 */ | 1476 | /* Temperatures 1-3 */ |
1463 | 1477 | ||
@@ -1576,7 +1590,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* for ISA devices */ | |||
1576 | * created unconditionally. The attributes that need modification of their | 1590 | * created unconditionally. The attributes that need modification of their |
1577 | * permissions are created read-only and write permissions are added or removed | 1591 | * permissions are created read-only and write permissions are added or removed |
1578 | * on the fly when required */ | 1592 | * on the fly when required */ |
1579 | static struct attribute *dme1737_attr[] ={ | 1593 | static struct attribute *dme1737_attr[] = { |
1580 | /* Voltages */ | 1594 | /* Voltages */ |
1581 | &sensor_dev_attr_in0_input.dev_attr.attr, | 1595 | &sensor_dev_attr_in0_input.dev_attr.attr, |
1582 | &sensor_dev_attr_in0_min.dev_attr.attr, | 1596 | &sensor_dev_attr_in0_min.dev_attr.attr, |
@@ -1681,7 +1695,7 @@ static const struct attribute_group dme1737_zone3_group = { | |||
1681 | }; | 1695 | }; |
1682 | 1696 | ||
1683 | 1697 | ||
1684 | /* The following struct holds temp zone hysteresis related attributes, which | 1698 | /* The following struct holds temp zone hysteresis related attributes, which |
1685 | * are not available in all chips. The following chips support them: | 1699 | * are not available in all chips. The following chips support them: |
1686 | * DME1737, SCH311x */ | 1700 | * DME1737, SCH311x */ |
1687 | static struct attribute *dme1737_zone_hyst_attr[] = { | 1701 | static struct attribute *dme1737_zone_hyst_attr[] = { |
@@ -1695,6 +1709,21 @@ static const struct attribute_group dme1737_zone_hyst_group = { | |||
1695 | .attrs = dme1737_zone_hyst_attr, | 1709 | .attrs = dme1737_zone_hyst_attr, |
1696 | }; | 1710 | }; |
1697 | 1711 | ||
1712 | /* The following struct holds voltage in7 related attributes, which | ||
1713 | * are not available in all chips. The following chips support them: | ||
1714 | * SCH5127 */ | ||
1715 | static struct attribute *dme1737_in7_attr[] = { | ||
1716 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
1717 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
1718 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
1719 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
1720 | NULL | ||
1721 | }; | ||
1722 | |||
1723 | static const struct attribute_group dme1737_in7_group = { | ||
1724 | .attrs = dme1737_in7_attr, | ||
1725 | }; | ||
1726 | |||
1698 | /* The following structs hold the PWM attributes, some of which are optional. | 1727 | /* The following structs hold the PWM attributes, some of which are optional. |
1699 | * Their creation depends on the chip configuration which is determined during | 1728 | * Their creation depends on the chip configuration which is determined during |
1700 | * module load. */ | 1729 | * module load. */ |
@@ -1986,6 +2015,9 @@ static void dme1737_remove_files(struct device *dev) | |||
1986 | if (data->has_features & HAS_ZONE_HYST) { | 2015 | if (data->has_features & HAS_ZONE_HYST) { |
1987 | sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group); | 2016 | sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group); |
1988 | } | 2017 | } |
2018 | if (data->has_features & HAS_IN7) { | ||
2019 | sysfs_remove_group(&dev->kobj, &dme1737_in7_group); | ||
2020 | } | ||
1989 | sysfs_remove_group(&dev->kobj, &dme1737_group); | 2021 | sysfs_remove_group(&dev->kobj, &dme1737_group); |
1990 | 2022 | ||
1991 | if (!data->client) { | 2023 | if (!data->client) { |
@@ -1999,43 +2031,58 @@ static int dme1737_create_files(struct device *dev) | |||
1999 | int err, ix; | 2031 | int err, ix; |
2000 | 2032 | ||
2001 | /* Create a name attribute for ISA devices */ | 2033 | /* Create a name attribute for ISA devices */ |
2002 | if (!data->client && | 2034 | if (!data->client) { |
2003 | (err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr))) { | 2035 | err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr); |
2004 | goto exit; | 2036 | if (err) { |
2037 | goto exit; | ||
2038 | } | ||
2005 | } | 2039 | } |
2006 | 2040 | ||
2007 | /* Create standard sysfs attributes */ | 2041 | /* Create standard sysfs attributes */ |
2008 | if ((err = sysfs_create_group(&dev->kobj, &dme1737_group))) { | 2042 | err = sysfs_create_group(&dev->kobj, &dme1737_group); |
2043 | if (err) { | ||
2009 | goto exit_remove; | 2044 | goto exit_remove; |
2010 | } | 2045 | } |
2011 | 2046 | ||
2012 | /* Create chip-dependent sysfs attributes */ | 2047 | /* Create chip-dependent sysfs attributes */ |
2013 | if ((data->has_features & HAS_TEMP_OFFSET) && | 2048 | if (data->has_features & HAS_TEMP_OFFSET) { |
2014 | (err = sysfs_create_group(&dev->kobj, | 2049 | err = sysfs_create_group(&dev->kobj, |
2015 | &dme1737_temp_offset_group))) { | 2050 | &dme1737_temp_offset_group); |
2016 | goto exit_remove; | 2051 | if (err) { |
2052 | goto exit_remove; | ||
2053 | } | ||
2017 | } | 2054 | } |
2018 | if ((data->has_features & HAS_VID) && | 2055 | if (data->has_features & HAS_VID) { |
2019 | (err = sysfs_create_group(&dev->kobj, | 2056 | err = sysfs_create_group(&dev->kobj, &dme1737_vid_group); |
2020 | &dme1737_vid_group))) { | 2057 | if (err) { |
2021 | goto exit_remove; | 2058 | goto exit_remove; |
2059 | } | ||
2022 | } | 2060 | } |
2023 | if ((data->has_features & HAS_ZONE3) && | 2061 | if (data->has_features & HAS_ZONE3) { |
2024 | (err = sysfs_create_group(&dev->kobj, | 2062 | err = sysfs_create_group(&dev->kobj, &dme1737_zone3_group); |
2025 | &dme1737_zone3_group))) { | 2063 | if (err) { |
2026 | goto exit_remove; | 2064 | goto exit_remove; |
2065 | } | ||
2027 | } | 2066 | } |
2028 | if ((data->has_features & HAS_ZONE_HYST) && | 2067 | if (data->has_features & HAS_ZONE_HYST) { |
2029 | (err = sysfs_create_group(&dev->kobj, | 2068 | err = sysfs_create_group(&dev->kobj, &dme1737_zone_hyst_group); |
2030 | &dme1737_zone_hyst_group))) { | 2069 | if (err) { |
2031 | goto exit_remove; | 2070 | goto exit_remove; |
2071 | } | ||
2072 | } | ||
2073 | if (data->has_features & HAS_IN7) { | ||
2074 | err = sysfs_create_group(&dev->kobj, &dme1737_in7_group); | ||
2075 | if (err) { | ||
2076 | goto exit_remove; | ||
2077 | } | ||
2032 | } | 2078 | } |
2033 | 2079 | ||
2034 | /* Create fan sysfs attributes */ | 2080 | /* Create fan sysfs attributes */ |
2035 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 2081 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
2036 | if (data->has_features & HAS_FAN(ix)) { | 2082 | if (data->has_features & HAS_FAN(ix)) { |
2037 | if ((err = sysfs_create_group(&dev->kobj, | 2083 | err = sysfs_create_group(&dev->kobj, |
2038 | &dme1737_fan_group[ix]))) { | 2084 | &dme1737_fan_group[ix]); |
2085 | if (err) { | ||
2039 | goto exit_remove; | 2086 | goto exit_remove; |
2040 | } | 2087 | } |
2041 | } | 2088 | } |
@@ -2044,14 +2091,17 @@ static int dme1737_create_files(struct device *dev) | |||
2044 | /* Create PWM sysfs attributes */ | 2091 | /* Create PWM sysfs attributes */ |
2045 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | 2092 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
2046 | if (data->has_features & HAS_PWM(ix)) { | 2093 | if (data->has_features & HAS_PWM(ix)) { |
2047 | if ((err = sysfs_create_group(&dev->kobj, | 2094 | err = sysfs_create_group(&dev->kobj, |
2048 | &dme1737_pwm_group[ix]))) { | 2095 | &dme1737_pwm_group[ix]); |
2096 | if (err) { | ||
2049 | goto exit_remove; | 2097 | goto exit_remove; |
2050 | } | 2098 | } |
2051 | if ((data->has_features & HAS_PWM_MIN) && ix < 3 && | 2099 | if ((data->has_features & HAS_PWM_MIN) && (ix < 3)) { |
2052 | (err = sysfs_create_file(&dev->kobj, | 2100 | err = sysfs_create_file(&dev->kobj, |
2053 | dme1737_auto_pwm_min_attr[ix]))) { | 2101 | dme1737_auto_pwm_min_attr[ix]); |
2054 | goto exit_remove; | 2102 | if (err) { |
2103 | goto exit_remove; | ||
2104 | } | ||
2055 | } | 2105 | } |
2056 | } | 2106 | } |
2057 | } | 2107 | } |
@@ -2188,7 +2238,7 @@ static int dme1737_init_device(struct device *dev) | |||
2188 | data->has_features |= HAS_ZONE3; | 2238 | data->has_features |= HAS_ZONE3; |
2189 | break; | 2239 | break; |
2190 | case sch5127: | 2240 | case sch5127: |
2191 | data->has_features |= HAS_FAN(2) | HAS_PWM(2); | 2241 | data->has_features |= HAS_FAN(2) | HAS_PWM(2) | HAS_IN7; |
2192 | break; | 2242 | break; |
2193 | default: | 2243 | default: |
2194 | break; | 2244 | break; |
@@ -2281,8 +2331,9 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
2281 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); | 2331 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); |
2282 | 2332 | ||
2283 | /* Get the base address of the runtime registers */ | 2333 | /* Get the base address of the runtime registers */ |
2284 | if (!(addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | | 2334 | addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | |
2285 | dme1737_sio_inb(sio_cip, 0x61))) { | 2335 | dme1737_sio_inb(sio_cip, 0x61); |
2336 | if (!addr) { | ||
2286 | err = -ENODEV; | 2337 | err = -ENODEV; |
2287 | goto exit; | 2338 | goto exit; |
2288 | } | 2339 | } |
@@ -2363,13 +2414,15 @@ static int dme1737_i2c_probe(struct i2c_client *client, | |||
2363 | mutex_init(&data->update_lock); | 2414 | mutex_init(&data->update_lock); |
2364 | 2415 | ||
2365 | /* Initialize the DME1737 chip */ | 2416 | /* Initialize the DME1737 chip */ |
2366 | if ((err = dme1737_init_device(dev))) { | 2417 | err = dme1737_init_device(dev); |
2418 | if (err) { | ||
2367 | dev_err(dev, "Failed to initialize device.\n"); | 2419 | dev_err(dev, "Failed to initialize device.\n"); |
2368 | goto exit_kfree; | 2420 | goto exit_kfree; |
2369 | } | 2421 | } |
2370 | 2422 | ||
2371 | /* Create sysfs files */ | 2423 | /* Create sysfs files */ |
2372 | if ((err = dme1737_create_files(dev))) { | 2424 | err = dme1737_create_files(dev); |
2425 | if (err) { | ||
2373 | dev_err(dev, "Failed to create sysfs files.\n"); | 2426 | dev_err(dev, "Failed to create sysfs files.\n"); |
2374 | goto exit_kfree; | 2427 | goto exit_kfree; |
2375 | } | 2428 | } |
@@ -2446,8 +2499,9 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) | |||
2446 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); | 2499 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); |
2447 | 2500 | ||
2448 | /* Get the base address of the runtime registers */ | 2501 | /* Get the base address of the runtime registers */ |
2449 | if (!(base_addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | | 2502 | base_addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | |
2450 | dme1737_sio_inb(sio_cip, 0x61))) { | 2503 | dme1737_sio_inb(sio_cip, 0x61); |
2504 | if (!base_addr) { | ||
2451 | pr_err("Base address not set\n"); | 2505 | pr_err("Base address not set\n"); |
2452 | err = -ENODEV; | 2506 | err = -ENODEV; |
2453 | goto exit; | 2507 | goto exit; |
@@ -2476,18 +2530,21 @@ static int __init dme1737_isa_device_add(unsigned short addr) | |||
2476 | if (err) | 2530 | if (err) |
2477 | goto exit; | 2531 | goto exit; |
2478 | 2532 | ||
2479 | if (!(pdev = platform_device_alloc("dme1737", addr))) { | 2533 | pdev = platform_device_alloc("dme1737", addr); |
2534 | if (!pdev) { | ||
2480 | pr_err("Failed to allocate device\n"); | 2535 | pr_err("Failed to allocate device\n"); |
2481 | err = -ENOMEM; | 2536 | err = -ENOMEM; |
2482 | goto exit; | 2537 | goto exit; |
2483 | } | 2538 | } |
2484 | 2539 | ||
2485 | if ((err = platform_device_add_resources(pdev, &res, 1))) { | 2540 | err = platform_device_add_resources(pdev, &res, 1); |
2541 | if (err) { | ||
2486 | pr_err("Failed to add device resource (err = %d)\n", err); | 2542 | pr_err("Failed to add device resource (err = %d)\n", err); |
2487 | goto exit_device_put; | 2543 | goto exit_device_put; |
2488 | } | 2544 | } |
2489 | 2545 | ||
2490 | if ((err = platform_device_add(pdev))) { | 2546 | err = platform_device_add(pdev); |
2547 | if (err) { | ||
2491 | pr_err("Failed to add device (err = %d)\n", err); | 2548 | pr_err("Failed to add device (err = %d)\n", err); |
2492 | goto exit_device_put; | 2549 | goto exit_device_put; |
2493 | } | 2550 | } |
@@ -2514,11 +2571,12 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) | |||
2514 | dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", | 2571 | dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", |
2515 | (unsigned short)res->start, | 2572 | (unsigned short)res->start, |
2516 | (unsigned short)res->start + DME1737_EXTENT - 1); | 2573 | (unsigned short)res->start + DME1737_EXTENT - 1); |
2517 | err = -EBUSY; | 2574 | err = -EBUSY; |
2518 | goto exit; | 2575 | goto exit; |
2519 | } | 2576 | } |
2520 | 2577 | ||
2521 | if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) { | 2578 | data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL); |
2579 | if (!data) { | ||
2522 | err = -ENOMEM; | 2580 | err = -ENOMEM; |
2523 | goto exit_release_region; | 2581 | goto exit_release_region; |
2524 | } | 2582 | } |
@@ -2565,13 +2623,15 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) | |||
2565 | data->type == sch5127 ? "SCH5127" : "SCH311x", data->addr); | 2623 | data->type == sch5127 ? "SCH5127" : "SCH311x", data->addr); |
2566 | 2624 | ||
2567 | /* Initialize the chip */ | 2625 | /* Initialize the chip */ |
2568 | if ((err = dme1737_init_device(dev))) { | 2626 | err = dme1737_init_device(dev); |
2627 | if (err) { | ||
2569 | dev_err(dev, "Failed to initialize device.\n"); | 2628 | dev_err(dev, "Failed to initialize device.\n"); |
2570 | goto exit_kfree; | 2629 | goto exit_kfree; |
2571 | } | 2630 | } |
2572 | 2631 | ||
2573 | /* Create sysfs files */ | 2632 | /* Create sysfs files */ |
2574 | if ((err = dme1737_create_files(dev))) { | 2633 | err = dme1737_create_files(dev); |
2634 | if (err) { | ||
2575 | dev_err(dev, "Failed to create sysfs files.\n"); | 2635 | dev_err(dev, "Failed to create sysfs files.\n"); |
2576 | goto exit_kfree; | 2636 | goto exit_kfree; |
2577 | } | 2637 | } |
@@ -2628,7 +2688,8 @@ static int __init dme1737_init(void) | |||
2628 | int err; | 2688 | int err; |
2629 | unsigned short addr; | 2689 | unsigned short addr; |
2630 | 2690 | ||
2631 | if ((err = i2c_add_driver(&dme1737_i2c_driver))) { | 2691 | err = i2c_add_driver(&dme1737_i2c_driver); |
2692 | if (err) { | ||
2632 | goto exit; | 2693 | goto exit; |
2633 | } | 2694 | } |
2634 | 2695 | ||
@@ -2641,12 +2702,14 @@ static int __init dme1737_init(void) | |||
2641 | return 0; | 2702 | return 0; |
2642 | } | 2703 | } |
2643 | 2704 | ||
2644 | if ((err = platform_driver_register(&dme1737_isa_driver))) { | 2705 | err = platform_driver_register(&dme1737_isa_driver); |
2706 | if (err) { | ||
2645 | goto exit_del_i2c_driver; | 2707 | goto exit_del_i2c_driver; |
2646 | } | 2708 | } |
2647 | 2709 | ||
2648 | /* Sets global pdev as a side effect */ | 2710 | /* Sets global pdev as a side effect */ |
2649 | if ((err = dme1737_isa_device_add(addr))) { | 2711 | err = dme1737_isa_device_add(addr); |
2712 | if (err) { | ||
2650 | goto exit_del_isa_driver; | 2713 | goto exit_del_isa_driver; |
2651 | } | 2714 | } |
2652 | 2715 | ||
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 8dee3f38fdf..5dea9faa165 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c | |||
@@ -269,23 +269,30 @@ static int emc1403_detect(struct i2c_client *client, | |||
269 | struct i2c_board_info *info) | 269 | struct i2c_board_info *info) |
270 | { | 270 | { |
271 | int id; | 271 | int id; |
272 | /* Check if thermal chip is SMSC and EMC1403 */ | 272 | /* Check if thermal chip is SMSC and EMC1403 or EMC1423 */ |
273 | 273 | ||
274 | id = i2c_smbus_read_byte_data(client, THERMAL_SMSC_ID_REG); | 274 | id = i2c_smbus_read_byte_data(client, THERMAL_SMSC_ID_REG); |
275 | if (id != 0x5d) | 275 | if (id != 0x5d) |
276 | return -ENODEV; | 276 | return -ENODEV; |
277 | 277 | ||
278 | id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG); | ||
279 | switch (id) { | ||
280 | case 0x21: | ||
281 | strlcpy(info->type, "emc1403", I2C_NAME_SIZE); | ||
282 | break; | ||
283 | case 0x23: | ||
284 | strlcpy(info->type, "emc1423", I2C_NAME_SIZE); | ||
285 | break; | ||
278 | /* Note: 0x25 is the 1404 which is very similar and this | 286 | /* Note: 0x25 is the 1404 which is very similar and this |
279 | driver could be extended */ | 287 | driver could be extended */ |
280 | id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG); | 288 | default: |
281 | if (id != 0x21) | ||
282 | return -ENODEV; | 289 | return -ENODEV; |
290 | } | ||
283 | 291 | ||
284 | id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG); | 292 | id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG); |
285 | if (id != 0x01) | 293 | if (id != 0x01) |
286 | return -ENODEV; | 294 | return -ENODEV; |
287 | 295 | ||
288 | strlcpy(info->type, "emc1403", I2C_NAME_SIZE); | ||
289 | return 0; | 296 | return 0; |
290 | } | 297 | } |
291 | 298 | ||
@@ -342,6 +349,7 @@ static const unsigned short emc1403_address_list[] = { | |||
342 | 349 | ||
343 | static const struct i2c_device_id emc1403_idtable[] = { | 350 | static const struct i2c_device_id emc1403_idtable[] = { |
344 | { "emc1403", 0 }, | 351 | { "emc1403", 0 }, |
352 | { "emc1423", 0 }, | ||
345 | { } | 353 | { } |
346 | }; | 354 | }; |
347 | MODULE_DEVICE_TABLE(i2c, emc1403_idtable); | 355 | MODULE_DEVICE_TABLE(i2c, emc1403_idtable); |
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index d4d4ca65d37..aa6d8b686f8 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/kref.h> | 49 | #include <linux/kref.h> |
50 | 50 | ||
51 | /* Addresses to scan */ | 51 | /* Addresses to scan */ |
52 | static DEFINE_MUTEX(watchdog_mutex); | ||
53 | static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; | 52 | static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; |
54 | 53 | ||
55 | /* Insmod parameters */ | 54 | /* Insmod parameters */ |
@@ -850,7 +849,7 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf, | |||
850 | 849 | ||
851 | static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 850 | static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
852 | { | 851 | { |
853 | static struct watchdog_info ident = { | 852 | struct watchdog_info ident = { |
854 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | 853 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
855 | WDIOF_CARDRESET, | 854 | WDIOF_CARDRESET, |
856 | .identity = "FSC watchdog" | 855 | .identity = "FSC watchdog" |
@@ -858,7 +857,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long ar | |||
858 | int i, ret = 0; | 857 | int i, ret = 0; |
859 | struct fschmd_data *data = filp->private_data; | 858 | struct fschmd_data *data = filp->private_data; |
860 | 859 | ||
861 | mutex_lock(&watchdog_mutex); | ||
862 | switch (cmd) { | 860 | switch (cmd) { |
863 | case WDIOC_GETSUPPORT: | 861 | case WDIOC_GETSUPPORT: |
864 | ident.firmware_version = data->revision; | 862 | ident.firmware_version = data->revision; |
@@ -915,7 +913,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long ar | |||
915 | default: | 913 | default: |
916 | ret = -ENOTTY; | 914 | ret = -ENOTTY; |
917 | } | 915 | } |
918 | mutex_unlock(&watchdog_mutex); | ||
919 | return ret; | 916 | return ret; |
920 | } | 917 | } |
921 | 918 | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index a428a926419..316b64823f7 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -38,6 +38,8 @@ | |||
38 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 38 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
39 | */ | 39 | */ |
40 | 40 | ||
41 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
42 | |||
41 | #include <linux/module.h> | 43 | #include <linux/module.h> |
42 | #include <linux/init.h> | 44 | #include <linux/init.h> |
43 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
@@ -1570,26 +1572,25 @@ static int __init it87_find(unsigned short *address, | |||
1570 | case 0xffff: /* No device at all */ | 1572 | case 0xffff: /* No device at all */ |
1571 | goto exit; | 1573 | goto exit; |
1572 | default: | 1574 | default: |
1573 | pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n", | 1575 | pr_debug("Unsupported chip (DEVID=0x%x)\n", chip_type); |
1574 | chip_type); | ||
1575 | goto exit; | 1576 | goto exit; |
1576 | } | 1577 | } |
1577 | 1578 | ||
1578 | superio_select(PME); | 1579 | superio_select(PME); |
1579 | if (!(superio_inb(IT87_ACT_REG) & 0x01)) { | 1580 | if (!(superio_inb(IT87_ACT_REG) & 0x01)) { |
1580 | pr_info("it87: Device not activated, skipping\n"); | 1581 | pr_info("Device not activated, skipping\n"); |
1581 | goto exit; | 1582 | goto exit; |
1582 | } | 1583 | } |
1583 | 1584 | ||
1584 | *address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1); | 1585 | *address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1); |
1585 | if (*address == 0) { | 1586 | if (*address == 0) { |
1586 | pr_info("it87: Base address not set, skipping\n"); | 1587 | pr_info("Base address not set, skipping\n"); |
1587 | goto exit; | 1588 | goto exit; |
1588 | } | 1589 | } |
1589 | 1590 | ||
1590 | err = 0; | 1591 | err = 0; |
1591 | sio_data->revision = superio_inb(DEVREV) & 0x0f; | 1592 | sio_data->revision = superio_inb(DEVREV) & 0x0f; |
1592 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", | 1593 | pr_info("Found IT%04xF chip at 0x%x, revision %d\n", |
1593 | chip_type, *address, sio_data->revision); | 1594 | chip_type, *address, sio_data->revision); |
1594 | 1595 | ||
1595 | /* in8 (Vbat) is always internal */ | 1596 | /* in8 (Vbat) is always internal */ |
@@ -1615,7 +1616,7 @@ static int __init it87_find(unsigned short *address, | |||
1615 | } else { | 1616 | } else { |
1616 | /* We need at least 4 VID pins */ | 1617 | /* We need at least 4 VID pins */ |
1617 | if (reg & 0x0f) { | 1618 | if (reg & 0x0f) { |
1618 | pr_info("it87: VID is disabled (pins used for GPIO)\n"); | 1619 | pr_info("VID is disabled (pins used for GPIO)\n"); |
1619 | sio_data->skip_vid = 1; | 1620 | sio_data->skip_vid = 1; |
1620 | } | 1621 | } |
1621 | } | 1622 | } |
@@ -1651,7 +1652,7 @@ static int __init it87_find(unsigned short *address, | |||
1651 | if (sio_data->type == it8720 && !(reg & (1 << 1))) { | 1652 | if (sio_data->type == it8720 && !(reg & (1 << 1))) { |
1652 | reg |= (1 << 1); | 1653 | reg |= (1 << 1); |
1653 | superio_outb(IT87_SIO_PINX2_REG, reg); | 1654 | superio_outb(IT87_SIO_PINX2_REG, reg); |
1654 | pr_notice("it87: Routing internal VCCH to in7\n"); | 1655 | pr_notice("Routing internal VCCH to in7\n"); |
1655 | } | 1656 | } |
1656 | if (reg & (1 << 0)) | 1657 | if (reg & (1 << 0)) |
1657 | sio_data->internal |= (1 << 0); | 1658 | sio_data->internal |= (1 << 0); |
@@ -1661,7 +1662,7 @@ static int __init it87_find(unsigned short *address, | |||
1661 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 1662 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; |
1662 | } | 1663 | } |
1663 | if (sio_data->beep_pin) | 1664 | if (sio_data->beep_pin) |
1664 | pr_info("it87: Beeping is supported\n"); | 1665 | pr_info("Beeping is supported\n"); |
1665 | 1666 | ||
1666 | /* Disable specific features based on DMI strings */ | 1667 | /* Disable specific features based on DMI strings */ |
1667 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | 1668 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); |
@@ -1675,8 +1676,7 @@ static int __init it87_find(unsigned short *address, | |||
1675 | the PWM2 duty cycle, so we disable it. | 1676 | the PWM2 duty cycle, so we disable it. |
1676 | I use the board name string as the trigger in case | 1677 | I use the board name string as the trigger in case |
1677 | the same board is ever used in other systems. */ | 1678 | the same board is ever used in other systems. */ |
1678 | pr_info("it87: Disabling pwm2 due to " | 1679 | pr_info("Disabling pwm2 due to hardware constraints\n"); |
1679 | "hardware constraints\n"); | ||
1680 | sio_data->skip_pwm = (1 << 1); | 1680 | sio_data->skip_pwm = (1 << 1); |
1681 | } | 1681 | } |
1682 | } | 1682 | } |
@@ -2189,28 +2189,26 @@ static int __init it87_device_add(unsigned short address, | |||
2189 | pdev = platform_device_alloc(DRVNAME, address); | 2189 | pdev = platform_device_alloc(DRVNAME, address); |
2190 | if (!pdev) { | 2190 | if (!pdev) { |
2191 | err = -ENOMEM; | 2191 | err = -ENOMEM; |
2192 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | 2192 | pr_err("Device allocation failed\n"); |
2193 | goto exit; | 2193 | goto exit; |
2194 | } | 2194 | } |
2195 | 2195 | ||
2196 | err = platform_device_add_resources(pdev, &res, 1); | 2196 | err = platform_device_add_resources(pdev, &res, 1); |
2197 | if (err) { | 2197 | if (err) { |
2198 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | 2198 | pr_err("Device resource addition failed (%d)\n", err); |
2199 | "(%d)\n", err); | ||
2200 | goto exit_device_put; | 2199 | goto exit_device_put; |
2201 | } | 2200 | } |
2202 | 2201 | ||
2203 | err = platform_device_add_data(pdev, sio_data, | 2202 | err = platform_device_add_data(pdev, sio_data, |
2204 | sizeof(struct it87_sio_data)); | 2203 | sizeof(struct it87_sio_data)); |
2205 | if (err) { | 2204 | if (err) { |
2206 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | 2205 | pr_err("Platform data allocation failed\n"); |
2207 | goto exit_device_put; | 2206 | goto exit_device_put; |
2208 | } | 2207 | } |
2209 | 2208 | ||
2210 | err = platform_device_add(pdev); | 2209 | err = platform_device_add(pdev); |
2211 | if (err) { | 2210 | if (err) { |
2212 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | 2211 | pr_err("Device addition failed (%d)\n", err); |
2213 | err); | ||
2214 | goto exit_device_put; | 2212 | goto exit_device_put; |
2215 | } | 2213 | } |
2216 | 2214 | ||
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 72ff2c4e757..4cb24eafe31 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -19,6 +19,8 @@ | |||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/init.h> | 25 | #include <linux/init.h> |
24 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
@@ -858,7 +860,7 @@ static int __init lm78_isa_found(unsigned short address) | |||
858 | * individually for the probing phase. */ | 860 | * individually for the probing phase. */ |
859 | for (port = address; port < address + LM78_EXTENT; port++) { | 861 | for (port = address; port < address + LM78_EXTENT; port++) { |
860 | if (!request_region(port, 1, "lm78")) { | 862 | if (!request_region(port, 1, "lm78")) { |
861 | pr_debug("lm78: Failed to request port 0x%x\n", port); | 863 | pr_debug("Failed to request port 0x%x\n", port); |
862 | goto release; | 864 | goto release; |
863 | } | 865 | } |
864 | } | 866 | } |
@@ -920,7 +922,7 @@ static int __init lm78_isa_found(unsigned short address) | |||
920 | found = 1; | 922 | found = 1; |
921 | 923 | ||
922 | if (found) | 924 | if (found) |
923 | pr_info("lm78: Found an %s chip at %#x\n", | 925 | pr_info("Found an %s chip at %#x\n", |
924 | val & 0x80 ? "LM79" : "LM78", (int)address); | 926 | val & 0x80 ? "LM79" : "LM78", (int)address); |
925 | 927 | ||
926 | release: | 928 | release: |
@@ -942,21 +944,19 @@ static int __init lm78_isa_device_add(unsigned short address) | |||
942 | pdev = platform_device_alloc("lm78", address); | 944 | pdev = platform_device_alloc("lm78", address); |
943 | if (!pdev) { | 945 | if (!pdev) { |
944 | err = -ENOMEM; | 946 | err = -ENOMEM; |
945 | printk(KERN_ERR "lm78: Device allocation failed\n"); | 947 | pr_err("Device allocation failed\n"); |
946 | goto exit; | 948 | goto exit; |
947 | } | 949 | } |
948 | 950 | ||
949 | err = platform_device_add_resources(pdev, &res, 1); | 951 | err = platform_device_add_resources(pdev, &res, 1); |
950 | if (err) { | 952 | if (err) { |
951 | printk(KERN_ERR "lm78: Device resource addition failed " | 953 | pr_err("Device resource addition failed (%d)\n", err); |
952 | "(%d)\n", err); | ||
953 | goto exit_device_put; | 954 | goto exit_device_put; |
954 | } | 955 | } |
955 | 956 | ||
956 | err = platform_device_add(pdev); | 957 | err = platform_device_add(pdev); |
957 | if (err) { | 958 | if (err) { |
958 | printk(KERN_ERR "lm78: Device addition failed (%d)\n", | 959 | pr_err("Device addition failed (%d)\n", err); |
959 | err); | ||
960 | goto exit_device_put; | 960 | goto exit_device_put; |
961 | } | 961 | } |
962 | 962 | ||
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 68e69a49633..3d99b8854d7 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -33,6 +33,8 @@ | |||
33 | * the standard Super-I/O addresses is used (0x2E/0x2F or 0x4E/0x4F). | 33 | * the standard Super-I/O addresses is used (0x2E/0x2F or 0x4E/0x4F). |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
37 | |||
36 | #include <linux/module.h> | 38 | #include <linux/module.h> |
37 | #include <linux/init.h> | 39 | #include <linux/init.h> |
38 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
@@ -1031,16 +1033,15 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses | |||
1031 | 1033 | ||
1032 | val = superio_inb(sioaddr, ACT); | 1034 | val = superio_inb(sioaddr, ACT); |
1033 | if (!(val & 0x01)) { | 1035 | if (!(val & 0x01)) { |
1034 | printk(KERN_INFO "pc87360: Device 0x%02x not " | 1036 | pr_info("Device 0x%02x not activated\n", logdev[i]); |
1035 | "activated\n", logdev[i]); | ||
1036 | continue; | 1037 | continue; |
1037 | } | 1038 | } |
1038 | 1039 | ||
1039 | val = (superio_inb(sioaddr, BASE) << 8) | 1040 | val = (superio_inb(sioaddr, BASE) << 8) |
1040 | | superio_inb(sioaddr, BASE + 1); | 1041 | | superio_inb(sioaddr, BASE + 1); |
1041 | if (!val) { | 1042 | if (!val) { |
1042 | printk(KERN_INFO "pc87360: Base address not set for " | 1043 | pr_info("Base address not set for device 0x%02x\n", |
1043 | "device 0x%02x\n", logdev[i]); | 1044 | logdev[i]); |
1044 | continue; | 1045 | continue; |
1045 | } | 1046 | } |
1046 | 1047 | ||
@@ -1050,17 +1051,15 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses | |||
1050 | confreg[0] = superio_inb(sioaddr, 0xF0); | 1051 | confreg[0] = superio_inb(sioaddr, 0xF0); |
1051 | confreg[1] = superio_inb(sioaddr, 0xF1); | 1052 | confreg[1] = superio_inb(sioaddr, 0xF1); |
1052 | 1053 | ||
1053 | #ifdef DEBUG | 1054 | pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 1, |
1054 | printk(KERN_DEBUG "pc87360: Fan 1: mon=%d " | 1055 | (confreg[0] >> 2) & 1, (confreg[0] >> 3) & 1, |
1055 | "ctrl=%d inv=%d\n", (confreg[0]>>2)&1, | 1056 | (confreg[0] >> 4) & 1); |
1056 | (confreg[0]>>3)&1, (confreg[0]>>4)&1); | 1057 | pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 2, |
1057 | printk(KERN_DEBUG "pc87360: Fan 2: mon=%d " | 1058 | (confreg[0] >> 5) & 1, (confreg[0] >> 6) & 1, |
1058 | "ctrl=%d inv=%d\n", (confreg[0]>>5)&1, | 1059 | (confreg[0] >> 7) & 1); |
1059 | (confreg[0]>>6)&1, (confreg[0]>>7)&1); | 1060 | pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 3, |
1060 | printk(KERN_DEBUG "pc87360: Fan 3: mon=%d " | 1061 | confreg[1] & 1, (confreg[1] >> 1) & 1, |
1061 | "ctrl=%d inv=%d\n", confreg[1]&1, | 1062 | (confreg[1] >> 2) & 1); |
1062 | (confreg[1]>>1)&1, (confreg[1]>>2)&1); | ||
1063 | #endif | ||
1064 | } else if (i==1) { /* Voltages */ | 1063 | } else if (i==1) { /* Voltages */ |
1065 | /* Are we using thermistors? */ | 1064 | /* Are we using thermistors? */ |
1066 | if (*devid == 0xE9) { /* PC87366 */ | 1065 | if (*devid == 0xE9) { /* PC87366 */ |
@@ -1071,14 +1070,12 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses | |||
1071 | confreg[3] = superio_inb(sioaddr, 0x25); | 1070 | confreg[3] = superio_inb(sioaddr, 0x25); |
1072 | 1071 | ||
1073 | if (confreg[2] & 0x40) { | 1072 | if (confreg[2] & 0x40) { |
1074 | printk(KERN_INFO "pc87360: Using " | 1073 | pr_info("Using thermistors for " |
1075 | "thermistors for temperature " | 1074 | "temperature monitoring\n"); |
1076 | "monitoring\n"); | ||
1077 | } | 1075 | } |
1078 | if (confreg[3] & 0xE0) { | 1076 | if (confreg[3] & 0xE0) { |
1079 | printk(KERN_INFO "pc87360: VID " | 1077 | pr_info("VID inputs routed (mode %u)\n", |
1080 | "inputs routed (mode %u)\n", | 1078 | confreg[3] >> 5); |
1081 | confreg[3] >> 5); | ||
1082 | } | 1079 | } |
1083 | } | 1080 | } |
1084 | } | 1081 | } |
@@ -1616,7 +1613,7 @@ static int __init pc87360_device_add(unsigned short address) | |||
1616 | pdev = platform_device_alloc("pc87360", address); | 1613 | pdev = platform_device_alloc("pc87360", address); |
1617 | if (!pdev) { | 1614 | if (!pdev) { |
1618 | err = -ENOMEM; | 1615 | err = -ENOMEM; |
1619 | printk(KERN_ERR "pc87360: Device allocation failed\n"); | 1616 | pr_err("Device allocation failed\n"); |
1620 | goto exit; | 1617 | goto exit; |
1621 | } | 1618 | } |
1622 | 1619 | ||
@@ -1639,15 +1636,13 @@ static int __init pc87360_device_add(unsigned short address) | |||
1639 | 1636 | ||
1640 | err = platform_device_add_resources(pdev, res, res_count); | 1637 | err = platform_device_add_resources(pdev, res, res_count); |
1641 | if (err) { | 1638 | if (err) { |
1642 | printk(KERN_ERR "pc87360: Device resources addition failed " | 1639 | pr_err("Device resources addition failed (%d)\n", err); |
1643 | "(%d)\n", err); | ||
1644 | goto exit_device_put; | 1640 | goto exit_device_put; |
1645 | } | 1641 | } |
1646 | 1642 | ||
1647 | err = platform_device_add(pdev); | 1643 | err = platform_device_add(pdev); |
1648 | if (err) { | 1644 | if (err) { |
1649 | printk(KERN_ERR "pc87360: Device addition failed (%d)\n", | 1645 | pr_err("Device addition failed (%d)\n", err); |
1650 | err); | ||
1651 | goto exit_device_put; | 1646 | goto exit_device_put; |
1652 | } | 1647 | } |
1653 | 1648 | ||
@@ -1666,8 +1661,7 @@ static int __init pc87360_init(void) | |||
1666 | 1661 | ||
1667 | if (pc87360_find(0x2e, &devid, extra_isa) | 1662 | if (pc87360_find(0x2e, &devid, extra_isa) |
1668 | && pc87360_find(0x4e, &devid, extra_isa)) { | 1663 | && pc87360_find(0x4e, &devid, extra_isa)) { |
1669 | printk(KERN_WARNING "pc87360: PC8736x not detected, " | 1664 | pr_warn("PC8736x not detected, module not inserted\n"); |
1670 | "module not inserted.\n"); | ||
1671 | return -ENODEV; | 1665 | return -ENODEV; |
1672 | } | 1666 | } |
1673 | 1667 | ||
@@ -1680,8 +1674,7 @@ static int __init pc87360_init(void) | |||
1680 | } | 1674 | } |
1681 | 1675 | ||
1682 | if (address == 0x0000) { | 1676 | if (address == 0x0000) { |
1683 | printk(KERN_WARNING "pc87360: No active logical device, " | 1677 | pr_warn("No active logical device, module not inserted\n"); |
1684 | "module not inserted.\n"); | ||
1685 | return -ENODEV; | 1678 | return -ENODEV; |
1686 | } | 1679 | } |
1687 | 1680 | ||
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 9ec4daaf6ca..8da2181630b 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c | |||
@@ -22,6 +22,8 @@ | |||
22 | * mode, and voltages aren't supported at all. | 22 | * mode, and voltages aren't supported at all. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
26 | |||
25 | #include <linux/module.h> | 27 | #include <linux/module.h> |
26 | #include <linux/init.h> | 28 | #include <linux/init.h> |
27 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
@@ -1077,7 +1079,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev) | |||
1077 | data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL); | 1079 | data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL); |
1078 | if (!data) { | 1080 | if (!data) { |
1079 | err = -ENOMEM; | 1081 | err = -ENOMEM; |
1080 | printk(KERN_ERR DRVNAME ": Out of memory\n"); | 1082 | pr_err("Out of memory\n"); |
1081 | goto exit; | 1083 | goto exit; |
1082 | } | 1084 | } |
1083 | 1085 | ||
@@ -1196,28 +1198,26 @@ static int __init pc87427_device_add(const struct pc87427_sio_data *sio_data) | |||
1196 | pdev = platform_device_alloc(DRVNAME, res[0].start); | 1198 | pdev = platform_device_alloc(DRVNAME, res[0].start); |
1197 | if (!pdev) { | 1199 | if (!pdev) { |
1198 | err = -ENOMEM; | 1200 | err = -ENOMEM; |
1199 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | 1201 | pr_err("Device allocation failed\n"); |
1200 | goto exit; | 1202 | goto exit; |
1201 | } | 1203 | } |
1202 | 1204 | ||
1203 | err = platform_device_add_resources(pdev, res, res_count); | 1205 | err = platform_device_add_resources(pdev, res, res_count); |
1204 | if (err) { | 1206 | if (err) { |
1205 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | 1207 | pr_err("Device resource addition failed (%d)\n", err); |
1206 | "(%d)\n", err); | ||
1207 | goto exit_device_put; | 1208 | goto exit_device_put; |
1208 | } | 1209 | } |
1209 | 1210 | ||
1210 | err = platform_device_add_data(pdev, sio_data, | 1211 | err = platform_device_add_data(pdev, sio_data, |
1211 | sizeof(struct pc87427_sio_data)); | 1212 | sizeof(struct pc87427_sio_data)); |
1212 | if (err) { | 1213 | if (err) { |
1213 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | 1214 | pr_err("Platform data allocation failed\n"); |
1214 | goto exit_device_put; | 1215 | goto exit_device_put; |
1215 | } | 1216 | } |
1216 | 1217 | ||
1217 | err = platform_device_add(pdev); | 1218 | err = platform_device_add(pdev); |
1218 | if (err) { | 1219 | if (err) { |
1219 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | 1220 | pr_err("Device addition failed (%d)\n", err); |
1220 | err); | ||
1221 | goto exit_device_put; | 1221 | goto exit_device_put; |
1222 | } | 1222 | } |
1223 | 1223 | ||
@@ -1249,23 +1249,23 @@ static int __init pc87427_find(int sioaddr, struct pc87427_sio_data *sio_data) | |||
1249 | 1249 | ||
1250 | val = superio_inb(sioaddr, SIOREG_ACT); | 1250 | val = superio_inb(sioaddr, SIOREG_ACT); |
1251 | if (!(val & 0x01)) { | 1251 | if (!(val & 0x01)) { |
1252 | printk(KERN_INFO DRVNAME ": Logical device 0x%02x " | 1252 | pr_info("Logical device 0x%02x not activated\n", |
1253 | "not activated\n", logdev[i]); | 1253 | logdev[i]); |
1254 | continue; | 1254 | continue; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | val = superio_inb(sioaddr, SIOREG_MAP); | 1257 | val = superio_inb(sioaddr, SIOREG_MAP); |
1258 | if (val & 0x01) { | 1258 | if (val & 0x01) { |
1259 | printk(KERN_WARNING DRVNAME ": Logical device 0x%02x " | 1259 | pr_warn("Logical device 0x%02x is memory-mapped, " |
1260 | "is memory-mapped, can't use\n", logdev[i]); | 1260 | "can't use\n", logdev[i]); |
1261 | continue; | 1261 | continue; |
1262 | } | 1262 | } |
1263 | 1263 | ||
1264 | val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8) | 1264 | val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8) |
1265 | | superio_inb(sioaddr, SIOREG_IOBASE + 1); | 1265 | | superio_inb(sioaddr, SIOREG_IOBASE + 1); |
1266 | if (!val) { | 1266 | if (!val) { |
1267 | printk(KERN_INFO DRVNAME ": I/O base address not set " | 1267 | pr_info("I/O base address not set for logical device " |
1268 | "for logical device 0x%02x\n", logdev[i]); | 1268 | "0x%02x\n", logdev[i]); |
1269 | continue; | 1269 | continue; |
1270 | } | 1270 | } |
1271 | sio_data->address[i] = val; | 1271 | sio_data->address[i] = val; |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 13e8d218e49..25e91665a0a 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -689,6 +689,13 @@ static int __devexit via686a_remove(struct platform_device *pdev) | |||
689 | return 0; | 689 | return 0; |
690 | } | 690 | } |
691 | 691 | ||
692 | static void via686a_update_fan_div(struct via686a_data *data) | ||
693 | { | ||
694 | int reg = via686a_read_value(data, VIA686A_REG_FANDIV); | ||
695 | data->fan_div[0] = (reg >> 4) & 0x03; | ||
696 | data->fan_div[1] = reg >> 6; | ||
697 | } | ||
698 | |||
692 | static void __devinit via686a_init_device(struct via686a_data *data) | 699 | static void __devinit via686a_init_device(struct via686a_data *data) |
693 | { | 700 | { |
694 | u8 reg; | 701 | u8 reg; |
@@ -702,6 +709,9 @@ static void __devinit via686a_init_device(struct via686a_data *data) | |||
702 | via686a_write_value(data, VIA686A_REG_TEMP_MODE, | 709 | via686a_write_value(data, VIA686A_REG_TEMP_MODE, |
703 | (reg & ~VIA686A_TEMP_MODE_MASK) | 710 | (reg & ~VIA686A_TEMP_MODE_MASK) |
704 | | VIA686A_TEMP_MODE_CONTINUOUS); | 711 | | VIA686A_TEMP_MODE_CONTINUOUS); |
712 | |||
713 | /* Pre-read fan clock divisor values */ | ||
714 | via686a_update_fan_div(data); | ||
705 | } | 715 | } |
706 | 716 | ||
707 | static struct via686a_data *via686a_update_device(struct device *dev) | 717 | static struct via686a_data *via686a_update_device(struct device *dev) |
@@ -753,9 +763,7 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
753 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & | 763 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
754 | 0xc0) >> 6; | 764 | 0xc0) >> 6; |
755 | 765 | ||
756 | i = via686a_read_value(data, VIA686A_REG_FANDIV); | 766 | via686a_update_fan_div(data); |
757 | data->fan_div[0] = (i >> 4) & 0x03; | ||
758 | data->fan_div[1] = i >> 6; | ||
759 | data->alarms = | 767 | data->alarms = |
760 | via686a_read_value(data, | 768 | via686a_read_value(data, |
761 | VIA686A_REG_ALARM1) | | 769 | VIA686A_REG_ALARM1) | |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index c84b9b4e696..eed43a008be 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -33,6 +33,8 @@ | |||
33 | 33 | ||
34 | */ | 34 | */ |
35 | 35 | ||
36 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
37 | |||
36 | #include <linux/module.h> | 38 | #include <linux/module.h> |
37 | #include <linux/init.h> | 39 | #include <linux/init.h> |
38 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
@@ -1798,8 +1800,7 @@ w83781d_isa_found(unsigned short address) | |||
1798 | * individually for the probing phase. */ | 1800 | * individually for the probing phase. */ |
1799 | for (port = address; port < address + W83781D_EXTENT; port++) { | 1801 | for (port = address; port < address + W83781D_EXTENT; port++) { |
1800 | if (!request_region(port, 1, "w83781d")) { | 1802 | if (!request_region(port, 1, "w83781d")) { |
1801 | pr_debug("w83781d: Failed to request port 0x%x\n", | 1803 | pr_debug("Failed to request port 0x%x\n", port); |
1802 | port); | ||
1803 | goto release; | 1804 | goto release; |
1804 | } | 1805 | } |
1805 | } | 1806 | } |
@@ -1811,7 +1812,7 @@ w83781d_isa_found(unsigned short address) | |||
1811 | if (inb_p(address + 2) != val | 1812 | if (inb_p(address + 2) != val |
1812 | || inb_p(address + 3) != val | 1813 | || inb_p(address + 3) != val |
1813 | || inb_p(address + 7) != val) { | 1814 | || inb_p(address + 7) != val) { |
1814 | pr_debug("w83781d: Detection failed at step 1\n"); | 1815 | pr_debug("Detection failed at step %d\n", 1); |
1815 | goto release; | 1816 | goto release; |
1816 | } | 1817 | } |
1817 | #undef REALLY_SLOW_IO | 1818 | #undef REALLY_SLOW_IO |
@@ -1820,14 +1821,14 @@ w83781d_isa_found(unsigned short address) | |||
1820 | MSB (busy flag) should be clear initially, set after the write. */ | 1821 | MSB (busy flag) should be clear initially, set after the write. */ |
1821 | save = inb_p(address + W83781D_ADDR_REG_OFFSET); | 1822 | save = inb_p(address + W83781D_ADDR_REG_OFFSET); |
1822 | if (save & 0x80) { | 1823 | if (save & 0x80) { |
1823 | pr_debug("w83781d: Detection failed at step 2\n"); | 1824 | pr_debug("Detection failed at step %d\n", 2); |
1824 | goto release; | 1825 | goto release; |
1825 | } | 1826 | } |
1826 | val = ~save & 0x7f; | 1827 | val = ~save & 0x7f; |
1827 | outb_p(val, address + W83781D_ADDR_REG_OFFSET); | 1828 | outb_p(val, address + W83781D_ADDR_REG_OFFSET); |
1828 | if (inb_p(address + W83781D_ADDR_REG_OFFSET) != (val | 0x80)) { | 1829 | if (inb_p(address + W83781D_ADDR_REG_OFFSET) != (val | 0x80)) { |
1829 | outb_p(save, address + W83781D_ADDR_REG_OFFSET); | 1830 | outb_p(save, address + W83781D_ADDR_REG_OFFSET); |
1830 | pr_debug("w83781d: Detection failed at step 3\n"); | 1831 | pr_debug("Detection failed at step %d\n", 3); |
1831 | goto release; | 1832 | goto release; |
1832 | } | 1833 | } |
1833 | 1834 | ||
@@ -1835,7 +1836,7 @@ w83781d_isa_found(unsigned short address) | |||
1835 | outb_p(W83781D_REG_CONFIG, address + W83781D_ADDR_REG_OFFSET); | 1836 | outb_p(W83781D_REG_CONFIG, address + W83781D_ADDR_REG_OFFSET); |
1836 | val = inb_p(address + W83781D_DATA_REG_OFFSET); | 1837 | val = inb_p(address + W83781D_DATA_REG_OFFSET); |
1837 | if (val & 0x80) { | 1838 | if (val & 0x80) { |
1838 | pr_debug("w83781d: Detection failed at step 4\n"); | 1839 | pr_debug("Detection failed at step %d\n", 4); |
1839 | goto release; | 1840 | goto release; |
1840 | } | 1841 | } |
1841 | outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET); | 1842 | outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET); |
@@ -1844,19 +1845,19 @@ w83781d_isa_found(unsigned short address) | |||
1844 | val = inb_p(address + W83781D_DATA_REG_OFFSET); | 1845 | val = inb_p(address + W83781D_DATA_REG_OFFSET); |
1845 | if ((!(save & 0x80) && (val != 0xa3)) | 1846 | if ((!(save & 0x80) && (val != 0xa3)) |
1846 | || ((save & 0x80) && (val != 0x5c))) { | 1847 | || ((save & 0x80) && (val != 0x5c))) { |
1847 | pr_debug("w83781d: Detection failed at step 5\n"); | 1848 | pr_debug("Detection failed at step %d\n", 5); |
1848 | goto release; | 1849 | goto release; |
1849 | } | 1850 | } |
1850 | outb_p(W83781D_REG_I2C_ADDR, address + W83781D_ADDR_REG_OFFSET); | 1851 | outb_p(W83781D_REG_I2C_ADDR, address + W83781D_ADDR_REG_OFFSET); |
1851 | val = inb_p(address + W83781D_DATA_REG_OFFSET); | 1852 | val = inb_p(address + W83781D_DATA_REG_OFFSET); |
1852 | if (val < 0x03 || val > 0x77) { /* Not a valid I2C address */ | 1853 | if (val < 0x03 || val > 0x77) { /* Not a valid I2C address */ |
1853 | pr_debug("w83781d: Detection failed at step 6\n"); | 1854 | pr_debug("Detection failed at step %d\n", 6); |
1854 | goto release; | 1855 | goto release; |
1855 | } | 1856 | } |
1856 | 1857 | ||
1857 | /* The busy flag should be clear again */ | 1858 | /* The busy flag should be clear again */ |
1858 | if (inb_p(address + W83781D_ADDR_REG_OFFSET) & 0x80) { | 1859 | if (inb_p(address + W83781D_ADDR_REG_OFFSET) & 0x80) { |
1859 | pr_debug("w83781d: Detection failed at step 7\n"); | 1860 | pr_debug("Detection failed at step %d\n", 7); |
1860 | goto release; | 1861 | goto release; |
1861 | } | 1862 | } |
1862 | 1863 | ||
@@ -1871,7 +1872,7 @@ w83781d_isa_found(unsigned short address) | |||
1871 | found = 1; | 1872 | found = 1; |
1872 | 1873 | ||
1873 | if (found) | 1874 | if (found) |
1874 | pr_info("w83781d: Found a %s chip at %#x\n", | 1875 | pr_info("Found a %s chip at %#x\n", |
1875 | val == 0x30 ? "W83782D" : "W83781D", (int)address); | 1876 | val == 0x30 ? "W83782D" : "W83781D", (int)address); |
1876 | 1877 | ||
1877 | release: | 1878 | release: |
@@ -1894,21 +1895,19 @@ w83781d_isa_device_add(unsigned short address) | |||
1894 | pdev = platform_device_alloc("w83781d", address); | 1895 | pdev = platform_device_alloc("w83781d", address); |
1895 | if (!pdev) { | 1896 | if (!pdev) { |
1896 | err = -ENOMEM; | 1897 | err = -ENOMEM; |
1897 | printk(KERN_ERR "w83781d: Device allocation failed\n"); | 1898 | pr_err("Device allocation failed\n"); |
1898 | goto exit; | 1899 | goto exit; |
1899 | } | 1900 | } |
1900 | 1901 | ||
1901 | err = platform_device_add_resources(pdev, &res, 1); | 1902 | err = platform_device_add_resources(pdev, &res, 1); |
1902 | if (err) { | 1903 | if (err) { |
1903 | printk(KERN_ERR "w83781d: Device resource addition failed " | 1904 | pr_err("Device resource addition failed (%d)\n", err); |
1904 | "(%d)\n", err); | ||
1905 | goto exit_device_put; | 1905 | goto exit_device_put; |
1906 | } | 1906 | } |
1907 | 1907 | ||
1908 | err = platform_device_add(pdev); | 1908 | err = platform_device_add(pdev); |
1909 | if (err) { | 1909 | if (err) { |
1910 | printk(KERN_ERR "w83781d: Device addition failed (%d)\n", | 1910 | pr_err("Device addition failed (%d)\n", err); |
1911 | err); | ||
1912 | goto exit_device_put; | 1911 | goto exit_device_put; |
1913 | } | 1912 | } |
1914 | 1913 | ||
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 679718e6b01..63841f8cec0 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -691,7 +691,7 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, | |||
691 | } | 691 | } |
692 | 692 | ||
693 | static ssize_t | 693 | static ssize_t |
694 | show_regs_chassis(struct device *dev, struct device_attribute *attr, | 694 | show_chassis(struct device *dev, struct device_attribute *attr, |
695 | char *buf) | 695 | char *buf) |
696 | { | 696 | { |
697 | struct w83792d_data *data = w83792d_update_device(dev); | 697 | struct w83792d_data *data = w83792d_update_device(dev); |
@@ -699,6 +699,16 @@ show_regs_chassis(struct device *dev, struct device_attribute *attr, | |||
699 | } | 699 | } |
700 | 700 | ||
701 | static ssize_t | 701 | static ssize_t |
702 | show_regs_chassis(struct device *dev, struct device_attribute *attr, | ||
703 | char *buf) | ||
704 | { | ||
705 | dev_warn(dev, | ||
706 | "Attribute %s is deprecated, use intrusion0_alarm instead\n", | ||
707 | "chassis"); | ||
708 | return show_chassis(dev, attr, buf); | ||
709 | } | ||
710 | |||
711 | static ssize_t | ||
702 | show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf) | 712 | show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf) |
703 | { | 713 | { |
704 | struct w83792d_data *data = w83792d_update_device(dev); | 714 | struct w83792d_data *data = w83792d_update_device(dev); |
@@ -706,7 +716,7 @@ show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf) | |||
706 | } | 716 | } |
707 | 717 | ||
708 | static ssize_t | 718 | static ssize_t |
709 | store_chassis_clear(struct device *dev, struct device_attribute *attr, | 719 | store_chassis_clear_legacy(struct device *dev, struct device_attribute *attr, |
710 | const char *buf, size_t count) | 720 | const char *buf, size_t count) |
711 | { | 721 | { |
712 | struct i2c_client *client = to_i2c_client(dev); | 722 | struct i2c_client *client = to_i2c_client(dev); |
@@ -714,6 +724,10 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr, | |||
714 | u32 val; | 724 | u32 val; |
715 | u8 temp1 = 0, temp2 = 0; | 725 | u8 temp1 = 0, temp2 = 0; |
716 | 726 | ||
727 | dev_warn(dev, | ||
728 | "Attribute %s is deprecated, use intrusion0_alarm instead\n", | ||
729 | "chassis_clear"); | ||
730 | |||
717 | val = simple_strtoul(buf, NULL, 10); | 731 | val = simple_strtoul(buf, NULL, 10); |
718 | mutex_lock(&data->update_lock); | 732 | mutex_lock(&data->update_lock); |
719 | data->chassis_clear = SENSORS_LIMIT(val, 0 ,1); | 733 | data->chassis_clear = SENSORS_LIMIT(val, 0 ,1); |
@@ -726,6 +740,27 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr, | |||
726 | return count; | 740 | return count; |
727 | } | 741 | } |
728 | 742 | ||
743 | static ssize_t | ||
744 | store_chassis_clear(struct device *dev, struct device_attribute *attr, | ||
745 | const char *buf, size_t count) | ||
746 | { | ||
747 | struct i2c_client *client = to_i2c_client(dev); | ||
748 | struct w83792d_data *data = i2c_get_clientdata(client); | ||
749 | unsigned long val; | ||
750 | u8 reg; | ||
751 | |||
752 | if (strict_strtoul(buf, 10, &val) || val != 0) | ||
753 | return -EINVAL; | ||
754 | |||
755 | mutex_lock(&data->update_lock); | ||
756 | reg = w83792d_read_value(client, W83792D_REG_CHASSIS_CLR); | ||
757 | w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, reg | 0x80); | ||
758 | data->valid = 0; /* Force cache refresh */ | ||
759 | mutex_unlock(&data->update_lock); | ||
760 | |||
761 | return count; | ||
762 | } | ||
763 | |||
729 | /* For Smart Fan I / Thermal Cruise */ | 764 | /* For Smart Fan I / Thermal Cruise */ |
730 | static ssize_t | 765 | static ssize_t |
731 | show_thermal_cruise(struct device *dev, struct device_attribute *attr, | 766 | show_thermal_cruise(struct device *dev, struct device_attribute *attr, |
@@ -1012,7 +1047,9 @@ static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22); | |||
1012 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 23); | 1047 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 23); |
1013 | static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); | 1048 | static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); |
1014 | static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, | 1049 | static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, |
1015 | show_chassis_clear, store_chassis_clear); | 1050 | show_chassis_clear, store_chassis_clear_legacy); |
1051 | static DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, | ||
1052 | show_chassis, store_chassis_clear); | ||
1016 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0); | 1053 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0); |
1017 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1); | 1054 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1); |
1018 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2); | 1055 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2); |
@@ -1214,6 +1251,7 @@ static struct attribute *w83792d_attributes[] = { | |||
1214 | &dev_attr_alarms.attr, | 1251 | &dev_attr_alarms.attr, |
1215 | &dev_attr_chassis.attr, | 1252 | &dev_attr_chassis.attr, |
1216 | &dev_attr_chassis_clear.attr, | 1253 | &dev_attr_chassis_clear.attr, |
1254 | &dev_attr_intrusion0_alarm.attr, | ||
1217 | &sensor_dev_attr_tolerance1.dev_attr.attr, | 1255 | &sensor_dev_attr_tolerance1.dev_attr.attr, |
1218 | &sensor_dev_attr_thermal_cruise1.dev_attr.attr, | 1256 | &sensor_dev_attr_thermal_cruise1.dev_attr.attr, |
1219 | &sensor_dev_attr_tolerance2.dev_attr.attr, | 1257 | &sensor_dev_attr_tolerance2.dev_attr.attr, |
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 8e540ada47d..e3bdedfb534 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */ | 51 | #define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */ |
52 | 52 | ||
53 | /* Addresses to scan */ | 53 | /* Addresses to scan */ |
54 | static DEFINE_MUTEX(watchdog_mutex); | ||
55 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, | 54 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, |
56 | I2C_CLIENT_END }; | 55 | I2C_CLIENT_END }; |
57 | 56 | ||
@@ -421,14 +420,17 @@ store_beep_enable(struct device *dev, struct device_attribute *attr, | |||
421 | 420 | ||
422 | /* Write any value to clear chassis alarm */ | 421 | /* Write any value to clear chassis alarm */ |
423 | static ssize_t | 422 | static ssize_t |
424 | store_chassis_clear(struct device *dev, | 423 | store_chassis_clear_legacy(struct device *dev, |
425 | struct device_attribute *attr, const char *buf, | 424 | struct device_attribute *attr, const char *buf, |
426 | size_t count) | 425 | size_t count) |
427 | { | 426 | { |
428 | struct i2c_client *client = to_i2c_client(dev); | 427 | struct i2c_client *client = to_i2c_client(dev); |
429 | struct w83793_data *data = i2c_get_clientdata(client); | 428 | struct w83793_data *data = i2c_get_clientdata(client); |
430 | u8 val; | 429 | u8 val; |
431 | 430 | ||
431 | dev_warn(dev, "Attribute chassis is deprecated, " | ||
432 | "use intrusion0_alarm instead\n"); | ||
433 | |||
432 | mutex_lock(&data->update_lock); | 434 | mutex_lock(&data->update_lock); |
433 | val = w83793_read_value(client, W83793_REG_CLR_CHASSIS); | 435 | val = w83793_read_value(client, W83793_REG_CLR_CHASSIS); |
434 | val |= 0x80; | 436 | val |= 0x80; |
@@ -437,6 +439,28 @@ store_chassis_clear(struct device *dev, | |||
437 | return count; | 439 | return count; |
438 | } | 440 | } |
439 | 441 | ||
442 | /* Write 0 to clear chassis alarm */ | ||
443 | static ssize_t | ||
444 | store_chassis_clear(struct device *dev, | ||
445 | struct device_attribute *attr, const char *buf, | ||
446 | size_t count) | ||
447 | { | ||
448 | struct i2c_client *client = to_i2c_client(dev); | ||
449 | struct w83793_data *data = i2c_get_clientdata(client); | ||
450 | unsigned long val; | ||
451 | u8 reg; | ||
452 | |||
453 | if (strict_strtoul(buf, 10, &val) || val != 0) | ||
454 | return -EINVAL; | ||
455 | |||
456 | mutex_lock(&data->update_lock); | ||
457 | reg = w83793_read_value(client, W83793_REG_CLR_CHASSIS); | ||
458 | w83793_write_value(client, W83793_REG_CLR_CHASSIS, reg | 0x80); | ||
459 | data->valid = 0; /* Force cache refresh */ | ||
460 | mutex_unlock(&data->update_lock); | ||
461 | return count; | ||
462 | } | ||
463 | |||
440 | #define FAN_INPUT 0 | 464 | #define FAN_INPUT 0 |
441 | #define FAN_MIN 1 | 465 | #define FAN_MIN 1 |
442 | static ssize_t | 466 | static ssize_t |
@@ -1102,6 +1126,8 @@ static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm); | |||
1102 | 1126 | ||
1103 | static struct sensor_device_attribute_2 sda_single_files[] = { | 1127 | static struct sensor_device_attribute_2 sda_single_files[] = { |
1104 | SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, | 1128 | SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, |
1129 | store_chassis_clear_legacy, ALARM_STATUS, 30), | ||
1130 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1105 | store_chassis_clear, ALARM_STATUS, 30), | 1131 | store_chassis_clear, ALARM_STATUS, 30), |
1106 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable, | 1132 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable, |
1107 | store_beep_enable, NOT_USED, NOT_USED), | 1133 | store_beep_enable, NOT_USED, NOT_USED), |
@@ -1323,7 +1349,7 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf, | |||
1323 | static long watchdog_ioctl(struct file *filp, unsigned int cmd, | 1349 | static long watchdog_ioctl(struct file *filp, unsigned int cmd, |
1324 | unsigned long arg) | 1350 | unsigned long arg) |
1325 | { | 1351 | { |
1326 | static struct watchdog_info ident = { | 1352 | struct watchdog_info ident = { |
1327 | .options = WDIOF_KEEPALIVEPING | | 1353 | .options = WDIOF_KEEPALIVEPING | |
1328 | WDIOF_SETTIMEOUT | | 1354 | WDIOF_SETTIMEOUT | |
1329 | WDIOF_CARDRESET, | 1355 | WDIOF_CARDRESET, |
@@ -1333,7 +1359,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, | |||
1333 | int val, ret = 0; | 1359 | int val, ret = 0; |
1334 | struct w83793_data *data = filp->private_data; | 1360 | struct w83793_data *data = filp->private_data; |
1335 | 1361 | ||
1336 | mutex_lock(&watchdog_mutex); | ||
1337 | switch (cmd) { | 1362 | switch (cmd) { |
1338 | case WDIOC_GETSUPPORT: | 1363 | case WDIOC_GETSUPPORT: |
1339 | if (!nowayout) | 1364 | if (!nowayout) |
@@ -1387,7 +1412,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, | |||
1387 | default: | 1412 | default: |
1388 | ret = -ENOTTY; | 1413 | ret = -ENOTTY; |
1389 | } | 1414 | } |
1390 | mutex_unlock(&watchdog_mutex); | ||
1391 | return ret; | 1415 | return ret; |
1392 | } | 1416 | } |
1393 | 1417 | ||
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index cdbc7448491..845232d7f61 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c | |||
@@ -458,6 +458,7 @@ static void w83795_update_limits(struct i2c_client *client) | |||
458 | { | 458 | { |
459 | struct w83795_data *data = i2c_get_clientdata(client); | 459 | struct w83795_data *data = i2c_get_clientdata(client); |
460 | int i, limit; | 460 | int i, limit; |
461 | u8 lsb; | ||
461 | 462 | ||
462 | /* Read the voltage limits */ | 463 | /* Read the voltage limits */ |
463 | for (i = 0; i < ARRAY_SIZE(data->in); i++) { | 464 | for (i = 0; i < ARRAY_SIZE(data->in); i++) { |
@@ -479,9 +480,8 @@ static void w83795_update_limits(struct i2c_client *client) | |||
479 | } | 480 | } |
480 | 481 | ||
481 | /* Read the fan limits */ | 482 | /* Read the fan limits */ |
483 | lsb = 0; /* Silent false gcc warning */ | ||
482 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { | 484 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { |
483 | u8 lsb; | ||
484 | |||
485 | /* Each register contains LSB for 2 fans, but we want to | 485 | /* Each register contains LSB for 2 fans, but we want to |
486 | * read it only once to save time */ | 486 | * read it only once to save time */ |
487 | if ((i & 1) == 0 && (data->has_fan & (3 << i))) | 487 | if ((i & 1) == 0 && (data->has_fan & (3 << i))) |
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index c9fffd0389f..2bd3469b307 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c | |||
@@ -434,7 +434,7 @@ static int read_i2c(struct nmk_i2c_dev *dev) | |||
434 | } | 434 | } |
435 | 435 | ||
436 | if (timeout == 0) { | 436 | if (timeout == 0) { |
437 | /* controler has timedout, re-init the h/w */ | 437 | /* controller has timedout, re-init the h/w */ |
438 | dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n"); | 438 | dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n"); |
439 | (void) init_hw(dev); | 439 | (void) init_hw(dev); |
440 | status = -ETIMEDOUT; | 440 | status = -ETIMEDOUT; |
@@ -498,7 +498,7 @@ static int write_i2c(struct nmk_i2c_dev *dev) | |||
498 | } | 498 | } |
499 | 499 | ||
500 | if (timeout == 0) { | 500 | if (timeout == 0) { |
501 | /* controler has timedout, re-init the h/w */ | 501 | /* controller has timedout, re-init the h/w */ |
502 | dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n"); | 502 | dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n"); |
503 | (void) init_hw(dev); | 503 | (void) init_hw(dev); |
504 | status = -ETIMEDOUT; | 504 | status = -ETIMEDOUT; |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index 4bb997aa39d..83d2e19d31a 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h | |||
@@ -689,7 +689,7 @@ struct t3_swrq { | |||
689 | * A T3 WQ implements both the SQ and RQ. | 689 | * A T3 WQ implements both the SQ and RQ. |
690 | */ | 690 | */ |
691 | struct t3_wq { | 691 | struct t3_wq { |
692 | union t3_wr *queue; /* DMA accessable memory */ | 692 | union t3_wr *queue; /* DMA accessible memory */ |
693 | dma_addr_t dma_addr; /* DMA address for HW */ | 693 | dma_addr_t dma_addr; /* DMA address for HW */ |
694 | DEFINE_DMA_UNMAP_ADDR(mapping); /* unmap kruft */ | 694 | DEFINE_DMA_UNMAP_ADDR(mapping); /* unmap kruft */ |
695 | u32 error; /* 1 once we go to ERROR */ | 695 | u32 error; /* 1 once we go to ERROR */ |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index cc600c2dd0b..2fe19ec9ba6 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/timer.h> | 46 | #include <linux/timer.h> |
47 | #include <linux/io.h> | 47 | #include <linux/io.h> |
48 | #include <linux/kfifo.h> | 48 | #include <linux/kfifo.h> |
49 | #include <linux/mutex.h> | ||
50 | 49 | ||
51 | #include <asm/byteorder.h> | 50 | #include <asm/byteorder.h> |
52 | 51 | ||
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index dbbb0e85afe..abd409d592e 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -332,7 +332,7 @@ MODULE_PARM_DESC(txselect, \ | |||
332 | #define krp_serdesctrl KREG_IBPORT_IDX(IBSerdesCtrl) | 332 | #define krp_serdesctrl KREG_IBPORT_IDX(IBSerdesCtrl) |
333 | 333 | ||
334 | /* | 334 | /* |
335 | * Per-context kernel registers. Acess only with qib_read_kreg_ctxt() | 335 | * Per-context kernel registers. Access only with qib_read_kreg_ctxt() |
336 | * or qib_write_kreg_ctxt() | 336 | * or qib_write_kreg_ctxt() |
337 | */ | 337 | */ |
338 | #define krc_rcvhdraddr KREG_IDX(RcvHdrAddr0) | 338 | #define krc_rcvhdraddr KREG_IDX(RcvHdrAddr0) |
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 5b596165b57..56eb471b557 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig | |||
@@ -255,6 +255,16 @@ config JOYSTICK_AMIGA | |||
255 | To compile this driver as a module, choose M here: the | 255 | To compile this driver as a module, choose M here: the |
256 | module will be called amijoy. | 256 | module will be called amijoy. |
257 | 257 | ||
258 | config JOYSTICK_AS5011 | ||
259 | tristate "Austria Microsystem AS5011 joystick" | ||
260 | depends on I2C | ||
261 | help | ||
262 | Say Y here if you have an AS5011 digital joystick connected to your | ||
263 | system. | ||
264 | |||
265 | To compile this driver as a module, choose M here: the | ||
266 | module will be called as5011. | ||
267 | |||
258 | config JOYSTICK_JOYDUMP | 268 | config JOYSTICK_JOYDUMP |
259 | tristate "Gameport data dumper" | 269 | tristate "Gameport data dumper" |
260 | select GAMEPORT | 270 | select GAMEPORT |
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile index f3a8cbe2abb..92dc0de9dfe 100644 --- a/drivers/input/joystick/Makefile +++ b/drivers/input/joystick/Makefile | |||
@@ -7,6 +7,7 @@ | |||
7 | obj-$(CONFIG_JOYSTICK_A3D) += a3d.o | 7 | obj-$(CONFIG_JOYSTICK_A3D) += a3d.o |
8 | obj-$(CONFIG_JOYSTICK_ADI) += adi.o | 8 | obj-$(CONFIG_JOYSTICK_ADI) += adi.o |
9 | obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o | 9 | obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o |
10 | obj-$(CONFIG_JOYSTICK_AS5011) += as5011.o | ||
10 | obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o | 11 | obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o |
11 | obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o | 12 | obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o |
12 | obj-$(CONFIG_JOYSTICK_DB9) += db9.o | 13 | obj-$(CONFIG_JOYSTICK_DB9) += db9.o |
diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c new file mode 100644 index 00000000000..f6732b57ca0 --- /dev/null +++ b/drivers/input/joystick/as5011.c | |||
@@ -0,0 +1,367 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com> | ||
3 | * Sponsored by ARMadeus Systems | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | * Driver for Austria Microsystems joysticks AS5011 | ||
20 | * | ||
21 | * TODO: | ||
22 | * - Power on the chip when open() and power down when close() | ||
23 | * - Manage power mode | ||
24 | */ | ||
25 | |||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/input.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/input/as5011.h> | ||
32 | #include <linux/slab.h> | ||
33 | |||
34 | #define DRIVER_DESC "Driver for Austria Microsystems AS5011 joystick" | ||
35 | #define MODULE_DEVICE_ALIAS "as5011" | ||
36 | |||
37 | MODULE_AUTHOR("Fabien Marteau <fabien.marteau@armadeus.com>"); | ||
38 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
39 | MODULE_LICENSE("GPL"); | ||
40 | |||
41 | /* registers */ | ||
42 | #define AS5011_CTRL1 0x76 | ||
43 | #define AS5011_CTRL2 0x75 | ||
44 | #define AS5011_XP 0x43 | ||
45 | #define AS5011_XN 0x44 | ||
46 | #define AS5011_YP 0x53 | ||
47 | #define AS5011_YN 0x54 | ||
48 | #define AS5011_X_REG 0x41 | ||
49 | #define AS5011_Y_REG 0x42 | ||
50 | #define AS5011_X_RES_INT 0x51 | ||
51 | #define AS5011_Y_RES_INT 0x52 | ||
52 | |||
53 | /* CTRL1 bits */ | ||
54 | #define AS5011_CTRL1_LP_PULSED 0x80 | ||
55 | #define AS5011_CTRL1_LP_ACTIVE 0x40 | ||
56 | #define AS5011_CTRL1_LP_CONTINUE 0x20 | ||
57 | #define AS5011_CTRL1_INT_WUP_EN 0x10 | ||
58 | #define AS5011_CTRL1_INT_ACT_EN 0x08 | ||
59 | #define AS5011_CTRL1_EXT_CLK_EN 0x04 | ||
60 | #define AS5011_CTRL1_SOFT_RST 0x02 | ||
61 | #define AS5011_CTRL1_DATA_VALID 0x01 | ||
62 | |||
63 | /* CTRL2 bits */ | ||
64 | #define AS5011_CTRL2_EXT_SAMPLE_EN 0x08 | ||
65 | #define AS5011_CTRL2_RC_BIAS_ON 0x04 | ||
66 | #define AS5011_CTRL2_INV_SPINNING 0x02 | ||
67 | |||
68 | #define AS5011_MAX_AXIS 80 | ||
69 | #define AS5011_MIN_AXIS (-80) | ||
70 | #define AS5011_FUZZ 8 | ||
71 | #define AS5011_FLAT 40 | ||
72 | |||
73 | struct as5011_device { | ||
74 | struct input_dev *input_dev; | ||
75 | struct i2c_client *i2c_client; | ||
76 | unsigned int button_gpio; | ||
77 | unsigned int button_irq; | ||
78 | unsigned int axis_irq; | ||
79 | }; | ||
80 | |||
81 | static int as5011_i2c_write(struct i2c_client *client, | ||
82 | uint8_t aregaddr, | ||
83 | uint8_t avalue) | ||
84 | { | ||
85 | uint8_t data[2] = { aregaddr, avalue }; | ||
86 | struct i2c_msg msg = { | ||
87 | client->addr, I2C_M_IGNORE_NAK, 2, (uint8_t *)data | ||
88 | }; | ||
89 | int error; | ||
90 | |||
91 | error = i2c_transfer(client->adapter, &msg, 1); | ||
92 | return error < 0 ? error : 0; | ||
93 | } | ||
94 | |||
95 | static int as5011_i2c_read(struct i2c_client *client, | ||
96 | uint8_t aregaddr, signed char *value) | ||
97 | { | ||
98 | uint8_t data[2] = { aregaddr }; | ||
99 | struct i2c_msg msg_set[2] = { | ||
100 | { client->addr, I2C_M_REV_DIR_ADDR, 1, (uint8_t *)data }, | ||
101 | { client->addr, I2C_M_RD | I2C_M_NOSTART, 1, (uint8_t *)data } | ||
102 | }; | ||
103 | int error; | ||
104 | |||
105 | error = i2c_transfer(client->adapter, msg_set, 2); | ||
106 | if (error < 0) | ||
107 | return error; | ||
108 | |||
109 | *value = data[0] & 0x80 ? -1 * (1 + ~data[0]) : data[0]; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static irqreturn_t as5011_button_interrupt(int irq, void *dev_id) | ||
114 | { | ||
115 | struct as5011_device *as5011 = dev_id; | ||
116 | int val = gpio_get_value_cansleep(as5011->button_gpio); | ||
117 | |||
118 | input_report_key(as5011->input_dev, BTN_JOYSTICK, !val); | ||
119 | input_sync(as5011->input_dev); | ||
120 | |||
121 | return IRQ_HANDLED; | ||
122 | } | ||
123 | |||
124 | static irqreturn_t as5011_axis_interrupt(int irq, void *dev_id) | ||
125 | { | ||
126 | struct as5011_device *as5011 = dev_id; | ||
127 | int error; | ||
128 | signed char x, y; | ||
129 | |||
130 | error = as5011_i2c_read(as5011->i2c_client, AS5011_X_RES_INT, &x); | ||
131 | if (error < 0) | ||
132 | goto out; | ||
133 | |||
134 | error = as5011_i2c_read(as5011->i2c_client, AS5011_Y_RES_INT, &y); | ||
135 | if (error < 0) | ||
136 | goto out; | ||
137 | |||
138 | input_report_abs(as5011->input_dev, ABS_X, x); | ||
139 | input_report_abs(as5011->input_dev, ABS_Y, y); | ||
140 | input_sync(as5011->input_dev); | ||
141 | |||
142 | out: | ||
143 | return IRQ_HANDLED; | ||
144 | } | ||
145 | |||
146 | static int __devinit as5011_configure_chip(struct as5011_device *as5011, | ||
147 | const struct as5011_platform_data *plat_dat) | ||
148 | { | ||
149 | struct i2c_client *client = as5011->i2c_client; | ||
150 | int error; | ||
151 | signed char value; | ||
152 | |||
153 | /* chip soft reset */ | ||
154 | error = as5011_i2c_write(client, AS5011_CTRL1, | ||
155 | AS5011_CTRL1_SOFT_RST); | ||
156 | if (error < 0) { | ||
157 | dev_err(&client->dev, "Soft reset failed\n"); | ||
158 | return error; | ||
159 | } | ||
160 | |||
161 | mdelay(10); | ||
162 | |||
163 | error = as5011_i2c_write(client, AS5011_CTRL1, | ||
164 | AS5011_CTRL1_LP_PULSED | | ||
165 | AS5011_CTRL1_LP_ACTIVE | | ||
166 | AS5011_CTRL1_INT_ACT_EN); | ||
167 | if (error < 0) { | ||
168 | dev_err(&client->dev, "Power config failed\n"); | ||
169 | return error; | ||
170 | } | ||
171 | |||
172 | error = as5011_i2c_write(client, AS5011_CTRL2, | ||
173 | AS5011_CTRL2_INV_SPINNING); | ||
174 | if (error < 0) { | ||
175 | dev_err(&client->dev, "Can't invert spinning\n"); | ||
176 | return error; | ||
177 | } | ||
178 | |||
179 | /* write threshold */ | ||
180 | error = as5011_i2c_write(client, AS5011_XP, plat_dat->xp); | ||
181 | if (error < 0) { | ||
182 | dev_err(&client->dev, "Can't write threshold\n"); | ||
183 | return error; | ||
184 | } | ||
185 | |||
186 | error = as5011_i2c_write(client, AS5011_XN, plat_dat->xn); | ||
187 | if (error < 0) { | ||
188 | dev_err(&client->dev, "Can't write threshold\n"); | ||
189 | return error; | ||
190 | } | ||
191 | |||
192 | error = as5011_i2c_write(client, AS5011_YP, plat_dat->yp); | ||
193 | if (error < 0) { | ||
194 | dev_err(&client->dev, "Can't write threshold\n"); | ||
195 | return error; | ||
196 | } | ||
197 | |||
198 | error = as5011_i2c_write(client, AS5011_YN, plat_dat->yn); | ||
199 | if (error < 0) { | ||
200 | dev_err(&client->dev, "Can't write threshold\n"); | ||
201 | return error; | ||
202 | } | ||
203 | |||
204 | /* to free irq gpio in chip */ | ||
205 | error = as5011_i2c_read(client, AS5011_X_RES_INT, &value); | ||
206 | if (error < 0) { | ||
207 | dev_err(&client->dev, "Can't read i2c X resolution value\n"); | ||
208 | return error; | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int __devinit as5011_probe(struct i2c_client *client, | ||
215 | const struct i2c_device_id *id) | ||
216 | { | ||
217 | const struct as5011_platform_data *plat_data; | ||
218 | struct as5011_device *as5011; | ||
219 | struct input_dev *input_dev; | ||
220 | int irq; | ||
221 | int error; | ||
222 | |||
223 | plat_data = client->dev.platform_data; | ||
224 | if (!plat_data) | ||
225 | return -EINVAL; | ||
226 | |||
227 | if (!plat_data->axis_irq) { | ||
228 | dev_err(&client->dev, "No axis IRQ?\n"); | ||
229 | return -EINVAL; | ||
230 | } | ||
231 | |||
232 | if (!i2c_check_functionality(client->adapter, | ||
233 | I2C_FUNC_PROTOCOL_MANGLING)) { | ||
234 | dev_err(&client->dev, | ||
235 | "need i2c bus that supports protocol mangling\n"); | ||
236 | return -ENODEV; | ||
237 | } | ||
238 | |||
239 | as5011 = kmalloc(sizeof(struct as5011_device), GFP_KERNEL); | ||
240 | input_dev = input_allocate_device(); | ||
241 | if (!as5011 || !input_dev) { | ||
242 | dev_err(&client->dev, | ||
243 | "Can't allocate memory for device structure\n"); | ||
244 | error = -ENOMEM; | ||
245 | goto err_free_mem; | ||
246 | } | ||
247 | |||
248 | as5011->i2c_client = client; | ||
249 | as5011->input_dev = input_dev; | ||
250 | as5011->button_gpio = plat_data->button_gpio; | ||
251 | as5011->axis_irq = plat_data->axis_irq; | ||
252 | |||
253 | input_dev->name = "Austria Microsystem as5011 joystick"; | ||
254 | input_dev->id.bustype = BUS_I2C; | ||
255 | input_dev->dev.parent = &client->dev; | ||
256 | |||
257 | __set_bit(EV_KEY, input_dev->evbit); | ||
258 | __set_bit(EV_ABS, input_dev->evbit); | ||
259 | __set_bit(BTN_JOYSTICK, input_dev->keybit); | ||
260 | |||
261 | input_set_abs_params(input_dev, ABS_X, | ||
262 | AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT); | ||
263 | input_set_abs_params(as5011->input_dev, ABS_Y, | ||
264 | AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT); | ||
265 | |||
266 | error = gpio_request(as5011->button_gpio, "AS5011 button"); | ||
267 | if (error < 0) { | ||
268 | dev_err(&client->dev, "Failed to request button gpio\n"); | ||
269 | goto err_free_mem; | ||
270 | } | ||
271 | |||
272 | irq = gpio_to_irq(as5011->button_gpio); | ||
273 | if (irq < 0) { | ||
274 | dev_err(&client->dev, | ||
275 | "Failed to get irq number for button gpio\n"); | ||
276 | goto err_free_button_gpio; | ||
277 | } | ||
278 | |||
279 | as5011->button_irq = irq; | ||
280 | |||
281 | error = request_threaded_irq(as5011->button_irq, | ||
282 | NULL, as5011_button_interrupt, | ||
283 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
284 | "as5011_button", as5011); | ||
285 | if (error < 0) { | ||
286 | dev_err(&client->dev, | ||
287 | "Can't allocate button irq %d\n", as5011->button_irq); | ||
288 | goto err_free_button_gpio; | ||
289 | } | ||
290 | |||
291 | error = as5011_configure_chip(as5011, plat_data); | ||
292 | if (error) | ||
293 | goto err_free_button_irq; | ||
294 | |||
295 | error = request_threaded_irq(as5011->axis_irq, NULL, | ||
296 | as5011_axis_interrupt, | ||
297 | plat_data->axis_irqflags, | ||
298 | "as5011_joystick", as5011); | ||
299 | if (error) { | ||
300 | dev_err(&client->dev, | ||
301 | "Can't allocate axis irq %d\n", plat_data->axis_irq); | ||
302 | goto err_free_button_irq; | ||
303 | } | ||
304 | |||
305 | error = input_register_device(as5011->input_dev); | ||
306 | if (error) { | ||
307 | dev_err(&client->dev, "Failed to register input device\n"); | ||
308 | goto err_free_axis_irq; | ||
309 | } | ||
310 | |||
311 | i2c_set_clientdata(client, as5011); | ||
312 | |||
313 | return 0; | ||
314 | |||
315 | err_free_axis_irq: | ||
316 | free_irq(as5011->axis_irq, as5011); | ||
317 | err_free_button_irq: | ||
318 | free_irq(as5011->button_irq, as5011); | ||
319 | err_free_button_gpio: | ||
320 | gpio_free(as5011->button_gpio); | ||
321 | err_free_mem: | ||
322 | input_free_device(input_dev); | ||
323 | kfree(as5011); | ||
324 | |||
325 | return error; | ||
326 | } | ||
327 | |||
328 | static int __devexit as5011_remove(struct i2c_client *client) | ||
329 | { | ||
330 | struct as5011_device *as5011 = i2c_get_clientdata(client); | ||
331 | |||
332 | free_irq(as5011->axis_irq, as5011); | ||
333 | free_irq(as5011->button_irq, as5011); | ||
334 | gpio_free(as5011->button_gpio); | ||
335 | |||
336 | input_unregister_device(as5011->input_dev); | ||
337 | kfree(as5011); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static const struct i2c_device_id as5011_id[] = { | ||
343 | { MODULE_DEVICE_ALIAS, 0 }, | ||
344 | { } | ||
345 | }; | ||
346 | MODULE_DEVICE_TABLE(i2c, as5011_id); | ||
347 | |||
348 | static struct i2c_driver as5011_driver = { | ||
349 | .driver = { | ||
350 | .name = "as5011", | ||
351 | }, | ||
352 | .probe = as5011_probe, | ||
353 | .remove = __devexit_p(as5011_remove), | ||
354 | .id_table = as5011_id, | ||
355 | }; | ||
356 | |||
357 | static int __init as5011_init(void) | ||
358 | { | ||
359 | return i2c_add_driver(&as5011_driver); | ||
360 | } | ||
361 | module_init(as5011_init); | ||
362 | |||
363 | static void __exit as5011_exit(void) | ||
364 | { | ||
365 | i2c_del_driver(&as5011_driver); | ||
366 | } | ||
367 | module_exit(as5011_exit); | ||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index f829998fabe..7b3c0b8fa43 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -12,18 +12,6 @@ menuconfig INPUT_KEYBOARD | |||
12 | 12 | ||
13 | if INPUT_KEYBOARD | 13 | if INPUT_KEYBOARD |
14 | 14 | ||
15 | config KEYBOARD_AAED2000 | ||
16 | tristate "AAED-2000 keyboard" | ||
17 | depends on MACH_AAED2000 | ||
18 | select INPUT_POLLDEV | ||
19 | default y | ||
20 | help | ||
21 | Say Y here to enable the keyboard on the Agilent AAED-2000 | ||
22 | development board. | ||
23 | |||
24 | To compile this driver as a module, choose M here: the | ||
25 | module will be called aaed2000_kbd. | ||
26 | |||
27 | config KEYBOARD_ADP5520 | 15 | config KEYBOARD_ADP5520 |
28 | tristate "Keypad Support for ADP5520 PMIC" | 16 | tristate "Keypad Support for ADP5520 PMIC" |
29 | depends on PMIC_ADP5520 | 17 | depends on PMIC_ADP5520 |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 8933e9ca938..4e5571b72cd 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -4,7 +4,6 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | ||
8 | obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o | 7 | obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o |
9 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o | 8 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o |
10 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | 9 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o |
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c deleted file mode 100644 index 18222a689a0..00000000000 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ /dev/null | |||
@@ -1,186 +0,0 @@ | |||
1 | /* | ||
2 | * Keyboard driver for the AAED-2000 dev board | ||
3 | * | ||
4 | * Copyright (c) 2006 Nicolas Bellido Y Ortega | ||
5 | * | ||
6 | * Based on corgikbd.c | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input-polldev.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/jiffies.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include <mach/hardware.h> | ||
24 | #include <mach/aaed2000.h> | ||
25 | |||
26 | #define KB_ROWS 12 | ||
27 | #define KB_COLS 8 | ||
28 | #define KB_ROWMASK(r) (1 << (r)) | ||
29 | #define SCANCODE(r,c) (((c) * KB_ROWS) + (r)) | ||
30 | #define NR_SCANCODES (KB_COLS * KB_ROWS) | ||
31 | |||
32 | #define SCAN_INTERVAL (50) /* ms */ | ||
33 | #define KB_ACTIVATE_DELAY (20) /* us */ | ||
34 | |||
35 | static unsigned char aaedkbd_keycode[NR_SCANCODES] = { | ||
36 | KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, 0, KEY_SPACE, KEY_KP6, 0, KEY_KPDOT, 0, 0, | ||
37 | KEY_K, KEY_M, KEY_O, KEY_DOT, KEY_SLASH, 0, KEY_F, 0, 0, 0, KEY_LEFTSHIFT, 0, | ||
38 | KEY_I, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, 0, 0, 0, 0, KEY_RIGHTSHIFT, 0, | ||
39 | KEY_8, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0, | ||
40 | KEY_J, KEY_H, KEY_B, KEY_KP8, KEY_KP4, 0, KEY_C, KEY_D, KEY_S, KEY_A, 0, KEY_CAPSLOCK, | ||
41 | KEY_Y, KEY_U, KEY_N, KEY_T, 0, 0, KEY_R, KEY_E, KEY_W, KEY_Q, 0, KEY_TAB, | ||
42 | KEY_7, KEY_6, KEY_G, 0, KEY_5, 0, KEY_4, KEY_3, KEY_2, KEY_1, 0, KEY_GRAVE, | ||
43 | 0, 0, KEY_COMMA, 0, KEY_KP2, 0, KEY_V, KEY_LEFTALT, KEY_X, KEY_Z, 0, KEY_LEFTCTRL | ||
44 | }; | ||
45 | |||
46 | struct aaedkbd { | ||
47 | unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)]; | ||
48 | struct input_polled_dev *poll_dev; | ||
49 | int kbdscan_state[KB_COLS]; | ||
50 | int kbdscan_count[KB_COLS]; | ||
51 | }; | ||
52 | |||
53 | #define KBDSCAN_STABLE_COUNT 2 | ||
54 | |||
55 | static void aaedkbd_report_col(struct aaedkbd *aaedkbd, | ||
56 | unsigned int col, unsigned int rowd) | ||
57 | { | ||
58 | unsigned int scancode, pressed; | ||
59 | unsigned int row; | ||
60 | |||
61 | for (row = 0; row < KB_ROWS; row++) { | ||
62 | scancode = SCANCODE(row, col); | ||
63 | pressed = rowd & KB_ROWMASK(row); | ||
64 | |||
65 | input_report_key(aaedkbd->poll_dev->input, | ||
66 | aaedkbd->keycode[scancode], pressed); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | /* Scan the hardware keyboard and push any changes up through the input layer */ | ||
71 | static void aaedkbd_poll(struct input_polled_dev *dev) | ||
72 | { | ||
73 | struct aaedkbd *aaedkbd = dev->private; | ||
74 | unsigned int col, rowd; | ||
75 | |||
76 | col = 0; | ||
77 | do { | ||
78 | AAEC_GPIO_KSCAN = col + 8; | ||
79 | udelay(KB_ACTIVATE_DELAY); | ||
80 | rowd = AAED_EXT_GPIO & AAED_EGPIO_KBD_SCAN; | ||
81 | |||
82 | if (rowd != aaedkbd->kbdscan_state[col]) { | ||
83 | aaedkbd->kbdscan_count[col] = 0; | ||
84 | aaedkbd->kbdscan_state[col] = rowd; | ||
85 | } else if (++aaedkbd->kbdscan_count[col] >= KBDSCAN_STABLE_COUNT) { | ||
86 | aaedkbd_report_col(aaedkbd, col, rowd); | ||
87 | col++; | ||
88 | } | ||
89 | } while (col < KB_COLS); | ||
90 | |||
91 | AAEC_GPIO_KSCAN = 0x07; | ||
92 | input_sync(dev->input); | ||
93 | } | ||
94 | |||
95 | static int __devinit aaedkbd_probe(struct platform_device *pdev) | ||
96 | { | ||
97 | struct aaedkbd *aaedkbd; | ||
98 | struct input_polled_dev *poll_dev; | ||
99 | struct input_dev *input_dev; | ||
100 | int i; | ||
101 | int error; | ||
102 | |||
103 | aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL); | ||
104 | poll_dev = input_allocate_polled_device(); | ||
105 | if (!aaedkbd || !poll_dev) { | ||
106 | error = -ENOMEM; | ||
107 | goto fail; | ||
108 | } | ||
109 | |||
110 | platform_set_drvdata(pdev, aaedkbd); | ||
111 | |||
112 | aaedkbd->poll_dev = poll_dev; | ||
113 | memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode)); | ||
114 | |||
115 | poll_dev->private = aaedkbd; | ||
116 | poll_dev->poll = aaedkbd_poll; | ||
117 | poll_dev->poll_interval = SCAN_INTERVAL; | ||
118 | |||
119 | input_dev = poll_dev->input; | ||
120 | input_dev->name = "AAED-2000 Keyboard"; | ||
121 | input_dev->phys = "aaedkbd/input0"; | ||
122 | input_dev->id.bustype = BUS_HOST; | ||
123 | input_dev->id.vendor = 0x0001; | ||
124 | input_dev->id.product = 0x0001; | ||
125 | input_dev->id.version = 0x0100; | ||
126 | input_dev->dev.parent = &pdev->dev; | ||
127 | |||
128 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
129 | input_dev->keycode = aaedkbd->keycode; | ||
130 | input_dev->keycodesize = sizeof(unsigned char); | ||
131 | input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode); | ||
132 | |||
133 | for (i = 0; i < ARRAY_SIZE(aaedkbd_keycode); i++) | ||
134 | set_bit(aaedkbd->keycode[i], input_dev->keybit); | ||
135 | clear_bit(0, input_dev->keybit); | ||
136 | |||
137 | error = input_register_polled_device(aaedkbd->poll_dev); | ||
138 | if (error) | ||
139 | goto fail; | ||
140 | |||
141 | return 0; | ||
142 | |||
143 | fail: kfree(aaedkbd); | ||
144 | input_free_polled_device(poll_dev); | ||
145 | return error; | ||
146 | } | ||
147 | |||
148 | static int __devexit aaedkbd_remove(struct platform_device *pdev) | ||
149 | { | ||
150 | struct aaedkbd *aaedkbd = platform_get_drvdata(pdev); | ||
151 | |||
152 | input_unregister_polled_device(aaedkbd->poll_dev); | ||
153 | input_free_polled_device(aaedkbd->poll_dev); | ||
154 | kfree(aaedkbd); | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | /* work with hotplug and coldplug */ | ||
160 | MODULE_ALIAS("platform:aaed2000-keyboard"); | ||
161 | |||
162 | static struct platform_driver aaedkbd_driver = { | ||
163 | .probe = aaedkbd_probe, | ||
164 | .remove = __devexit_p(aaedkbd_remove), | ||
165 | .driver = { | ||
166 | .name = "aaed2000-keyboard", | ||
167 | .owner = THIS_MODULE, | ||
168 | }, | ||
169 | }; | ||
170 | |||
171 | static int __init aaedkbd_init(void) | ||
172 | { | ||
173 | return platform_driver_register(&aaedkbd_driver); | ||
174 | } | ||
175 | |||
176 | static void __exit aaedkbd_exit(void) | ||
177 | { | ||
178 | platform_driver_unregister(&aaedkbd_driver); | ||
179 | } | ||
180 | |||
181 | module_init(aaedkbd_init); | ||
182 | module_exit(aaedkbd_exit); | ||
183 | |||
184 | MODULE_AUTHOR("Nicolas Bellido Y Ortega"); | ||
185 | MODULE_DESCRIPTION("AAED-2000 Keyboard Driver"); | ||
186 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index bcb1fdedb59..307eef77a17 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -229,7 +229,7 @@ config SERIO_PS2MULT | |||
229 | tristate "TQC PS/2 multiplexer" | 229 | tristate "TQC PS/2 multiplexer" |
230 | help | 230 | help |
231 | Say Y here if you have the PS/2 line multiplexer like the one | 231 | Say Y here if you have the PS/2 line multiplexer like the one |
232 | present on TQC boads. | 232 | present on TQC boards. |
233 | 233 | ||
234 | To compile this driver as a module, choose M here: the | 234 | To compile this driver as a module, choose M here: the |
235 | module will be called ps2mult. | 235 | module will be called ps2mult. |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5ae0fc4578f..bb9f5d31f0d 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -424,6 +424,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | |||
424 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), | 424 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), |
425 | }, | 425 | }, |
426 | }, | 426 | }, |
427 | { | ||
428 | /* Dell Vostro V13 */ | ||
429 | .matches = { | ||
430 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
431 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), | ||
432 | }, | ||
433 | }, | ||
427 | { } | 434 | { } |
428 | }; | 435 | }; |
429 | 436 | ||
@@ -545,6 +552,17 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { | |||
545 | }; | 552 | }; |
546 | #endif | 553 | #endif |
547 | 554 | ||
555 | static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { | ||
556 | { | ||
557 | /* Dell Vostro V13 */ | ||
558 | .matches = { | ||
559 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
560 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), | ||
561 | }, | ||
562 | }, | ||
563 | { } | ||
564 | }; | ||
565 | |||
548 | /* | 566 | /* |
549 | * Some Wistron based laptops need us to explicitly enable the 'Dritek | 567 | * Some Wistron based laptops need us to explicitly enable the 'Dritek |
550 | * keyboard extension' to make their extra keys start generating scancodes. | 568 | * keyboard extension' to make their extra keys start generating scancodes. |
@@ -896,6 +914,9 @@ static int __init i8042_platform_init(void) | |||
896 | if (dmi_check_system(i8042_dmi_nomux_table)) | 914 | if (dmi_check_system(i8042_dmi_nomux_table)) |
897 | i8042_nomux = true; | 915 | i8042_nomux = true; |
898 | 916 | ||
917 | if (dmi_check_system(i8042_dmi_notimeout_table)) | ||
918 | i8042_notimeout = true; | ||
919 | |||
899 | if (dmi_check_system(i8042_dmi_dritek_table)) | 920 | if (dmi_check_system(i8042_dmi_dritek_table)) |
900 | i8042_dritek = true; | 921 | i8042_dritek = true; |
901 | #endif /* CONFIG_X86 */ | 922 | #endif /* CONFIG_X86 */ |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index c04ff00a366..ac4c93689ab 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -63,6 +63,10 @@ static bool i8042_noloop; | |||
63 | module_param_named(noloop, i8042_noloop, bool, 0); | 63 | module_param_named(noloop, i8042_noloop, bool, 0); |
64 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); | 64 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); |
65 | 65 | ||
66 | static bool i8042_notimeout; | ||
67 | module_param_named(notimeout, i8042_notimeout, bool, 0); | ||
68 | MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042"); | ||
69 | |||
66 | #ifdef CONFIG_X86 | 70 | #ifdef CONFIG_X86 |
67 | static bool i8042_dritek; | 71 | static bool i8042_dritek; |
68 | module_param_named(dritek, i8042_dritek, bool, 0); | 72 | module_param_named(dritek, i8042_dritek, bool, 0); |
@@ -504,7 +508,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
504 | } else { | 508 | } else { |
505 | 509 | ||
506 | dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | | 510 | dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | |
507 | ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0); | 511 | ((str & I8042_STR_TIMEOUT && !i8042_notimeout) ? SERIO_TIMEOUT : 0); |
508 | 512 | ||
509 | port_no = (str & I8042_STR_AUXDATA) ? | 513 | port_no = (str & I8042_STR_AUXDATA) ? |
510 | I8042_AUX_PORT_NO : I8042_KBD_PORT_NO; | 514 | I8042_AUX_PORT_NO : I8042_KBD_PORT_NO; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 07ac77d393a..0c9f4b158ff 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -610,7 +610,7 @@ config TOUCHSCREEN_USB_ZYTRONIC | |||
610 | 610 | ||
611 | config TOUCHSCREEN_USB_ETT_TC45USB | 611 | config TOUCHSCREEN_USB_ETT_TC45USB |
612 | default y | 612 | default y |
613 | bool "ET&T USB series TC4UM/TC5UH touchscreen controler support" if EMBEDDED | 613 | bool "ET&T USB series TC4UM/TC5UH touchscreen controller support" if EMBEDDED |
614 | depends on TOUCHSCREEN_USB_COMPOSITE | 614 | depends on TOUCHSCREEN_USB_COMPOSITE |
615 | 615 | ||
616 | config TOUCHSCREEN_USB_NEXIO | 616 | config TOUCHSCREEN_USB_NEXIO |
diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c index d82a38ee9a3..4e4e58cec6c 100644 --- a/drivers/input/touchscreen/ad7879-i2c.c +++ b/drivers/input/touchscreen/ad7879-i2c.c | |||
@@ -10,14 +10,16 @@ | |||
10 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/pm.h> | ||
13 | 14 | ||
14 | #include "ad7879.h" | 15 | #include "ad7879.h" |
15 | 16 | ||
16 | #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ | 17 | #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ |
17 | 18 | ||
18 | #ifdef CONFIG_PM | 19 | #ifdef CONFIG_PM |
19 | static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) | 20 | static int ad7879_i2c_suspend(struct device *dev) |
20 | { | 21 | { |
22 | struct i2c_client *client = to_i2c_client(dev); | ||
21 | struct ad7879 *ts = i2c_get_clientdata(client); | 23 | struct ad7879 *ts = i2c_get_clientdata(client); |
22 | 24 | ||
23 | ad7879_suspend(ts); | 25 | ad7879_suspend(ts); |
@@ -25,17 +27,17 @@ static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) | |||
25 | return 0; | 27 | return 0; |
26 | } | 28 | } |
27 | 29 | ||
28 | static int ad7879_i2c_resume(struct i2c_client *client) | 30 | static int ad7879_i2c_resume(struct device *dev) |
29 | { | 31 | { |
32 | struct i2c_client *client = to_i2c_client(dev); | ||
30 | struct ad7879 *ts = i2c_get_clientdata(client); | 33 | struct ad7879 *ts = i2c_get_clientdata(client); |
31 | 34 | ||
32 | ad7879_resume(ts); | 35 | ad7879_resume(ts); |
33 | 36 | ||
34 | return 0; | 37 | return 0; |
35 | } | 38 | } |
36 | #else | 39 | |
37 | # define ad7879_i2c_suspend NULL | 40 | static SIMPLE_DEV_PM_OPS(ad7879_i2c_pm, ad7879_i2c_suspend, ad7879_i2c_resume); |
38 | # define ad7879_i2c_resume NULL | ||
39 | #endif | 41 | #endif |
40 | 42 | ||
41 | /* All registers are word-sized. | 43 | /* All registers are word-sized. |
@@ -117,11 +119,12 @@ static struct i2c_driver ad7879_i2c_driver = { | |||
117 | .driver = { | 119 | .driver = { |
118 | .name = "ad7879", | 120 | .name = "ad7879", |
119 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
122 | #ifdef CONFIG_PM | ||
123 | .pm = &ad7879_i2c_pm, | ||
124 | #endif | ||
120 | }, | 125 | }, |
121 | .probe = ad7879_i2c_probe, | 126 | .probe = ad7879_i2c_probe, |
122 | .remove = __devexit_p(ad7879_i2c_remove), | 127 | .remove = __devexit_p(ad7879_i2c_remove), |
123 | .suspend = ad7879_i2c_suspend, | ||
124 | .resume = ad7879_i2c_resume, | ||
125 | .id_table = ad7879_id, | 128 | .id_table = ad7879_id, |
126 | }; | 129 | }; |
127 | 130 | ||
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index d0c3a7229ad..a93c5c26ab3 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
@@ -280,8 +280,9 @@ err_free_mem: | |||
280 | } | 280 | } |
281 | 281 | ||
282 | #ifdef CONFIG_PM | 282 | #ifdef CONFIG_PM |
283 | static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) | 283 | static int cy8ctmg110_suspend(struct device *dev) |
284 | { | 284 | { |
285 | struct i2c_client *client = to_i2c_client(dev); | ||
285 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | 286 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); |
286 | 287 | ||
287 | if (device_may_wakeup(&client->dev)) | 288 | if (device_may_wakeup(&client->dev)) |
@@ -293,8 +294,9 @@ static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) | |||
293 | return 0; | 294 | return 0; |
294 | } | 295 | } |
295 | 296 | ||
296 | static int cy8ctmg110_resume(struct i2c_client *client) | 297 | static int cy8ctmg110_resume(struct device *dev) |
297 | { | 298 | { |
299 | struct i2c_client *client = to_i2c_client(dev); | ||
298 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | 300 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); |
299 | 301 | ||
300 | if (device_may_wakeup(&client->dev)) | 302 | if (device_may_wakeup(&client->dev)) |
@@ -305,6 +307,8 @@ static int cy8ctmg110_resume(struct i2c_client *client) | |||
305 | } | 307 | } |
306 | return 0; | 308 | return 0; |
307 | } | 309 | } |
310 | |||
311 | static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); | ||
308 | #endif | 312 | #endif |
309 | 313 | ||
310 | static int __devexit cy8ctmg110_remove(struct i2c_client *client) | 314 | static int __devexit cy8ctmg110_remove(struct i2c_client *client) |
@@ -335,14 +339,13 @@ static struct i2c_driver cy8ctmg110_driver = { | |||
335 | .driver = { | 339 | .driver = { |
336 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
337 | .name = CY8CTMG110_DRIVER_NAME, | 341 | .name = CY8CTMG110_DRIVER_NAME, |
342 | #ifdef CONFIG_PM | ||
343 | .pm = &cy8ctmg110_pm, | ||
344 | #endif | ||
338 | }, | 345 | }, |
339 | .id_table = cy8ctmg110_idtable, | 346 | .id_table = cy8ctmg110_idtable, |
340 | .probe = cy8ctmg110_probe, | 347 | .probe = cy8ctmg110_probe, |
341 | .remove = __devexit_p(cy8ctmg110_remove), | 348 | .remove = __devexit_p(cy8ctmg110_remove), |
342 | #ifdef CONFIG_PM | ||
343 | .suspend = cy8ctmg110_suspend, | ||
344 | .resume = cy8ctmg110_resume, | ||
345 | #endif | ||
346 | }; | 349 | }; |
347 | 350 | ||
348 | static int __init cy8ctmg110_init(void) | 351 | static int __init cy8ctmg110_init(void) |
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 7a3a916f84a..7f8f538a980 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
@@ -261,8 +261,9 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
261 | } | 261 | } |
262 | 262 | ||
263 | #ifdef CONFIG_PM | 263 | #ifdef CONFIG_PM |
264 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 264 | static int eeti_ts_suspend(struct device *dev) |
265 | { | 265 | { |
266 | struct i2c_client *client = to_i2c_client(dev); | ||
266 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 267 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
267 | struct input_dev *input_dev = priv->input; | 268 | struct input_dev *input_dev = priv->input; |
268 | 269 | ||
@@ -279,8 +280,9 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
279 | return 0; | 280 | return 0; |
280 | } | 281 | } |
281 | 282 | ||
282 | static int eeti_ts_resume(struct i2c_client *client) | 283 | static int eeti_ts_resume(struct device *dev) |
283 | { | 284 | { |
285 | struct i2c_client *client = to_i2c_client(dev); | ||
284 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 286 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
285 | struct input_dev *input_dev = priv->input; | 287 | struct input_dev *input_dev = priv->input; |
286 | 288 | ||
@@ -296,9 +298,8 @@ static int eeti_ts_resume(struct i2c_client *client) | |||
296 | 298 | ||
297 | return 0; | 299 | return 0; |
298 | } | 300 | } |
299 | #else | 301 | |
300 | #define eeti_ts_suspend NULL | 302 | static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); |
301 | #define eeti_ts_resume NULL | ||
302 | #endif | 303 | #endif |
303 | 304 | ||
304 | static const struct i2c_device_id eeti_ts_id[] = { | 305 | static const struct i2c_device_id eeti_ts_id[] = { |
@@ -310,11 +311,12 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id); | |||
310 | static struct i2c_driver eeti_ts_driver = { | 311 | static struct i2c_driver eeti_ts_driver = { |
311 | .driver = { | 312 | .driver = { |
312 | .name = "eeti_ts", | 313 | .name = "eeti_ts", |
314 | #ifdef CONFIG_PM | ||
315 | .pm = &eeti_ts_pm, | ||
316 | #endif | ||
313 | }, | 317 | }, |
314 | .probe = eeti_ts_probe, | 318 | .probe = eeti_ts_probe, |
315 | .remove = __devexit_p(eeti_ts_remove), | 319 | .remove = __devexit_p(eeti_ts_remove), |
316 | .suspend = eeti_ts_suspend, | ||
317 | .resume = eeti_ts_resume, | ||
318 | .id_table = eeti_ts_id, | 320 | .id_table = eeti_ts_id, |
319 | }; | 321 | }; |
320 | 322 | ||
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 6ee9940aaf5..2d84c80ceb6 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c | |||
@@ -261,25 +261,27 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client) | |||
261 | } | 261 | } |
262 | 262 | ||
263 | #ifdef CONFIG_PM | 263 | #ifdef CONFIG_PM |
264 | static int mcs5000_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 264 | static int mcs5000_ts_suspend(struct device *dev) |
265 | { | 265 | { |
266 | struct i2c_client *client = to_i2c_client(dev); | ||
267 | |||
266 | /* Touch sleep mode */ | 268 | /* Touch sleep mode */ |
267 | i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); | 269 | i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); |
268 | 270 | ||
269 | return 0; | 271 | return 0; |
270 | } | 272 | } |
271 | 273 | ||
272 | static int mcs5000_ts_resume(struct i2c_client *client) | 274 | static int mcs5000_ts_resume(struct device *dev) |
273 | { | 275 | { |
276 | struct i2c_client *client = to_i2c_client(dev); | ||
274 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | 277 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); |
275 | 278 | ||
276 | mcs5000_ts_phys_init(data); | 279 | mcs5000_ts_phys_init(data); |
277 | 280 | ||
278 | return 0; | 281 | return 0; |
279 | } | 282 | } |
280 | #else | 283 | |
281 | #define mcs5000_ts_suspend NULL | 284 | static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume); |
282 | #define mcs5000_ts_resume NULL | ||
283 | #endif | 285 | #endif |
284 | 286 | ||
285 | static const struct i2c_device_id mcs5000_ts_id[] = { | 287 | static const struct i2c_device_id mcs5000_ts_id[] = { |
@@ -291,10 +293,11 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); | |||
291 | static struct i2c_driver mcs5000_ts_driver = { | 293 | static struct i2c_driver mcs5000_ts_driver = { |
292 | .probe = mcs5000_ts_probe, | 294 | .probe = mcs5000_ts_probe, |
293 | .remove = __devexit_p(mcs5000_ts_remove), | 295 | .remove = __devexit_p(mcs5000_ts_remove), |
294 | .suspend = mcs5000_ts_suspend, | ||
295 | .resume = mcs5000_ts_resume, | ||
296 | .driver = { | 296 | .driver = { |
297 | .name = "mcs5000_ts", | 297 | .name = "mcs5000_ts", |
298 | #ifdef CONFIG_PM | ||
299 | .pm = &mcs5000_ts_pm, | ||
300 | #endif | ||
298 | }, | 301 | }, |
299 | .id_table = mcs5000_ts_id, | 302 | .id_table = mcs5000_ts_id, |
300 | }; | 303 | }; |
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index defe5dd3627..5803bd0c1cc 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/pm.h> | ||
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
@@ -226,8 +227,9 @@ static int migor_ts_remove(struct i2c_client *client) | |||
226 | return 0; | 227 | return 0; |
227 | } | 228 | } |
228 | 229 | ||
229 | static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 230 | static int migor_ts_suspend(struct device *dev) |
230 | { | 231 | { |
232 | struct i2c_client *client = to_i2c_client(dev); | ||
231 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | 233 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); |
232 | 234 | ||
233 | if (device_may_wakeup(&client->dev)) | 235 | if (device_may_wakeup(&client->dev)) |
@@ -236,8 +238,9 @@ static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
236 | return 0; | 238 | return 0; |
237 | } | 239 | } |
238 | 240 | ||
239 | static int migor_ts_resume(struct i2c_client *client) | 241 | static int migor_ts_resume(struct device *dev) |
240 | { | 242 | { |
243 | struct i2c_client *client = to_i2c_client(dev); | ||
241 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | 244 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); |
242 | 245 | ||
243 | if (device_may_wakeup(&client->dev)) | 246 | if (device_may_wakeup(&client->dev)) |
@@ -246,6 +249,8 @@ static int migor_ts_resume(struct i2c_client *client) | |||
246 | return 0; | 249 | return 0; |
247 | } | 250 | } |
248 | 251 | ||
252 | static SIMPLE_DEV_PM_OPS(migor_ts_pm, migor_ts_suspend, migor_ts_resume); | ||
253 | |||
249 | static const struct i2c_device_id migor_ts_id[] = { | 254 | static const struct i2c_device_id migor_ts_id[] = { |
250 | { "migor_ts", 0 }, | 255 | { "migor_ts", 0 }, |
251 | { } | 256 | { } |
@@ -255,11 +260,10 @@ MODULE_DEVICE_TABLE(i2c, migor_ts); | |||
255 | static struct i2c_driver migor_ts_driver = { | 260 | static struct i2c_driver migor_ts_driver = { |
256 | .driver = { | 261 | .driver = { |
257 | .name = "migor_ts", | 262 | .name = "migor_ts", |
263 | .pm = &migor_ts_pm, | ||
258 | }, | 264 | }, |
259 | .probe = migor_ts_probe, | 265 | .probe = migor_ts_probe, |
260 | .remove = migor_ts_remove, | 266 | .remove = migor_ts_remove, |
261 | .suspend = migor_ts_suspend, | ||
262 | .resume = migor_ts_resume, | ||
263 | .id_table = migor_ts_id, | 267 | .id_table = migor_ts_id, |
264 | }; | 268 | }; |
265 | 269 | ||
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 8ed53aded2d..5cb8449c909 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2008 Jaya Kumar | 4 | * Copyright (c) 2008 Jaya Kumar |
5 | * Copyright (c) 2010 Red Hat, Inc. | 5 | * Copyright (c) 2010 Red Hat, Inc. |
6 | * Copyright (c) 2010 - 2011 Ping Cheng, Wacom. <pingc@wacom.com> | ||
6 | * | 7 | * |
7 | * This file is subject to the terms and conditions of the GNU General Public | 8 | * This file is subject to the terms and conditions of the GNU General Public |
8 | * License. See the file COPYING in the main directory of this archive for | 9 | * License. See the file COPYING in the main directory of this archive for |
@@ -64,11 +65,11 @@ struct w8001_coord { | |||
64 | 65 | ||
65 | /* touch query reply packet */ | 66 | /* touch query reply packet */ |
66 | struct w8001_touch_query { | 67 | struct w8001_touch_query { |
68 | u16 x; | ||
69 | u16 y; | ||
67 | u8 panel_res; | 70 | u8 panel_res; |
68 | u8 capacity_res; | 71 | u8 capacity_res; |
69 | u8 sensor_id; | 72 | u8 sensor_id; |
70 | u16 x; | ||
71 | u16 y; | ||
72 | }; | 73 | }; |
73 | 74 | ||
74 | /* | 75 | /* |
@@ -87,9 +88,14 @@ struct w8001 { | |||
87 | char phys[32]; | 88 | char phys[32]; |
88 | int type; | 89 | int type; |
89 | unsigned int pktlen; | 90 | unsigned int pktlen; |
91 | u16 max_touch_x; | ||
92 | u16 max_touch_y; | ||
93 | u16 max_pen_x; | ||
94 | u16 max_pen_y; | ||
95 | char name[64]; | ||
90 | }; | 96 | }; |
91 | 97 | ||
92 | static void parse_data(u8 *data, struct w8001_coord *coord) | 98 | static void parse_pen_data(u8 *data, struct w8001_coord *coord) |
93 | { | 99 | { |
94 | memset(coord, 0, sizeof(*coord)); | 100 | memset(coord, 0, sizeof(*coord)); |
95 | 101 | ||
@@ -113,11 +119,30 @@ static void parse_data(u8 *data, struct w8001_coord *coord) | |||
113 | coord->tilt_y = data[8] & 0x7F; | 119 | coord->tilt_y = data[8] & 0x7F; |
114 | } | 120 | } |
115 | 121 | ||
116 | static void parse_touch(struct w8001 *w8001) | 122 | static void parse_single_touch(u8 *data, struct w8001_coord *coord) |
123 | { | ||
124 | coord->x = (data[1] << 7) | data[2]; | ||
125 | coord->y = (data[3] << 7) | data[4]; | ||
126 | coord->tsw = data[0] & 0x01; | ||
127 | } | ||
128 | |||
129 | static void scale_touch_coordinates(struct w8001 *w8001, | ||
130 | unsigned int *x, unsigned int *y) | ||
131 | { | ||
132 | if (w8001->max_pen_x && w8001->max_touch_x) | ||
133 | *x = *x * w8001->max_pen_x / w8001->max_touch_x; | ||
134 | |||
135 | if (w8001->max_pen_y && w8001->max_touch_y) | ||
136 | *y = *y * w8001->max_pen_y / w8001->max_touch_y; | ||
137 | } | ||
138 | |||
139 | static void parse_multi_touch(struct w8001 *w8001) | ||
117 | { | 140 | { |
118 | struct input_dev *dev = w8001->dev; | 141 | struct input_dev *dev = w8001->dev; |
119 | unsigned char *data = w8001->data; | 142 | unsigned char *data = w8001->data; |
143 | unsigned int x, y; | ||
120 | int i; | 144 | int i; |
145 | int count = 0; | ||
121 | 146 | ||
122 | for (i = 0; i < 2; i++) { | 147 | for (i = 0; i < 2; i++) { |
123 | bool touch = data[0] & (1 << i); | 148 | bool touch = data[0] & (1 << i); |
@@ -125,15 +150,29 @@ static void parse_touch(struct w8001 *w8001) | |||
125 | input_mt_slot(dev, i); | 150 | input_mt_slot(dev, i); |
126 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); | 151 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); |
127 | if (touch) { | 152 | if (touch) { |
128 | int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]); | 153 | x = (data[6 * i + 1] << 7) | data[6 * i + 2]; |
129 | int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]); | 154 | y = (data[6 * i + 3] << 7) | data[6 * i + 4]; |
130 | /* data[5,6] and [11,12] is finger capacity */ | 155 | /* data[5,6] and [11,12] is finger capacity */ |
131 | 156 | ||
157 | /* scale to pen maximum */ | ||
158 | scale_touch_coordinates(w8001, &x, &y); | ||
159 | |||
132 | input_report_abs(dev, ABS_MT_POSITION_X, x); | 160 | input_report_abs(dev, ABS_MT_POSITION_X, x); |
133 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | 161 | input_report_abs(dev, ABS_MT_POSITION_Y, y); |
162 | count++; | ||
134 | } | 163 | } |
135 | } | 164 | } |
136 | 165 | ||
166 | /* emulate single touch events when stylus is out of proximity. | ||
167 | * This is to make single touch backward support consistent | ||
168 | * across all Wacom single touch devices. | ||
169 | */ | ||
170 | if (w8001->type != BTN_TOOL_PEN && | ||
171 | w8001->type != BTN_TOOL_RUBBER) { | ||
172 | w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED; | ||
173 | input_mt_report_pointer_emulation(dev, true); | ||
174 | } | ||
175 | |||
137 | input_sync(dev); | 176 | input_sync(dev); |
138 | } | 177 | } |
139 | 178 | ||
@@ -152,6 +191,15 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query) | |||
152 | query->y = data[5] << 9; | 191 | query->y = data[5] << 9; |
153 | query->y |= data[6] << 2; | 192 | query->y |= data[6] << 2; |
154 | query->y |= (data[2] >> 3) & 0x3; | 193 | query->y |= (data[2] >> 3) & 0x3; |
194 | |||
195 | /* Early days' single-finger touch models need the following defaults */ | ||
196 | if (!query->x && !query->y) { | ||
197 | query->x = 1024; | ||
198 | query->y = 1024; | ||
199 | if (query->panel_res) | ||
200 | query->x = query->y = (1 << query->panel_res); | ||
201 | query->panel_res = 10; | ||
202 | } | ||
155 | } | 203 | } |
156 | 204 | ||
157 | static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) | 205 | static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) |
@@ -161,16 +209,15 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) | |||
161 | /* | 209 | /* |
162 | * We have 1 bit for proximity (rdy) and 3 bits for tip, side, | 210 | * We have 1 bit for proximity (rdy) and 3 bits for tip, side, |
163 | * side2/eraser. If rdy && f2 are set, this can be either pen + side2, | 211 | * side2/eraser. If rdy && f2 are set, this can be either pen + side2, |
164 | * or eraser. assume | 212 | * or eraser. Assume: |
165 | * - if dev is already in proximity and f2 is toggled → pen + side2 | 213 | * - if dev is already in proximity and f2 is toggled → pen + side2 |
166 | * - if dev comes into proximity with f2 set → eraser | 214 | * - if dev comes into proximity with f2 set → eraser |
167 | * If f2 disappears after assuming eraser, fake proximity out for | 215 | * If f2 disappears after assuming eraser, fake proximity out for |
168 | * eraser and in for pen. | 216 | * eraser and in for pen. |
169 | */ | 217 | */ |
170 | 218 | ||
171 | if (!w8001->type) { | 219 | switch (w8001->type) { |
172 | w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 220 | case BTN_TOOL_RUBBER: |
173 | } else if (w8001->type == BTN_TOOL_RUBBER) { | ||
174 | if (!coord->f2) { | 221 | if (!coord->f2) { |
175 | input_report_abs(dev, ABS_PRESSURE, 0); | 222 | input_report_abs(dev, ABS_PRESSURE, 0); |
176 | input_report_key(dev, BTN_TOUCH, 0); | 223 | input_report_key(dev, BTN_TOUCH, 0); |
@@ -180,8 +227,21 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) | |||
180 | input_sync(dev); | 227 | input_sync(dev); |
181 | w8001->type = BTN_TOOL_PEN; | 228 | w8001->type = BTN_TOOL_PEN; |
182 | } | 229 | } |
183 | } else { | 230 | break; |
231 | |||
232 | case BTN_TOOL_FINGER: | ||
233 | input_report_key(dev, BTN_TOUCH, 0); | ||
234 | input_report_key(dev, BTN_TOOL_FINGER, 0); | ||
235 | input_sync(dev); | ||
236 | /* fall through */ | ||
237 | |||
238 | case KEY_RESERVED: | ||
239 | w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
240 | break; | ||
241 | |||
242 | default: | ||
184 | input_report_key(dev, BTN_STYLUS2, coord->f2); | 243 | input_report_key(dev, BTN_STYLUS2, coord->f2); |
244 | break; | ||
185 | } | 245 | } |
186 | 246 | ||
187 | input_report_abs(dev, ABS_X, coord->x); | 247 | input_report_abs(dev, ABS_X, coord->x); |
@@ -193,7 +253,26 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) | |||
193 | input_sync(dev); | 253 | input_sync(dev); |
194 | 254 | ||
195 | if (!coord->rdy) | 255 | if (!coord->rdy) |
196 | w8001->type = 0; | 256 | w8001->type = KEY_RESERVED; |
257 | } | ||
258 | |||
259 | static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord) | ||
260 | { | ||
261 | struct input_dev *dev = w8001->dev; | ||
262 | unsigned int x = coord->x; | ||
263 | unsigned int y = coord->y; | ||
264 | |||
265 | /* scale to pen maximum */ | ||
266 | scale_touch_coordinates(w8001, &x, &y); | ||
267 | |||
268 | input_report_abs(dev, ABS_X, x); | ||
269 | input_report_abs(dev, ABS_Y, y); | ||
270 | input_report_key(dev, BTN_TOUCH, coord->tsw); | ||
271 | input_report_key(dev, BTN_TOOL_FINGER, coord->tsw); | ||
272 | |||
273 | input_sync(dev); | ||
274 | |||
275 | w8001->type = coord->tsw ? BTN_TOOL_FINGER : KEY_RESERVED; | ||
197 | } | 276 | } |
198 | 277 | ||
199 | static irqreturn_t w8001_interrupt(struct serio *serio, | 278 | static irqreturn_t w8001_interrupt(struct serio *serio, |
@@ -214,9 +293,18 @@ static irqreturn_t w8001_interrupt(struct serio *serio, | |||
214 | 293 | ||
215 | case W8001_PKTLEN_TOUCH93 - 1: | 294 | case W8001_PKTLEN_TOUCH93 - 1: |
216 | case W8001_PKTLEN_TOUCH9A - 1: | 295 | case W8001_PKTLEN_TOUCH9A - 1: |
217 | /* ignore one-finger touch packet. */ | 296 | tmp = w8001->data[0] & W8001_TOUCH_BYTE; |
218 | if (w8001->pktlen == w8001->idx) | 297 | if (tmp != W8001_TOUCH_BYTE) |
298 | break; | ||
299 | |||
300 | if (w8001->pktlen == w8001->idx) { | ||
219 | w8001->idx = 0; | 301 | w8001->idx = 0; |
302 | if (w8001->type != BTN_TOOL_PEN && | ||
303 | w8001->type != BTN_TOOL_RUBBER) { | ||
304 | parse_single_touch(w8001->data, &coord); | ||
305 | report_single_touch(w8001, &coord); | ||
306 | } | ||
307 | } | ||
220 | break; | 308 | break; |
221 | 309 | ||
222 | /* Pen coordinates packet */ | 310 | /* Pen coordinates packet */ |
@@ -225,18 +313,18 @@ static irqreturn_t w8001_interrupt(struct serio *serio, | |||
225 | if (unlikely(tmp == W8001_TAB_BYTE)) | 313 | if (unlikely(tmp == W8001_TAB_BYTE)) |
226 | break; | 314 | break; |
227 | 315 | ||
228 | tmp = (w8001->data[0] & W8001_TOUCH_BYTE); | 316 | tmp = w8001->data[0] & W8001_TOUCH_BYTE; |
229 | if (tmp == W8001_TOUCH_BYTE) | 317 | if (tmp == W8001_TOUCH_BYTE) |
230 | break; | 318 | break; |
231 | 319 | ||
232 | w8001->idx = 0; | 320 | w8001->idx = 0; |
233 | parse_data(w8001->data, &coord); | 321 | parse_pen_data(w8001->data, &coord); |
234 | report_pen_events(w8001, &coord); | 322 | report_pen_events(w8001, &coord); |
235 | break; | 323 | break; |
236 | 324 | ||
237 | /* control packet */ | 325 | /* control packet */ |
238 | case W8001_PKTLEN_TPCCTL - 1: | 326 | case W8001_PKTLEN_TPCCTL - 1: |
239 | tmp = (w8001->data[0] & W8001_TOUCH_MASK); | 327 | tmp = w8001->data[0] & W8001_TOUCH_MASK; |
240 | if (tmp == W8001_TOUCH_BYTE) | 328 | if (tmp == W8001_TOUCH_BYTE) |
241 | break; | 329 | break; |
242 | 330 | ||
@@ -249,7 +337,7 @@ static irqreturn_t w8001_interrupt(struct serio *serio, | |||
249 | /* 2 finger touch packet */ | 337 | /* 2 finger touch packet */ |
250 | case W8001_PKTLEN_TOUCH2FG - 1: | 338 | case W8001_PKTLEN_TOUCH2FG - 1: |
251 | w8001->idx = 0; | 339 | w8001->idx = 0; |
252 | parse_touch(w8001); | 340 | parse_multi_touch(w8001); |
253 | break; | 341 | break; |
254 | } | 342 | } |
255 | 343 | ||
@@ -279,6 +367,7 @@ static int w8001_setup(struct w8001 *w8001) | |||
279 | { | 367 | { |
280 | struct input_dev *dev = w8001->dev; | 368 | struct input_dev *dev = w8001->dev; |
281 | struct w8001_coord coord; | 369 | struct w8001_coord coord; |
370 | struct w8001_touch_query touch; | ||
282 | int error; | 371 | int error; |
283 | 372 | ||
284 | error = w8001_command(w8001, W8001_CMD_STOP, false); | 373 | error = w8001_command(w8001, W8001_CMD_STOP, false); |
@@ -287,14 +376,21 @@ static int w8001_setup(struct w8001 *w8001) | |||
287 | 376 | ||
288 | msleep(250); /* wait 250ms before querying the device */ | 377 | msleep(250); /* wait 250ms before querying the device */ |
289 | 378 | ||
379 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
380 | strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name)); | ||
381 | |||
290 | /* penabled? */ | 382 | /* penabled? */ |
291 | error = w8001_command(w8001, W8001_CMD_QUERY, true); | 383 | error = w8001_command(w8001, W8001_CMD_QUERY, true); |
292 | if (!error) { | 384 | if (!error) { |
385 | __set_bit(BTN_TOUCH, dev->keybit); | ||
293 | __set_bit(BTN_TOOL_PEN, dev->keybit); | 386 | __set_bit(BTN_TOOL_PEN, dev->keybit); |
294 | __set_bit(BTN_TOOL_RUBBER, dev->keybit); | 387 | __set_bit(BTN_TOOL_RUBBER, dev->keybit); |
295 | __set_bit(BTN_STYLUS, dev->keybit); | 388 | __set_bit(BTN_STYLUS, dev->keybit); |
296 | __set_bit(BTN_STYLUS2, dev->keybit); | 389 | __set_bit(BTN_STYLUS2, dev->keybit); |
297 | parse_data(w8001->response, &coord); | 390 | |
391 | parse_pen_data(w8001->response, &coord); | ||
392 | w8001->max_pen_x = coord.x; | ||
393 | w8001->max_pen_y = coord.y; | ||
298 | 394 | ||
299 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); | 395 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); |
300 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); | 396 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); |
@@ -303,6 +399,8 @@ static int w8001_setup(struct w8001 *w8001) | |||
303 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | 399 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); |
304 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | 400 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); |
305 | } | 401 | } |
402 | w8001->id = 0x90; | ||
403 | strlcat(w8001->name, " Penabled", sizeof(w8001->name)); | ||
306 | } | 404 | } |
307 | 405 | ||
308 | /* Touch enabled? */ | 406 | /* Touch enabled? */ |
@@ -313,24 +411,38 @@ static int w8001_setup(struct w8001 *w8001) | |||
313 | * second byte is empty, which indicates touch is not supported. | 411 | * second byte is empty, which indicates touch is not supported. |
314 | */ | 412 | */ |
315 | if (!error && w8001->response[1]) { | 413 | if (!error && w8001->response[1]) { |
316 | struct w8001_touch_query touch; | 414 | __set_bit(BTN_TOUCH, dev->keybit); |
415 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
317 | 416 | ||
318 | parse_touchquery(w8001->response, &touch); | 417 | parse_touchquery(w8001->response, &touch); |
418 | w8001->max_touch_x = touch.x; | ||
419 | w8001->max_touch_y = touch.y; | ||
420 | |||
421 | /* scale to pen maximum */ | ||
422 | if (w8001->max_pen_x && w8001->max_pen_y) { | ||
423 | touch.x = w8001->max_pen_x; | ||
424 | touch.y = w8001->max_pen_y; | ||
425 | } | ||
319 | 426 | ||
320 | input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); | 427 | input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); |
321 | input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); | 428 | input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); |
322 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
323 | 429 | ||
324 | switch (touch.sensor_id) { | 430 | switch (touch.sensor_id) { |
325 | case 0: | 431 | case 0: |
326 | case 2: | 432 | case 2: |
327 | w8001->pktlen = W8001_PKTLEN_TOUCH93; | 433 | w8001->pktlen = W8001_PKTLEN_TOUCH93; |
434 | w8001->id = 0x93; | ||
435 | strlcat(w8001->name, " 1FG", sizeof(w8001->name)); | ||
328 | break; | 436 | break; |
437 | |||
329 | case 1: | 438 | case 1: |
330 | case 3: | 439 | case 3: |
331 | case 4: | 440 | case 4: |
332 | w8001->pktlen = W8001_PKTLEN_TOUCH9A; | 441 | w8001->pktlen = W8001_PKTLEN_TOUCH9A; |
442 | strlcat(w8001->name, " 1FG", sizeof(w8001->name)); | ||
443 | w8001->id = 0x9a; | ||
333 | break; | 444 | break; |
445 | |||
334 | case 5: | 446 | case 5: |
335 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; | 447 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; |
336 | 448 | ||
@@ -341,10 +453,18 @@ static int w8001_setup(struct w8001 *w8001) | |||
341 | 0, touch.y, 0, 0); | 453 | 0, touch.y, 0, 0); |
342 | input_set_abs_params(dev, ABS_MT_TOOL_TYPE, | 454 | input_set_abs_params(dev, ABS_MT_TOOL_TYPE, |
343 | 0, MT_TOOL_MAX, 0, 0); | 455 | 0, MT_TOOL_MAX, 0, 0); |
456 | |||
457 | strlcat(w8001->name, " 2FG", sizeof(w8001->name)); | ||
458 | if (w8001->max_pen_x && w8001->max_pen_y) | ||
459 | w8001->id = 0xE3; | ||
460 | else | ||
461 | w8001->id = 0xE2; | ||
344 | break; | 462 | break; |
345 | } | 463 | } |
346 | } | 464 | } |
347 | 465 | ||
466 | strlcat(w8001->name, " Touchscreen", sizeof(w8001->name)); | ||
467 | |||
348 | return w8001_command(w8001, W8001_CMD_START, false); | 468 | return w8001_command(w8001, W8001_CMD_START, false); |
349 | } | 469 | } |
350 | 470 | ||
@@ -384,22 +504,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
384 | } | 504 | } |
385 | 505 | ||
386 | w8001->serio = serio; | 506 | w8001->serio = serio; |
387 | w8001->id = serio->id.id; | ||
388 | w8001->dev = input_dev; | 507 | w8001->dev = input_dev; |
389 | init_completion(&w8001->cmd_done); | 508 | init_completion(&w8001->cmd_done); |
390 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); | 509 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); |
391 | 510 | ||
392 | input_dev->name = "Wacom W8001 Penabled Serial TouchScreen"; | ||
393 | input_dev->phys = w8001->phys; | ||
394 | input_dev->id.bustype = BUS_RS232; | ||
395 | input_dev->id.vendor = SERIO_W8001; | ||
396 | input_dev->id.product = w8001->id; | ||
397 | input_dev->id.version = 0x0100; | ||
398 | input_dev->dev.parent = &serio->dev; | ||
399 | |||
400 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
401 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
402 | |||
403 | serio_set_drvdata(serio, w8001); | 511 | serio_set_drvdata(serio, w8001); |
404 | err = serio_open(serio, drv); | 512 | err = serio_open(serio, drv); |
405 | if (err) | 513 | if (err) |
@@ -409,6 +517,14 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
409 | if (err) | 517 | if (err) |
410 | goto fail3; | 518 | goto fail3; |
411 | 519 | ||
520 | input_dev->name = w8001->name; | ||
521 | input_dev->phys = w8001->phys; | ||
522 | input_dev->id.product = w8001->id; | ||
523 | input_dev->id.bustype = BUS_RS232; | ||
524 | input_dev->id.vendor = 0x056a; | ||
525 | input_dev->id.version = 0x0100; | ||
526 | input_dev->dev.parent = &serio->dev; | ||
527 | |||
412 | err = input_register_device(w8001->dev); | 528 | err = input_register_device(w8001->dev); |
413 | if (err) | 529 | if (err) |
414 | goto fail3; | 530 | goto fail3; |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 178942a2ee6..8a3c5cfc4fe 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -2318,7 +2318,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2318 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 2318 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
2319 | le16_to_cpu(udev->descriptor.idProduct)); | 2319 | le16_to_cpu(udev->descriptor.idProduct)); |
2320 | 2320 | ||
2321 | /* allocate memory for our device state and intialize it */ | 2321 | /* allocate memory for our device state and initialize it */ |
2322 | cs = gigaset_initcs(driver, BAS_CHANNELS, 0, 0, cidmode, | 2322 | cs = gigaset_initcs(driver, BAS_CHANNELS, 0, 0, cidmode, |
2323 | GIGASET_MODULENAME); | 2323 | GIGASET_MODULENAME); |
2324 | if (!cs) | 2324 | if (!cs) |
@@ -2576,7 +2576,7 @@ static int __init bas_gigaset_init(void) | |||
2576 | { | 2576 | { |
2577 | int result; | 2577 | int result; |
2578 | 2578 | ||
2579 | /* allocate memory for our driver state and intialize it */ | 2579 | /* allocate memory for our driver state and initialize it */ |
2580 | driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 2580 | driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
2581 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 2581 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
2582 | &gigops, THIS_MODULE); | 2582 | &gigops, THIS_MODULE); |
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index d151dcbf770..0ef09d0eb96 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
@@ -513,7 +513,7 @@ gigaset_tty_open(struct tty_struct *tty) | |||
513 | return -ENODEV; | 513 | return -ENODEV; |
514 | } | 514 | } |
515 | 515 | ||
516 | /* allocate memory for our device state and intialize it */ | 516 | /* allocate memory for our device state and initialize it */ |
517 | cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); | 517 | cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); |
518 | if (!cs) | 518 | if (!cs) |
519 | goto error; | 519 | goto error; |
@@ -771,7 +771,7 @@ static int __init ser_gigaset_init(void) | |||
771 | return rc; | 771 | return rc; |
772 | } | 772 | } |
773 | 773 | ||
774 | /* allocate memory for our driver state and intialize it */ | 774 | /* allocate memory for our driver state and initialize it */ |
775 | driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 775 | driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
776 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 776 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
777 | &ops, THIS_MODULE); | 777 | &ops, THIS_MODULE); |
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index 4a66338f4e7..5e3300d8a2a 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
@@ -695,7 +695,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
695 | 695 | ||
696 | dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); | 696 | dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); |
697 | 697 | ||
698 | /* allocate memory for our device state and intialize it */ | 698 | /* allocate memory for our device state and initialize it */ |
699 | cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); | 699 | cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); |
700 | if (!cs) | 700 | if (!cs) |
701 | return -ENODEV; | 701 | return -ENODEV; |
@@ -894,7 +894,7 @@ static int __init usb_gigaset_init(void) | |||
894 | { | 894 | { |
895 | int result; | 895 | int result; |
896 | 896 | ||
897 | /* allocate memory for our driver state and intialize it */ | 897 | /* allocate memory for our driver state and initialize it */ |
898 | driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 898 | driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
899 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 899 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
900 | &ops, THIS_MODULE); | 900 | &ops, THIS_MODULE); |
diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h index 74a6ccf9065..8121e046b73 100644 --- a/drivers/isdn/hardware/mISDN/ipac.h +++ b/drivers/isdn/hardware/mISDN/ipac.h | |||
@@ -29,7 +29,7 @@ struct isac_hw { | |||
29 | u32 type; | 29 | u32 type; |
30 | u32 off; /* offset to isac regs */ | 30 | u32 off; /* offset to isac regs */ |
31 | char *name; | 31 | char *name; |
32 | spinlock_t *hwlock; /* lock HW acccess */ | 32 | spinlock_t *hwlock; /* lock HW access */ |
33 | read_reg_func *read_reg; | 33 | read_reg_func *read_reg; |
34 | write_reg_func *write_reg; | 34 | write_reg_func *write_reg; |
35 | fifo_func *read_fifo; | 35 | fifo_func *read_fifo; |
@@ -70,7 +70,7 @@ struct ipac_hw { | |||
70 | struct hscx_hw hscx[2]; | 70 | struct hscx_hw hscx[2]; |
71 | char *name; | 71 | char *name; |
72 | void *hw; | 72 | void *hw; |
73 | spinlock_t *hwlock; /* lock HW acccess */ | 73 | spinlock_t *hwlock; /* lock HW access */ |
74 | struct module *owner; | 74 | struct module *owner; |
75 | u32 type; | 75 | u32 type; |
76 | read_reg_func *read_reg; | 76 | read_reg_func *read_reg; |
diff --git a/drivers/isdn/hardware/mISDN/isar.h b/drivers/isdn/hardware/mISDN/isar.h index 4a134acd44d..9962bdf699c 100644 --- a/drivers/isdn/hardware/mISDN/isar.h +++ b/drivers/isdn/hardware/mISDN/isar.h | |||
@@ -44,7 +44,7 @@ struct isar_ch { | |||
44 | struct isar_hw { | 44 | struct isar_hw { |
45 | struct isar_ch ch[2]; | 45 | struct isar_ch ch[2]; |
46 | void *hw; | 46 | void *hw; |
47 | spinlock_t *hwlock; /* lock HW acccess */ | 47 | spinlock_t *hwlock; /* lock HW access */ |
48 | char *name; | 48 | char *name; |
49 | struct module *owner; | 49 | struct module *owner; |
50 | read_reg_func *read_reg; | 50 | read_reg_func *read_reg; |
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 76d9e673b4e..309bacf1fad 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c | |||
@@ -112,7 +112,7 @@ | |||
112 | * Disable rx-data: | 112 | * Disable rx-data: |
113 | * If cmx is realized in hardware, rx data will be disabled if requested by | 113 | * If cmx is realized in hardware, rx data will be disabled if requested by |
114 | * the upper layer. If dtmf decoding is done by software and enabled, rx data | 114 | * the upper layer. If dtmf decoding is done by software and enabled, rx data |
115 | * will not be diabled but blocked to the upper layer. | 115 | * will not be disabled but blocked to the upper layer. |
116 | * | 116 | * |
117 | * HFC conference engine: | 117 | * HFC conference engine: |
118 | * If it is possible to realize all features using hardware, hardware will be | 118 | * If it is possible to realize all features using hardware, hardware will be |
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index 33facd0c45d..80a3ae3c00b 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c | |||
@@ -98,7 +98,6 @@ | |||
98 | #define LP5521_EXT_CLK_USED 0x08 | 98 | #define LP5521_EXT_CLK_USED 0x08 |
99 | 99 | ||
100 | struct lp5521_engine { | 100 | struct lp5521_engine { |
101 | const struct attribute_group *attributes; | ||
102 | int id; | 101 | int id; |
103 | u8 mode; | 102 | u8 mode; |
104 | u8 prog_page; | 103 | u8 prog_page; |
@@ -225,25 +224,22 @@ static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr) | |||
225 | curr); | 224 | curr); |
226 | } | 225 | } |
227 | 226 | ||
228 | static void lp5521_init_engine(struct lp5521_chip *chip, | 227 | static void lp5521_init_engine(struct lp5521_chip *chip) |
229 | const struct attribute_group *attr_group) | ||
230 | { | 228 | { |
231 | int i; | 229 | int i; |
232 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { | 230 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { |
233 | chip->engines[i].id = i + 1; | 231 | chip->engines[i].id = i + 1; |
234 | chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2); | 232 | chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2); |
235 | chip->engines[i].prog_page = i; | 233 | chip->engines[i].prog_page = i; |
236 | chip->engines[i].attributes = &attr_group[i]; | ||
237 | } | 234 | } |
238 | } | 235 | } |
239 | 236 | ||
240 | static int lp5521_configure(struct i2c_client *client, | 237 | static int lp5521_configure(struct i2c_client *client) |
241 | const struct attribute_group *attr_group) | ||
242 | { | 238 | { |
243 | struct lp5521_chip *chip = i2c_get_clientdata(client); | 239 | struct lp5521_chip *chip = i2c_get_clientdata(client); |
244 | int ret; | 240 | int ret; |
245 | 241 | ||
246 | lp5521_init_engine(chip, attr_group); | 242 | lp5521_init_engine(chip); |
247 | 243 | ||
248 | /* Set all PWMs to direct control mode */ | 244 | /* Set all PWMs to direct control mode */ |
249 | ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); | 245 | ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); |
@@ -329,9 +325,6 @@ static int lp5521_detect(struct i2c_client *client) | |||
329 | /* Set engine mode and create appropriate sysfs attributes, if required. */ | 325 | /* Set engine mode and create appropriate sysfs attributes, if required. */ |
330 | static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) | 326 | static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) |
331 | { | 327 | { |
332 | struct lp5521_chip *chip = engine_to_lp5521(engine); | ||
333 | struct i2c_client *client = chip->client; | ||
334 | struct device *dev = &client->dev; | ||
335 | int ret = 0; | 328 | int ret = 0; |
336 | 329 | ||
337 | /* if in that mode already do nothing, except for run */ | 330 | /* if in that mode already do nothing, except for run */ |
@@ -343,18 +336,10 @@ static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) | |||
343 | } else if (mode == LP5521_CMD_LOAD) { | 336 | } else if (mode == LP5521_CMD_LOAD) { |
344 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); | 337 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); |
345 | lp5521_set_engine_mode(engine, LP5521_CMD_LOAD); | 338 | lp5521_set_engine_mode(engine, LP5521_CMD_LOAD); |
346 | |||
347 | ret = sysfs_create_group(&dev->kobj, engine->attributes); | ||
348 | if (ret) | ||
349 | return ret; | ||
350 | } else if (mode == LP5521_CMD_DISABLED) { | 339 | } else if (mode == LP5521_CMD_DISABLED) { |
351 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); | 340 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); |
352 | } | 341 | } |
353 | 342 | ||
354 | /* remove load attribute from sysfs if not in load mode */ | ||
355 | if (engine->mode == LP5521_CMD_LOAD && mode != LP5521_CMD_LOAD) | ||
356 | sysfs_remove_group(&dev->kobj, engine->attributes); | ||
357 | |||
358 | engine->mode = mode; | 343 | engine->mode = mode; |
359 | 344 | ||
360 | return ret; | 345 | return ret; |
@@ -373,6 +358,8 @@ static int lp5521_do_store_load(struct lp5521_engine *engine, | |||
373 | while ((offset < len - 1) && (i < LP5521_PROGRAM_LENGTH)) { | 358 | while ((offset < len - 1) && (i < LP5521_PROGRAM_LENGTH)) { |
374 | /* separate sscanfs because length is working only for %s */ | 359 | /* separate sscanfs because length is working only for %s */ |
375 | ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); | 360 | ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); |
361 | if (ret != 2) | ||
362 | goto fail; | ||
376 | ret = sscanf(c, "%2x", &cmd); | 363 | ret = sscanf(c, "%2x", &cmd); |
377 | if (ret != 1) | 364 | if (ret != 1) |
378 | goto fail; | 365 | goto fail; |
@@ -387,7 +374,10 @@ static int lp5521_do_store_load(struct lp5521_engine *engine, | |||
387 | goto fail; | 374 | goto fail; |
388 | 375 | ||
389 | mutex_lock(&chip->lock); | 376 | mutex_lock(&chip->lock); |
390 | ret = lp5521_load_program(engine, pattern); | 377 | if (engine->mode == LP5521_CMD_LOAD) |
378 | ret = lp5521_load_program(engine, pattern); | ||
379 | else | ||
380 | ret = -EINVAL; | ||
391 | mutex_unlock(&chip->lock); | 381 | mutex_unlock(&chip->lock); |
392 | 382 | ||
393 | if (ret) { | 383 | if (ret) { |
@@ -574,20 +564,8 @@ static struct attribute *lp5521_attributes[] = { | |||
574 | &dev_attr_engine2_mode.attr, | 564 | &dev_attr_engine2_mode.attr, |
575 | &dev_attr_engine3_mode.attr, | 565 | &dev_attr_engine3_mode.attr, |
576 | &dev_attr_selftest.attr, | 566 | &dev_attr_selftest.attr, |
577 | NULL | ||
578 | }; | ||
579 | |||
580 | static struct attribute *lp5521_engine1_attributes[] = { | ||
581 | &dev_attr_engine1_load.attr, | 567 | &dev_attr_engine1_load.attr, |
582 | NULL | ||
583 | }; | ||
584 | |||
585 | static struct attribute *lp5521_engine2_attributes[] = { | ||
586 | &dev_attr_engine2_load.attr, | 568 | &dev_attr_engine2_load.attr, |
587 | NULL | ||
588 | }; | ||
589 | |||
590 | static struct attribute *lp5521_engine3_attributes[] = { | ||
591 | &dev_attr_engine3_load.attr, | 569 | &dev_attr_engine3_load.attr, |
592 | NULL | 570 | NULL |
593 | }; | 571 | }; |
@@ -596,12 +574,6 @@ static const struct attribute_group lp5521_group = { | |||
596 | .attrs = lp5521_attributes, | 574 | .attrs = lp5521_attributes, |
597 | }; | 575 | }; |
598 | 576 | ||
599 | static const struct attribute_group lp5521_engine_group[] = { | ||
600 | {.attrs = lp5521_engine1_attributes }, | ||
601 | {.attrs = lp5521_engine2_attributes }, | ||
602 | {.attrs = lp5521_engine3_attributes }, | ||
603 | }; | ||
604 | |||
605 | static int lp5521_register_sysfs(struct i2c_client *client) | 577 | static int lp5521_register_sysfs(struct i2c_client *client) |
606 | { | 578 | { |
607 | struct device *dev = &client->dev; | 579 | struct device *dev = &client->dev; |
@@ -616,12 +588,6 @@ static void lp5521_unregister_sysfs(struct i2c_client *client) | |||
616 | 588 | ||
617 | sysfs_remove_group(&dev->kobj, &lp5521_group); | 589 | sysfs_remove_group(&dev->kobj, &lp5521_group); |
618 | 590 | ||
619 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { | ||
620 | if (chip->engines[i].mode == LP5521_CMD_LOAD) | ||
621 | sysfs_remove_group(&dev->kobj, | ||
622 | chip->engines[i].attributes); | ||
623 | } | ||
624 | |||
625 | for (i = 0; i < chip->num_leds; i++) | 591 | for (i = 0; i < chip->num_leds; i++) |
626 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, | 592 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, |
627 | &lp5521_led_attribute_group); | 593 | &lp5521_led_attribute_group); |
@@ -651,7 +617,8 @@ static int __init lp5521_init_led(struct lp5521_led *led, | |||
651 | return -EINVAL; | 617 | return -EINVAL; |
652 | } | 618 | } |
653 | 619 | ||
654 | snprintf(name, sizeof(name), "%s:channel%d", client->name, chan); | 620 | snprintf(name, sizeof(name), "%s:channel%d", |
621 | pdata->label ?: client->name, chan); | ||
655 | led->cdev.brightness_set = lp5521_set_brightness; | 622 | led->cdev.brightness_set = lp5521_set_brightness; |
656 | led->cdev.name = name; | 623 | led->cdev.name = name; |
657 | res = led_classdev_register(dev, &led->cdev); | 624 | res = led_classdev_register(dev, &led->cdev); |
@@ -723,7 +690,7 @@ static int lp5521_probe(struct i2c_client *client, | |||
723 | 690 | ||
724 | dev_info(&client->dev, "%s programmable led chip found\n", id->name); | 691 | dev_info(&client->dev, "%s programmable led chip found\n", id->name); |
725 | 692 | ||
726 | ret = lp5521_configure(client, lp5521_engine_group); | 693 | ret = lp5521_configure(client); |
727 | if (ret < 0) { | 694 | if (ret < 0) { |
728 | dev_err(&client->dev, "error configuring chip\n"); | 695 | dev_err(&client->dev, "error configuring chip\n"); |
729 | goto fail2; | 696 | goto fail2; |
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index 0cc4ead2fd8..d0c4068ecdd 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c | |||
@@ -105,7 +105,6 @@ | |||
105 | #define SHIFT_MASK(id) (((id) - 1) * 2) | 105 | #define SHIFT_MASK(id) (((id) - 1) * 2) |
106 | 106 | ||
107 | struct lp5523_engine { | 107 | struct lp5523_engine { |
108 | const struct attribute_group *attributes; | ||
109 | int id; | 108 | int id; |
110 | u8 mode; | 109 | u8 mode; |
111 | u8 prog_page; | 110 | u8 prog_page; |
@@ -403,14 +402,23 @@ static ssize_t store_engine_leds(struct device *dev, | |||
403 | struct i2c_client *client = to_i2c_client(dev); | 402 | struct i2c_client *client = to_i2c_client(dev); |
404 | struct lp5523_chip *chip = i2c_get_clientdata(client); | 403 | struct lp5523_chip *chip = i2c_get_clientdata(client); |
405 | u16 mux = 0; | 404 | u16 mux = 0; |
405 | ssize_t ret; | ||
406 | 406 | ||
407 | if (lp5523_mux_parse(buf, &mux, len)) | 407 | if (lp5523_mux_parse(buf, &mux, len)) |
408 | return -EINVAL; | 408 | return -EINVAL; |
409 | 409 | ||
410 | mutex_lock(&chip->lock); | ||
411 | ret = -EINVAL; | ||
412 | if (chip->engines[nr - 1].mode != LP5523_CMD_LOAD) | ||
413 | goto leave; | ||
414 | |||
410 | if (lp5523_load_mux(&chip->engines[nr - 1], mux)) | 415 | if (lp5523_load_mux(&chip->engines[nr - 1], mux)) |
411 | return -EINVAL; | 416 | goto leave; |
412 | 417 | ||
413 | return len; | 418 | ret = len; |
419 | leave: | ||
420 | mutex_unlock(&chip->lock); | ||
421 | return ret; | ||
414 | } | 422 | } |
415 | 423 | ||
416 | #define store_leds(nr) \ | 424 | #define store_leds(nr) \ |
@@ -556,7 +564,11 @@ static int lp5523_do_store_load(struct lp5523_engine *engine, | |||
556 | 564 | ||
557 | mutex_lock(&chip->lock); | 565 | mutex_lock(&chip->lock); |
558 | 566 | ||
559 | ret = lp5523_load_program(engine, pattern); | 567 | if (engine->mode == LP5523_CMD_LOAD) |
568 | ret = lp5523_load_program(engine, pattern); | ||
569 | else | ||
570 | ret = -EINVAL; | ||
571 | |||
560 | mutex_unlock(&chip->lock); | 572 | mutex_unlock(&chip->lock); |
561 | 573 | ||
562 | if (ret) { | 574 | if (ret) { |
@@ -737,37 +749,18 @@ static struct attribute *lp5523_attributes[] = { | |||
737 | &dev_attr_engine2_mode.attr, | 749 | &dev_attr_engine2_mode.attr, |
738 | &dev_attr_engine3_mode.attr, | 750 | &dev_attr_engine3_mode.attr, |
739 | &dev_attr_selftest.attr, | 751 | &dev_attr_selftest.attr, |
740 | NULL | ||
741 | }; | ||
742 | |||
743 | static struct attribute *lp5523_engine1_attributes[] = { | ||
744 | &dev_attr_engine1_load.attr, | 752 | &dev_attr_engine1_load.attr, |
745 | &dev_attr_engine1_leds.attr, | 753 | &dev_attr_engine1_leds.attr, |
746 | NULL | ||
747 | }; | ||
748 | |||
749 | static struct attribute *lp5523_engine2_attributes[] = { | ||
750 | &dev_attr_engine2_load.attr, | 754 | &dev_attr_engine2_load.attr, |
751 | &dev_attr_engine2_leds.attr, | 755 | &dev_attr_engine2_leds.attr, |
752 | NULL | ||
753 | }; | ||
754 | |||
755 | static struct attribute *lp5523_engine3_attributes[] = { | ||
756 | &dev_attr_engine3_load.attr, | 756 | &dev_attr_engine3_load.attr, |
757 | &dev_attr_engine3_leds.attr, | 757 | &dev_attr_engine3_leds.attr, |
758 | NULL | ||
759 | }; | 758 | }; |
760 | 759 | ||
761 | static const struct attribute_group lp5523_group = { | 760 | static const struct attribute_group lp5523_group = { |
762 | .attrs = lp5523_attributes, | 761 | .attrs = lp5523_attributes, |
763 | }; | 762 | }; |
764 | 763 | ||
765 | static const struct attribute_group lp5523_engine_group[] = { | ||
766 | {.attrs = lp5523_engine1_attributes }, | ||
767 | {.attrs = lp5523_engine2_attributes }, | ||
768 | {.attrs = lp5523_engine3_attributes }, | ||
769 | }; | ||
770 | |||
771 | static int lp5523_register_sysfs(struct i2c_client *client) | 764 | static int lp5523_register_sysfs(struct i2c_client *client) |
772 | { | 765 | { |
773 | struct device *dev = &client->dev; | 766 | struct device *dev = &client->dev; |
@@ -788,10 +781,6 @@ static void lp5523_unregister_sysfs(struct i2c_client *client) | |||
788 | 781 | ||
789 | sysfs_remove_group(&dev->kobj, &lp5523_group); | 782 | sysfs_remove_group(&dev->kobj, &lp5523_group); |
790 | 783 | ||
791 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) | ||
792 | if (chip->engines[i].mode == LP5523_CMD_LOAD) | ||
793 | sysfs_remove_group(&dev->kobj, &lp5523_engine_group[i]); | ||
794 | |||
795 | for (i = 0; i < chip->num_leds; i++) | 784 | for (i = 0; i < chip->num_leds; i++) |
796 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, | 785 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, |
797 | &lp5523_led_attribute_group); | 786 | &lp5523_led_attribute_group); |
@@ -802,10 +791,6 @@ static void lp5523_unregister_sysfs(struct i2c_client *client) | |||
802 | /*--------------------------------------------------------------*/ | 791 | /*--------------------------------------------------------------*/ |
803 | static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) | 792 | static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) |
804 | { | 793 | { |
805 | /* engine to chip */ | ||
806 | struct lp5523_chip *chip = engine_to_lp5523(engine); | ||
807 | struct i2c_client *client = chip->client; | ||
808 | struct device *dev = &client->dev; | ||
809 | int ret = 0; | 794 | int ret = 0; |
810 | 795 | ||
811 | /* if in that mode already do nothing, except for run */ | 796 | /* if in that mode already do nothing, except for run */ |
@@ -817,18 +802,10 @@ static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) | |||
817 | } else if (mode == LP5523_CMD_LOAD) { | 802 | } else if (mode == LP5523_CMD_LOAD) { |
818 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); | 803 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); |
819 | lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); | 804 | lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); |
820 | |||
821 | ret = sysfs_create_group(&dev->kobj, engine->attributes); | ||
822 | if (ret) | ||
823 | return ret; | ||
824 | } else if (mode == LP5523_CMD_DISABLED) { | 805 | } else if (mode == LP5523_CMD_DISABLED) { |
825 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); | 806 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); |
826 | } | 807 | } |
827 | 808 | ||
828 | /* remove load attribute from sysfs if not in load mode */ | ||
829 | if (engine->mode == LP5523_CMD_LOAD && mode != LP5523_CMD_LOAD) | ||
830 | sysfs_remove_group(&dev->kobj, engine->attributes); | ||
831 | |||
832 | engine->mode = mode; | 809 | engine->mode = mode; |
833 | 810 | ||
834 | return ret; | 811 | return ret; |
@@ -845,7 +822,6 @@ static int __init lp5523_init_engine(struct lp5523_engine *engine, int id) | |||
845 | engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id); | 822 | engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id); |
846 | engine->prog_page = id - 1; | 823 | engine->prog_page = id - 1; |
847 | engine->mux_page = id + 2; | 824 | engine->mux_page = id + 2; |
848 | engine->attributes = &lp5523_engine_group[id - 1]; | ||
849 | 825 | ||
850 | return 0; | 826 | return 0; |
851 | } | 827 | } |
@@ -870,7 +846,8 @@ static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev, | |||
870 | return -EINVAL; | 846 | return -EINVAL; |
871 | } | 847 | } |
872 | 848 | ||
873 | snprintf(name, 32, "lp5523:channel%d", chan); | 849 | snprintf(name, sizeof(name), "%s:channel%d", |
850 | pdata->label ?: "lp5523", chan); | ||
874 | 851 | ||
875 | led->cdev.name = name; | 852 | led->cdev.name = name; |
876 | led->cdev.brightness_set = lp5523_set_brightness; | 853 | led->cdev.brightness_set = lp5523_set_brightness; |
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 43d08756d82..afac338d502 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c | |||
@@ -200,6 +200,32 @@ static void pca9532_led_work(struct work_struct *work) | |||
200 | pca9532_setled(led); | 200 | pca9532_setled(led); |
201 | } | 201 | } |
202 | 202 | ||
203 | static void pca9532_destroy_devices(struct pca9532_data *data, int n_devs) | ||
204 | { | ||
205 | int i = n_devs; | ||
206 | |||
207 | if (!data) | ||
208 | return; | ||
209 | |||
210 | while (--i >= 0) { | ||
211 | switch (data->leds[i].type) { | ||
212 | case PCA9532_TYPE_NONE: | ||
213 | break; | ||
214 | case PCA9532_TYPE_LED: | ||
215 | led_classdev_unregister(&data->leds[i].ldev); | ||
216 | cancel_work_sync(&data->leds[i].work); | ||
217 | break; | ||
218 | case PCA9532_TYPE_N2100_BEEP: | ||
219 | if (data->idev != NULL) { | ||
220 | input_unregister_device(data->idev); | ||
221 | cancel_work_sync(&data->work); | ||
222 | data->idev = NULL; | ||
223 | } | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | |||
203 | static int pca9532_configure(struct i2c_client *client, | 229 | static int pca9532_configure(struct i2c_client *client, |
204 | struct pca9532_data *data, struct pca9532_platform_data *pdata) | 230 | struct pca9532_data *data, struct pca9532_platform_data *pdata) |
205 | { | 231 | { |
@@ -274,25 +300,7 @@ static int pca9532_configure(struct i2c_client *client, | |||
274 | return 0; | 300 | return 0; |
275 | 301 | ||
276 | exit: | 302 | exit: |
277 | if (i > 0) | 303 | pca9532_destroy_devices(data, i); |
278 | for (i = i - 1; i >= 0; i--) | ||
279 | switch (data->leds[i].type) { | ||
280 | case PCA9532_TYPE_NONE: | ||
281 | break; | ||
282 | case PCA9532_TYPE_LED: | ||
283 | led_classdev_unregister(&data->leds[i].ldev); | ||
284 | cancel_work_sync(&data->leds[i].work); | ||
285 | break; | ||
286 | case PCA9532_TYPE_N2100_BEEP: | ||
287 | if (data->idev != NULL) { | ||
288 | input_unregister_device(data->idev); | ||
289 | input_free_device(data->idev); | ||
290 | cancel_work_sync(&data->work); | ||
291 | data->idev = NULL; | ||
292 | } | ||
293 | break; | ||
294 | } | ||
295 | |||
296 | return err; | 304 | return err; |
297 | } | 305 | } |
298 | 306 | ||
@@ -329,25 +337,7 @@ static int pca9532_probe(struct i2c_client *client, | |||
329 | static int pca9532_remove(struct i2c_client *client) | 337 | static int pca9532_remove(struct i2c_client *client) |
330 | { | 338 | { |
331 | struct pca9532_data *data = i2c_get_clientdata(client); | 339 | struct pca9532_data *data = i2c_get_clientdata(client); |
332 | int i; | 340 | pca9532_destroy_devices(data, 16); |
333 | for (i = 0; i < 16; i++) | ||
334 | switch (data->leds[i].type) { | ||
335 | case PCA9532_TYPE_NONE: | ||
336 | break; | ||
337 | case PCA9532_TYPE_LED: | ||
338 | led_classdev_unregister(&data->leds[i].ldev); | ||
339 | cancel_work_sync(&data->leds[i].work); | ||
340 | break; | ||
341 | case PCA9532_TYPE_N2100_BEEP: | ||
342 | if (data->idev != NULL) { | ||
343 | input_unregister_device(data->idev); | ||
344 | input_free_device(data->idev); | ||
345 | cancel_work_sync(&data->work); | ||
346 | data->idev = NULL; | ||
347 | } | ||
348 | break; | ||
349 | } | ||
350 | |||
351 | kfree(data); | 341 | kfree(data); |
352 | return 0; | 342 | return 0; |
353 | } | 343 | } |
diff --git a/drivers/leds/ledtrig-backlight.c b/drivers/leds/ledtrig-backlight.c index f948e57bd9b..2b513a2ad7d 100644 --- a/drivers/leds/ledtrig-backlight.c +++ b/drivers/leds/ledtrig-backlight.c | |||
@@ -26,6 +26,7 @@ struct bl_trig_notifier { | |||
26 | int brightness; | 26 | int brightness; |
27 | int old_status; | 27 | int old_status; |
28 | struct notifier_block notifier; | 28 | struct notifier_block notifier; |
29 | unsigned invert; | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | static int fb_notifier_callback(struct notifier_block *p, | 32 | static int fb_notifier_callback(struct notifier_block *p, |
@@ -36,23 +37,64 @@ static int fb_notifier_callback(struct notifier_block *p, | |||
36 | struct led_classdev *led = n->led; | 37 | struct led_classdev *led = n->led; |
37 | struct fb_event *fb_event = data; | 38 | struct fb_event *fb_event = data; |
38 | int *blank = fb_event->data; | 39 | int *blank = fb_event->data; |
40 | int new_status = *blank ? BLANK : UNBLANK; | ||
39 | 41 | ||
40 | switch (event) { | 42 | switch (event) { |
41 | case FB_EVENT_BLANK : | 43 | case FB_EVENT_BLANK : |
42 | if (*blank && n->old_status == UNBLANK) { | 44 | if (new_status == n->old_status) |
45 | break; | ||
46 | |||
47 | if ((n->old_status == UNBLANK) ^ n->invert) { | ||
43 | n->brightness = led->brightness; | 48 | n->brightness = led->brightness; |
44 | led_set_brightness(led, LED_OFF); | 49 | led_set_brightness(led, LED_OFF); |
45 | n->old_status = BLANK; | 50 | } else { |
46 | } else if (!*blank && n->old_status == BLANK) { | ||
47 | led_set_brightness(led, n->brightness); | 51 | led_set_brightness(led, n->brightness); |
48 | n->old_status = UNBLANK; | ||
49 | } | 52 | } |
53 | |||
54 | n->old_status = new_status; | ||
55 | |||
50 | break; | 56 | break; |
51 | } | 57 | } |
52 | 58 | ||
53 | return 0; | 59 | return 0; |
54 | } | 60 | } |
55 | 61 | ||
62 | static ssize_t bl_trig_invert_show(struct device *dev, | ||
63 | struct device_attribute *attr, char *buf) | ||
64 | { | ||
65 | struct led_classdev *led = dev_get_drvdata(dev); | ||
66 | struct bl_trig_notifier *n = led->trigger_data; | ||
67 | |||
68 | return sprintf(buf, "%u\n", n->invert); | ||
69 | } | ||
70 | |||
71 | static ssize_t bl_trig_invert_store(struct device *dev, | ||
72 | struct device_attribute *attr, const char *buf, size_t num) | ||
73 | { | ||
74 | struct led_classdev *led = dev_get_drvdata(dev); | ||
75 | struct bl_trig_notifier *n = led->trigger_data; | ||
76 | unsigned long invert; | ||
77 | int ret; | ||
78 | |||
79 | ret = strict_strtoul(buf, 10, &invert); | ||
80 | if (ret < 0) | ||
81 | return ret; | ||
82 | |||
83 | if (invert > 1) | ||
84 | return -EINVAL; | ||
85 | |||
86 | n->invert = invert; | ||
87 | |||
88 | /* After inverting, we need to update the LED. */ | ||
89 | if ((n->old_status == BLANK) ^ n->invert) | ||
90 | led_set_brightness(led, LED_OFF); | ||
91 | else | ||
92 | led_set_brightness(led, n->brightness); | ||
93 | |||
94 | return num; | ||
95 | } | ||
96 | static DEVICE_ATTR(inverted, 0644, bl_trig_invert_show, bl_trig_invert_store); | ||
97 | |||
56 | static void bl_trig_activate(struct led_classdev *led) | 98 | static void bl_trig_activate(struct led_classdev *led) |
57 | { | 99 | { |
58 | int ret; | 100 | int ret; |
@@ -66,6 +108,10 @@ static void bl_trig_activate(struct led_classdev *led) | |||
66 | return; | 108 | return; |
67 | } | 109 | } |
68 | 110 | ||
111 | ret = device_create_file(led->dev, &dev_attr_inverted); | ||
112 | if (ret) | ||
113 | goto err_invert; | ||
114 | |||
69 | n->led = led; | 115 | n->led = led; |
70 | n->brightness = led->brightness; | 116 | n->brightness = led->brightness; |
71 | n->old_status = UNBLANK; | 117 | n->old_status = UNBLANK; |
@@ -74,6 +120,12 @@ static void bl_trig_activate(struct led_classdev *led) | |||
74 | ret = fb_register_client(&n->notifier); | 120 | ret = fb_register_client(&n->notifier); |
75 | if (ret) | 121 | if (ret) |
76 | dev_err(led->dev, "unable to register backlight trigger\n"); | 122 | dev_err(led->dev, "unable to register backlight trigger\n"); |
123 | |||
124 | return; | ||
125 | |||
126 | err_invert: | ||
127 | led->trigger_data = NULL; | ||
128 | kfree(n); | ||
77 | } | 129 | } |
78 | 130 | ||
79 | static void bl_trig_deactivate(struct led_classdev *led) | 131 | static void bl_trig_deactivate(struct led_classdev *led) |
@@ -82,6 +134,7 @@ static void bl_trig_deactivate(struct led_classdev *led) | |||
82 | (struct bl_trig_notifier *) led->trigger_data; | 134 | (struct bl_trig_notifier *) led->trigger_data; |
83 | 135 | ||
84 | if (n) { | 136 | if (n) { |
137 | device_remove_file(led->dev, &dev_attr_inverted); | ||
85 | fb_unregister_client(&n->notifier); | 138 | fb_unregister_client(&n->notifier); |
86 | kfree(n); | 139 | kfree(n); |
87 | } | 140 | } |
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index 1cec02f6c43..ade1e656bfb 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #define MAX_PMU_LEVEL 0xFF | 16 | #define MAX_PMU_LEVEL 0xFF |
17 | 17 | ||
18 | static struct backlight_ops pmu_backlight_data; | 18 | static const struct backlight_ops pmu_backlight_data; |
19 | static DEFINE_SPINLOCK(pmu_backlight_lock); | 19 | static DEFINE_SPINLOCK(pmu_backlight_lock); |
20 | static int sleeping, uses_pmu_bl; | 20 | static int sleeping, uses_pmu_bl; |
21 | static u8 bl_curve[FB_BACKLIGHT_LEVELS]; | 21 | static u8 bl_curve[FB_BACKLIGHT_LEVELS]; |
@@ -115,7 +115,7 @@ static int pmu_backlight_get_brightness(struct backlight_device *bd) | |||
115 | return bd->props.brightness; | 115 | return bd->props.brightness; |
116 | } | 116 | } |
117 | 117 | ||
118 | static struct backlight_ops pmu_backlight_data = { | 118 | static const struct backlight_ops pmu_backlight_data = { |
119 | .get_brightness = pmu_backlight_get_brightness, | 119 | .get_brightness = pmu_backlight_get_brightness, |
120 | .update_status = pmu_backlight_update_status, | 120 | .update_status = pmu_backlight_update_status, |
121 | 121 | ||
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index cd29c824838..8b021eb0d48 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -2257,7 +2257,7 @@ static int pmu_sleep_valid(suspend_state_t state) | |||
2257 | && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0); | 2257 | && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0); |
2258 | } | 2258 | } |
2259 | 2259 | ||
2260 | static struct platform_suspend_ops pmu_pm_ops = { | 2260 | static const struct platform_suspend_ops pmu_pm_ops = { |
2261 | .enter = powerbook_sleep, | 2261 | .enter = powerbook_sleep, |
2262 | .valid = pmu_sleep_valid, | 2262 | .valid = pmu_sleep_valid, |
2263 | }; | 2263 | }; |
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h index 2c00980acfc..7e40035028d 100644 --- a/drivers/media/video/cx18/cx23418.h +++ b/drivers/media/video/cx18/cx23418.h | |||
@@ -177,7 +177,7 @@ | |||
177 | IN[0] - Task handle. | 177 | IN[0] - Task handle. |
178 | IN[1] - luma type: 0 = disable, 1 = 1D horizontal only, 2 = 1D vertical only, | 178 | IN[1] - luma type: 0 = disable, 1 = 1D horizontal only, 2 = 1D vertical only, |
179 | 3 = 2D H/V separable, 4 = 2D symmetric non-separable | 179 | 3 = 2D H/V separable, 4 = 2D symmetric non-separable |
180 | IN[2] - chroma type: 0 - diable, 1 = 1D horizontal | 180 | IN[2] - chroma type: 0 - disable, 1 = 1D horizontal |
181 | ReturnCode - One of the ERR_CAPTURE_... */ | 181 | ReturnCode - One of the ERR_CAPTURE_... */ |
182 | #define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C) | 182 | #define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C) |
183 | 183 | ||
diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/video/cx25840/cx25840-ir.c index 627926f6bde..7eb79af28aa 100644 --- a/drivers/media/video/cx25840/cx25840-ir.c +++ b/drivers/media/video/cx25840/cx25840-ir.c | |||
@@ -261,7 +261,7 @@ static u16 ns_to_pulse_width_count(u32 ns, u16 divider) | |||
261 | u32 rem; | 261 | u32 rem; |
262 | 262 | ||
263 | /* | 263 | /* |
264 | * The 2 lsb's of the pulse width timer count are not accessable, hence | 264 | * The 2 lsb's of the pulse width timer count are not accessible, hence |
265 | * the (1 << 2) | 265 | * the (1 << 2) |
266 | */ | 266 | */ |
267 | n = ((u64) ns) * CX25840_IR_REFCLK_FREQ / 1000000; /* millicycles */ | 267 | n = ((u64) ns) * CX25840_IR_REFCLK_FREQ / 1000000; /* millicycles */ |
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h index 188841b476e..ebd5c4338eb 100644 --- a/drivers/media/video/davinci/vpif.h +++ b/drivers/media/video/davinci/vpif.h | |||
@@ -33,7 +33,7 @@ extern spinlock_t vpif_lock; | |||
33 | #define regr(reg) readl((reg) + vpif_base) | 33 | #define regr(reg) readl((reg) + vpif_base) |
34 | #define regw(value, reg) writel(value, (reg + vpif_base)) | 34 | #define regw(value, reg) writel(value, (reg + vpif_base)) |
35 | 35 | ||
36 | /* Register Addresss Offsets */ | 36 | /* Register Address Offsets */ |
37 | #define VPIF_PID (0x0000) | 37 | #define VPIF_PID (0x0000) |
38 | #define VPIF_CH0_CTRL (0x0004) | 38 | #define VPIF_CH0_CTRL (0x0004) |
39 | #define VPIF_CH1_CTRL (0x0008) | 39 | #define VPIF_CH1_CTRL (0x0008) |
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c index 7918680917d..3e5cf27ec2b 100644 --- a/drivers/media/video/davinci/vpss.c +++ b/drivers/media/video/davinci/vpss.c | |||
@@ -85,7 +85,7 @@ enum vpss_platform_type { | |||
85 | /* | 85 | /* |
86 | * vpss operations. Depends on platform. Not all functions are available | 86 | * vpss operations. Depends on platform. Not all functions are available |
87 | * on all platforms. The api, first check if a functio is available before | 87 | * on all platforms. The api, first check if a functio is available before |
88 | * invoking it. In the probe, the function ptrs are intialized based on | 88 | * invoking it. In the probe, the function ptrs are initialized based on |
89 | * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc. | 89 | * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc. |
90 | */ | 90 | */ |
91 | struct vpss_hw_ops { | 91 | struct vpss_hw_ops { |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 83de97ad971..029a4babfd6 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -1286,7 +1286,7 @@ static int omap_vout_release(struct file *file) | |||
1286 | videobuf_mmap_free(q); | 1286 | videobuf_mmap_free(q); |
1287 | 1287 | ||
1288 | /* Even if apply changes fails we should continue | 1288 | /* Even if apply changes fails we should continue |
1289 | freeing allocated memeory */ | 1289 | freeing allocated memory */ |
1290 | if (vout->streaming) { | 1290 | if (vout->streaming) { |
1291 | u32 mask = 0; | 1291 | u32 mask = 0; |
1292 | 1292 | ||
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c index d6bf3f82cc3..58af67f2278 100644 --- a/drivers/media/video/saa7164/saa7164-core.c +++ b/drivers/media/video/saa7164/saa7164-core.c | |||
@@ -655,8 +655,8 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id) | |||
655 | goto out; | 655 | goto out; |
656 | } | 656 | } |
657 | 657 | ||
658 | /* Check that the hardware is accessable. If the status bytes are | 658 | /* Check that the hardware is accessible. If the status bytes are |
659 | * 0xFF then the device is not accessable, the the IRQ belongs | 659 | * 0xFF then the device is not accessible, the the IRQ belongs |
660 | * to another driver. | 660 | * to another driver. |
661 | * 4 x u32 interrupt registers. | 661 | * 4 x u32 interrupt registers. |
662 | */ | 662 | */ |
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h index 494957b10ba..7f38549715b 100644 --- a/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/drivers/media/video/sn9c102/sn9c102_sensor.h | |||
@@ -147,7 +147,7 @@ enum sn9c102_i2c_interface { | |||
147 | 147 | ||
148 | struct sn9c102_sensor { | 148 | struct sn9c102_sensor { |
149 | char name[32], /* sensor name */ | 149 | char name[32], /* sensor name */ |
150 | maintainer[64]; /* name of the mantainer <email> */ | 150 | maintainer[64]; /* name of the maintainer <email> */ |
151 | 151 | ||
152 | enum sn9c102_bridge supported_bridge; /* supported SN9C1xx bridges */ | 152 | enum sn9c102_bridge supported_bridge; /* supported SN9C1xx bridges */ |
153 | 153 | ||
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c index e63b40f5a70..c799e4eb6fc 100644 --- a/drivers/media/video/tvp7002.c +++ b/drivers/media/video/tvp7002.c | |||
@@ -789,7 +789,7 @@ static int tvp7002_query_dv_preset(struct v4l2_subdev *sd, | |||
789 | * Get the value of a TVP7002 decoder device register. | 789 | * Get the value of a TVP7002 decoder device register. |
790 | * Returns zero when successful, -EINVAL if register read fails or | 790 | * Returns zero when successful, -EINVAL if register read fails or |
791 | * access to I2C client fails, -EPERM if the call is not allowed | 791 | * access to I2C client fails, -EPERM if the call is not allowed |
792 | * by diabled CAP_SYS_ADMIN. | 792 | * by disabled CAP_SYS_ADMIN. |
793 | */ | 793 | */ |
794 | static int tvp7002_g_register(struct v4l2_subdev *sd, | 794 | static int tvp7002_g_register(struct v4l2_subdev *sd, |
795 | struct v4l2_dbg_register *reg) | 795 | struct v4l2_dbg_register *reg) |
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c index e25aca5759f..2f973cd5640 100644 --- a/drivers/media/video/via-camera.c +++ b/drivers/media/video/via-camera.c | |||
@@ -13,14 +13,12 @@ | |||
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/pci.h> | ||
17 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
18 | #include <linux/videodev2.h> | 17 | #include <linux/videodev2.h> |
19 | #include <media/v4l2-device.h> | 18 | #include <media/v4l2-device.h> |
20 | #include <media/v4l2-ioctl.h> | 19 | #include <media/v4l2-ioctl.h> |
21 | #include <media/v4l2-chip-ident.h> | 20 | #include <media/v4l2-chip-ident.h> |
22 | #include <media/videobuf-dma-sg.h> | 21 | #include <media/videobuf-dma-sg.h> |
23 | #include <linux/device.h> | ||
24 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
25 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
26 | #include <linux/pm_qos_params.h> | 24 | #include <linux/pm_qos_params.h> |
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index c00fe8253c5..e9a3eab7b0c 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c | |||
@@ -465,6 +465,7 @@ static void memstick_check(struct work_struct *work) | |||
465 | if (!host->card) { | 465 | if (!host->card) { |
466 | host->card = card; | 466 | host->card = card; |
467 | if (device_register(&card->dev)) { | 467 | if (device_register(&card->dev)) { |
468 | put_device(&card->dev); | ||
468 | kfree(host->card); | 469 | kfree(host->card); |
469 | host->card = NULL; | 470 | host->card = NULL; |
470 | } | 471 | } |
@@ -510,14 +511,18 @@ int memstick_add_host(struct memstick_host *host) | |||
510 | { | 511 | { |
511 | int rc; | 512 | int rc; |
512 | 513 | ||
513 | if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL)) | 514 | while (1) { |
514 | return -ENOMEM; | 515 | if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL)) |
516 | return -ENOMEM; | ||
515 | 517 | ||
516 | spin_lock(&memstick_host_lock); | 518 | spin_lock(&memstick_host_lock); |
517 | rc = idr_get_new(&memstick_host_idr, host, &host->id); | 519 | rc = idr_get_new(&memstick_host_idr, host, &host->id); |
518 | spin_unlock(&memstick_host_lock); | 520 | spin_unlock(&memstick_host_lock); |
519 | if (rc) | 521 | if (!rc) |
520 | return rc; | 522 | break; |
523 | else if (rc != -EAGAIN) | ||
524 | return rc; | ||
525 | } | ||
521 | 526 | ||
522 | dev_set_name(&host->dev, "memstick%u", host->id); | 527 | dev_set_name(&host->dev, "memstick%u", host->id); |
523 | 528 | ||
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 02362eccc58..57b42bfc7d2 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #define DRIVER_NAME "mspro_block" | 24 | #define DRIVER_NAME "mspro_block" |
25 | 25 | ||
26 | static DEFINE_MUTEX(mspro_block_mutex); | ||
27 | static int major; | 26 | static int major; |
28 | module_param(major, int, 0644); | 27 | module_param(major, int, 0644); |
29 | 28 | ||
@@ -160,6 +159,13 @@ struct mspro_block_data { | |||
160 | int (*mrq_handler)(struct memstick_dev *card, | 159 | int (*mrq_handler)(struct memstick_dev *card, |
161 | struct memstick_request **mrq); | 160 | struct memstick_request **mrq); |
162 | 161 | ||
162 | |||
163 | /* Default request setup function for data access method preferred by | ||
164 | * this host instance. | ||
165 | */ | ||
166 | void (*setup_transfer)(struct memstick_dev *card, | ||
167 | u64 offset, size_t length); | ||
168 | |||
163 | struct attribute_group attr_group; | 169 | struct attribute_group attr_group; |
164 | 170 | ||
165 | struct scatterlist req_sg[MSPRO_BLOCK_MAX_SEGS]; | 171 | struct scatterlist req_sg[MSPRO_BLOCK_MAX_SEGS]; |
@@ -181,7 +187,6 @@ static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode) | |||
181 | struct mspro_block_data *msb = disk->private_data; | 187 | struct mspro_block_data *msb = disk->private_data; |
182 | int rc = -ENXIO; | 188 | int rc = -ENXIO; |
183 | 189 | ||
184 | mutex_lock(&mspro_block_mutex); | ||
185 | mutex_lock(&mspro_block_disk_lock); | 190 | mutex_lock(&mspro_block_disk_lock); |
186 | 191 | ||
187 | if (msb && msb->card) { | 192 | if (msb && msb->card) { |
@@ -193,7 +198,6 @@ static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode) | |||
193 | } | 198 | } |
194 | 199 | ||
195 | mutex_unlock(&mspro_block_disk_lock); | 200 | mutex_unlock(&mspro_block_disk_lock); |
196 | mutex_unlock(&mspro_block_mutex); | ||
197 | 201 | ||
198 | return rc; | 202 | return rc; |
199 | } | 203 | } |
@@ -225,11 +229,7 @@ static int mspro_block_disk_release(struct gendisk *disk) | |||
225 | 229 | ||
226 | static int mspro_block_bd_release(struct gendisk *disk, fmode_t mode) | 230 | static int mspro_block_bd_release(struct gendisk *disk, fmode_t mode) |
227 | { | 231 | { |
228 | int ret; | 232 | return mspro_block_disk_release(disk); |
229 | mutex_lock(&mspro_block_mutex); | ||
230 | ret = mspro_block_disk_release(disk); | ||
231 | mutex_unlock(&mspro_block_mutex); | ||
232 | return ret; | ||
233 | } | 233 | } |
234 | 234 | ||
235 | static int mspro_block_bd_getgeo(struct block_device *bdev, | 235 | static int mspro_block_bd_getgeo(struct block_device *bdev, |
@@ -663,14 +663,43 @@ has_int_reg: | |||
663 | } | 663 | } |
664 | } | 664 | } |
665 | 665 | ||
666 | /*** Transfer setup functions for different access methods. ***/ | ||
667 | |||
668 | /** Setup data transfer request for SET_CMD TPC with arguments in card | ||
669 | * registers. | ||
670 | * | ||
671 | * @card Current media instance | ||
672 | * @offset Target data offset in bytes | ||
673 | * @length Required transfer length in bytes. | ||
674 | */ | ||
675 | static void h_mspro_block_setup_cmd(struct memstick_dev *card, u64 offset, | ||
676 | size_t length) | ||
677 | { | ||
678 | struct mspro_block_data *msb = memstick_get_drvdata(card); | ||
679 | struct mspro_param_register param = { | ||
680 | .system = msb->system, | ||
681 | .data_count = cpu_to_be16((uint16_t)(length / msb->page_size)), | ||
682 | /* ISO C90 warning precludes direct initialization for now. */ | ||
683 | .data_address = 0, | ||
684 | .tpc_param = 0 | ||
685 | }; | ||
686 | |||
687 | do_div(offset, msb->page_size); | ||
688 | param.data_address = cpu_to_be32((uint32_t)offset); | ||
689 | |||
690 | card->next_request = h_mspro_block_req_init; | ||
691 | msb->mrq_handler = h_mspro_block_transfer_data; | ||
692 | memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, | ||
693 | ¶m, sizeof(param)); | ||
694 | } | ||
695 | |||
666 | /*** Data transfer ***/ | 696 | /*** Data transfer ***/ |
667 | 697 | ||
668 | static int mspro_block_issue_req(struct memstick_dev *card, int chunk) | 698 | static int mspro_block_issue_req(struct memstick_dev *card, int chunk) |
669 | { | 699 | { |
670 | struct mspro_block_data *msb = memstick_get_drvdata(card); | 700 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
671 | sector_t t_sec; | 701 | u64 t_off; |
672 | unsigned int count; | 702 | unsigned int count; |
673 | struct mspro_param_register param; | ||
674 | 703 | ||
675 | try_again: | 704 | try_again: |
676 | while (chunk) { | 705 | while (chunk) { |
@@ -685,30 +714,17 @@ try_again: | |||
685 | continue; | 714 | continue; |
686 | } | 715 | } |
687 | 716 | ||
688 | t_sec = blk_rq_pos(msb->block_req) << 9; | 717 | t_off = blk_rq_pos(msb->block_req); |
689 | sector_div(t_sec, msb->page_size); | 718 | t_off <<= 9; |
690 | |||
691 | count = blk_rq_bytes(msb->block_req); | 719 | count = blk_rq_bytes(msb->block_req); |
692 | count /= msb->page_size; | ||
693 | 720 | ||
694 | param.system = msb->system; | 721 | msb->setup_transfer(card, t_off, count); |
695 | param.data_count = cpu_to_be16(count); | ||
696 | param.data_address = cpu_to_be32((uint32_t)t_sec); | ||
697 | param.tpc_param = 0; | ||
698 | 722 | ||
699 | msb->data_dir = rq_data_dir(msb->block_req); | 723 | msb->data_dir = rq_data_dir(msb->block_req); |
700 | msb->transfer_cmd = msb->data_dir == READ | 724 | msb->transfer_cmd = msb->data_dir == READ |
701 | ? MSPRO_CMD_READ_DATA | 725 | ? MSPRO_CMD_READ_DATA |
702 | : MSPRO_CMD_WRITE_DATA; | 726 | : MSPRO_CMD_WRITE_DATA; |
703 | 727 | ||
704 | dev_dbg(&card->dev, "data transfer: cmd %x, " | ||
705 | "lba %x, count %x\n", msb->transfer_cmd, | ||
706 | be32_to_cpu(param.data_address), count); | ||
707 | |||
708 | card->next_request = h_mspro_block_req_init; | ||
709 | msb->mrq_handler = h_mspro_block_transfer_data; | ||
710 | memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, | ||
711 | ¶m, sizeof(param)); | ||
712 | memstick_new_req(card->host); | 728 | memstick_new_req(card->host); |
713 | return 0; | 729 | return 0; |
714 | } | 730 | } |
@@ -963,18 +979,16 @@ try_again: | |||
963 | static int mspro_block_read_attributes(struct memstick_dev *card) | 979 | static int mspro_block_read_attributes(struct memstick_dev *card) |
964 | { | 980 | { |
965 | struct mspro_block_data *msb = memstick_get_drvdata(card); | 981 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
966 | struct mspro_param_register param = { | ||
967 | .system = msb->system, | ||
968 | .data_count = cpu_to_be16(1), | ||
969 | .data_address = 0, | ||
970 | .tpc_param = 0 | ||
971 | }; | ||
972 | struct mspro_attribute *attr = NULL; | 982 | struct mspro_attribute *attr = NULL; |
973 | struct mspro_sys_attr *s_attr = NULL; | 983 | struct mspro_sys_attr *s_attr = NULL; |
974 | unsigned char *buffer = NULL; | 984 | unsigned char *buffer = NULL; |
975 | int cnt, rc, attr_count; | 985 | int cnt, rc, attr_count; |
976 | unsigned int addr; | 986 | /* While normally physical device offsets, represented here by |
977 | unsigned short page_count; | 987 | * attr_offset and attr_len will be of large numeric types, we can be |
988 | * sure, that attributes are close enough to the beginning of the | ||
989 | * device, to save ourselves some trouble. | ||
990 | */ | ||
991 | unsigned int addr, attr_offset = 0, attr_len = msb->page_size; | ||
978 | 992 | ||
979 | attr = kmalloc(msb->page_size, GFP_KERNEL); | 993 | attr = kmalloc(msb->page_size, GFP_KERNEL); |
980 | if (!attr) | 994 | if (!attr) |
@@ -987,10 +1001,8 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
987 | msb->data_dir = READ; | 1001 | msb->data_dir = READ; |
988 | msb->transfer_cmd = MSPRO_CMD_READ_ATRB; | 1002 | msb->transfer_cmd = MSPRO_CMD_READ_ATRB; |
989 | 1003 | ||
990 | card->next_request = h_mspro_block_req_init; | 1004 | msb->setup_transfer(card, attr_offset, attr_len); |
991 | msb->mrq_handler = h_mspro_block_transfer_data; | 1005 | |
992 | memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, ¶m, | ||
993 | sizeof(param)); | ||
994 | memstick_new_req(card->host); | 1006 | memstick_new_req(card->host); |
995 | wait_for_completion(&card->mrq_complete); | 1007 | wait_for_completion(&card->mrq_complete); |
996 | if (card->current_mrq.error) { | 1008 | if (card->current_mrq.error) { |
@@ -1021,13 +1033,12 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
1021 | } | 1033 | } |
1022 | msb->attr_group.name = "media_attributes"; | 1034 | msb->attr_group.name = "media_attributes"; |
1023 | 1035 | ||
1024 | buffer = kmalloc(msb->page_size, GFP_KERNEL); | 1036 | buffer = kmalloc(attr_len, GFP_KERNEL); |
1025 | if (!buffer) { | 1037 | if (!buffer) { |
1026 | rc = -ENOMEM; | 1038 | rc = -ENOMEM; |
1027 | goto out_free_attr; | 1039 | goto out_free_attr; |
1028 | } | 1040 | } |
1029 | memcpy(buffer, (char *)attr, msb->page_size); | 1041 | memcpy(buffer, (char *)attr, attr_len); |
1030 | page_count = 1; | ||
1031 | 1042 | ||
1032 | for (cnt = 0; cnt < attr_count; ++cnt) { | 1043 | for (cnt = 0; cnt < attr_count; ++cnt) { |
1033 | s_attr = kzalloc(sizeof(struct mspro_sys_attr), GFP_KERNEL); | 1044 | s_attr = kzalloc(sizeof(struct mspro_sys_attr), GFP_KERNEL); |
@@ -1038,9 +1049,10 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
1038 | 1049 | ||
1039 | msb->attr_group.attrs[cnt] = &s_attr->dev_attr.attr; | 1050 | msb->attr_group.attrs[cnt] = &s_attr->dev_attr.attr; |
1040 | addr = be32_to_cpu(attr->entries[cnt].address); | 1051 | addr = be32_to_cpu(attr->entries[cnt].address); |
1041 | rc = be32_to_cpu(attr->entries[cnt].size); | 1052 | s_attr->size = be32_to_cpu(attr->entries[cnt].size); |
1042 | dev_dbg(&card->dev, "adding attribute %d: id %x, address %x, " | 1053 | dev_dbg(&card->dev, "adding attribute %d: id %x, address %x, " |
1043 | "size %x\n", cnt, attr->entries[cnt].id, addr, rc); | 1054 | "size %zx\n", cnt, attr->entries[cnt].id, addr, |
1055 | s_attr->size); | ||
1044 | s_attr->id = attr->entries[cnt].id; | 1056 | s_attr->id = attr->entries[cnt].id; |
1045 | if (mspro_block_attr_name(s_attr->id)) | 1057 | if (mspro_block_attr_name(s_attr->id)) |
1046 | snprintf(s_attr->name, sizeof(s_attr->name), "%s", | 1058 | snprintf(s_attr->name, sizeof(s_attr->name), "%s", |
@@ -1054,57 +1066,47 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
1054 | s_attr->dev_attr.attr.mode = S_IRUGO; | 1066 | s_attr->dev_attr.attr.mode = S_IRUGO; |
1055 | s_attr->dev_attr.show = mspro_block_attr_show(s_attr->id); | 1067 | s_attr->dev_attr.show = mspro_block_attr_show(s_attr->id); |
1056 | 1068 | ||
1057 | if (!rc) | 1069 | if (!s_attr->size) |
1058 | continue; | 1070 | continue; |
1059 | 1071 | ||
1060 | s_attr->size = rc; | 1072 | s_attr->data = kmalloc(s_attr->size, GFP_KERNEL); |
1061 | s_attr->data = kmalloc(rc, GFP_KERNEL); | ||
1062 | if (!s_attr->data) { | 1073 | if (!s_attr->data) { |
1063 | rc = -ENOMEM; | 1074 | rc = -ENOMEM; |
1064 | goto out_free_buffer; | 1075 | goto out_free_buffer; |
1065 | } | 1076 | } |
1066 | 1077 | ||
1067 | if (((addr / msb->page_size) | 1078 | if (((addr / msb->page_size) == (attr_offset / msb->page_size)) |
1068 | == be32_to_cpu(param.data_address)) | 1079 | && (((addr + s_attr->size - 1) / msb->page_size) |
1069 | && (((addr + rc - 1) / msb->page_size) | 1080 | == (attr_offset / msb->page_size))) { |
1070 | == be32_to_cpu(param.data_address))) { | ||
1071 | memcpy(s_attr->data, buffer + addr % msb->page_size, | 1081 | memcpy(s_attr->data, buffer + addr % msb->page_size, |
1072 | rc); | 1082 | s_attr->size); |
1073 | continue; | 1083 | continue; |
1074 | } | 1084 | } |
1075 | 1085 | ||
1076 | if (page_count <= (rc / msb->page_size)) { | 1086 | attr_offset = (addr / msb->page_size) * msb->page_size; |
1087 | |||
1088 | if ((attr_offset + attr_len) < (addr + s_attr->size)) { | ||
1077 | kfree(buffer); | 1089 | kfree(buffer); |
1078 | page_count = (rc / msb->page_size) + 1; | 1090 | attr_len = (((addr + s_attr->size) / msb->page_size) |
1079 | buffer = kmalloc(page_count * msb->page_size, | 1091 | + 1 ) * msb->page_size - attr_offset; |
1080 | GFP_KERNEL); | 1092 | buffer = kmalloc(attr_len, GFP_KERNEL); |
1081 | if (!buffer) { | 1093 | if (!buffer) { |
1082 | rc = -ENOMEM; | 1094 | rc = -ENOMEM; |
1083 | goto out_free_attr; | 1095 | goto out_free_attr; |
1084 | } | 1096 | } |
1085 | } | 1097 | } |
1086 | 1098 | ||
1087 | param.system = msb->system; | 1099 | sg_init_one(&msb->req_sg[0], buffer, attr_len); |
1088 | param.data_count = cpu_to_be16((rc / msb->page_size) + 1); | ||
1089 | param.data_address = cpu_to_be32(addr / msb->page_size); | ||
1090 | param.tpc_param = 0; | ||
1091 | |||
1092 | sg_init_one(&msb->req_sg[0], buffer, | ||
1093 | be16_to_cpu(param.data_count) * msb->page_size); | ||
1094 | msb->seg_count = 1; | 1100 | msb->seg_count = 1; |
1095 | msb->current_seg = 0; | 1101 | msb->current_seg = 0; |
1096 | msb->current_page = 0; | 1102 | msb->current_page = 0; |
1097 | msb->data_dir = READ; | 1103 | msb->data_dir = READ; |
1098 | msb->transfer_cmd = MSPRO_CMD_READ_ATRB; | 1104 | msb->transfer_cmd = MSPRO_CMD_READ_ATRB; |
1099 | 1105 | ||
1100 | dev_dbg(&card->dev, "reading attribute pages %x, %x\n", | 1106 | dev_dbg(&card->dev, "reading attribute range %x, %x\n", |
1101 | be32_to_cpu(param.data_address), | 1107 | attr_offset, attr_len); |
1102 | be16_to_cpu(param.data_count)); | ||
1103 | 1108 | ||
1104 | card->next_request = h_mspro_block_req_init; | 1109 | msb->setup_transfer(card, attr_offset, attr_len); |
1105 | msb->mrq_handler = h_mspro_block_transfer_data; | ||
1106 | memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, | ||
1107 | (char *)¶m, sizeof(param)); | ||
1108 | memstick_new_req(card->host); | 1110 | memstick_new_req(card->host); |
1109 | wait_for_completion(&card->mrq_complete); | 1111 | wait_for_completion(&card->mrq_complete); |
1110 | if (card->current_mrq.error) { | 1112 | if (card->current_mrq.error) { |
@@ -1112,7 +1114,8 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
1112 | goto out_free_buffer; | 1114 | goto out_free_buffer; |
1113 | } | 1115 | } |
1114 | 1116 | ||
1115 | memcpy(s_attr->data, buffer + addr % msb->page_size, rc); | 1117 | memcpy(s_attr->data, buffer + addr % msb->page_size, |
1118 | s_attr->size); | ||
1116 | } | 1119 | } |
1117 | 1120 | ||
1118 | rc = 0; | 1121 | rc = 0; |
@@ -1130,6 +1133,8 @@ static int mspro_block_init_card(struct memstick_dev *card) | |||
1130 | int rc = 0; | 1133 | int rc = 0; |
1131 | 1134 | ||
1132 | msb->system = MEMSTICK_SYS_SERIAL; | 1135 | msb->system = MEMSTICK_SYS_SERIAL; |
1136 | msb->setup_transfer = h_mspro_block_setup_cmd; | ||
1137 | |||
1133 | card->reg_addr.r_offset = offsetof(struct mspro_register, status); | 1138 | card->reg_addr.r_offset = offsetof(struct mspro_register, status); |
1134 | card->reg_addr.r_length = sizeof(struct ms_status_register); | 1139 | card->reg_addr.r_length = sizeof(struct ms_status_register); |
1135 | card->reg_addr.w_offset = offsetof(struct mspro_register, param); | 1140 | card->reg_addr.w_offset = offsetof(struct mspro_register, param); |
@@ -1206,10 +1211,12 @@ static int mspro_block_init_disk(struct memstick_dev *card) | |||
1206 | 1211 | ||
1207 | msb->page_size = be16_to_cpu(sys_info->unit_size); | 1212 | msb->page_size = be16_to_cpu(sys_info->unit_size); |
1208 | 1213 | ||
1209 | if (!idr_pre_get(&mspro_block_disk_idr, GFP_KERNEL)) | 1214 | mutex_lock(&mspro_block_disk_lock); |
1215 | if (!idr_pre_get(&mspro_block_disk_idr, GFP_KERNEL)) { | ||
1216 | mutex_unlock(&mspro_block_disk_lock); | ||
1210 | return -ENOMEM; | 1217 | return -ENOMEM; |
1218 | } | ||
1211 | 1219 | ||
1212 | mutex_lock(&mspro_block_disk_lock); | ||
1213 | rc = idr_get_new(&mspro_block_disk_idr, card, &disk_id); | 1220 | rc = idr_get_new(&mspro_block_disk_idr, card, &disk_id); |
1214 | mutex_unlock(&mspro_block_disk_lock); | 1221 | mutex_unlock(&mspro_block_disk_lock); |
1215 | 1222 | ||
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index f2b894cd8b0..d89d925caec 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c | |||
@@ -61,6 +61,7 @@ struct jmb38x_ms_host { | |||
61 | struct memstick_request *req; | 61 | struct memstick_request *req; |
62 | unsigned char cmd_flags; | 62 | unsigned char cmd_flags; |
63 | unsigned char io_pos; | 63 | unsigned char io_pos; |
64 | unsigned char ifmode; | ||
64 | unsigned int io_word[2]; | 65 | unsigned int io_word[2]; |
65 | }; | 66 | }; |
66 | 67 | ||
@@ -136,15 +137,14 @@ struct jmb38x_ms { | |||
136 | #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000 | 137 | #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000 |
137 | #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 | 138 | #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 |
138 | 139 | ||
140 | #define CLOCK_CONTROL_BY_MMIO 0x00000008 | ||
139 | #define CLOCK_CONTROL_40MHZ 0x00000001 | 141 | #define CLOCK_CONTROL_40MHZ 0x00000001 |
140 | #define CLOCK_CONTROL_50MHZ 0x0000000a | 142 | #define CLOCK_CONTROL_50MHZ 0x00000002 |
141 | #define CLOCK_CONTROL_60MHZ 0x00000008 | 143 | #define CLOCK_CONTROL_60MHZ 0x00000010 |
142 | #define CLOCK_CONTROL_62_5MHZ 0x0000000c | 144 | #define CLOCK_CONTROL_62_5MHZ 0x00000004 |
143 | #define CLOCK_CONTROL_OFF 0x00000000 | 145 | #define CLOCK_CONTROL_OFF 0x00000000 |
144 | 146 | ||
145 | #define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0 | 147 | #define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0 |
146 | #define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00 | ||
147 | #define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000 | ||
148 | 148 | ||
149 | enum { | 149 | enum { |
150 | CMD_READY = 0x01, | 150 | CMD_READY = 0x01, |
@@ -390,8 +390,13 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh) | |||
390 | 390 | ||
391 | if (host->req->data_dir == READ) | 391 | if (host->req->data_dir == READ) |
392 | cmd |= TPC_DIR; | 392 | cmd |= TPC_DIR; |
393 | if (host->req->need_card_int) | 393 | |
394 | cmd |= TPC_WAIT_INT; | 394 | if (host->req->need_card_int) { |
395 | if (host->ifmode == MEMSTICK_SERIAL) | ||
396 | cmd |= TPC_GET_INT; | ||
397 | else | ||
398 | cmd |= TPC_WAIT_INT; | ||
399 | } | ||
395 | 400 | ||
396 | data = host->req->data; | 401 | data = host->req->data; |
397 | 402 | ||
@@ -529,7 +534,10 @@ static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id) | |||
529 | if (irq_status & INT_STATUS_ANY_ERR) { | 534 | if (irq_status & INT_STATUS_ANY_ERR) { |
530 | if (irq_status & INT_STATUS_CRC_ERR) | 535 | if (irq_status & INT_STATUS_CRC_ERR) |
531 | host->req->error = -EILSEQ; | 536 | host->req->error = -EILSEQ; |
532 | else | 537 | else if (irq_status & INT_STATUS_TPC_ERR) { |
538 | dev_dbg(&host->chip->pdev->dev, "TPC_ERR\n"); | ||
539 | jmb38x_ms_complete_cmd(msh, 0); | ||
540 | } else | ||
533 | host->req->error = -ETIME; | 541 | host->req->error = -ETIME; |
534 | } else { | 542 | } else { |
535 | if (host->cmd_flags & DMA_DATA) { | 543 | if (host->cmd_flags & DMA_DATA) { |
@@ -644,7 +652,6 @@ static int jmb38x_ms_reset(struct jmb38x_ms_host *host) | |||
644 | ndelay(20); | 652 | ndelay(20); |
645 | } | 653 | } |
646 | dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); | 654 | dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); |
647 | /* return -EIO; */ | ||
648 | 655 | ||
649 | reset_next: | 656 | reset_next: |
650 | writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN | 657 | writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN |
@@ -675,7 +682,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh, | |||
675 | { | 682 | { |
676 | struct jmb38x_ms_host *host = memstick_priv(msh); | 683 | struct jmb38x_ms_host *host = memstick_priv(msh); |
677 | unsigned int host_ctl = readl(host->addr + HOST_CONTROL); | 684 | unsigned int host_ctl = readl(host->addr + HOST_CONTROL); |
678 | unsigned int clock_ctl = CLOCK_CONTROL_40MHZ, clock_delay = 0; | 685 | unsigned int clock_ctl = CLOCK_CONTROL_BY_MMIO, clock_delay = 0; |
679 | int rc = 0; | 686 | int rc = 0; |
680 | 687 | ||
681 | switch (param) { | 688 | switch (param) { |
@@ -687,9 +694,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh, | |||
687 | 694 | ||
688 | host_ctl = 7; | 695 | host_ctl = 7; |
689 | host_ctl |= HOST_CONTROL_POWER_EN | 696 | host_ctl |= HOST_CONTROL_POWER_EN |
690 | | HOST_CONTROL_CLOCK_EN | 697 | | HOST_CONTROL_CLOCK_EN; |
691 | | HOST_CONTROL_HW_OC_P | ||
692 | | HOST_CONTROL_TDELAY_EN; | ||
693 | writel(host_ctl, host->addr + HOST_CONTROL); | 698 | writel(host_ctl, host->addr + HOST_CONTROL); |
694 | 699 | ||
695 | writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 | 700 | writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 |
@@ -712,46 +717,88 @@ static int jmb38x_ms_set_param(struct memstick_host *msh, | |||
712 | return -EINVAL; | 717 | return -EINVAL; |
713 | break; | 718 | break; |
714 | case MEMSTICK_INTERFACE: | 719 | case MEMSTICK_INTERFACE: |
720 | dev_dbg(&host->chip->pdev->dev, | ||
721 | "Set Host Interface Mode to %d\n", value); | ||
722 | host_ctl &= ~(HOST_CONTROL_FAST_CLK | HOST_CONTROL_REI | | ||
723 | HOST_CONTROL_REO); | ||
724 | host_ctl |= HOST_CONTROL_TDELAY_EN | HOST_CONTROL_HW_OC_P; | ||
715 | host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); | 725 | host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); |
716 | pci_read_config_dword(host->chip->pdev, | ||
717 | PCI_CTL_CLOCK_DLY_ADDR, | ||
718 | &clock_delay); | ||
719 | clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B | ||
720 | : ~PCI_CTL_CLOCK_DLY_MASK_A; | ||
721 | 726 | ||
722 | if (value == MEMSTICK_SERIAL) { | 727 | if (value == MEMSTICK_SERIAL) { |
723 | host_ctl &= ~HOST_CONTROL_FAST_CLK; | ||
724 | host_ctl &= ~HOST_CONTROL_REO; | ||
725 | host_ctl |= HOST_CONTROL_IF_SERIAL | 728 | host_ctl |= HOST_CONTROL_IF_SERIAL |
726 | << HOST_CONTROL_IF_SHIFT; | 729 | << HOST_CONTROL_IF_SHIFT; |
727 | host_ctl |= HOST_CONTROL_REI; | 730 | host_ctl |= HOST_CONTROL_REI; |
728 | clock_ctl = CLOCK_CONTROL_40MHZ; | 731 | clock_ctl |= CLOCK_CONTROL_40MHZ; |
732 | clock_delay = 0; | ||
729 | } else if (value == MEMSTICK_PAR4) { | 733 | } else if (value == MEMSTICK_PAR4) { |
730 | host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO; | 734 | host_ctl |= HOST_CONTROL_FAST_CLK; |
731 | host_ctl |= HOST_CONTROL_IF_PAR4 | 735 | host_ctl |= HOST_CONTROL_IF_PAR4 |
732 | << HOST_CONTROL_IF_SHIFT; | 736 | << HOST_CONTROL_IF_SHIFT; |
733 | host_ctl &= ~HOST_CONTROL_REI; | 737 | host_ctl |= HOST_CONTROL_REO; |
734 | clock_ctl = CLOCK_CONTROL_40MHZ; | 738 | clock_ctl |= CLOCK_CONTROL_40MHZ; |
735 | clock_delay |= host->id ? (4 << 12) : (4 << 8); | 739 | clock_delay = 4; |
736 | } else if (value == MEMSTICK_PAR8) { | 740 | } else if (value == MEMSTICK_PAR8) { |
737 | host_ctl |= HOST_CONTROL_FAST_CLK; | 741 | host_ctl |= HOST_CONTROL_FAST_CLK; |
738 | host_ctl |= HOST_CONTROL_IF_PAR8 | 742 | host_ctl |= HOST_CONTROL_IF_PAR8 |
739 | << HOST_CONTROL_IF_SHIFT; | 743 | << HOST_CONTROL_IF_SHIFT; |
740 | host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO); | 744 | clock_ctl |= CLOCK_CONTROL_50MHZ; |
741 | clock_ctl = CLOCK_CONTROL_50MHZ; | 745 | clock_delay = 0; |
742 | } else | 746 | } else |
743 | return -EINVAL; | 747 | return -EINVAL; |
744 | 748 | ||
745 | writel(host_ctl, host->addr + HOST_CONTROL); | 749 | writel(host_ctl, host->addr + HOST_CONTROL); |
750 | writel(CLOCK_CONTROL_OFF, host->addr + CLOCK_CONTROL); | ||
746 | writel(clock_ctl, host->addr + CLOCK_CONTROL); | 751 | writel(clock_ctl, host->addr + CLOCK_CONTROL); |
747 | pci_write_config_dword(host->chip->pdev, | 752 | pci_write_config_byte(host->chip->pdev, |
748 | PCI_CTL_CLOCK_DLY_ADDR, | 753 | PCI_CTL_CLOCK_DLY_ADDR + 1, |
749 | clock_delay); | 754 | clock_delay); |
755 | host->ifmode = value; | ||
750 | break; | 756 | break; |
751 | }; | 757 | }; |
752 | return 0; | 758 | return 0; |
753 | } | 759 | } |
754 | 760 | ||
761 | #define PCI_PMOS0_CONTROL 0xae | ||
762 | #define PMOS0_ENABLE 0x01 | ||
763 | #define PMOS0_OVERCURRENT_LEVEL_2_4V 0x06 | ||
764 | #define PMOS0_EN_OVERCURRENT_DEBOUNCE 0x40 | ||
765 | #define PMOS0_SW_LED_POLARITY_ENABLE 0x80 | ||
766 | #define PMOS0_ACTIVE_BITS (PMOS0_ENABLE | PMOS0_EN_OVERCURRENT_DEBOUNCE | \ | ||
767 | PMOS0_OVERCURRENT_LEVEL_2_4V) | ||
768 | #define PCI_PMOS1_CONTROL 0xbd | ||
769 | #define PMOS1_ACTIVE_BITS 0x4a | ||
770 | #define PCI_CLOCK_CTL 0xb9 | ||
771 | |||
772 | static int jmb38x_ms_pmos(struct pci_dev *pdev, int flag) | ||
773 | { | ||
774 | unsigned char val; | ||
775 | |||
776 | pci_read_config_byte(pdev, PCI_PMOS0_CONTROL, &val); | ||
777 | if (flag) | ||
778 | val |= PMOS0_ACTIVE_BITS; | ||
779 | else | ||
780 | val &= ~PMOS0_ACTIVE_BITS; | ||
781 | pci_write_config_byte(pdev, PCI_PMOS0_CONTROL, val); | ||
782 | dev_dbg(&pdev->dev, "JMB38x: set PMOS0 val 0x%x\n", val); | ||
783 | |||
784 | if (pci_resource_flags(pdev, 1)) { | ||
785 | pci_read_config_byte(pdev, PCI_PMOS1_CONTROL, &val); | ||
786 | if (flag) | ||
787 | val |= PMOS1_ACTIVE_BITS; | ||
788 | else | ||
789 | val &= ~PMOS1_ACTIVE_BITS; | ||
790 | pci_write_config_byte(pdev, PCI_PMOS1_CONTROL, val); | ||
791 | dev_dbg(&pdev->dev, "JMB38x: set PMOS1 val 0x%x\n", val); | ||
792 | } | ||
793 | |||
794 | pci_read_config_byte(pdev, PCI_CLOCK_CTL, &val); | ||
795 | pci_write_config_byte(pdev, PCI_CLOCK_CTL, val & ~0x0f); | ||
796 | pci_write_config_byte(pdev, PCI_CLOCK_CTL, val | 0x01); | ||
797 | dev_dbg(&pdev->dev, "Clock Control by PCI config is disabled!\n"); | ||
798 | |||
799 | return 0; | ||
800 | } | ||
801 | |||
755 | #ifdef CONFIG_PM | 802 | #ifdef CONFIG_PM |
756 | 803 | ||
757 | static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state) | 804 | static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state) |
@@ -784,8 +831,7 @@ static int jmb38x_ms_resume(struct pci_dev *dev) | |||
784 | return rc; | 831 | return rc; |
785 | pci_set_master(dev); | 832 | pci_set_master(dev); |
786 | 833 | ||
787 | pci_read_config_dword(dev, 0xac, &rc); | 834 | jmb38x_ms_pmos(dev, 1); |
788 | pci_write_config_dword(dev, 0xac, rc | 0x00470000); | ||
789 | 835 | ||
790 | for (rc = 0; rc < jm->host_cnt; ++rc) { | 836 | for (rc = 0; rc < jm->host_cnt; ++rc) { |
791 | if (!jm->hosts[rc]) | 837 | if (!jm->hosts[rc]) |
@@ -894,8 +940,7 @@ static int jmb38x_ms_probe(struct pci_dev *pdev, | |||
894 | goto err_out; | 940 | goto err_out; |
895 | } | 941 | } |
896 | 942 | ||
897 | pci_read_config_dword(pdev, 0xac, &rc); | 943 | jmb38x_ms_pmos(pdev, 1); |
898 | pci_write_config_dword(pdev, 0xac, rc | 0x00470000); | ||
899 | 944 | ||
900 | cnt = jmb38x_ms_count_slots(pdev); | 945 | cnt = jmb38x_ms_count_slots(pdev); |
901 | if (!cnt) { | 946 | if (!cnt) { |
@@ -976,6 +1021,8 @@ static void jmb38x_ms_remove(struct pci_dev *dev) | |||
976 | jmb38x_ms_free_host(jm->hosts[cnt]); | 1021 | jmb38x_ms_free_host(jm->hosts[cnt]); |
977 | } | 1022 | } |
978 | 1023 | ||
1024 | jmb38x_ms_pmos(dev, 0); | ||
1025 | |||
979 | pci_set_drvdata(dev, NULL); | 1026 | pci_set_drvdata(dev, NULL); |
980 | pci_release_regions(dev); | 1027 | pci_release_regions(dev); |
981 | pci_disable_device(dev); | 1028 | pci_disable_device(dev); |
@@ -983,8 +1030,9 @@ static void jmb38x_ms_remove(struct pci_dev *dev) | |||
983 | } | 1030 | } |
984 | 1031 | ||
985 | static struct pci_device_id jmb38x_ms_id_tbl [] = { | 1032 | static struct pci_device_id jmb38x_ms_id_tbl [] = { |
986 | { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS, PCI_ANY_ID, | 1033 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS) }, |
987 | PCI_ANY_ID, 0, 0, 0 }, | 1034 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB385_MS) }, |
1035 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB390_MS) }, | ||
988 | { } | 1036 | { } |
989 | }; | 1037 | }; |
990 | 1038 | ||
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index 691620dbedd..8b04810df46 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h | |||
@@ -268,7 +268,7 @@ | |||
268 | 268 | ||
269 | /* Compatibility Error : IR Disabled */ | 269 | /* Compatibility Error : IR Disabled */ |
270 | #define IR_LOGINFO_COMPAT_ERROR_RAID_DISABLED (0x00010030) | 270 | #define IR_LOGINFO_COMPAT_ERROR_RAID_DISABLED (0x00010030) |
271 | /* Compatibility Error : Inquiry Comand failed */ | 271 | /* Compatibility Error : Inquiry Command failed */ |
272 | #define IR_LOGINFO_COMPAT_ERROR_INQUIRY_FAILED (0x00010031) | 272 | #define IR_LOGINFO_COMPAT_ERROR_INQUIRY_FAILED (0x00010031) |
273 | /* Compatibility Error : Device not direct access device */ | 273 | /* Compatibility Error : Device not direct access device */ |
274 | #define IR_LOGINFO_COMPAT_ERROR_NOT_DIRECT_ACCESS (0x00010032) | 274 | #define IR_LOGINFO_COMPAT_ERROR_NOT_DIRECT_ACCESS (0x00010032) |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 3e57b61ca44..3358c0af346 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -7977,7 +7977,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
7977 | NULL, /* 2Eh */ | 7977 | NULL, /* 2Eh */ |
7978 | NULL, /* 2Fh */ | 7978 | NULL, /* 2Fh */ |
7979 | "Compatibility Error: IR Disabled", /* 30h */ | 7979 | "Compatibility Error: IR Disabled", /* 30h */ |
7980 | "Compatibility Error: Inquiry Comand Failed", /* 31h */ | 7980 | "Compatibility Error: Inquiry Command Failed", /* 31h */ |
7981 | "Compatibility Error: Device not Direct Access " | 7981 | "Compatibility Error: Device not Direct Access " |
7982 | "Device ", /* 32h */ | 7982 | "Device ", /* 32h */ |
7983 | "Compatibility Error: Removable Device Found", /* 33h */ | 7983 | "Compatibility Error: Removable Device Found", /* 33h */ |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index d48c2c6058e..8aefb1829fc 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -1146,7 +1146,7 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, | |||
1146 | * | 1146 | * |
1147 | * This function will delete scheduled target reset from the list and | 1147 | * This function will delete scheduled target reset from the list and |
1148 | * try to send next target reset. This will be called from completion | 1148 | * try to send next target reset. This will be called from completion |
1149 | * context of any Task managment command. | 1149 | * context of any Task management command. |
1150 | */ | 1150 | */ |
1151 | 1151 | ||
1152 | void | 1152 | void |
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index f87a9d405a5..ae7cad18589 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c | |||
@@ -309,7 +309,7 @@ static inline void i2o_block_request_free(struct i2o_block_request *ireq) | |||
309 | * @ireq: I2O block request | 309 | * @ireq: I2O block request |
310 | * @mptr: message body pointer | 310 | * @mptr: message body pointer |
311 | * | 311 | * |
312 | * Builds the SG list and map it to be accessable by the controller. | 312 | * Builds the SG list and map it to be accessible by the controller. |
313 | * | 313 | * |
314 | * Returns 0 on failure or 1 on success. | 314 | * Returns 0 on failure or 1 on success. |
315 | */ | 315 | */ |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 4d073f1e450..1e1a4be8eb6 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -402,7 +402,7 @@ config TI_DAC7512 | |||
402 | DAC7512 16-bit digital-to-analog converter. | 402 | DAC7512 16-bit digital-to-analog converter. |
403 | 403 | ||
404 | This driver can also be built as a module. If so, the module | 404 | This driver can also be built as a module. If so, the module |
405 | will be calles ti_dac7512. | 405 | will be called ti_dac7512. |
406 | 406 | ||
407 | config VMWARE_BALLOON | 407 | config VMWARE_BALLOON |
408 | tristate "VMware Balloon Driver" | 408 | tristate "VMware Balloon Driver" |
diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c index 9e3879ef58f..fe8616a8d28 100644 --- a/drivers/misc/arm-charlcd.c +++ b/drivers/misc/arm-charlcd.c | |||
@@ -313,7 +313,7 @@ static int __init charlcd_probe(struct platform_device *pdev) | |||
313 | INIT_DELAYED_WORK(&lcd->init_work, charlcd_init_work); | 313 | INIT_DELAYED_WORK(&lcd->init_work, charlcd_init_work); |
314 | schedule_delayed_work(&lcd->init_work, 0); | 314 | schedule_delayed_work(&lcd->init_work, 0); |
315 | 315 | ||
316 | dev_info(&pdev->dev, "initalized ARM character LCD at %08x\n", | 316 | dev_info(&pdev->dev, "initialized ARM character LCD at %08x\n", |
317 | lcd->phybase); | 317 | lcd->phybase); |
318 | 318 | ||
319 | return 0; | 319 | return 0; |
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 2a1e804a71a..4d2ea8e8014 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 | } |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 217f82037fc..bfc8a8ae55d 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -257,7 +257,7 @@ static u32 get_card_status(struct mmc_card *card, struct request *req) | |||
257 | cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; | 257 | cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; |
258 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | 258 | err = mmc_wait_for_cmd(card->host, &cmd, 0); |
259 | if (err) | 259 | if (err) |
260 | printk(KERN_ERR "%s: error %d sending status comand", | 260 | printk(KERN_ERR "%s: error %d sending status command", |
261 | req->rq_disk->disk_name, err); | 261 | req->rq_disk->disk_name, err); |
262 | return cmd.resp[0]; | 262 | return cmd.resp[0]; |
263 | } | 263 | } |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index c22a4c03998..afe8c6fa166 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -501,7 +501,7 @@ config MMC_SH_MMCIF | |||
501 | tristate "SuperH Internal MMCIF support" | 501 | tristate "SuperH Internal MMCIF support" |
502 | depends on MMC_BLOCK && (SUPERH || ARCH_SHMOBILE) | 502 | depends on MMC_BLOCK && (SUPERH || ARCH_SHMOBILE) |
503 | help | 503 | help |
504 | This selects the MMC Host Interface controler (MMCIF). | 504 | This selects the MMC Host Interface controller (MMCIF). |
505 | 505 | ||
506 | This driver supports MMCIF in sh7724/sh7757/sh7372. | 506 | This driver supports MMCIF in sh7724/sh7757/sh7372. |
507 | 507 | ||
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 41e5a60493a..ef72e874ca3 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -192,7 +192,7 @@ static inline void SEND_STOP(struct au1xmmc_host *host) | |||
192 | au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); | 192 | au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); |
193 | au_sync(); | 193 | au_sync(); |
194 | 194 | ||
195 | /* Send the stop commmand */ | 195 | /* Send the stop command */ |
196 | au_writel(STOP_CMD, HOST_CMD(host)); | 196 | au_writel(STOP_CMD, HOST_CMD(host)); |
197 | } | 197 | } |
198 | 198 | ||
diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index f472c2714eb..bbc298fd2a1 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c | |||
@@ -446,7 +446,7 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev, | |||
446 | mmc->max_seg_size = 1024 * 512; | 446 | mmc->max_seg_size = 1024 * 512; |
447 | mmc->max_blk_size = 512; | 447 | mmc->max_blk_size = 512; |
448 | 448 | ||
449 | /* reset the controler */ | 449 | /* reset the controller */ |
450 | if (sdricoh_reset(host)) { | 450 | if (sdricoh_reset(host)) { |
451 | dev_dbg(dev, "could not reset\n"); | 451 | dev_dbg(dev, "could not reset\n"); |
452 | result = -EIO; | 452 | result = -EIO; |
@@ -478,7 +478,7 @@ static int sdricoh_pcmcia_probe(struct pcmcia_device *pcmcia_dev) | |||
478 | dev_info(&pcmcia_dev->dev, "Searching MMC controller for pcmcia device" | 478 | dev_info(&pcmcia_dev->dev, "Searching MMC controller for pcmcia device" |
479 | " %s %s ...\n", pcmcia_dev->prod_id[0], pcmcia_dev->prod_id[1]); | 479 | " %s %s ...\n", pcmcia_dev->prod_id[0], pcmcia_dev->prod_id[1]); |
480 | 480 | ||
481 | /* search pci cardbus bridge that contains the mmc controler */ | 481 | /* search pci cardbus bridge that contains the mmc controller */ |
482 | /* the io region is already claimed by yenta_socket... */ | 482 | /* the io region is already claimed by yenta_socket... */ |
483 | while ((pci_dev = | 483 | while ((pci_dev = |
484 | pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, | 484 | pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, |
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 1ee72f3f051..c948150079b 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c | |||
@@ -307,6 +307,11 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper, | |||
307 | unsigned long l1_cpy, l2_cpy; | 307 | unsigned long l1_cpy, l2_cpy; |
308 | char *dst; | 308 | char *dst; |
309 | 309 | ||
310 | if (reason != KMSG_DUMP_OOPS && | ||
311 | reason != KMSG_DUMP_PANIC && | ||
312 | reason != KMSG_DUMP_KEXEC) | ||
313 | return; | ||
314 | |||
310 | /* Only dump oopses if dump_oops is set */ | 315 | /* Only dump oopses if dump_oops is set */ |
311 | if (reason == KMSG_DUMP_OOPS && !dump_oops) | 316 | if (reason == KMSG_DUMP_OOPS && !dump_oops) |
312 | return; | 317 | return; |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1f75a1b1f7c..31bf376b82a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -821,7 +821,7 @@ retry: | |||
821 | * | 821 | * |
822 | * Wait for command done. This is a helper function for nand_wait used when | 822 | * Wait for command done. This is a helper function for nand_wait used when |
823 | * we are in interrupt context. May happen when in panic and trying to write | 823 | * we are in interrupt context. May happen when in panic and trying to write |
824 | * an oops trough mtdoops. | 824 | * an oops through mtdoops. |
825 | */ | 825 | */ |
826 | static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, | 826 | static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, |
827 | unsigned long timeo) | 827 | unsigned long timeo) |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ff652c77a0a..4c8bfc97fb4 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2963,6 +2963,7 @@ config TILE_NET | |||
2963 | config XEN_NETDEV_FRONTEND | 2963 | config XEN_NETDEV_FRONTEND |
2964 | tristate "Xen network device frontend driver" | 2964 | tristate "Xen network device frontend driver" |
2965 | depends on XEN | 2965 | depends on XEN |
2966 | select XEN_XENBUS_FRONTEND | ||
2966 | default y | 2967 | default y |
2967 | help | 2968 | help |
2968 | The network device frontend driver allows the kernel to | 2969 | The network device frontend driver allows the kernel to |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 6a858a29db5..a6cd335c943 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -1415,12 +1415,12 @@ struct bnx2x_func_init_params { | |||
1415 | else | 1415 | else |
1416 | 1416 | ||
1417 | /* skip rx queue | 1417 | /* skip rx queue |
1418 | * if FCOE l2 support is diabled and this is the fcoe L2 queue | 1418 | * if FCOE l2 support is disabled and this is the fcoe L2 queue |
1419 | */ | 1419 | */ |
1420 | #define skip_rx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) | 1420 | #define skip_rx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) |
1421 | 1421 | ||
1422 | /* skip tx queue | 1422 | /* skip tx queue |
1423 | * if FCOE l2 support is diabled and this is the fcoe L2 queue | 1423 | * if FCOE l2 support is disabled and this is the fcoe L2 queue |
1424 | */ | 1424 | */ |
1425 | #define skip_tx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) | 1425 | #define skip_tx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) |
1426 | 1426 | ||
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 84e1af4d65e..8cdcf5b39d1 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -5037,7 +5037,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) | |||
5037 | memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); | 5037 | memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); |
5038 | memset(&ilt, 0, sizeof(struct bnx2x_ilt)); | 5038 | memset(&ilt, 0, sizeof(struct bnx2x_ilt)); |
5039 | 5039 | ||
5040 | /* initalize dummy TM client */ | 5040 | /* initialize dummy TM client */ |
5041 | ilt_cli.start = 0; | 5041 | ilt_cli.start = 0; |
5042 | ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; | 5042 | ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; |
5043 | ilt_cli.client_num = ILT_CLIENT_TM; | 5043 | ilt_cli.client_num = ILT_CLIENT_TM; |
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 38ef7ca9f21..c939683e3d6 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h | |||
@@ -1633,7 +1633,7 @@ | |||
1633 | (~misc_registers_sw_timer_cfg_4.sw_timer_cfg_4[1] ) is set */ | 1633 | (~misc_registers_sw_timer_cfg_4.sw_timer_cfg_4[1] ) is set */ |
1634 | #define MISC_REG_SW_TIMER_RELOAD_VAL_4 0xa2fc | 1634 | #define MISC_REG_SW_TIMER_RELOAD_VAL_4 0xa2fc |
1635 | /* [RW 32] the value of the counter for sw timers1-8. there are 8 addresses | 1635 | /* [RW 32] the value of the counter for sw timers1-8. there are 8 addresses |
1636 | in this register. addres 0 - timer 1; address 1 - timer 2, ... address 7 - | 1636 | in this register. address 0 - timer 1; address 1 - timer 2, ... address 7 - |
1637 | timer 8 */ | 1637 | timer 8 */ |
1638 | #define MISC_REG_SW_TIMER_VAL 0xa5c0 | 1638 | #define MISC_REG_SW_TIMER_VAL 0xa5c0 |
1639 | /* [RW 1] Set by the MCP to remember if one or more of the drivers is/are | 1639 | /* [RW 1] Set by the MCP to remember if one or more of the drivers is/are |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 48cf24ff4e6..171782e2bb3 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -840,7 +840,7 @@ static int ad_lacpdu_send(struct port *port) | |||
840 | lacpdu_header = (struct lacpdu_header *)skb_put(skb, length); | 840 | lacpdu_header = (struct lacpdu_header *)skb_put(skb, length); |
841 | 841 | ||
842 | memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); | 842 | memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); |
843 | /* Note: source addres is set to be the member's PERMANENT address, | 843 | /* Note: source address is set to be the member's PERMANENT address, |
844 | because we use it to identify loopback lacpdus in receive. */ | 844 | because we use it to identify loopback lacpdus in receive. */ |
845 | memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); | 845 | memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); |
846 | lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU; | 846 | lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU; |
@@ -881,7 +881,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) | |||
881 | marker_header = (struct bond_marker_header *)skb_put(skb, length); | 881 | marker_header = (struct bond_marker_header *)skb_put(skb, length); |
882 | 882 | ||
883 | memcpy(marker_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); | 883 | memcpy(marker_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); |
884 | /* Note: source addres is set to be the member's PERMANENT address, | 884 | /* Note: source address is set to be the member's PERMANENT address, |
885 | because we use it to identify loopback MARKERs in receive. */ | 885 | because we use it to identify loopback MARKERs in receive. */ |
886 | memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); | 886 | memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); |
887 | marker_header->hdr.h_proto = PKT_TYPE_LACPDU; | 887 | marker_header->hdr.h_proto = PKT_TYPE_LACPDU; |
@@ -1916,7 +1916,7 @@ int bond_3ad_bind_slave(struct slave *slave) | |||
1916 | return -1; | 1916 | return -1; |
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | //check that the slave has not been intialized yet. | 1919 | //check that the slave has not been initialized yet. |
1920 | if (SLAVE_AD_INFO(slave).port.slave != slave) { | 1920 | if (SLAVE_AD_INFO(slave).port.slave != slave) { |
1921 | 1921 | ||
1922 | // port initialization | 1922 | // port initialization |
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c index 63ebf76d239..8a43c7e1970 100644 --- a/drivers/net/chelsio/subr.c +++ b/drivers/net/chelsio/subr.c | |||
@@ -556,7 +556,7 @@ struct chelsio_vpd_t { | |||
556 | #define EEPROM_MAX_POLL 4 | 556 | #define EEPROM_MAX_POLL 4 |
557 | 557 | ||
558 | /* | 558 | /* |
559 | * Read SEEPROM. A zero is written to the flag register when the addres is | 559 | * Read SEEPROM. A zero is written to the flag register when the address is |
560 | * written to the Control register. The hardware device will set the flag to a | 560 | * written to the Control register. The hardware device will set the flag to a |
561 | * one when 4B have been transferred to the Data register. | 561 | * one when 4B have been transferred to the Data register. |
562 | */ | 562 | */ |
diff --git a/drivers/net/cxgb3/mc5.c b/drivers/net/cxgb3/mc5.c index a8766fb2f9a..e13b7fe9d08 100644 --- a/drivers/net/cxgb3/mc5.c +++ b/drivers/net/cxgb3/mc5.c | |||
@@ -318,7 +318,7 @@ static void mc5_dbgi_mode_disable(const struct mc5 *mc5) | |||
318 | 318 | ||
319 | /* | 319 | /* |
320 | * Initialization that requires the OS and protocol layers to already | 320 | * Initialization that requires the OS and protocol layers to already |
321 | * be intialized goes here. | 321 | * be initialized goes here. |
322 | */ | 322 | */ |
323 | int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, | 323 | int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, |
324 | unsigned int nroutes) | 324 | unsigned int nroutes) |
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index ec8579a0a80..d55db6b38e7 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -607,7 +607,7 @@ struct t3_vpd { | |||
607 | * | 607 | * |
608 | * Read a 32-bit word from a location in VPD EEPROM using the card's PCI | 608 | * Read a 32-bit word from a location in VPD EEPROM using the card's PCI |
609 | * VPD ROM capability. A zero is written to the flag bit when the | 609 | * VPD ROM capability. A zero is written to the flag bit when the |
610 | * addres is written to the control register. The hardware device will | 610 | * address is written to the control register. The hardware device will |
611 | * set the flag to 1 when 4 bytes have been read into the data register. | 611 | * set the flag to 1 when 4 bytes have been read into the data register. |
612 | */ | 612 | */ |
613 | int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data) | 613 | int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data) |
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index f5514a0d5be..196eeda2dd6 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h | |||
@@ -41,7 +41,7 @@ struct e1000_hw; | |||
41 | struct e1000_hw_stats; | 41 | struct e1000_hw_stats; |
42 | 42 | ||
43 | /* Enumerated types specific to the e1000 hardware */ | 43 | /* Enumerated types specific to the e1000 hardware */ |
44 | /* Media Access Controlers */ | 44 | /* Media Access Controllers */ |
45 | typedef enum { | 45 | typedef enum { |
46 | e1000_undefined = 0, | 46 | e1000_undefined = 0, |
47 | e1000_82542_rev2_0, | 47 | e1000_82542_rev2_0, |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4ff88a683f6..de69c54301c 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2233,7 +2233,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2233 | * addresses take precedence to avoid disabling unicast filtering | 2233 | * addresses take precedence to avoid disabling unicast filtering |
2234 | * when possible. | 2234 | * when possible. |
2235 | * | 2235 | * |
2236 | * RAR 0 is used for the station MAC adddress | 2236 | * RAR 0 is used for the station MAC address |
2237 | * if there are not 14 addresses, go ahead and clear the filters | 2237 | * if there are not 14 addresses, go ahead and clear the filters |
2238 | */ | 2238 | */ |
2239 | i = 1; | 2239 | i = 1; |
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index cb6c7b1c1fb..1397da118f0 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -328,7 +328,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) | |||
328 | 328 | ||
329 | /* | 329 | /* |
330 | * Ensure that the inter-port SWSM.SMBI lock bit is clear before | 330 | * Ensure that the inter-port SWSM.SMBI lock bit is clear before |
331 | * first NVM or PHY acess. This should be done for single-port | 331 | * first NVM or PHY access. This should be done for single-port |
332 | * devices, and for one port only on dual-port devices so that | 332 | * devices, and for one port only on dual-port devices so that |
333 | * for those devices we can still use the SMBI lock to synchronize | 333 | * for those devices we can still use the SMBI lock to synchronize |
334 | * inter-port accesses to the PHY & NVM. | 334 | * inter-port accesses to the PHY & NVM. |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 5328a292773..5bb65b7382d 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -321,7 +321,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
321 | } | 321 | } |
322 | 322 | ||
323 | /* | 323 | /* |
324 | * Reset the PHY before any acccess to it. Doing so, ensures that | 324 | * Reset the PHY before any access to it. Doing so, ensures that |
325 | * the PHY is in a known good state before we read/write PHY registers. | 325 | * the PHY is in a known good state before we read/write PHY registers. |
326 | * The generic reset is sufficient here, because we haven't determined | 326 | * The generic reset is sufficient here, because we haven't determined |
327 | * the PHY type yet. | 327 | * the PHY type yet. |
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index a640f1c369a..00f89e8a9fa 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -2986,7 +2986,7 @@ s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data) | |||
2986 | } | 2986 | } |
2987 | 2987 | ||
2988 | /** | 2988 | /** |
2989 | * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page | 2989 | * e1000_get_phy_addr_for_hv_page - Get PHY address based on page |
2990 | * @page: page to be accessed | 2990 | * @page: page to be accessed |
2991 | **/ | 2991 | **/ |
2992 | static u32 e1000_get_phy_addr_for_hv_page(u32 page) | 2992 | static u32 e1000_get_phy_addr_for_hv_page(u32 page) |
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 4fa8d2a4aef..eb35951a244 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c | |||
@@ -1761,7 +1761,7 @@ module_param_array(io, int, NULL, 0); | |||
1761 | module_param_array(irq, int, NULL, 0); | 1761 | module_param_array(irq, int, NULL, 0); |
1762 | module_param_array(mem, int, NULL, 0); | 1762 | module_param_array(mem, int, NULL, 0); |
1763 | module_param(autodetect, int, 0); | 1763 | module_param(autodetect, int, 0); |
1764 | MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)"); | 1764 | MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base address(es)"); |
1765 | MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)"); | 1765 | MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)"); |
1766 | MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)"); | 1766 | MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)"); |
1767 | MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)"); | 1767 | MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)"); |
diff --git a/drivers/net/irda/donauboe.h b/drivers/net/irda/donauboe.h index 4dc39e5f015..77fcf445916 100644 --- a/drivers/net/irda/donauboe.h +++ b/drivers/net/irda/donauboe.h | |||
@@ -30,7 +30,7 @@ | |||
30 | * or the type-DO IR port. | 30 | * or the type-DO IR port. |
31 | * | 31 | * |
32 | * IrDA chip set list from Toshiba Computer Engineering Corp. | 32 | * IrDA chip set list from Toshiba Computer Engineering Corp. |
33 | * model method maker controler Version | 33 | * model method maker controller Version |
34 | * Portege 320CT FIR,SIR Toshiba Oboe(Triangle) | 34 | * Portege 320CT FIR,SIR Toshiba Oboe(Triangle) |
35 | * Portege 3010CT FIR,SIR Toshiba Oboe(Sydney) | 35 | * Portege 3010CT FIR,SIR Toshiba Oboe(Sydney) |
36 | * Portege 3015CT FIR,SIR Toshiba Oboe(Sydney) | 36 | * Portege 3015CT FIR,SIR Toshiba Oboe(Sydney) |
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 8d316d9cd29..a21f5817685 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -1079,7 +1079,7 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) | |||
1079 | 1079 | ||
1080 | /* | 1080 | /* |
1081 | * The defaults in the HW for RX PB 1-7 are not zero and so should be | 1081 | * The defaults in the HW for RX PB 1-7 are not zero and so should be |
1082 | * intialized to zero for non DCB mode otherwise actual total RX PB | 1082 | * initialized to zero for non DCB mode otherwise actual total RX PB |
1083 | * would be bigger than programmed and filter space would run into | 1083 | * would be bigger than programmed and filter space would run into |
1084 | * the PB 0 region. | 1084 | * the PB 0 region. |
1085 | */ | 1085 | */ |
@@ -1167,7 +1167,7 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) | |||
1167 | 1167 | ||
1168 | /* | 1168 | /* |
1169 | * The defaults in the HW for RX PB 1-7 are not zero and so should be | 1169 | * The defaults in the HW for RX PB 1-7 are not zero and so should be |
1170 | * intialized to zero for non DCB mode otherwise actual total RX PB | 1170 | * initialized to zero for non DCB mode otherwise actual total RX PB |
1171 | * would be bigger than programmed and filter space would run into | 1171 | * would be bigger than programmed and filter space would run into |
1172 | * the PB 0 region. | 1172 | * the PB 0 region. |
1173 | */ | 1173 | */ |
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 183765cb7f2..f35554d1144 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c | |||
@@ -238,7 +238,7 @@ static int temac_dma_bd_init(struct net_device *ndev) | |||
238 | goto out; | 238 | goto out; |
239 | } | 239 | } |
240 | /* allocate the tx and rx ring buffer descriptors. */ | 240 | /* allocate the tx and rx ring buffer descriptors. */ |
241 | /* returns a virtual addres and a physical address. */ | 241 | /* returns a virtual address and a physical address. */ |
242 | lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, | 242 | lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, |
243 | sizeof(*lp->tx_bd_v) * TX_BD_NUM, | 243 | sizeof(*lp->tx_bd_v) * TX_BD_NUM, |
244 | &lp->tx_bd_p, GFP_KERNEL); | 244 | &lp->tx_bd_p, GFP_KERNEL); |
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 58183686709..5976d1d51df 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c | |||
@@ -36,7 +36,7 @@ | |||
36 | Rev 1.07.06 Nov. 7 2000 Jeff Garzik <jgarzik@pobox.com> some bug fix and cleaning | 36 | Rev 1.07.06 Nov. 7 2000 Jeff Garzik <jgarzik@pobox.com> some bug fix and cleaning |
37 | Rev 1.07.05 Nov. 6 2000 metapirat<metapirat@gmx.de> contribute media type select by ifconfig | 37 | Rev 1.07.05 Nov. 6 2000 metapirat<metapirat@gmx.de> contribute media type select by ifconfig |
38 | Rev 1.07.04 Sep. 6 2000 Lei-Chun Chang added ICS1893 PHY support | 38 | Rev 1.07.04 Sep. 6 2000 Lei-Chun Chang added ICS1893 PHY support |
39 | Rev 1.07.03 Aug. 24 2000 Lei-Chun Chang (lcchang@sis.com.tw) modified 630E eqaulizer workaround rule | 39 | Rev 1.07.03 Aug. 24 2000 Lei-Chun Chang (lcchang@sis.com.tw) modified 630E equalizer workaround rule |
40 | Rev 1.07.01 Aug. 08 2000 Ollie Lho minor update for SiS 630E and SiS 630E A1 | 40 | Rev 1.07.01 Aug. 08 2000 Ollie Lho minor update for SiS 630E and SiS 630E A1 |
41 | Rev 1.07 Mar. 07 2000 Ollie Lho bug fix in Rx buffer ring | 41 | Rev 1.07 Mar. 07 2000 Ollie Lho bug fix in Rx buffer ring |
42 | Rev 1.06.04 Feb. 11 2000 Jeff Garzik <jgarzik@pobox.com> softnet and init for kernel 2.4 | 42 | Rev 1.06.04 Feb. 11 2000 Jeff Garzik <jgarzik@pobox.com> softnet and init for kernel 2.4 |
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 296000bf5a2..3397618d4d9 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c | |||
@@ -12,7 +12,7 @@ | |||
12 | /* | 12 | /* |
13 | * RX HW/SW interaction overview | 13 | * RX HW/SW interaction overview |
14 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 14 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
15 | * There are 2 types of RX communication channels betwean driver and NIC. | 15 | * There are 2 types of RX communication channels between driver and NIC. |
16 | * 1) RX Free Fifo - RXF - holds descriptors of empty buffers to accept incoming | 16 | * 1) RX Free Fifo - RXF - holds descriptors of empty buffers to accept incoming |
17 | * traffic. This Fifo is filled by SW and is readen by HW. Each descriptor holds | 17 | * traffic. This Fifo is filled by SW and is readen by HW. Each descriptor holds |
18 | * info about buffer's location, size and ID. An ID field is used to identify a | 18 | * info about buffer's location, size and ID. An ID field is used to identify a |
@@ -821,7 +821,7 @@ static void bdx_setmulti(struct net_device *ndev) | |||
821 | } | 821 | } |
822 | 822 | ||
823 | /* use PMF to accept first MAC_MCST_NUM (15) addresses */ | 823 | /* use PMF to accept first MAC_MCST_NUM (15) addresses */ |
824 | /* TBD: sort addreses and write them in ascending order | 824 | /* TBD: sort addresses and write them in ascending order |
825 | * into RX_MAC_MCST regs. we skip this phase now and accept ALL | 825 | * into RX_MAC_MCST regs. we skip this phase now and accept ALL |
826 | * multicast frames throu IMF */ | 826 | * multicast frames throu IMF */ |
827 | /* accept the rest of addresses throu IMF */ | 827 | /* accept the rest of addresses throu IMF */ |
@@ -1346,7 +1346,7 @@ static void print_rxfd(struct rxf_desc *rxfd) | |||
1346 | /* | 1346 | /* |
1347 | * TX HW/SW interaction overview | 1347 | * TX HW/SW interaction overview |
1348 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 1348 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1349 | * There are 2 types of TX communication channels betwean driver and NIC. | 1349 | * There are 2 types of TX communication channels between driver and NIC. |
1350 | * 1) TX Free Fifo - TXF - holds ack descriptors for sent packets | 1350 | * 1) TX Free Fifo - TXF - holds ack descriptors for sent packets |
1351 | * 2) TX Data Fifo - TXD - holds descriptors of full buffers. | 1351 | * 2) TX Data Fifo - TXD - holds descriptors of full buffers. |
1352 | * | 1352 | * |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 7599c457abd..b100bd50a0d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -1309,7 +1309,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1309 | break; | 1309 | break; |
1310 | 1310 | ||
1311 | case SIOCGIFHWADDR: | 1311 | case SIOCGIFHWADDR: |
1312 | /* Get hw addres */ | 1312 | /* Get hw address */ |
1313 | memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); | 1313 | memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); |
1314 | ifr.ifr_hwaddr.sa_family = tun->dev->type; | 1314 | ifr.ifr_hwaddr.sa_family = tun->dev->type; |
1315 | if (copy_to_user(argp, &ifr, ifreq_len)) | 1315 | if (copy_to_user(argp, &ifr, ifreq_len)) |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index cab96ad49e6..09cac704fdd 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -898,7 +898,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) | |||
898 | set_mii_flow_control(vptr); | 898 | set_mii_flow_control(vptr); |
899 | 899 | ||
900 | /* | 900 | /* |
901 | Check if new status is consisent with current status | 901 | Check if new status is consistent with current status |
902 | if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) || | 902 | if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) || |
903 | (mii_status==curr_status)) { | 903 | (mii_status==curr_status)) { |
904 | vptr->mii_status=mii_check_media_mode(vptr->mac_regs); | 904 | vptr->mii_status=mii_check_media_mode(vptr->mac_regs); |
diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index 8c3103fb644..d48486d6afa 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h | |||
@@ -1695,7 +1695,7 @@ struct vxge_hw_device_stats_sw_err { | |||
1695 | * struct vxge_hw_device_stats - Contains HW per-device statistics, | 1695 | * struct vxge_hw_device_stats - Contains HW per-device statistics, |
1696 | * including hw. | 1696 | * including hw. |
1697 | * @devh: HW device handle. | 1697 | * @devh: HW device handle. |
1698 | * @dma_addr: DMA addres of the %hw_info. Given to device to fill-in the stats. | 1698 | * @dma_addr: DMA address of the %hw_info. Given to device to fill-in the stats. |
1699 | * @hw_info_dmah: DMA handle used to map hw statistics onto the device memory | 1699 | * @hw_info_dmah: DMA handle used to map hw statistics onto the device memory |
1700 | * space. | 1700 | * space. |
1701 | * @hw_info_dma_acch: One more DMA handle used subsequently to free the | 1701 | * @hw_info_dma_acch: One more DMA handle used subsequently to free the |
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 34cff6ce6d2..4578e5b4b41 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c | |||
@@ -125,7 +125,7 @@ static u32 dscc4_pci_config_store[16]; | |||
125 | /* Module parameters */ | 125 | /* Module parameters */ |
126 | 126 | ||
127 | MODULE_AUTHOR("Maintainer: Francois Romieu <romieu@cogenit.fr>"); | 127 | MODULE_AUTHOR("Maintainer: Francois Romieu <romieu@cogenit.fr>"); |
128 | MODULE_DESCRIPTION("Siemens PEB20534 PCI Controler"); | 128 | MODULE_DESCRIPTION("Siemens PEB20534 PCI Controller"); |
129 | MODULE_LICENSE("GPL"); | 129 | MODULE_LICENSE("GPL"); |
130 | module_param(debug, int, 0); | 130 | module_param(debug, int, 0); |
131 | MODULE_PARM_DESC(debug,"Enable/disable extra messages"); | 131 | MODULE_PARM_DESC(debug,"Enable/disable extra messages"); |
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index f0603327aaf..65bc334ed57 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c | |||
@@ -232,7 +232,7 @@ int i2400m_check_mac_addr(struct i2400m *i2400m) | |||
232 | result); | 232 | result); |
233 | goto error; | 233 | goto error; |
234 | } | 234 | } |
235 | /* Extract MAC addresss */ | 235 | /* Extract MAC address */ |
236 | ddi = (void *) skb->data; | 236 | ddi = (void *) skb->data; |
237 | BUILD_BUG_ON(ETH_ALEN != sizeof(ddi->mac_address)); | 237 | BUILD_BUG_ON(ETH_ALEN != sizeof(ddi->mac_address)); |
238 | d_printf(2, dev, "GET DEVICE INFO: mac addr %pM\n", | 238 | d_printf(2, dev, "GET DEVICE INFO: mac addr %pM\n", |
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 17ecaa41a80..030cbfd3170 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h | |||
@@ -186,7 +186,7 @@ enum { | |||
186 | * struct i2400m_poke_table - Hardware poke table for the Intel 2400m | 186 | * struct i2400m_poke_table - Hardware poke table for the Intel 2400m |
187 | * | 187 | * |
188 | * This structure will be used to create a device specific poke table | 188 | * This structure will be used to create a device specific poke table |
189 | * to put the device in a consistant state at boot time. | 189 | * to put the device in a consistent state at boot time. |
190 | * | 190 | * |
191 | * @address: The device address to poke | 191 | * @address: The device address to poke |
192 | * | 192 | * |
@@ -703,7 +703,7 @@ enum i2400m_bm_cmd_flags { | |||
703 | * @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot | 703 | * @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot |
704 | * rom after reading the MAC address. This is quite a dirty hack, | 704 | * rom after reading the MAC address. This is quite a dirty hack, |
705 | * if you ask me -- the device requires the bootrom to be | 705 | * if you ask me -- the device requires the bootrom to be |
706 | * intialized after reading the MAC address. | 706 | * initialized after reading the MAC address. |
707 | */ | 707 | */ |
708 | enum i2400m_bri { | 708 | enum i2400m_bri { |
709 | I2400M_BRI_SOFT = 1 << 1, | 709 | I2400M_BRI_SOFT = 1 << 1, |
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 7ad05d401ab..fd14b910395 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h | |||
@@ -1064,7 +1064,7 @@ | |||
1064 | /* | 1064 | /* |
1065 | * EEPROM command register | 1065 | * EEPROM command register |
1066 | */ | 1066 | */ |
1067 | #define AR5K_EEPROM_CMD 0x6008 /* Register Addres */ | 1067 | #define AR5K_EEPROM_CMD 0x6008 /* Register Address */ |
1068 | #define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */ | 1068 | #define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */ |
1069 | #define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */ | 1069 | #define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */ |
1070 | #define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */ | 1070 | #define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */ |
@@ -1084,7 +1084,7 @@ | |||
1084 | /* | 1084 | /* |
1085 | * EEPROM config register | 1085 | * EEPROM config register |
1086 | */ | 1086 | */ |
1087 | #define AR5K_EEPROM_CFG 0x6010 /* Register Addres */ | 1087 | #define AR5K_EEPROM_CFG 0x6010 /* Register Address */ |
1088 | #define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ | 1088 | #define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ |
1089 | #define AR5K_EEPROM_CFG_SIZE_AUTO 0 | 1089 | #define AR5K_EEPROM_CFG_SIZE_AUTO 0 |
1090 | #define AR5K_EEPROM_CFG_SIZE_4KBIT 1 | 1090 | #define AR5K_EEPROM_CFG_SIZE_4KBIT 1 |
@@ -1126,7 +1126,7 @@ | |||
1126 | * Second station id register (Upper 16 bits of MAC address + PCU settings) | 1126 | * Second station id register (Upper 16 bits of MAC address + PCU settings) |
1127 | */ | 1127 | */ |
1128 | #define AR5K_STA_ID1 0x8004 /* Register Address */ | 1128 | #define AR5K_STA_ID1 0x8004 /* Register Address */ |
1129 | #define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC addres */ | 1129 | #define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC address */ |
1130 | #define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */ | 1130 | #define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */ |
1131 | #define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */ | 1131 | #define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */ |
1132 | #define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */ | 1132 | #define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */ |
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 0dc33b65e86..be482816701 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c | |||
@@ -1919,7 +1919,7 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev) | |||
1919 | b43_hf_write(dev, b43_hf_read(dev) | B43_HF_HWPCTL); | 1919 | b43_hf_write(dev, b43_hf_read(dev) | B43_HF_HWPCTL); |
1920 | } | 1920 | } |
1921 | 1921 | ||
1922 | /* Intialize B/G PHY power control */ | 1922 | /* Initialize B/G PHY power control */ |
1923 | static void b43_phy_init_pctl(struct b43_wldev *dev) | 1923 | static void b43_phy_init_pctl(struct b43_wldev *dev) |
1924 | { | 1924 | { |
1925 | struct ssb_bus *bus = dev->dev->bus; | 1925 | struct ssb_bus *bus = dev->dev->bus; |
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 35033dd342c..28e477d0158 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c | |||
@@ -153,7 +153,7 @@ void b43legacy_phy_calibrate(struct b43legacy_wldev *dev) | |||
153 | phy->calibrated = 1; | 153 | phy->calibrated = 1; |
154 | } | 154 | } |
155 | 155 | ||
156 | /* intialize B PHY power control | 156 | /* initialize B PHY power control |
157 | * as described in http://bcm-specs.sipsolutions.net/InitPowerControl | 157 | * as described in http://bcm-specs.sipsolutions.net/InitPowerControl |
158 | */ | 158 | */ |
159 | static void b43legacy_phy_init_pctl(struct b43legacy_wldev *dev) | 159 | static void b43legacy_phy_init_pctl(struct b43legacy_wldev *dev) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index a5dbfea1bfa..b5cb3be0eb4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c | |||
@@ -197,7 +197,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
197 | 197 | ||
198 | none: | 198 | none: |
199 | /* re-enable interrupts here since we don't have anything to service. */ | 199 | /* re-enable interrupts here since we don't have anything to service. */ |
200 | /* only Re-enable if diabled by irq and no schedules tasklet. */ | 200 | /* only Re-enable if disabled by irq and no schedules tasklet. */ |
201 | if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) | 201 | if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) |
202 | iwl_enable_interrupts(priv); | 202 | iwl_enable_interrupts(priv); |
203 | 203 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f13a83a7e62..36335b1b54d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1154,7 +1154,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1154 | } | 1154 | } |
1155 | 1155 | ||
1156 | /* Re-enable all interrupts */ | 1156 | /* Re-enable all interrupts */ |
1157 | /* only Re-enable if diabled by irq */ | 1157 | /* only Re-enable if disabled by irq */ |
1158 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1158 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
1159 | iwl_enable_interrupts(priv); | 1159 | iwl_enable_interrupts(priv); |
1160 | 1160 | ||
@@ -1368,7 +1368,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | /* Re-enable all interrupts */ | 1370 | /* Re-enable all interrupts */ |
1371 | /* only Re-enable if diabled by irq */ | 1371 | /* only Re-enable if disabled by irq */ |
1372 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1372 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
1373 | iwl_enable_interrupts(priv); | 1373 | iwl_enable_interrupts(priv); |
1374 | } | 1374 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c index a08b4e56e6b..bb1a742a98a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c | |||
@@ -619,7 +619,7 @@ unplugged: | |||
619 | 619 | ||
620 | none: | 620 | none: |
621 | /* re-enable interrupts here since we don't have anything to service. */ | 621 | /* re-enable interrupts here since we don't have anything to service. */ |
622 | /* only Re-enable if diabled by irq */ | 622 | /* only Re-enable if disabled by irq */ |
623 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 623 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
624 | iwl_enable_interrupts(priv); | 624 | iwl_enable_interrupts(priv); |
625 | spin_unlock_irqrestore(&priv->lock, flags); | 625 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 4776323b1eb..49493d17651 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -107,7 +107,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
107 | /* | 107 | /* |
108 | * XXX: The MAC address in the command buffer is often changed from | 108 | * XXX: The MAC address in the command buffer is often changed from |
109 | * the original sent to the device. That is, the MAC address | 109 | * the original sent to the device. That is, the MAC address |
110 | * written to the command buffer often is not the same MAC adress | 110 | * written to the command buffer often is not the same MAC address |
111 | * read from the command buffer when the command returns. This | 111 | * read from the command buffer when the command returns. This |
112 | * issue has not yet been resolved and this debugging is left to | 112 | * issue has not yet been resolved and this debugging is left to |
113 | * observe the problem. | 113 | * observe the problem. |
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 2c8cc954d1b..ec2c75d77ce 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c | |||
@@ -630,7 +630,7 @@ islpci_alloc_memory(islpci_private *priv) | |||
630 | printk(KERN_DEBUG "islpci_alloc_memory\n"); | 630 | printk(KERN_DEBUG "islpci_alloc_memory\n"); |
631 | #endif | 631 | #endif |
632 | 632 | ||
633 | /* remap the PCI device base address to accessable */ | 633 | /* remap the PCI device base address to accessible */ |
634 | if (!(priv->device_base = | 634 | if (!(priv->device_base = |
635 | ioremap(pci_resource_start(priv->pdev, 0), | 635 | ioremap(pci_resource_start(priv->pdev, 0), |
636 | ISL38XX_PCI_MEM_SIZE))) { | 636 | ISL38XX_PCI_MEM_SIZE))) { |
@@ -709,7 +709,7 @@ islpci_alloc_memory(islpci_private *priv) | |||
709 | PCI_DMA_FROMDEVICE); | 709 | PCI_DMA_FROMDEVICE); |
710 | if (!priv->pci_map_rx_address[counter]) { | 710 | if (!priv->pci_map_rx_address[counter]) { |
711 | /* error mapping the buffer to device | 711 | /* error mapping the buffer to device |
712 | accessable memory address */ | 712 | accessible memory address */ |
713 | printk(KERN_ERR "failed to map skb DMA'able\n"); | 713 | printk(KERN_ERR "failed to map skb DMA'able\n"); |
714 | goto out_free; | 714 | goto out_free; |
715 | } | 715 | } |
@@ -773,7 +773,7 @@ islpci_free_memory(islpci_private *priv) | |||
773 | priv->data_low_rx[counter] = NULL; | 773 | priv->data_low_rx[counter] = NULL; |
774 | } | 774 | } |
775 | 775 | ||
776 | /* Free the acces control list and the WPA list */ | 776 | /* Free the access control list and the WPA list */ |
777 | prism54_acl_clean(&priv->acl); | 777 | prism54_acl_clean(&priv->acl); |
778 | prism54_wpa_bss_ie_clean(priv); | 778 | prism54_wpa_bss_ie_clean(priv); |
779 | mgt_clean(priv); | 779 | mgt_clean(priv); |
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 2fc52bc2d7d..d44f8e20cce 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c | |||
@@ -450,7 +450,7 @@ islpci_eth_receive(islpci_private *priv) | |||
450 | MAX_FRAGMENT_SIZE_RX + 2, | 450 | MAX_FRAGMENT_SIZE_RX + 2, |
451 | PCI_DMA_FROMDEVICE); | 451 | PCI_DMA_FROMDEVICE); |
452 | if (unlikely(!priv->pci_map_rx_address[index])) { | 452 | if (unlikely(!priv->pci_map_rx_address[index])) { |
453 | /* error mapping the buffer to device accessable memory address */ | 453 | /* error mapping the buffer to device accessible memory address */ |
454 | DEBUG(SHOW_ERROR_MESSAGES, | 454 | DEBUG(SHOW_ERROR_MESSAGES, |
455 | "Error mapping DMA address\n"); | 455 | "Error mapping DMA address\n"); |
456 | 456 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 658542d2efe..f3da051df39 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -273,7 +273,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
273 | intf->beacon = entry; | 273 | intf->beacon = entry; |
274 | 274 | ||
275 | /* | 275 | /* |
276 | * The MAC adddress must be configured after the device | 276 | * The MAC address must be configured after the device |
277 | * has been initialized. Otherwise the device can reset | 277 | * has been initialized. Otherwise the device can reset |
278 | * the MAC registers. | 278 | * the MAC registers. |
279 | * The BSSID address must only be configured in AP mode, | 279 | * The BSSID address must only be configured in AP mode, |
diff --git a/drivers/net/wireless/wl1251/acx.h b/drivers/net/wireless/wl1251/acx.h index e54b21a4f8b..efcc3aaca14 100644 --- a/drivers/net/wireless/wl1251/acx.h +++ b/drivers/net/wireless/wl1251/acx.h | |||
@@ -1272,10 +1272,10 @@ struct wl1251_acx_tid_cfg { | |||
1272 | /* OBSOLETE */ | 1272 | /* OBSOLETE */ |
1273 | #define WL1251_ACX_INTR_WAKE_ON_HOST BIT(6) | 1273 | #define WL1251_ACX_INTR_WAKE_ON_HOST BIT(6) |
1274 | 1274 | ||
1275 | /* Trace meassge on MBOX #A */ | 1275 | /* Trace message on MBOX #A */ |
1276 | #define WL1251_ACX_INTR_TRACE_A BIT(7) | 1276 | #define WL1251_ACX_INTR_TRACE_A BIT(7) |
1277 | 1277 | ||
1278 | /* Trace meassge on MBOX #B */ | 1278 | /* Trace message on MBOX #B */ |
1279 | #define WL1251_ACX_INTR_TRACE_B BIT(8) | 1279 | #define WL1251_ACX_INTR_TRACE_B BIT(8) |
1280 | 1280 | ||
1281 | /* Command processing completion */ | 1281 | /* Command processing completion */ |
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index 13fbeeccf60..c0ce2c8b43b 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h | |||
@@ -419,7 +419,7 @@ void wl1251_disable_interrupts(struct wl1251 *wl); | |||
419 | #define WL1251_FW_NAME "wl1251-fw.bin" | 419 | #define WL1251_FW_NAME "wl1251-fw.bin" |
420 | #define WL1251_NVS_NAME "wl1251-nvs.bin" | 420 | #define WL1251_NVS_NAME "wl1251-nvs.bin" |
421 | 421 | ||
422 | #define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */ | 422 | #define WL1251_POWER_ON_SLEEP 10 /* in milliseconds */ |
423 | 423 | ||
424 | #define WL1251_PART_DOWN_MEM_START 0x0 | 424 | #define WL1251_PART_DOWN_MEM_START 0x0 |
425 | #define WL1251_PART_DOWN_MEM_SIZE 0x16800 | 425 | #define WL1251_PART_DOWN_MEM_SIZE 0x16800 |
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 9cbc3f40c8d..7bd8e4db4a7 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h | |||
@@ -47,9 +47,9 @@ | |||
47 | #define WL1271_ACX_INTR_HW_AVAILABLE BIT(5) | 47 | #define WL1271_ACX_INTR_HW_AVAILABLE BIT(5) |
48 | /* The MISC bit is used for aggregation of RX, TxComplete and TX rate update */ | 48 | /* The MISC bit is used for aggregation of RX, TxComplete and TX rate update */ |
49 | #define WL1271_ACX_INTR_DATA BIT(6) | 49 | #define WL1271_ACX_INTR_DATA BIT(6) |
50 | /* Trace meassge on MBOX #A */ | 50 | /* Trace message on MBOX #A */ |
51 | #define WL1271_ACX_INTR_TRACE_A BIT(7) | 51 | #define WL1271_ACX_INTR_TRACE_A BIT(7) |
52 | /* Trace meassge on MBOX #B */ | 52 | /* Trace message on MBOX #B */ |
53 | #define WL1271_ACX_INTR_TRACE_B BIT(8) | 53 | #define WL1271_ACX_INTR_TRACE_B BIT(8) |
54 | 54 | ||
55 | #define WL1271_ACX_INTR_ALL 0xFFFFFFFF | 55 | #define WL1271_ACX_INTR_ALL 0xFFFFFFFF |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index ce3d31f98c5..9050dd9b62d 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -416,8 +416,8 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
416 | 416 | ||
417 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power | 417 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power |
418 | on in case is has been shut down shortly before */ | 418 | on in case is has been shut down shortly before */ |
419 | #define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */ | 419 | #define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */ |
420 | #define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ | 420 | #define WL1271_POWER_ON_SLEEP 200 /* in milliseconds */ |
421 | 421 | ||
422 | /* Macros to handle wl1271.sta_rate_set */ | 422 | /* Macros to handle wl1271.sta_rate_set */ |
423 | #define HW_BG_RATES_MASK 0xffff | 423 | #define HW_BG_RATES_MASK 0xffff |
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index ee82df62e64..3e5befe4d03 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -192,7 +192,7 @@ static inline void wl3501_switch_page(struct wl3501_card *this, u8 page) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | /* | 194 | /* |
195 | * Get Ethernet MAC addresss. | 195 | * Get Ethernet MAC address. |
196 | * | 196 | * |
197 | * WARNING: We switch to FPAGE0 and switc back again. | 197 | * WARNING: We switch to FPAGE0 and switc back again. |
198 | * Making sure there is no other WL function beening called by ISR. | 198 | * Making sure there is no other WL function beening called by ISR. |
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig new file mode 100644 index 00000000000..ffedfd49275 --- /dev/null +++ b/drivers/nfc/Kconfig | |||
@@ -0,0 +1,30 @@ | |||
1 | # | ||
2 | # Near Field Communication (NFC) devices | ||
3 | # | ||
4 | |||
5 | menuconfig NFC_DEVICES | ||
6 | bool "NFC devices" | ||
7 | default n | ||
8 | ---help--- | ||
9 | You'll have to say Y if your computer contains an NFC device that | ||
10 | you want to use under Linux. | ||
11 | |||
12 | You can say N here if you don't have any Near Field Communication | ||
13 | devices connected to your computer. | ||
14 | |||
15 | if NFC_DEVICES | ||
16 | |||
17 | config PN544_NFC | ||
18 | tristate "PN544 NFC driver" | ||
19 | depends on I2C | ||
20 | select CRC_CCITT | ||
21 | default n | ||
22 | ---help--- | ||
23 | Say yes if you want PN544 Near Field Communication driver. | ||
24 | This is for i2c connected version. If unsure, say N here. | ||
25 | |||
26 | To compile this driver as a module, choose m here. The module will | ||
27 | be called pn544. | ||
28 | |||
29 | |||
30 | endif # NFC_DEVICES | ||
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile new file mode 100644 index 00000000000..a4efb164ec4 --- /dev/null +++ b/drivers/nfc/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile for nfc devices | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_PN544_NFC) += pn544.o | ||
diff --git a/drivers/nfc/pn544.c b/drivers/nfc/pn544.c new file mode 100644 index 00000000000..401c44b6ead --- /dev/null +++ b/drivers/nfc/pn544.c | |||
@@ -0,0 +1,891 @@ | |||
1 | /* | ||
2 | * Driver for the PN544 NFC chip. | ||
3 | * | ||
4 | * Copyright (C) Nokia Corporation | ||
5 | * | ||
6 | * Author: Jari Vanhala <ext-jari.vanhala@nokia.com> | ||
7 | * Contact: Matti Aaltonen <matti.j.aaltonen@nokia.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * version 2 as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/completion.h> | ||
24 | #include <linux/crc-ccitt.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/miscdevice.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/mutex.h> | ||
31 | #include <linux/nfc/pn544.h> | ||
32 | #include <linux/poll.h> | ||
33 | #include <linux/regulator/consumer.h> | ||
34 | #include <linux/serial_core.h> /* for TCGETS */ | ||
35 | #include <linux/slab.h> | ||
36 | |||
37 | #define DRIVER_CARD "PN544 NFC" | ||
38 | #define DRIVER_DESC "NFC driver for PN544" | ||
39 | |||
40 | static struct i2c_device_id pn544_id_table[] = { | ||
41 | { PN544_DRIVER_NAME, 0 }, | ||
42 | { } | ||
43 | }; | ||
44 | MODULE_DEVICE_TABLE(i2c, pn544_id_table); | ||
45 | |||
46 | #define HCI_MODE 0 | ||
47 | #define FW_MODE 1 | ||
48 | |||
49 | enum pn544_state { | ||
50 | PN544_ST_COLD, | ||
51 | PN544_ST_FW_READY, | ||
52 | PN544_ST_READY, | ||
53 | }; | ||
54 | |||
55 | enum pn544_irq { | ||
56 | PN544_NONE, | ||
57 | PN544_INT, | ||
58 | }; | ||
59 | |||
60 | struct pn544_info { | ||
61 | struct miscdevice miscdev; | ||
62 | struct i2c_client *i2c_dev; | ||
63 | struct regulator_bulk_data regs[2]; | ||
64 | |||
65 | enum pn544_state state; | ||
66 | wait_queue_head_t read_wait; | ||
67 | loff_t read_offset; | ||
68 | enum pn544_irq read_irq; | ||
69 | struct mutex read_mutex; /* Serialize read_irq access */ | ||
70 | struct mutex mutex; /* Serialize info struct access */ | ||
71 | u8 *buf; | ||
72 | unsigned int buflen; | ||
73 | }; | ||
74 | |||
75 | static const char reg_vdd_io[] = "Vdd_IO"; | ||
76 | static const char reg_vbat[] = "VBat"; | ||
77 | |||
78 | /* sysfs interface */ | ||
79 | static ssize_t pn544_test(struct device *dev, | ||
80 | struct device_attribute *attr, char *buf) | ||
81 | { | ||
82 | struct pn544_info *info = dev_get_drvdata(dev); | ||
83 | struct i2c_client *client = info->i2c_dev; | ||
84 | struct pn544_nfc_platform_data *pdata = client->dev.platform_data; | ||
85 | |||
86 | return snprintf(buf, PAGE_SIZE, "%d\n", pdata->test()); | ||
87 | } | ||
88 | |||
89 | static int pn544_enable(struct pn544_info *info, int mode) | ||
90 | { | ||
91 | struct pn544_nfc_platform_data *pdata; | ||
92 | struct i2c_client *client = info->i2c_dev; | ||
93 | |||
94 | int r; | ||
95 | |||
96 | r = regulator_bulk_enable(ARRAY_SIZE(info->regs), info->regs); | ||
97 | if (r < 0) | ||
98 | return r; | ||
99 | |||
100 | pdata = client->dev.platform_data; | ||
101 | info->read_irq = PN544_NONE; | ||
102 | if (pdata->enable) | ||
103 | pdata->enable(mode); | ||
104 | |||
105 | if (mode) { | ||
106 | info->state = PN544_ST_FW_READY; | ||
107 | dev_dbg(&client->dev, "now in FW-mode\n"); | ||
108 | } else { | ||
109 | info->state = PN544_ST_READY; | ||
110 | dev_dbg(&client->dev, "now in HCI-mode\n"); | ||
111 | } | ||
112 | |||
113 | usleep_range(10000, 15000); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static void pn544_disable(struct pn544_info *info) | ||
119 | { | ||
120 | struct pn544_nfc_platform_data *pdata; | ||
121 | struct i2c_client *client = info->i2c_dev; | ||
122 | |||
123 | pdata = client->dev.platform_data; | ||
124 | if (pdata->disable) | ||
125 | pdata->disable(); | ||
126 | |||
127 | info->state = PN544_ST_COLD; | ||
128 | |||
129 | dev_dbg(&client->dev, "Now in OFF-mode\n"); | ||
130 | |||
131 | msleep(PN544_RESETVEN_TIME); | ||
132 | |||
133 | info->read_irq = PN544_NONE; | ||
134 | regulator_bulk_disable(ARRAY_SIZE(info->regs), info->regs); | ||
135 | } | ||
136 | |||
137 | static int check_crc(u8 *buf, int buflen) | ||
138 | { | ||
139 | u8 len; | ||
140 | u16 crc; | ||
141 | |||
142 | len = buf[0] + 1; | ||
143 | if (len < 4 || len != buflen || len > PN544_MSG_MAX_SIZE) { | ||
144 | pr_err(PN544_DRIVER_NAME | ||
145 | ": CRC; corrupt packet len %u (%d)\n", len, buflen); | ||
146 | print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, | ||
147 | 16, 2, buf, buflen, false); | ||
148 | return -EPERM; | ||
149 | } | ||
150 | crc = crc_ccitt(0xffff, buf, len - 2); | ||
151 | crc = ~crc; | ||
152 | |||
153 | if (buf[len-2] != (crc & 0xff) || buf[len-1] != (crc >> 8)) { | ||
154 | pr_err(PN544_DRIVER_NAME ": CRC error 0x%x != 0x%x 0x%x\n", | ||
155 | crc, buf[len-1], buf[len-2]); | ||
156 | |||
157 | print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, | ||
158 | 16, 2, buf, buflen, false); | ||
159 | return -EPERM; | ||
160 | } | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int pn544_i2c_write(struct i2c_client *client, u8 *buf, int len) | ||
165 | { | ||
166 | int r; | ||
167 | |||
168 | if (len < 4 || len != (buf[0] + 1)) { | ||
169 | dev_err(&client->dev, "%s: Illegal message length: %d\n", | ||
170 | __func__, len); | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | |||
174 | if (check_crc(buf, len)) | ||
175 | return -EINVAL; | ||
176 | |||
177 | usleep_range(3000, 6000); | ||
178 | |||
179 | r = i2c_master_send(client, buf, len); | ||
180 | dev_dbg(&client->dev, "send: %d\n", r); | ||
181 | |||
182 | if (r == -EREMOTEIO) { /* Retry, chip was in standby */ | ||
183 | usleep_range(6000, 10000); | ||
184 | r = i2c_master_send(client, buf, len); | ||
185 | dev_dbg(&client->dev, "send2: %d\n", r); | ||
186 | } | ||
187 | |||
188 | if (r != len) | ||
189 | return -EREMOTEIO; | ||
190 | |||
191 | return r; | ||
192 | } | ||
193 | |||
194 | static int pn544_i2c_read(struct i2c_client *client, u8 *buf, int buflen) | ||
195 | { | ||
196 | int r; | ||
197 | u8 len; | ||
198 | |||
199 | /* | ||
200 | * You could read a packet in one go, but then you'd need to read | ||
201 | * max size and rest would be 0xff fill, so we do split reads. | ||
202 | */ | ||
203 | r = i2c_master_recv(client, &len, 1); | ||
204 | dev_dbg(&client->dev, "recv1: %d\n", r); | ||
205 | |||
206 | if (r != 1) | ||
207 | return -EREMOTEIO; | ||
208 | |||
209 | if (len < PN544_LLC_HCI_OVERHEAD) | ||
210 | len = PN544_LLC_HCI_OVERHEAD; | ||
211 | else if (len > (PN544_MSG_MAX_SIZE - 1)) | ||
212 | len = PN544_MSG_MAX_SIZE - 1; | ||
213 | |||
214 | if (1 + len > buflen) /* len+(data+crc16) */ | ||
215 | return -EMSGSIZE; | ||
216 | |||
217 | buf[0] = len; | ||
218 | |||
219 | r = i2c_master_recv(client, buf + 1, len); | ||
220 | dev_dbg(&client->dev, "recv2: %d\n", r); | ||
221 | |||
222 | if (r != len) | ||
223 | return -EREMOTEIO; | ||
224 | |||
225 | usleep_range(3000, 6000); | ||
226 | |||
227 | return r + 1; | ||
228 | } | ||
229 | |||
230 | static int pn544_fw_write(struct i2c_client *client, u8 *buf, int len) | ||
231 | { | ||
232 | int r; | ||
233 | |||
234 | dev_dbg(&client->dev, "%s\n", __func__); | ||
235 | |||
236 | if (len < PN544_FW_HEADER_SIZE || | ||
237 | (PN544_FW_HEADER_SIZE + (buf[1] << 8) + buf[2]) != len) | ||
238 | return -EINVAL; | ||
239 | |||
240 | r = i2c_master_send(client, buf, len); | ||
241 | dev_dbg(&client->dev, "fw send: %d\n", r); | ||
242 | |||
243 | if (r == -EREMOTEIO) { /* Retry, chip was in standby */ | ||
244 | usleep_range(6000, 10000); | ||
245 | r = i2c_master_send(client, buf, len); | ||
246 | dev_dbg(&client->dev, "fw send2: %d\n", r); | ||
247 | } | ||
248 | |||
249 | if (r != len) | ||
250 | return -EREMOTEIO; | ||
251 | |||
252 | return r; | ||
253 | } | ||
254 | |||
255 | static int pn544_fw_read(struct i2c_client *client, u8 *buf, int buflen) | ||
256 | { | ||
257 | int r, len; | ||
258 | |||
259 | if (buflen < PN544_FW_HEADER_SIZE) | ||
260 | return -EINVAL; | ||
261 | |||
262 | r = i2c_master_recv(client, buf, PN544_FW_HEADER_SIZE); | ||
263 | dev_dbg(&client->dev, "FW recv1: %d\n", r); | ||
264 | |||
265 | if (r < 0) | ||
266 | return r; | ||
267 | |||
268 | if (r < PN544_FW_HEADER_SIZE) | ||
269 | return -EINVAL; | ||
270 | |||
271 | len = (buf[1] << 8) + buf[2]; | ||
272 | if (len == 0) /* just header, no additional data */ | ||
273 | return r; | ||
274 | |||
275 | if (len > buflen - PN544_FW_HEADER_SIZE) | ||
276 | return -EMSGSIZE; | ||
277 | |||
278 | r = i2c_master_recv(client, buf + PN544_FW_HEADER_SIZE, len); | ||
279 | dev_dbg(&client->dev, "fw recv2: %d\n", r); | ||
280 | |||
281 | if (r != len) | ||
282 | return -EINVAL; | ||
283 | |||
284 | return r + PN544_FW_HEADER_SIZE; | ||
285 | } | ||
286 | |||
287 | static irqreturn_t pn544_irq_thread_fn(int irq, void *dev_id) | ||
288 | { | ||
289 | struct pn544_info *info = dev_id; | ||
290 | struct i2c_client *client = info->i2c_dev; | ||
291 | |||
292 | BUG_ON(!info); | ||
293 | BUG_ON(irq != info->i2c_dev->irq); | ||
294 | |||
295 | dev_dbg(&client->dev, "IRQ\n"); | ||
296 | |||
297 | mutex_lock(&info->read_mutex); | ||
298 | info->read_irq = PN544_INT; | ||
299 | mutex_unlock(&info->read_mutex); | ||
300 | |||
301 | wake_up_interruptible(&info->read_wait); | ||
302 | |||
303 | return IRQ_HANDLED; | ||
304 | } | ||
305 | |||
306 | static enum pn544_irq pn544_irq_state(struct pn544_info *info) | ||
307 | { | ||
308 | enum pn544_irq irq; | ||
309 | |||
310 | mutex_lock(&info->read_mutex); | ||
311 | irq = info->read_irq; | ||
312 | mutex_unlock(&info->read_mutex); | ||
313 | /* | ||
314 | * XXX: should we check GPIO-line status directly? | ||
315 | * return pdata->irq_status() ? PN544_INT : PN544_NONE; | ||
316 | */ | ||
317 | |||
318 | return irq; | ||
319 | } | ||
320 | |||
321 | static ssize_t pn544_read(struct file *file, char __user *buf, | ||
322 | size_t count, loff_t *offset) | ||
323 | { | ||
324 | struct pn544_info *info = container_of(file->private_data, | ||
325 | struct pn544_info, miscdev); | ||
326 | struct i2c_client *client = info->i2c_dev; | ||
327 | enum pn544_irq irq; | ||
328 | size_t len; | ||
329 | int r = 0; | ||
330 | |||
331 | dev_dbg(&client->dev, "%s: info: %p, count: %zu\n", __func__, | ||
332 | info, count); | ||
333 | |||
334 | mutex_lock(&info->mutex); | ||
335 | |||
336 | if (info->state == PN544_ST_COLD) { | ||
337 | r = -ENODEV; | ||
338 | goto out; | ||
339 | } | ||
340 | |||
341 | irq = pn544_irq_state(info); | ||
342 | if (irq == PN544_NONE) { | ||
343 | if (file->f_flags & O_NONBLOCK) { | ||
344 | r = -EAGAIN; | ||
345 | goto out; | ||
346 | } | ||
347 | |||
348 | if (wait_event_interruptible(info->read_wait, | ||
349 | (info->read_irq == PN544_INT))) { | ||
350 | r = -ERESTARTSYS; | ||
351 | goto out; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | if (info->state == PN544_ST_FW_READY) { | ||
356 | len = min(count, info->buflen); | ||
357 | |||
358 | mutex_lock(&info->read_mutex); | ||
359 | r = pn544_fw_read(info->i2c_dev, info->buf, len); | ||
360 | info->read_irq = PN544_NONE; | ||
361 | mutex_unlock(&info->read_mutex); | ||
362 | |||
363 | if (r < 0) { | ||
364 | dev_err(&info->i2c_dev->dev, "FW read failed: %d\n", r); | ||
365 | goto out; | ||
366 | } | ||
367 | |||
368 | print_hex_dump(KERN_DEBUG, "FW read: ", DUMP_PREFIX_NONE, | ||
369 | 16, 2, info->buf, r, false); | ||
370 | |||
371 | *offset += r; | ||
372 | if (copy_to_user(buf, info->buf, r)) { | ||
373 | r = -EFAULT; | ||
374 | goto out; | ||
375 | } | ||
376 | } else { | ||
377 | len = min(count, info->buflen); | ||
378 | |||
379 | mutex_lock(&info->read_mutex); | ||
380 | r = pn544_i2c_read(info->i2c_dev, info->buf, len); | ||
381 | info->read_irq = PN544_NONE; | ||
382 | mutex_unlock(&info->read_mutex); | ||
383 | |||
384 | if (r < 0) { | ||
385 | dev_err(&info->i2c_dev->dev, "read failed (%d)\n", r); | ||
386 | goto out; | ||
387 | } | ||
388 | print_hex_dump(KERN_DEBUG, "read: ", DUMP_PREFIX_NONE, | ||
389 | 16, 2, info->buf, r, false); | ||
390 | |||
391 | *offset += r; | ||
392 | if (copy_to_user(buf, info->buf, r)) { | ||
393 | r = -EFAULT; | ||
394 | goto out; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | out: | ||
399 | mutex_unlock(&info->mutex); | ||
400 | |||
401 | return r; | ||
402 | } | ||
403 | |||
404 | static unsigned int pn544_poll(struct file *file, poll_table *wait) | ||
405 | { | ||
406 | struct pn544_info *info = container_of(file->private_data, | ||
407 | struct pn544_info, miscdev); | ||
408 | struct i2c_client *client = info->i2c_dev; | ||
409 | int r = 0; | ||
410 | |||
411 | dev_dbg(&client->dev, "%s: info: %p\n", __func__, info); | ||
412 | |||
413 | mutex_lock(&info->mutex); | ||
414 | |||
415 | if (info->state == PN544_ST_COLD) { | ||
416 | r = -ENODEV; | ||
417 | goto out; | ||
418 | } | ||
419 | |||
420 | poll_wait(file, &info->read_wait, wait); | ||
421 | |||
422 | if (pn544_irq_state(info) == PN544_INT) { | ||
423 | r = POLLIN | POLLRDNORM; | ||
424 | goto out; | ||
425 | } | ||
426 | out: | ||
427 | mutex_unlock(&info->mutex); | ||
428 | |||
429 | return r; | ||
430 | } | ||
431 | |||
432 | static ssize_t pn544_write(struct file *file, const char __user *buf, | ||
433 | size_t count, loff_t *ppos) | ||
434 | { | ||
435 | struct pn544_info *info = container_of(file->private_data, | ||
436 | struct pn544_info, miscdev); | ||
437 | struct i2c_client *client = info->i2c_dev; | ||
438 | ssize_t len; | ||
439 | int r; | ||
440 | |||
441 | dev_dbg(&client->dev, "%s: info: %p, count %zu\n", __func__, | ||
442 | info, count); | ||
443 | |||
444 | mutex_lock(&info->mutex); | ||
445 | |||
446 | if (info->state == PN544_ST_COLD) { | ||
447 | r = -ENODEV; | ||
448 | goto out; | ||
449 | } | ||
450 | |||
451 | /* | ||
452 | * XXX: should we detect rset-writes and clean possible | ||
453 | * read_irq state | ||
454 | */ | ||
455 | if (info->state == PN544_ST_FW_READY) { | ||
456 | size_t fw_len; | ||
457 | |||
458 | if (count < PN544_FW_HEADER_SIZE) { | ||
459 | r = -EINVAL; | ||
460 | goto out; | ||
461 | } | ||
462 | |||
463 | len = min(count, info->buflen); | ||
464 | if (copy_from_user(info->buf, buf, len)) { | ||
465 | r = -EFAULT; | ||
466 | goto out; | ||
467 | } | ||
468 | |||
469 | print_hex_dump(KERN_DEBUG, "FW write: ", DUMP_PREFIX_NONE, | ||
470 | 16, 2, info->buf, len, false); | ||
471 | |||
472 | fw_len = PN544_FW_HEADER_SIZE + (info->buf[1] << 8) + | ||
473 | info->buf[2]; | ||
474 | |||
475 | if (len > fw_len) /* 1 msg at a time */ | ||
476 | len = fw_len; | ||
477 | |||
478 | r = pn544_fw_write(info->i2c_dev, info->buf, len); | ||
479 | } else { | ||
480 | if (count < PN544_LLC_MIN_SIZE) { | ||
481 | r = -EINVAL; | ||
482 | goto out; | ||
483 | } | ||
484 | |||
485 | len = min(count, info->buflen); | ||
486 | if (copy_from_user(info->buf, buf, len)) { | ||
487 | r = -EFAULT; | ||
488 | goto out; | ||
489 | } | ||
490 | |||
491 | print_hex_dump(KERN_DEBUG, "write: ", DUMP_PREFIX_NONE, | ||
492 | 16, 2, info->buf, len, false); | ||
493 | |||
494 | if (len > (info->buf[0] + 1)) /* 1 msg at a time */ | ||
495 | len = info->buf[0] + 1; | ||
496 | |||
497 | r = pn544_i2c_write(info->i2c_dev, info->buf, len); | ||
498 | } | ||
499 | out: | ||
500 | mutex_unlock(&info->mutex); | ||
501 | |||
502 | return r; | ||
503 | |||
504 | } | ||
505 | |||
506 | static long pn544_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
507 | { | ||
508 | struct pn544_info *info = container_of(file->private_data, | ||
509 | struct pn544_info, miscdev); | ||
510 | struct i2c_client *client = info->i2c_dev; | ||
511 | struct pn544_nfc_platform_data *pdata; | ||
512 | unsigned int val; | ||
513 | int r = 0; | ||
514 | |||
515 | dev_dbg(&client->dev, "%s: info: %p, cmd: 0x%x\n", __func__, info, cmd); | ||
516 | |||
517 | mutex_lock(&info->mutex); | ||
518 | |||
519 | if (info->state == PN544_ST_COLD) { | ||
520 | r = -ENODEV; | ||
521 | goto out; | ||
522 | } | ||
523 | |||
524 | pdata = info->i2c_dev->dev.platform_data; | ||
525 | switch (cmd) { | ||
526 | case PN544_GET_FW_MODE: | ||
527 | dev_dbg(&client->dev, "%s: PN544_GET_FW_MODE\n", __func__); | ||
528 | |||
529 | val = (info->state == PN544_ST_FW_READY); | ||
530 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) { | ||
531 | r = -EFAULT; | ||
532 | goto out; | ||
533 | } | ||
534 | |||
535 | break; | ||
536 | |||
537 | case PN544_SET_FW_MODE: | ||
538 | dev_dbg(&client->dev, "%s: PN544_SET_FW_MODE\n", __func__); | ||
539 | |||
540 | if (copy_from_user(&val, (void __user *)arg, sizeof(val))) { | ||
541 | r = -EFAULT; | ||
542 | goto out; | ||
543 | } | ||
544 | |||
545 | if (val) { | ||
546 | if (info->state == PN544_ST_FW_READY) | ||
547 | break; | ||
548 | |||
549 | pn544_disable(info); | ||
550 | r = pn544_enable(info, FW_MODE); | ||
551 | if (r < 0) | ||
552 | goto out; | ||
553 | } else { | ||
554 | if (info->state == PN544_ST_READY) | ||
555 | break; | ||
556 | pn544_disable(info); | ||
557 | r = pn544_enable(info, HCI_MODE); | ||
558 | if (r < 0) | ||
559 | goto out; | ||
560 | } | ||
561 | file->f_pos = info->read_offset; | ||
562 | break; | ||
563 | |||
564 | case TCGETS: | ||
565 | dev_dbg(&client->dev, "%s: TCGETS\n", __func__); | ||
566 | |||
567 | r = -ENOIOCTLCMD; | ||
568 | break; | ||
569 | |||
570 | default: | ||
571 | dev_err(&client->dev, "Unknown ioctl 0x%x\n", cmd); | ||
572 | r = -ENOIOCTLCMD; | ||
573 | break; | ||
574 | } | ||
575 | |||
576 | out: | ||
577 | mutex_unlock(&info->mutex); | ||
578 | |||
579 | return r; | ||
580 | } | ||
581 | |||
582 | static int pn544_open(struct inode *inode, struct file *file) | ||
583 | { | ||
584 | struct pn544_info *info = container_of(file->private_data, | ||
585 | struct pn544_info, miscdev); | ||
586 | struct i2c_client *client = info->i2c_dev; | ||
587 | int r = 0; | ||
588 | |||
589 | dev_dbg(&client->dev, "%s: info: %p, client %p\n", __func__, | ||
590 | info, info->i2c_dev); | ||
591 | |||
592 | mutex_lock(&info->mutex); | ||
593 | |||
594 | /* | ||
595 | * Only 1 at a time. | ||
596 | * XXX: maybe user (counter) would work better | ||
597 | */ | ||
598 | if (info->state != PN544_ST_COLD) { | ||
599 | r = -EBUSY; | ||
600 | goto out; | ||
601 | } | ||
602 | |||
603 | file->f_pos = info->read_offset; | ||
604 | r = pn544_enable(info, HCI_MODE); | ||
605 | |||
606 | out: | ||
607 | mutex_unlock(&info->mutex); | ||
608 | return r; | ||
609 | } | ||
610 | |||
611 | static int pn544_close(struct inode *inode, struct file *file) | ||
612 | { | ||
613 | struct pn544_info *info = container_of(file->private_data, | ||
614 | struct pn544_info, miscdev); | ||
615 | struct i2c_client *client = info->i2c_dev; | ||
616 | |||
617 | dev_dbg(&client->dev, "%s: info: %p, client %p\n", | ||
618 | __func__, info, info->i2c_dev); | ||
619 | |||
620 | mutex_lock(&info->mutex); | ||
621 | pn544_disable(info); | ||
622 | mutex_unlock(&info->mutex); | ||
623 | |||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static const struct file_operations pn544_fops = { | ||
628 | .owner = THIS_MODULE, | ||
629 | .llseek = no_llseek, | ||
630 | .read = pn544_read, | ||
631 | .write = pn544_write, | ||
632 | .poll = pn544_poll, | ||
633 | .open = pn544_open, | ||
634 | .release = pn544_close, | ||
635 | .unlocked_ioctl = pn544_ioctl, | ||
636 | }; | ||
637 | |||
638 | #ifdef CONFIG_PM | ||
639 | static int pn544_suspend(struct device *dev) | ||
640 | { | ||
641 | struct i2c_client *client = to_i2c_client(dev); | ||
642 | struct pn544_info *info; | ||
643 | int r = 0; | ||
644 | |||
645 | dev_info(&client->dev, "***\n%s: client %p\n***\n", __func__, client); | ||
646 | |||
647 | info = i2c_get_clientdata(client); | ||
648 | dev_info(&client->dev, "%s: info: %p, client %p\n", __func__, | ||
649 | info, client); | ||
650 | |||
651 | mutex_lock(&info->mutex); | ||
652 | |||
653 | switch (info->state) { | ||
654 | case PN544_ST_FW_READY: | ||
655 | /* Do not suspend while upgrading FW, please! */ | ||
656 | r = -EPERM; | ||
657 | break; | ||
658 | |||
659 | case PN544_ST_READY: | ||
660 | /* | ||
661 | * CHECK: Device should be in standby-mode. No way to check? | ||
662 | * Allowing low power mode for the regulator is potentially | ||
663 | * dangerous if pn544 does not go to suspension. | ||
664 | */ | ||
665 | break; | ||
666 | |||
667 | case PN544_ST_COLD: | ||
668 | break; | ||
669 | }; | ||
670 | |||
671 | mutex_unlock(&info->mutex); | ||
672 | return r; | ||
673 | } | ||
674 | |||
675 | static int pn544_resume(struct device *dev) | ||
676 | { | ||
677 | struct i2c_client *client = to_i2c_client(dev); | ||
678 | struct pn544_info *info = i2c_get_clientdata(client); | ||
679 | int r = 0; | ||
680 | |||
681 | dev_dbg(&client->dev, "%s: info: %p, client %p\n", __func__, | ||
682 | info, client); | ||
683 | |||
684 | mutex_lock(&info->mutex); | ||
685 | |||
686 | switch (info->state) { | ||
687 | case PN544_ST_READY: | ||
688 | /* | ||
689 | * CHECK: If regulator low power mode is allowed in | ||
690 | * pn544_suspend, we should go back to normal mode | ||
691 | * here. | ||
692 | */ | ||
693 | break; | ||
694 | |||
695 | case PN544_ST_COLD: | ||
696 | break; | ||
697 | |||
698 | case PN544_ST_FW_READY: | ||
699 | break; | ||
700 | }; | ||
701 | |||
702 | mutex_unlock(&info->mutex); | ||
703 | |||
704 | return r; | ||
705 | } | ||
706 | |||
707 | static SIMPLE_DEV_PM_OPS(pn544_pm_ops, pn544_suspend, pn544_resume); | ||
708 | #endif | ||
709 | |||
710 | static struct device_attribute pn544_attr = | ||
711 | __ATTR(nfc_test, S_IRUGO, pn544_test, NULL); | ||
712 | |||
713 | static int __devinit pn544_probe(struct i2c_client *client, | ||
714 | const struct i2c_device_id *id) | ||
715 | { | ||
716 | struct pn544_info *info; | ||
717 | struct pn544_nfc_platform_data *pdata; | ||
718 | int r = 0; | ||
719 | |||
720 | dev_dbg(&client->dev, "%s\n", __func__); | ||
721 | dev_dbg(&client->dev, "IRQ: %d\n", client->irq); | ||
722 | |||
723 | /* private data allocation */ | ||
724 | info = kzalloc(sizeof(struct pn544_info), GFP_KERNEL); | ||
725 | if (!info) { | ||
726 | dev_err(&client->dev, | ||
727 | "Cannot allocate memory for pn544_info.\n"); | ||
728 | r = -ENOMEM; | ||
729 | goto err_info_alloc; | ||
730 | } | ||
731 | |||
732 | info->buflen = max(PN544_MSG_MAX_SIZE, PN544_MAX_I2C_TRANSFER); | ||
733 | info->buf = kzalloc(info->buflen, GFP_KERNEL); | ||
734 | if (!info->buf) { | ||
735 | dev_err(&client->dev, | ||
736 | "Cannot allocate memory for pn544_info->buf.\n"); | ||
737 | r = -ENOMEM; | ||
738 | goto err_buf_alloc; | ||
739 | } | ||
740 | |||
741 | info->regs[0].supply = reg_vdd_io; | ||
742 | info->regs[1].supply = reg_vbat; | ||
743 | r = regulator_bulk_get(&client->dev, ARRAY_SIZE(info->regs), | ||
744 | info->regs); | ||
745 | if (r < 0) | ||
746 | goto err_kmalloc; | ||
747 | |||
748 | info->i2c_dev = client; | ||
749 | info->state = PN544_ST_COLD; | ||
750 | info->read_irq = PN544_NONE; | ||
751 | mutex_init(&info->read_mutex); | ||
752 | mutex_init(&info->mutex); | ||
753 | init_waitqueue_head(&info->read_wait); | ||
754 | i2c_set_clientdata(client, info); | ||
755 | pdata = client->dev.platform_data; | ||
756 | if (!pdata) { | ||
757 | dev_err(&client->dev, "No platform data\n"); | ||
758 | r = -EINVAL; | ||
759 | goto err_reg; | ||
760 | } | ||
761 | |||
762 | if (!pdata->request_resources) { | ||
763 | dev_err(&client->dev, "request_resources() missing\n"); | ||
764 | r = -EINVAL; | ||
765 | goto err_reg; | ||
766 | } | ||
767 | |||
768 | r = pdata->request_resources(client); | ||
769 | if (r) { | ||
770 | dev_err(&client->dev, "Cannot get platform resources\n"); | ||
771 | goto err_reg; | ||
772 | } | ||
773 | |||
774 | r = request_threaded_irq(client->irq, NULL, pn544_irq_thread_fn, | ||
775 | IRQF_TRIGGER_RISING, PN544_DRIVER_NAME, | ||
776 | info); | ||
777 | if (r < 0) { | ||
778 | dev_err(&client->dev, "Unable to register IRQ handler\n"); | ||
779 | goto err_res; | ||
780 | } | ||
781 | |||
782 | /* If we don't have the test we don't need the sysfs file */ | ||
783 | if (pdata->test) { | ||
784 | r = device_create_file(&client->dev, &pn544_attr); | ||
785 | if (r) { | ||
786 | dev_err(&client->dev, | ||
787 | "sysfs registration failed, error %d\n", r); | ||
788 | goto err_irq; | ||
789 | } | ||
790 | } | ||
791 | |||
792 | info->miscdev.minor = MISC_DYNAMIC_MINOR; | ||
793 | info->miscdev.name = PN544_DRIVER_NAME; | ||
794 | info->miscdev.fops = &pn544_fops; | ||
795 | info->miscdev.parent = &client->dev; | ||
796 | r = misc_register(&info->miscdev); | ||
797 | if (r < 0) { | ||
798 | dev_err(&client->dev, "Device registration failed\n"); | ||
799 | goto err_sysfs; | ||
800 | } | ||
801 | |||
802 | dev_dbg(&client->dev, "%s: info: %p, pdata %p, client %p\n", | ||
803 | __func__, info, pdata, client); | ||
804 | |||
805 | return 0; | ||
806 | |||
807 | err_sysfs: | ||
808 | if (pdata->test) | ||
809 | device_remove_file(&client->dev, &pn544_attr); | ||
810 | err_irq: | ||
811 | free_irq(client->irq, info); | ||
812 | err_res: | ||
813 | if (pdata->free_resources) | ||
814 | pdata->free_resources(); | ||
815 | err_reg: | ||
816 | regulator_bulk_free(ARRAY_SIZE(info->regs), info->regs); | ||
817 | err_kmalloc: | ||
818 | kfree(info->buf); | ||
819 | err_buf_alloc: | ||
820 | kfree(info); | ||
821 | err_info_alloc: | ||
822 | return r; | ||
823 | } | ||
824 | |||
825 | static __devexit int pn544_remove(struct i2c_client *client) | ||
826 | { | ||
827 | struct pn544_info *info = i2c_get_clientdata(client); | ||
828 | struct pn544_nfc_platform_data *pdata = client->dev.platform_data; | ||
829 | |||
830 | dev_dbg(&client->dev, "%s\n", __func__); | ||
831 | |||
832 | misc_deregister(&info->miscdev); | ||
833 | if (pdata->test) | ||
834 | device_remove_file(&client->dev, &pn544_attr); | ||
835 | |||
836 | if (info->state != PN544_ST_COLD) { | ||
837 | if (pdata->disable) | ||
838 | pdata->disable(); | ||
839 | |||
840 | info->read_irq = PN544_NONE; | ||
841 | } | ||
842 | |||
843 | free_irq(client->irq, info); | ||
844 | if (pdata->free_resources) | ||
845 | pdata->free_resources(); | ||
846 | |||
847 | regulator_bulk_free(ARRAY_SIZE(info->regs), info->regs); | ||
848 | kfree(info->buf); | ||
849 | kfree(info); | ||
850 | |||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static struct i2c_driver pn544_driver = { | ||
855 | .driver = { | ||
856 | .name = PN544_DRIVER_NAME, | ||
857 | #ifdef CONFIG_PM | ||
858 | .pm = &pn544_pm_ops, | ||
859 | #endif | ||
860 | }, | ||
861 | .probe = pn544_probe, | ||
862 | .id_table = pn544_id_table, | ||
863 | .remove = __devexit_p(pn544_remove), | ||
864 | }; | ||
865 | |||
866 | static int __init pn544_init(void) | ||
867 | { | ||
868 | int r; | ||
869 | |||
870 | pr_debug(DRIVER_DESC ": %s\n", __func__); | ||
871 | |||
872 | r = i2c_add_driver(&pn544_driver); | ||
873 | if (r) { | ||
874 | pr_err(PN544_DRIVER_NAME ": driver registration failed\n"); | ||
875 | return r; | ||
876 | } | ||
877 | |||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | static void __exit pn544_exit(void) | ||
882 | { | ||
883 | i2c_del_driver(&pn544_driver); | ||
884 | pr_info(DRIVER_DESC ", Exiting.\n"); | ||
885 | } | ||
886 | |||
887 | module_init(pn544_init); | ||
888 | module_exit(pn544_exit); | ||
889 | |||
890 | MODULE_LICENSE("GPL"); | ||
891 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 5b1630e4e9e..a9523fdc691 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -45,6 +45,7 @@ config XEN_PCIDEV_FRONTEND | |||
45 | depends on PCI && X86 && XEN | 45 | depends on PCI && X86 && XEN |
46 | select HOTPLUG | 46 | select HOTPLUG |
47 | select PCI_XEN | 47 | select PCI_XEN |
48 | select XEN_XENBUS_FRONTEND | ||
48 | default y | 49 | default y |
49 | help | 50 | help |
50 | The PCI device frontend driver allows the kernel to import arbitrary | 51 | The PCI device frontend driver allows the kernel to import arbitrary |
diff --git a/drivers/pcmcia/m32r_cfc.h b/drivers/pcmcia/m32r_cfc.h index 8146e3bee2e..f558e1adf95 100644 --- a/drivers/pcmcia/m32r_cfc.h +++ b/drivers/pcmcia/m32r_cfc.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #endif | 9 | #endif |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * M32R PC Card Controler | 12 | * M32R PC Card Controller |
13 | */ | 13 | */ |
14 | #define M32R_PCC0_BASE 0x00ef7000 | 14 | #define M32R_PCC0_BASE 0x00ef7000 |
15 | #define M32R_PCC1_BASE 0x00ef7020 | 15 | #define M32R_PCC1_BASE 0x00ef7020 |
diff --git a/drivers/pcmcia/m32r_pcc.h b/drivers/pcmcia/m32r_pcc.h index e4fffe417ba..f95c58563bc 100644 --- a/drivers/pcmcia/m32r_pcc.h +++ b/drivers/pcmcia/m32r_pcc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | #define M32R_MAX_PCC 2 | 5 | #define M32R_MAX_PCC 2 |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * M32R PC Card Controler | 8 | * M32R PC Card Controller |
9 | */ | 9 | */ |
10 | #define M32R_PCC0_BASE 0x00ef7000 | 10 | #define M32R_PCC0_BASE 0x00ef7000 |
11 | #define M32R_PCC1_BASE 0x00ef7020 | 11 | #define M32R_PCC1_BASE 0x00ef7020 |
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 99d4f23cb43..0db482771fb 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -1198,7 +1198,7 @@ static int __init m8xx_probe(struct platform_device *ofdev, | |||
1198 | out_be32(M8XX_PGCRX(1), | 1198 | out_be32(M8XX_PGCRX(1), |
1199 | M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16)); | 1199 | M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16)); |
1200 | 1200 | ||
1201 | /* intialize the fixed memory windows */ | 1201 | /* initialize the fixed memory windows */ |
1202 | 1202 | ||
1203 | for (i = 0; i < PCMCIA_SOCKETS_NO; i++) { | 1203 | for (i = 0; i < PCMCIA_SOCKETS_NO; i++) { |
1204 | for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) { | 1204 | for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) { |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index ee40d681edd..c5c4b8c32eb 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -1021,7 +1021,7 @@ static int update_bl_status(struct backlight_device *bd) | |||
1021 | return 0; | 1021 | return 0; |
1022 | } | 1022 | } |
1023 | 1023 | ||
1024 | static struct backlight_ops acer_bl_ops = { | 1024 | static const struct backlight_ops acer_bl_ops = { |
1025 | .get_brightness = read_brightness, | 1025 | .get_brightness = read_brightness, |
1026 | .update_status = update_bl_status, | 1026 | .update_status = update_bl_status, |
1027 | }; | 1027 | }; |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index d235f44fd7a..f3aa6a7fdab 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -640,7 +640,7 @@ static int update_bl_status(struct backlight_device *bd) | |||
640 | return asus_lcd_set(asus, value); | 640 | return asus_lcd_set(asus, value); |
641 | } | 641 | } |
642 | 642 | ||
643 | static struct backlight_ops asusbl_ops = { | 643 | static const struct backlight_ops asusbl_ops = { |
644 | .get_brightness = asus_read_brightness, | 644 | .get_brightness = asus_read_brightness, |
645 | .update_status = update_bl_status, | 645 | .update_status = update_bl_status, |
646 | }; | 646 | }; |
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index ca05aefd03b..4633fd8532c 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c | |||
@@ -1467,7 +1467,7 @@ static int asus_hotk_remove(struct acpi_device *device, int type) | |||
1467 | return 0; | 1467 | return 0; |
1468 | } | 1468 | } |
1469 | 1469 | ||
1470 | static struct backlight_ops asus_backlight_data = { | 1470 | static const struct backlight_ops asus_backlight_data = { |
1471 | .get_brightness = read_brightness, | 1471 | .get_brightness = read_brightness, |
1472 | .update_status = set_brightness_status, | 1472 | .update_status = set_brightness_status, |
1473 | }; | 1473 | }; |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index cf8a89a0d8f..34657f96b5a 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -546,7 +546,7 @@ out: | |||
546 | return buffer->output[1]; | 546 | return buffer->output[1]; |
547 | } | 547 | } |
548 | 548 | ||
549 | static struct backlight_ops dell_ops = { | 549 | static const struct backlight_ops dell_ops = { |
550 | .get_brightness = dell_get_intensity, | 550 | .get_brightness = dell_get_intensity, |
551 | .update_status = dell_send_intensity, | 551 | .update_status = dell_send_intensity, |
552 | }; | 552 | }; |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index e9fc530e7dc..49d9ad708f8 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -1126,7 +1126,7 @@ static int update_bl_status(struct backlight_device *bd) | |||
1126 | return set_brightness(bd, bd->props.brightness); | 1126 | return set_brightness(bd, bd->props.brightness); |
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | static struct backlight_ops eeepcbl_ops = { | 1129 | static const struct backlight_ops eeepcbl_ops = { |
1130 | .get_brightness = read_brightness, | 1130 | .get_brightness = read_brightness, |
1131 | .update_status = update_bl_status, | 1131 | .update_status = update_bl_status, |
1132 | }; | 1132 | }; |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index ad88b2ec34a..19e92b2a7f7 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -437,7 +437,7 @@ static int bl_update_status(struct backlight_device *b) | |||
437 | return ret; | 437 | return ret; |
438 | } | 438 | } |
439 | 439 | ||
440 | static struct backlight_ops fujitsubl_ops = { | 440 | static const struct backlight_ops fujitsubl_ops = { |
441 | .get_brightness = bl_get_brightness, | 441 | .get_brightness = bl_get_brightness, |
442 | .update_status = bl_update_status, | 442 | .update_status = bl_update_status, |
443 | }; | 443 | }; |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index b4a95bb2f23..5e83370b081 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -858,7 +858,7 @@ static int sony_backlight_get_brightness(struct backlight_device *bd) | |||
858 | } | 858 | } |
859 | 859 | ||
860 | static struct backlight_device *sony_backlight_device; | 860 | static struct backlight_device *sony_backlight_device; |
861 | static struct backlight_ops sony_backlight_ops = { | 861 | static const struct backlight_ops sony_backlight_ops = { |
862 | .update_status = sony_backlight_update_status, | 862 | .update_status = sony_backlight_update_status, |
863 | .get_brightness = sony_backlight_get_brightness, | 863 | .get_brightness = sony_backlight_get_brightness, |
864 | }; | 864 | }; |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a974ca383cb..dd599585c6a 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -6110,7 +6110,7 @@ static void tpacpi_brightness_notify_change(void) | |||
6110 | BACKLIGHT_UPDATE_HOTKEY); | 6110 | BACKLIGHT_UPDATE_HOTKEY); |
6111 | } | 6111 | } |
6112 | 6112 | ||
6113 | static struct backlight_ops ibm_backlight_data = { | 6113 | static const struct backlight_ops ibm_backlight_data = { |
6114 | .get_brightness = brightness_get, | 6114 | .get_brightness = brightness_get, |
6115 | .update_status = brightness_update_status, | 6115 | .update_status = brightness_update_status, |
6116 | }; | 6116 | }; |
@@ -7194,7 +7194,7 @@ static struct ibm_struct volume_driver_data = { | |||
7194 | * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41) | 7194 | * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41) |
7195 | * | 7195 | * |
7196 | * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at | 7196 | * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at |
7197 | * boot. Apparently the EC does not intialize it, so unless ACPI DSDT | 7197 | * boot. Apparently the EC does not initialize it, so unless ACPI DSDT |
7198 | * does so, its initial value is meaningless (0x07). | 7198 | * does so, its initial value is meaningless (0x07). |
7199 | * | 7199 | * |
7200 | * For firmware bugs, refer to: | 7200 | * For firmware bugs, refer to: |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 4276da7291b..209cced786c 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -841,7 +841,7 @@ static void remove_toshiba_proc_entries(void) | |||
841 | remove_proc_entry("version", toshiba_proc_dir); | 841 | remove_proc_entry("version", toshiba_proc_dir); |
842 | } | 842 | } |
843 | 843 | ||
844 | static struct backlight_ops toshiba_backlight_data = { | 844 | static const struct backlight_ops toshiba_backlight_data = { |
845 | .get_brightness = get_lcd, | 845 | .get_brightness = get_lcd, |
846 | .update_status = set_lcd_status, | 846 | .update_status = set_lcd_status, |
847 | }; | 847 | }; |
diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c index fe16b482e91..4a8ae3935b3 100644 --- a/drivers/power/s3c_adc_battery.c +++ b/drivers/power/s3c_adc_battery.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * iPAQ h1930/h1940/rx1950 battery controler driver | 2 | * iPAQ h1930/h1940/rx1950 battery controller driver |
3 | * Copyright (c) Vasily Khoruzhick | 3 | * Copyright (c) Vasily Khoruzhick |
4 | * Based on h1940_battery.c by Arnaud Patard | 4 | * Based on h1940_battery.c by Arnaud Patard |
5 | * | 5 | * |
@@ -427,5 +427,5 @@ static void __exit s3c_adc_bat_exit(void) | |||
427 | module_exit(s3c_adc_bat_exit); | 427 | module_exit(s3c_adc_bat_exit); |
428 | 428 | ||
429 | MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>"); | 429 | MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>"); |
430 | MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controler driver"); | 430 | MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controller driver"); |
431 | MODULE_LICENSE("GPL"); | 431 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig index 1afe4e03440..f0d3376b58b 100644 --- a/drivers/pps/Kconfig +++ b/drivers/pps/Kconfig | |||
@@ -30,6 +30,17 @@ config PPS_DEBUG | |||
30 | messages to the system log. Select this if you are having a | 30 | messages to the system log. Select this if you are having a |
31 | problem with PPS support and want to see more of what is going on. | 31 | problem with PPS support and want to see more of what is going on. |
32 | 32 | ||
33 | config NTP_PPS | ||
34 | bool "PPS kernel consumer support" | ||
35 | depends on PPS && !NO_HZ | ||
36 | help | ||
37 | This option adds support for direct in-kernel time | ||
38 | syncronization using an external PPS signal. | ||
39 | |||
40 | It doesn't work on tickless systems at the moment. | ||
41 | |||
33 | source drivers/pps/clients/Kconfig | 42 | source drivers/pps/clients/Kconfig |
34 | 43 | ||
44 | source drivers/pps/generators/Kconfig | ||
45 | |||
35 | endmenu | 46 | endmenu |
diff --git a/drivers/pps/Makefile b/drivers/pps/Makefile index 98960ddd318..4483eaadadd 100644 --- a/drivers/pps/Makefile +++ b/drivers/pps/Makefile | |||
@@ -3,7 +3,8 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | pps_core-y := pps.o kapi.o sysfs.o | 5 | pps_core-y := pps.o kapi.o sysfs.o |
6 | pps_core-$(CONFIG_NTP_PPS) += kc.o | ||
6 | obj-$(CONFIG_PPS) := pps_core.o | 7 | obj-$(CONFIG_PPS) := pps_core.o |
7 | obj-y += clients/ | 8 | obj-y += clients/ generators/ |
8 | 9 | ||
9 | ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG | 10 | ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG |
diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig index 4e801bd7254..8520a7f4dd6 100644 --- a/drivers/pps/clients/Kconfig +++ b/drivers/pps/clients/Kconfig | |||
@@ -22,4 +22,11 @@ config PPS_CLIENT_LDISC | |||
22 | If you say yes here you get support for a PPS source connected | 22 | If you say yes here you get support for a PPS source connected |
23 | with the CD (Carrier Detect) pin of your serial port. | 23 | with the CD (Carrier Detect) pin of your serial port. |
24 | 24 | ||
25 | config PPS_CLIENT_PARPORT | ||
26 | tristate "Parallel port PPS client" | ||
27 | depends on PPS && PARPORT | ||
28 | help | ||
29 | If you say yes here you get support for a PPS source connected | ||
30 | with the interrupt pin of your parallel port. | ||
31 | |||
25 | endif | 32 | endif |
diff --git a/drivers/pps/clients/Makefile b/drivers/pps/clients/Makefile index 812c9b19b43..42517da0704 100644 --- a/drivers/pps/clients/Makefile +++ b/drivers/pps/clients/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_PPS_CLIENT_KTIMER) += pps-ktimer.o | 5 | obj-$(CONFIG_PPS_CLIENT_KTIMER) += pps-ktimer.o |
6 | obj-$(CONFIG_PPS_CLIENT_LDISC) += pps-ldisc.o | 6 | obj-$(CONFIG_PPS_CLIENT_LDISC) += pps-ldisc.o |
7 | obj-$(CONFIG_PPS_CLIENT_PARPORT) += pps_parport.o | ||
7 | 8 | ||
8 | ifeq ($(CONFIG_PPS_DEBUG),y) | 9 | ifeq ($(CONFIG_PPS_DEBUG),y) |
9 | EXTRA_CFLAGS += -DDEBUG | 10 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/pps/clients/pps-ktimer.c b/drivers/pps/clients/pps-ktimer.c index e7ef5b8186d..2728469d388 100644 --- a/drivers/pps/clients/pps-ktimer.c +++ b/drivers/pps/clients/pps-ktimer.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | 23 | ||
23 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
@@ -31,7 +32,7 @@ | |||
31 | * Global variables | 32 | * Global variables |
32 | */ | 33 | */ |
33 | 34 | ||
34 | static int source; | 35 | static struct pps_device *pps; |
35 | static struct timer_list ktimer; | 36 | static struct timer_list ktimer; |
36 | 37 | ||
37 | /* | 38 | /* |
@@ -40,19 +41,14 @@ static struct timer_list ktimer; | |||
40 | 41 | ||
41 | static void pps_ktimer_event(unsigned long ptr) | 42 | static void pps_ktimer_event(unsigned long ptr) |
42 | { | 43 | { |
43 | struct timespec __ts; | 44 | struct pps_event_time ts; |
44 | struct pps_ktime ts; | ||
45 | 45 | ||
46 | /* First of all we get the time stamp... */ | 46 | /* First of all we get the time stamp... */ |
47 | getnstimeofday(&__ts); | 47 | pps_get_ts(&ts); |
48 | 48 | ||
49 | pr_info("PPS event at %lu\n", jiffies); | 49 | dev_info(pps->dev, "PPS event at %lu\n", jiffies); |
50 | 50 | ||
51 | /* ... and translate it to PPS time data struct */ | 51 | pps_event(pps, &ts, PPS_CAPTUREASSERT, NULL); |
52 | ts.sec = __ts.tv_sec; | ||
53 | ts.nsec = __ts.tv_nsec; | ||
54 | |||
55 | pps_event(source, &ts, PPS_CAPTUREASSERT, NULL); | ||
56 | 52 | ||
57 | mod_timer(&ktimer, jiffies + HZ); | 53 | mod_timer(&ktimer, jiffies + HZ); |
58 | } | 54 | } |
@@ -61,12 +57,11 @@ static void pps_ktimer_event(unsigned long ptr) | |||
61 | * The echo function | 57 | * The echo function |
62 | */ | 58 | */ |
63 | 59 | ||
64 | static void pps_ktimer_echo(int source, int event, void *data) | 60 | static void pps_ktimer_echo(struct pps_device *pps, int event, void *data) |
65 | { | 61 | { |
66 | pr_info("echo %s %s for source %d\n", | 62 | dev_info(pps->dev, "echo %s %s\n", |
67 | event & PPS_CAPTUREASSERT ? "assert" : "", | 63 | event & PPS_CAPTUREASSERT ? "assert" : "", |
68 | event & PPS_CAPTURECLEAR ? "clear" : "", | 64 | event & PPS_CAPTURECLEAR ? "clear" : ""); |
69 | source); | ||
70 | } | 65 | } |
71 | 66 | ||
72 | /* | 67 | /* |
@@ -89,30 +84,27 @@ static struct pps_source_info pps_ktimer_info = { | |||
89 | 84 | ||
90 | static void __exit pps_ktimer_exit(void) | 85 | static void __exit pps_ktimer_exit(void) |
91 | { | 86 | { |
92 | del_timer_sync(&ktimer); | 87 | dev_info(pps->dev, "ktimer PPS source unregistered\n"); |
93 | pps_unregister_source(source); | ||
94 | 88 | ||
95 | pr_info("ktimer PPS source unregistered\n"); | 89 | del_timer_sync(&ktimer); |
90 | pps_unregister_source(pps); | ||
96 | } | 91 | } |
97 | 92 | ||
98 | static int __init pps_ktimer_init(void) | 93 | static int __init pps_ktimer_init(void) |
99 | { | 94 | { |
100 | int ret; | 95 | pps = pps_register_source(&pps_ktimer_info, |
101 | |||
102 | ret = pps_register_source(&pps_ktimer_info, | ||
103 | PPS_CAPTUREASSERT | PPS_OFFSETASSERT); | 96 | PPS_CAPTUREASSERT | PPS_OFFSETASSERT); |
104 | if (ret < 0) { | 97 | if (pps == NULL) { |
105 | printk(KERN_ERR "cannot register ktimer source\n"); | 98 | pr_err("cannot register PPS source\n"); |
106 | return ret; | 99 | return -ENOMEM; |
107 | } | 100 | } |
108 | source = ret; | ||
109 | 101 | ||
110 | setup_timer(&ktimer, pps_ktimer_event, 0); | 102 | setup_timer(&ktimer, pps_ktimer_event, 0); |
111 | mod_timer(&ktimer, jiffies + HZ); | 103 | mod_timer(&ktimer, jiffies + HZ); |
112 | 104 | ||
113 | pr_info("ktimer PPS source registered at %d\n", source); | 105 | dev_info(pps->dev, "ktimer PPS source registered\n"); |
114 | 106 | ||
115 | return 0; | 107 | return 0; |
116 | } | 108 | } |
117 | 109 | ||
118 | module_init(pps_ktimer_init); | 110 | module_init(pps_ktimer_init); |
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c index 8e1932d29fd..79451f2dea6 100644 --- a/drivers/pps/clients/pps-ldisc.c +++ b/drivers/pps/clients/pps-ldisc.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/serial_core.h> | 25 | #include <linux/serial_core.h> |
24 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
@@ -27,30 +29,18 @@ | |||
27 | #define PPS_TTY_MAGIC 0x0001 | 29 | #define PPS_TTY_MAGIC 0x0001 |
28 | 30 | ||
29 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, | 31 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, |
30 | struct timespec *ts) | 32 | struct pps_event_time *ts) |
31 | { | 33 | { |
32 | int id = (long)tty->disc_data; | 34 | struct pps_device *pps = (struct pps_device *)tty->disc_data; |
33 | struct timespec __ts; | 35 | |
34 | struct pps_ktime pps_ts; | 36 | BUG_ON(pps == NULL); |
35 | |||
36 | /* First of all we get the time stamp... */ | ||
37 | getnstimeofday(&__ts); | ||
38 | |||
39 | /* Does caller give us a timestamp? */ | ||
40 | if (ts) { /* Yes. Let's use it! */ | ||
41 | pps_ts.sec = ts->tv_sec; | ||
42 | pps_ts.nsec = ts->tv_nsec; | ||
43 | } else { /* No. Do it ourself! */ | ||
44 | pps_ts.sec = __ts.tv_sec; | ||
45 | pps_ts.nsec = __ts.tv_nsec; | ||
46 | } | ||
47 | 37 | ||
48 | /* Now do the PPS event report */ | 38 | /* Now do the PPS event report */ |
49 | pps_event(id, &pps_ts, status ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR, | 39 | pps_event(pps, ts, status ? PPS_CAPTUREASSERT : |
50 | NULL); | 40 | PPS_CAPTURECLEAR, NULL); |
51 | 41 | ||
52 | pr_debug("PPS %s at %lu on source #%d\n", | 42 | dev_dbg(pps->dev, "PPS %s at %lu\n", |
53 | status ? "assert" : "clear", jiffies, id); | 43 | status ? "assert" : "clear", jiffies); |
54 | } | 44 | } |
55 | 45 | ||
56 | static int (*alias_n_tty_open)(struct tty_struct *tty); | 46 | static int (*alias_n_tty_open)(struct tty_struct *tty); |
@@ -60,6 +50,7 @@ static int pps_tty_open(struct tty_struct *tty) | |||
60 | struct pps_source_info info; | 50 | struct pps_source_info info; |
61 | struct tty_driver *drv = tty->driver; | 51 | struct tty_driver *drv = tty->driver; |
62 | int index = tty->index + drv->name_base; | 52 | int index = tty->index + drv->name_base; |
53 | struct pps_device *pps; | ||
63 | int ret; | 54 | int ret; |
64 | 55 | ||
65 | info.owner = THIS_MODULE; | 56 | info.owner = THIS_MODULE; |
@@ -70,34 +61,42 @@ static int pps_tty_open(struct tty_struct *tty) | |||
70 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ | 61 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ |
71 | PPS_CANWAIT | PPS_TSFMT_TSPEC; | 62 | PPS_CANWAIT | PPS_TSFMT_TSPEC; |
72 | 63 | ||
73 | ret = pps_register_source(&info, PPS_CAPTUREBOTH | \ | 64 | pps = pps_register_source(&info, PPS_CAPTUREBOTH | \ |
74 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR); | 65 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR); |
75 | if (ret < 0) { | 66 | if (pps == NULL) { |
76 | pr_err("cannot register PPS source \"%s\"\n", info.path); | 67 | pr_err("cannot register PPS source \"%s\"\n", info.path); |
77 | return ret; | 68 | return -ENOMEM; |
78 | } | 69 | } |
79 | tty->disc_data = (void *)(long)ret; | 70 | tty->disc_data = pps; |
80 | 71 | ||
81 | /* Should open N_TTY ldisc too */ | 72 | /* Should open N_TTY ldisc too */ |
82 | ret = alias_n_tty_open(tty); | 73 | ret = alias_n_tty_open(tty); |
83 | if (ret < 0) | 74 | if (ret < 0) { |
84 | pps_unregister_source((long)tty->disc_data); | 75 | pr_err("cannot open tty ldisc \"%s\"\n", info.path); |
76 | goto err_unregister; | ||
77 | } | ||
85 | 78 | ||
86 | pr_info("PPS source #%d \"%s\" added\n", ret, info.path); | 79 | dev_info(pps->dev, "source \"%s\" added\n", info.path); |
87 | 80 | ||
88 | return 0; | 81 | return 0; |
82 | |||
83 | err_unregister: | ||
84 | tty->disc_data = NULL; | ||
85 | pps_unregister_source(pps); | ||
86 | return ret; | ||
89 | } | 87 | } |
90 | 88 | ||
91 | static void (*alias_n_tty_close)(struct tty_struct *tty); | 89 | static void (*alias_n_tty_close)(struct tty_struct *tty); |
92 | 90 | ||
93 | static void pps_tty_close(struct tty_struct *tty) | 91 | static void pps_tty_close(struct tty_struct *tty) |
94 | { | 92 | { |
95 | int id = (long)tty->disc_data; | 93 | struct pps_device *pps = (struct pps_device *)tty->disc_data; |
96 | 94 | ||
97 | pps_unregister_source(id); | ||
98 | alias_n_tty_close(tty); | 95 | alias_n_tty_close(tty); |
99 | 96 | ||
100 | pr_info("PPS source #%d removed\n", id); | 97 | tty->disc_data = NULL; |
98 | dev_info(pps->dev, "removed\n"); | ||
99 | pps_unregister_source(pps); | ||
101 | } | 100 | } |
102 | 101 | ||
103 | static struct tty_ldisc_ops pps_ldisc_ops; | 102 | static struct tty_ldisc_ops pps_ldisc_ops; |
diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c new file mode 100644 index 00000000000..32221efd9ca --- /dev/null +++ b/drivers/pps/clients/pps_parport.c | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | * pps_parport.c -- kernel parallel port PPS client | ||
3 | * | ||
4 | * | ||
5 | * Copyright (C) 2009 Alexander Gordeev <lasaine@lvk.cs.msu.su> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | |||
23 | /* | ||
24 | * TODO: | ||
25 | * implement echo over SEL pin | ||
26 | */ | ||
27 | |||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
29 | |||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/irqnr.h> | ||
34 | #include <linux/time.h> | ||
35 | #include <linux/parport.h> | ||
36 | #include <linux/pps_kernel.h> | ||
37 | |||
38 | #define DRVDESC "parallel port PPS client" | ||
39 | |||
40 | /* module parameters */ | ||
41 | |||
42 | #define CLEAR_WAIT_MAX 100 | ||
43 | #define CLEAR_WAIT_MAX_ERRORS 5 | ||
44 | |||
45 | static unsigned int clear_wait = 100; | ||
46 | MODULE_PARM_DESC(clear_wait, | ||
47 | "Maximum number of port reads when polling for signal clear," | ||
48 | " zero turns clear edge capture off entirely"); | ||
49 | module_param(clear_wait, uint, 0); | ||
50 | |||
51 | |||
52 | /* internal per port structure */ | ||
53 | struct pps_client_pp { | ||
54 | struct pardevice *pardev; /* parport device */ | ||
55 | struct pps_device *pps; /* PPS device */ | ||
56 | unsigned int cw; /* port clear timeout */ | ||
57 | unsigned int cw_err; /* number of timeouts */ | ||
58 | }; | ||
59 | |||
60 | static inline int signal_is_set(struct parport *port) | ||
61 | { | ||
62 | return (port->ops->read_status(port) & PARPORT_STATUS_ACK) != 0; | ||
63 | } | ||
64 | |||
65 | /* parport interrupt handler */ | ||
66 | static void parport_irq(void *handle) | ||
67 | { | ||
68 | struct pps_event_time ts_assert, ts_clear; | ||
69 | struct pps_client_pp *dev = handle; | ||
70 | struct parport *port = dev->pardev->port; | ||
71 | unsigned int i; | ||
72 | unsigned long flags; | ||
73 | |||
74 | /* first of all we get the time stamp... */ | ||
75 | pps_get_ts(&ts_assert); | ||
76 | |||
77 | if (dev->cw == 0) | ||
78 | /* clear edge capture disabled */ | ||
79 | goto out_assert; | ||
80 | |||
81 | /* try capture the clear edge */ | ||
82 | |||
83 | /* We have to disable interrupts here. The idea is to prevent | ||
84 | * other interrupts on the same processor to introduce random | ||
85 | * lags while polling the port. Reading from IO port is known | ||
86 | * to take approximately 1us while other interrupt handlers can | ||
87 | * take much more potentially. | ||
88 | * | ||
89 | * Interrupts won't be disabled for a long time because the | ||
90 | * number of polls is limited by clear_wait parameter which is | ||
91 | * kept rather low. So it should never be an issue. | ||
92 | */ | ||
93 | local_irq_save(flags); | ||
94 | /* check the signal (no signal means the pulse is lost this time) */ | ||
95 | if (!signal_is_set(port)) { | ||
96 | local_irq_restore(flags); | ||
97 | dev_err(dev->pps->dev, "lost the signal\n"); | ||
98 | goto out_assert; | ||
99 | } | ||
100 | |||
101 | /* poll the port until the signal is unset */ | ||
102 | for (i = dev->cw; i; i--) | ||
103 | if (!signal_is_set(port)) { | ||
104 | pps_get_ts(&ts_clear); | ||
105 | local_irq_restore(flags); | ||
106 | dev->cw_err = 0; | ||
107 | goto out_both; | ||
108 | } | ||
109 | local_irq_restore(flags); | ||
110 | |||
111 | /* timeout */ | ||
112 | dev->cw_err++; | ||
113 | if (dev->cw_err >= CLEAR_WAIT_MAX_ERRORS) { | ||
114 | dev_err(dev->pps->dev, "disabled clear edge capture after %d" | ||
115 | " timeouts\n", dev->cw_err); | ||
116 | dev->cw = 0; | ||
117 | dev->cw_err = 0; | ||
118 | } | ||
119 | |||
120 | out_assert: | ||
121 | /* fire assert event */ | ||
122 | pps_event(dev->pps, &ts_assert, | ||
123 | PPS_CAPTUREASSERT, NULL); | ||
124 | return; | ||
125 | |||
126 | out_both: | ||
127 | /* fire assert event */ | ||
128 | pps_event(dev->pps, &ts_assert, | ||
129 | PPS_CAPTUREASSERT, NULL); | ||
130 | /* fire clear event */ | ||
131 | pps_event(dev->pps, &ts_clear, | ||
132 | PPS_CAPTURECLEAR, NULL); | ||
133 | return; | ||
134 | } | ||
135 | |||
136 | /* the PPS echo function */ | ||
137 | static void pps_echo(struct pps_device *pps, int event, void *data) | ||
138 | { | ||
139 | dev_info(pps->dev, "echo %s %s\n", | ||
140 | event & PPS_CAPTUREASSERT ? "assert" : "", | ||
141 | event & PPS_CAPTURECLEAR ? "clear" : ""); | ||
142 | } | ||
143 | |||
144 | static void parport_attach(struct parport *port) | ||
145 | { | ||
146 | struct pps_client_pp *device; | ||
147 | struct pps_source_info info = { | ||
148 | .name = KBUILD_MODNAME, | ||
149 | .path = "", | ||
150 | .mode = PPS_CAPTUREBOTH | \ | ||
151 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ | ||
152 | PPS_ECHOASSERT | PPS_ECHOCLEAR | \ | ||
153 | PPS_CANWAIT | PPS_TSFMT_TSPEC, | ||
154 | .echo = pps_echo, | ||
155 | .owner = THIS_MODULE, | ||
156 | .dev = NULL | ||
157 | }; | ||
158 | |||
159 | device = kzalloc(sizeof(struct pps_client_pp), GFP_KERNEL); | ||
160 | if (!device) { | ||
161 | pr_err("memory allocation failed, not attaching\n"); | ||
162 | return; | ||
163 | } | ||
164 | |||
165 | device->pardev = parport_register_device(port, KBUILD_MODNAME, | ||
166 | NULL, NULL, parport_irq, 0, device); | ||
167 | if (!device->pardev) { | ||
168 | pr_err("couldn't register with %s\n", port->name); | ||
169 | goto err_free; | ||
170 | } | ||
171 | |||
172 | if (parport_claim_or_block(device->pardev) < 0) { | ||
173 | pr_err("couldn't claim %s\n", port->name); | ||
174 | goto err_unregister_dev; | ||
175 | } | ||
176 | |||
177 | device->pps = pps_register_source(&info, | ||
178 | PPS_CAPTUREBOTH | PPS_OFFSETASSERT | PPS_OFFSETCLEAR); | ||
179 | if (device->pps == NULL) { | ||
180 | pr_err("couldn't register PPS source\n"); | ||
181 | goto err_release_dev; | ||
182 | } | ||
183 | |||
184 | device->cw = clear_wait; | ||
185 | |||
186 | port->ops->enable_irq(port); | ||
187 | |||
188 | pr_info("attached to %s\n", port->name); | ||
189 | |||
190 | return; | ||
191 | |||
192 | err_release_dev: | ||
193 | parport_release(device->pardev); | ||
194 | err_unregister_dev: | ||
195 | parport_unregister_device(device->pardev); | ||
196 | err_free: | ||
197 | kfree(device); | ||
198 | } | ||
199 | |||
200 | static void parport_detach(struct parport *port) | ||
201 | { | ||
202 | struct pardevice *pardev = port->cad; | ||
203 | struct pps_client_pp *device; | ||
204 | |||
205 | /* FIXME: oooh, this is ugly! */ | ||
206 | if (strcmp(pardev->name, KBUILD_MODNAME)) | ||
207 | /* not our port */ | ||
208 | return; | ||
209 | |||
210 | device = pardev->private; | ||
211 | |||
212 | port->ops->disable_irq(port); | ||
213 | pps_unregister_source(device->pps); | ||
214 | parport_release(pardev); | ||
215 | parport_unregister_device(pardev); | ||
216 | kfree(device); | ||
217 | } | ||
218 | |||
219 | static struct parport_driver pps_parport_driver = { | ||
220 | .name = KBUILD_MODNAME, | ||
221 | .attach = parport_attach, | ||
222 | .detach = parport_detach, | ||
223 | }; | ||
224 | |||
225 | /* module staff */ | ||
226 | |||
227 | static int __init pps_parport_init(void) | ||
228 | { | ||
229 | int ret; | ||
230 | |||
231 | pr_info(DRVDESC "\n"); | ||
232 | |||
233 | if (clear_wait > CLEAR_WAIT_MAX) { | ||
234 | pr_err("clear_wait value should be not greater" | ||
235 | " then %d\n", CLEAR_WAIT_MAX); | ||
236 | return -EINVAL; | ||
237 | } | ||
238 | |||
239 | ret = parport_register_driver(&pps_parport_driver); | ||
240 | if (ret) { | ||
241 | pr_err("unable to register with parport\n"); | ||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static void __exit pps_parport_exit(void) | ||
249 | { | ||
250 | parport_unregister_driver(&pps_parport_driver); | ||
251 | } | ||
252 | |||
253 | module_init(pps_parport_init); | ||
254 | module_exit(pps_parport_exit); | ||
255 | |||
256 | MODULE_AUTHOR("Alexander Gordeev <lasaine@lvk.cs.msu.su>"); | ||
257 | MODULE_DESCRIPTION(DRVDESC); | ||
258 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig new file mode 100644 index 00000000000..f3a73dd7766 --- /dev/null +++ b/drivers/pps/generators/Kconfig | |||
@@ -0,0 +1,13 @@ | |||
1 | # | ||
2 | # PPS generators configuration | ||
3 | # | ||
4 | |||
5 | comment "PPS generators support" | ||
6 | |||
7 | config PPS_GENERATOR_PARPORT | ||
8 | tristate "Parallel port PPS signal generator" | ||
9 | depends on PARPORT | ||
10 | help | ||
11 | If you say yes here you get support for a PPS signal generator which | ||
12 | utilizes STROBE pin of a parallel port to send PPS signals. It uses | ||
13 | parport abstraction layer and hrtimers to precisely control the signal. | ||
diff --git a/drivers/pps/generators/Makefile b/drivers/pps/generators/Makefile new file mode 100644 index 00000000000..303304a6b8e --- /dev/null +++ b/drivers/pps/generators/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # | ||
2 | # Makefile for PPS generators. | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_PPS_GENERATOR_PARPORT) += pps_gen_parport.o | ||
6 | |||
7 | ifeq ($(CONFIG_PPS_DEBUG),y) | ||
8 | EXTRA_CFLAGS += -DDEBUG | ||
9 | endif | ||
diff --git a/drivers/pps/generators/pps_gen_parport.c b/drivers/pps/generators/pps_gen_parport.c new file mode 100644 index 00000000000..5c32f8dacf5 --- /dev/null +++ b/drivers/pps/generators/pps_gen_parport.c | |||
@@ -0,0 +1,282 @@ | |||
1 | /* | ||
2 | * pps_gen_parport.c -- kernel parallel port PPS signal generator | ||
3 | * | ||
4 | * | ||
5 | * Copyright (C) 2009 Alexander Gordeev <lasaine@lvk.cs.msu.su> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | |||
23 | /* | ||
24 | * TODO: | ||
25 | * fix issues when realtime clock is adjusted in a leap | ||
26 | */ | ||
27 | |||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
29 | |||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/time.h> | ||
34 | #include <linux/hrtimer.h> | ||
35 | #include <linux/parport.h> | ||
36 | |||
37 | #define DRVDESC "parallel port PPS signal generator" | ||
38 | |||
39 | #define SIGNAL 0 | ||
40 | #define NO_SIGNAL PARPORT_CONTROL_STROBE | ||
41 | |||
42 | /* module parameters */ | ||
43 | |||
44 | #define SEND_DELAY_MAX 100000 | ||
45 | |||
46 | static unsigned int send_delay = 30000; | ||
47 | MODULE_PARM_DESC(delay, | ||
48 | "Delay between setting and dropping the signal (ns)"); | ||
49 | module_param_named(delay, send_delay, uint, 0); | ||
50 | |||
51 | |||
52 | #define SAFETY_INTERVAL 3000 /* set the hrtimer earlier for safety (ns) */ | ||
53 | |||
54 | /* internal per port structure */ | ||
55 | struct pps_generator_pp { | ||
56 | struct pardevice *pardev; /* parport device */ | ||
57 | struct hrtimer timer; | ||
58 | long port_write_time; /* calibrated port write time (ns) */ | ||
59 | }; | ||
60 | |||
61 | static struct pps_generator_pp device = { | ||
62 | .pardev = NULL, | ||
63 | }; | ||
64 | |||
65 | static int attached; | ||
66 | |||
67 | /* calibrated time between a hrtimer event and the reaction */ | ||
68 | static long hrtimer_error = SAFETY_INTERVAL; | ||
69 | |||
70 | /* the kernel hrtimer event */ | ||
71 | static enum hrtimer_restart hrtimer_event(struct hrtimer *timer) | ||
72 | { | ||
73 | struct timespec expire_time, ts1, ts2, ts3, dts; | ||
74 | struct pps_generator_pp *dev; | ||
75 | struct parport *port; | ||
76 | long lim, delta; | ||
77 | unsigned long flags; | ||
78 | |||
79 | /* We have to disable interrupts here. The idea is to prevent | ||
80 | * other interrupts on the same processor to introduce random | ||
81 | * lags while polling the clock. getnstimeofday() takes <1us on | ||
82 | * most machines while other interrupt handlers can take much | ||
83 | * more potentially. | ||
84 | * | ||
85 | * NB: approx time with blocked interrupts = | ||
86 | * send_delay + 3 * SAFETY_INTERVAL | ||
87 | */ | ||
88 | local_irq_save(flags); | ||
89 | |||
90 | /* first of all we get the time stamp... */ | ||
91 | getnstimeofday(&ts1); | ||
92 | expire_time = ktime_to_timespec(hrtimer_get_softexpires(timer)); | ||
93 | dev = container_of(timer, struct pps_generator_pp, timer); | ||
94 | lim = NSEC_PER_SEC - send_delay - dev->port_write_time; | ||
95 | |||
96 | /* check if we are late */ | ||
97 | if (expire_time.tv_sec != ts1.tv_sec || ts1.tv_nsec > lim) { | ||
98 | local_irq_restore(flags); | ||
99 | pr_err("we are late this time %ld.%09ld\n", | ||
100 | ts1.tv_sec, ts1.tv_nsec); | ||
101 | goto done; | ||
102 | } | ||
103 | |||
104 | /* busy loop until the time is right for an assert edge */ | ||
105 | do { | ||
106 | getnstimeofday(&ts2); | ||
107 | } while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim); | ||
108 | |||
109 | /* set the signal */ | ||
110 | port = dev->pardev->port; | ||
111 | port->ops->write_control(port, SIGNAL); | ||
112 | |||
113 | /* busy loop until the time is right for a clear edge */ | ||
114 | lim = NSEC_PER_SEC - dev->port_write_time; | ||
115 | do { | ||
116 | getnstimeofday(&ts2); | ||
117 | } while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim); | ||
118 | |||
119 | /* unset the signal */ | ||
120 | port->ops->write_control(port, NO_SIGNAL); | ||
121 | |||
122 | getnstimeofday(&ts3); | ||
123 | |||
124 | local_irq_restore(flags); | ||
125 | |||
126 | /* update calibrated port write time */ | ||
127 | dts = timespec_sub(ts3, ts2); | ||
128 | dev->port_write_time = | ||
129 | (dev->port_write_time + timespec_to_ns(&dts)) >> 1; | ||
130 | |||
131 | done: | ||
132 | /* update calibrated hrtimer error */ | ||
133 | dts = timespec_sub(ts1, expire_time); | ||
134 | delta = timespec_to_ns(&dts); | ||
135 | /* If the new error value is bigger then the old, use the new | ||
136 | * value, if not then slowly move towards the new value. This | ||
137 | * way it should be safe in bad conditions and efficient in | ||
138 | * good conditions. | ||
139 | */ | ||
140 | if (delta >= hrtimer_error) | ||
141 | hrtimer_error = delta; | ||
142 | else | ||
143 | hrtimer_error = (3 * hrtimer_error + delta) >> 2; | ||
144 | |||
145 | /* update the hrtimer expire time */ | ||
146 | hrtimer_set_expires(timer, | ||
147 | ktime_set(expire_time.tv_sec + 1, | ||
148 | NSEC_PER_SEC - (send_delay + | ||
149 | dev->port_write_time + SAFETY_INTERVAL + | ||
150 | 2 * hrtimer_error))); | ||
151 | |||
152 | return HRTIMER_RESTART; | ||
153 | } | ||
154 | |||
155 | /* calibrate port write time */ | ||
156 | #define PORT_NTESTS_SHIFT 5 | ||
157 | static void calibrate_port(struct pps_generator_pp *dev) | ||
158 | { | ||
159 | struct parport *port = dev->pardev->port; | ||
160 | int i; | ||
161 | long acc = 0; | ||
162 | |||
163 | for (i = 0; i < (1 << PORT_NTESTS_SHIFT); i++) { | ||
164 | struct timespec a, b; | ||
165 | unsigned long irq_flags; | ||
166 | |||
167 | local_irq_save(irq_flags); | ||
168 | getnstimeofday(&a); | ||
169 | port->ops->write_control(port, NO_SIGNAL); | ||
170 | getnstimeofday(&b); | ||
171 | local_irq_restore(irq_flags); | ||
172 | |||
173 | b = timespec_sub(b, a); | ||
174 | acc += timespec_to_ns(&b); | ||
175 | } | ||
176 | |||
177 | dev->port_write_time = acc >> PORT_NTESTS_SHIFT; | ||
178 | pr_info("port write takes %ldns\n", dev->port_write_time); | ||
179 | } | ||
180 | |||
181 | static inline ktime_t next_intr_time(struct pps_generator_pp *dev) | ||
182 | { | ||
183 | struct timespec ts; | ||
184 | |||
185 | getnstimeofday(&ts); | ||
186 | |||
187 | return ktime_set(ts.tv_sec + | ||
188 | ((ts.tv_nsec > 990 * NSEC_PER_MSEC) ? 1 : 0), | ||
189 | NSEC_PER_SEC - (send_delay + | ||
190 | dev->port_write_time + 3 * SAFETY_INTERVAL)); | ||
191 | } | ||
192 | |||
193 | static void parport_attach(struct parport *port) | ||
194 | { | ||
195 | if (attached) { | ||
196 | /* we already have a port */ | ||
197 | return; | ||
198 | } | ||
199 | |||
200 | device.pardev = parport_register_device(port, KBUILD_MODNAME, | ||
201 | NULL, NULL, NULL, 0, &device); | ||
202 | if (!device.pardev) { | ||
203 | pr_err("couldn't register with %s\n", port->name); | ||
204 | return; | ||
205 | } | ||
206 | |||
207 | if (parport_claim_or_block(device.pardev) < 0) { | ||
208 | pr_err("couldn't claim %s\n", port->name); | ||
209 | goto err_unregister_dev; | ||
210 | } | ||
211 | |||
212 | pr_info("attached to %s\n", port->name); | ||
213 | attached = 1; | ||
214 | |||
215 | calibrate_port(&device); | ||
216 | |||
217 | hrtimer_init(&device.timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); | ||
218 | device.timer.function = hrtimer_event; | ||
219 | #ifdef CONFIG_PREEMPT_RT | ||
220 | /* hrtimer interrupt will run in the interrupt context with this */ | ||
221 | device.timer.irqsafe = 1; | ||
222 | #endif | ||
223 | |||
224 | hrtimer_start(&device.timer, next_intr_time(&device), HRTIMER_MODE_ABS); | ||
225 | |||
226 | return; | ||
227 | |||
228 | err_unregister_dev: | ||
229 | parport_unregister_device(device.pardev); | ||
230 | } | ||
231 | |||
232 | static void parport_detach(struct parport *port) | ||
233 | { | ||
234 | if (port->cad != device.pardev) | ||
235 | return; /* not our port */ | ||
236 | |||
237 | hrtimer_cancel(&device.timer); | ||
238 | parport_release(device.pardev); | ||
239 | parport_unregister_device(device.pardev); | ||
240 | } | ||
241 | |||
242 | static struct parport_driver pps_gen_parport_driver = { | ||
243 | .name = KBUILD_MODNAME, | ||
244 | .attach = parport_attach, | ||
245 | .detach = parport_detach, | ||
246 | }; | ||
247 | |||
248 | /* module staff */ | ||
249 | |||
250 | static int __init pps_gen_parport_init(void) | ||
251 | { | ||
252 | int ret; | ||
253 | |||
254 | pr_info(DRVDESC "\n"); | ||
255 | |||
256 | if (send_delay > SEND_DELAY_MAX) { | ||
257 | pr_err("delay value should be not greater" | ||
258 | " then %d\n", SEND_DELAY_MAX); | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | |||
262 | ret = parport_register_driver(&pps_gen_parport_driver); | ||
263 | if (ret) { | ||
264 | pr_err("unable to register with parport\n"); | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static void __exit pps_gen_parport_exit(void) | ||
272 | { | ||
273 | parport_unregister_driver(&pps_gen_parport_driver); | ||
274 | pr_info("hrtimer avg error is %ldns\n", hrtimer_error); | ||
275 | } | ||
276 | |||
277 | module_init(pps_gen_parport_init); | ||
278 | module_exit(pps_gen_parport_exit); | ||
279 | |||
280 | MODULE_AUTHOR("Alexander Gordeev <lasaine@lvk.cs.msu.su>"); | ||
281 | MODULE_DESCRIPTION(DRVDESC); | ||
282 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c index 1aa02db3ff4..cba1b43f751 100644 --- a/drivers/pps/kapi.c +++ b/drivers/pps/kapi.c | |||
@@ -19,24 +19,20 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | 23 | ||
23 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
26 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
27 | #include <linux/time.h> | 28 | #include <linux/time.h> |
29 | #include <linux/timex.h> | ||
28 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
29 | #include <linux/idr.h> | ||
30 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
31 | #include <linux/pps_kernel.h> | 32 | #include <linux/pps_kernel.h> |
32 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
33 | 34 | ||
34 | /* | 35 | #include "kc.h" |
35 | * Global variables | ||
36 | */ | ||
37 | |||
38 | DEFINE_SPINLOCK(pps_idr_lock); | ||
39 | DEFINE_IDR(pps_idr); | ||
40 | 36 | ||
41 | /* | 37 | /* |
42 | * Local functions | 38 | * Local functions |
@@ -60,60 +56,6 @@ static void pps_add_offset(struct pps_ktime *ts, struct pps_ktime *offset) | |||
60 | * Exported functions | 56 | * Exported functions |
61 | */ | 57 | */ |
62 | 58 | ||
63 | /* pps_get_source - find a PPS source | ||
64 | * @source: the PPS source ID. | ||
65 | * | ||
66 | * This function is used to find an already registered PPS source into the | ||
67 | * system. | ||
68 | * | ||
69 | * The function returns NULL if found nothing, otherwise it returns a pointer | ||
70 | * to the PPS source data struct (the refcounter is incremented by 1). | ||
71 | */ | ||
72 | |||
73 | struct pps_device *pps_get_source(int source) | ||
74 | { | ||
75 | struct pps_device *pps; | ||
76 | unsigned long flags; | ||
77 | |||
78 | spin_lock_irqsave(&pps_idr_lock, flags); | ||
79 | |||
80 | pps = idr_find(&pps_idr, source); | ||
81 | if (pps != NULL) | ||
82 | atomic_inc(&pps->usage); | ||
83 | |||
84 | spin_unlock_irqrestore(&pps_idr_lock, flags); | ||
85 | |||
86 | return pps; | ||
87 | } | ||
88 | |||
89 | /* pps_put_source - free the PPS source data | ||
90 | * @pps: a pointer to the PPS source. | ||
91 | * | ||
92 | * This function is used to free a PPS data struct if its refcount is 0. | ||
93 | */ | ||
94 | |||
95 | void pps_put_source(struct pps_device *pps) | ||
96 | { | ||
97 | unsigned long flags; | ||
98 | |||
99 | spin_lock_irqsave(&pps_idr_lock, flags); | ||
100 | BUG_ON(atomic_read(&pps->usage) == 0); | ||
101 | |||
102 | if (!atomic_dec_and_test(&pps->usage)) { | ||
103 | pps = NULL; | ||
104 | goto exit; | ||
105 | } | ||
106 | |||
107 | /* No more reference to the PPS source. We can safely remove the | ||
108 | * PPS data struct. | ||
109 | */ | ||
110 | idr_remove(&pps_idr, pps->id); | ||
111 | |||
112 | exit: | ||
113 | spin_unlock_irqrestore(&pps_idr_lock, flags); | ||
114 | kfree(pps); | ||
115 | } | ||
116 | |||
117 | /* pps_register_source - add a PPS source in the system | 59 | /* pps_register_source - add a PPS source in the system |
118 | * @info: the PPS info struct | 60 | * @info: the PPS info struct |
119 | * @default_params: the default PPS parameters of the new source | 61 | * @default_params: the default PPS parameters of the new source |
@@ -122,31 +64,31 @@ exit: | |||
122 | * source is described by info's fields and it will have, as default PPS | 64 | * source is described by info's fields and it will have, as default PPS |
123 | * parameters, the ones specified into default_params. | 65 | * parameters, the ones specified into default_params. |
124 | * | 66 | * |
125 | * The function returns, in case of success, the PPS source ID. | 67 | * The function returns, in case of success, the PPS device. Otherwise NULL. |
126 | */ | 68 | */ |
127 | 69 | ||
128 | int pps_register_source(struct pps_source_info *info, int default_params) | 70 | struct pps_device *pps_register_source(struct pps_source_info *info, |
71 | int default_params) | ||
129 | { | 72 | { |
130 | struct pps_device *pps; | 73 | struct pps_device *pps; |
131 | int id; | ||
132 | int err; | 74 | int err; |
133 | 75 | ||
134 | /* Sanity checks */ | 76 | /* Sanity checks */ |
135 | if ((info->mode & default_params) != default_params) { | 77 | if ((info->mode & default_params) != default_params) { |
136 | printk(KERN_ERR "pps: %s: unsupported default parameters\n", | 78 | pr_err("%s: unsupported default parameters\n", |
137 | info->name); | 79 | info->name); |
138 | err = -EINVAL; | 80 | err = -EINVAL; |
139 | goto pps_register_source_exit; | 81 | goto pps_register_source_exit; |
140 | } | 82 | } |
141 | if ((info->mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)) != 0 && | 83 | if ((info->mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)) != 0 && |
142 | info->echo == NULL) { | 84 | info->echo == NULL) { |
143 | printk(KERN_ERR "pps: %s: echo function is not defined\n", | 85 | pr_err("%s: echo function is not defined\n", |
144 | info->name); | 86 | info->name); |
145 | err = -EINVAL; | 87 | err = -EINVAL; |
146 | goto pps_register_source_exit; | 88 | goto pps_register_source_exit; |
147 | } | 89 | } |
148 | if ((info->mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { | 90 | if ((info->mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { |
149 | printk(KERN_ERR "pps: %s: unspecified time format\n", | 91 | pr_err("%s: unspecified time format\n", |
150 | info->name); | 92 | info->name); |
151 | err = -EINVAL; | 93 | err = -EINVAL; |
152 | goto pps_register_source_exit; | 94 | goto pps_register_source_exit; |
@@ -168,94 +110,48 @@ int pps_register_source(struct pps_source_info *info, int default_params) | |||
168 | 110 | ||
169 | init_waitqueue_head(&pps->queue); | 111 | init_waitqueue_head(&pps->queue); |
170 | spin_lock_init(&pps->lock); | 112 | spin_lock_init(&pps->lock); |
171 | atomic_set(&pps->usage, 1); | ||
172 | |||
173 | /* Get new ID for the new PPS source */ | ||
174 | if (idr_pre_get(&pps_idr, GFP_KERNEL) == 0) { | ||
175 | err = -ENOMEM; | ||
176 | goto kfree_pps; | ||
177 | } | ||
178 | |||
179 | spin_lock_irq(&pps_idr_lock); | ||
180 | |||
181 | /* Now really allocate the PPS source. | ||
182 | * After idr_get_new() calling the new source will be freely available | ||
183 | * into the kernel. | ||
184 | */ | ||
185 | err = idr_get_new(&pps_idr, pps, &id); | ||
186 | if (err < 0) { | ||
187 | spin_unlock_irq(&pps_idr_lock); | ||
188 | goto kfree_pps; | ||
189 | } | ||
190 | |||
191 | id = id & MAX_ID_MASK; | ||
192 | if (id >= PPS_MAX_SOURCES) { | ||
193 | spin_unlock_irq(&pps_idr_lock); | ||
194 | |||
195 | printk(KERN_ERR "pps: %s: too many PPS sources in the system\n", | ||
196 | info->name); | ||
197 | err = -EBUSY; | ||
198 | goto free_idr; | ||
199 | } | ||
200 | pps->id = id; | ||
201 | |||
202 | spin_unlock_irq(&pps_idr_lock); | ||
203 | 113 | ||
204 | /* Create the char device */ | 114 | /* Create the char device */ |
205 | err = pps_register_cdev(pps); | 115 | err = pps_register_cdev(pps); |
206 | if (err < 0) { | 116 | if (err < 0) { |
207 | printk(KERN_ERR "pps: %s: unable to create char device\n", | 117 | pr_err("%s: unable to create char device\n", |
208 | info->name); | 118 | info->name); |
209 | goto free_idr; | 119 | goto kfree_pps; |
210 | } | 120 | } |
211 | 121 | ||
212 | pr_info("new PPS source %s at ID %d\n", info->name, id); | 122 | dev_info(pps->dev, "new PPS source %s\n", info->name); |
213 | 123 | ||
214 | return id; | 124 | return pps; |
215 | |||
216 | free_idr: | ||
217 | spin_lock_irq(&pps_idr_lock); | ||
218 | idr_remove(&pps_idr, id); | ||
219 | spin_unlock_irq(&pps_idr_lock); | ||
220 | 125 | ||
221 | kfree_pps: | 126 | kfree_pps: |
222 | kfree(pps); | 127 | kfree(pps); |
223 | 128 | ||
224 | pps_register_source_exit: | 129 | pps_register_source_exit: |
225 | printk(KERN_ERR "pps: %s: unable to register source\n", info->name); | 130 | pr_err("%s: unable to register source\n", info->name); |
226 | 131 | ||
227 | return err; | 132 | return NULL; |
228 | } | 133 | } |
229 | EXPORT_SYMBOL(pps_register_source); | 134 | EXPORT_SYMBOL(pps_register_source); |
230 | 135 | ||
231 | /* pps_unregister_source - remove a PPS source from the system | 136 | /* pps_unregister_source - remove a PPS source from the system |
232 | * @source: the PPS source ID | 137 | * @pps: the PPS source |
233 | * | 138 | * |
234 | * This function is used to remove a previously registered PPS source from | 139 | * This function is used to remove a previously registered PPS source from |
235 | * the system. | 140 | * the system. |
236 | */ | 141 | */ |
237 | 142 | ||
238 | void pps_unregister_source(int source) | 143 | void pps_unregister_source(struct pps_device *pps) |
239 | { | 144 | { |
240 | struct pps_device *pps; | 145 | pps_kc_remove(pps); |
241 | |||
242 | spin_lock_irq(&pps_idr_lock); | ||
243 | pps = idr_find(&pps_idr, source); | ||
244 | |||
245 | if (!pps) { | ||
246 | BUG(); | ||
247 | spin_unlock_irq(&pps_idr_lock); | ||
248 | return; | ||
249 | } | ||
250 | spin_unlock_irq(&pps_idr_lock); | ||
251 | |||
252 | pps_unregister_cdev(pps); | 146 | pps_unregister_cdev(pps); |
253 | pps_put_source(pps); | 147 | |
148 | /* don't have to kfree(pps) here because it will be done on | ||
149 | * device destruction */ | ||
254 | } | 150 | } |
255 | EXPORT_SYMBOL(pps_unregister_source); | 151 | EXPORT_SYMBOL(pps_unregister_source); |
256 | 152 | ||
257 | /* pps_event - register a PPS event into the system | 153 | /* pps_event - register a PPS event into the system |
258 | * @source: the PPS source ID | 154 | * @pps: the PPS device |
259 | * @ts: the event timestamp | 155 | * @ts: the event timestamp |
260 | * @event: the event type | 156 | * @event: the event type |
261 | * @data: userdef pointer | 157 | * @data: userdef pointer |
@@ -263,78 +159,72 @@ EXPORT_SYMBOL(pps_unregister_source); | |||
263 | * This function is used by each PPS client in order to register a new | 159 | * This function is used by each PPS client in order to register a new |
264 | * PPS event into the system (it's usually called inside an IRQ handler). | 160 | * PPS event into the system (it's usually called inside an IRQ handler). |
265 | * | 161 | * |
266 | * If an echo function is associated with the PPS source it will be called | 162 | * If an echo function is associated with the PPS device it will be called |
267 | * as: | 163 | * as: |
268 | * pps->info.echo(source, event, data); | 164 | * pps->info.echo(pps, event, data); |
269 | */ | 165 | */ |
270 | 166 | void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, | |
271 | void pps_event(int source, struct pps_ktime *ts, int event, void *data) | 167 | void *data) |
272 | { | 168 | { |
273 | struct pps_device *pps; | ||
274 | unsigned long flags; | 169 | unsigned long flags; |
275 | int captured = 0; | 170 | int captured = 0; |
171 | struct pps_ktime ts_real; | ||
276 | 172 | ||
277 | if ((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0) { | 173 | /* check event type */ |
278 | printk(KERN_ERR "pps: unknown event (%x) for source %d\n", | 174 | BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0); |
279 | event, source); | ||
280 | return; | ||
281 | } | ||
282 | 175 | ||
283 | pps = pps_get_source(source); | 176 | dev_dbg(pps->dev, "PPS event at %ld.%09ld\n", |
284 | if (!pps) | 177 | ts->ts_real.tv_sec, ts->ts_real.tv_nsec); |
285 | return; | ||
286 | 178 | ||
287 | pr_debug("PPS event on source %d at %llu.%06u\n", | 179 | timespec_to_pps_ktime(&ts_real, ts->ts_real); |
288 | pps->id, (unsigned long long) ts->sec, ts->nsec); | ||
289 | 180 | ||
290 | spin_lock_irqsave(&pps->lock, flags); | 181 | spin_lock_irqsave(&pps->lock, flags); |
291 | 182 | ||
292 | /* Must call the echo function? */ | 183 | /* Must call the echo function? */ |
293 | if ((pps->params.mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR))) | 184 | if ((pps->params.mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR))) |
294 | pps->info.echo(source, event, data); | 185 | pps->info.echo(pps, event, data); |
295 | 186 | ||
296 | /* Check the event */ | 187 | /* Check the event */ |
297 | pps->current_mode = pps->params.mode; | 188 | pps->current_mode = pps->params.mode; |
298 | if ((event & PPS_CAPTUREASSERT) & | 189 | if (event & pps->params.mode & PPS_CAPTUREASSERT) { |
299 | (pps->params.mode & PPS_CAPTUREASSERT)) { | ||
300 | /* We have to add an offset? */ | 190 | /* We have to add an offset? */ |
301 | if (pps->params.mode & PPS_OFFSETASSERT) | 191 | if (pps->params.mode & PPS_OFFSETASSERT) |
302 | pps_add_offset(ts, &pps->params.assert_off_tu); | 192 | pps_add_offset(&ts_real, |
193 | &pps->params.assert_off_tu); | ||
303 | 194 | ||
304 | /* Save the time stamp */ | 195 | /* Save the time stamp */ |
305 | pps->assert_tu = *ts; | 196 | pps->assert_tu = ts_real; |
306 | pps->assert_sequence++; | 197 | pps->assert_sequence++; |
307 | pr_debug("capture assert seq #%u for source %d\n", | 198 | dev_dbg(pps->dev, "capture assert seq #%u\n", |
308 | pps->assert_sequence, source); | 199 | pps->assert_sequence); |
309 | 200 | ||
310 | captured = ~0; | 201 | captured = ~0; |
311 | } | 202 | } |
312 | if ((event & PPS_CAPTURECLEAR) & | 203 | if (event & pps->params.mode & PPS_CAPTURECLEAR) { |
313 | (pps->params.mode & PPS_CAPTURECLEAR)) { | ||
314 | /* We have to add an offset? */ | 204 | /* We have to add an offset? */ |
315 | if (pps->params.mode & PPS_OFFSETCLEAR) | 205 | if (pps->params.mode & PPS_OFFSETCLEAR) |
316 | pps_add_offset(ts, &pps->params.clear_off_tu); | 206 | pps_add_offset(&ts_real, |
207 | &pps->params.clear_off_tu); | ||
317 | 208 | ||
318 | /* Save the time stamp */ | 209 | /* Save the time stamp */ |
319 | pps->clear_tu = *ts; | 210 | pps->clear_tu = ts_real; |
320 | pps->clear_sequence++; | 211 | pps->clear_sequence++; |
321 | pr_debug("capture clear seq #%u for source %d\n", | 212 | dev_dbg(pps->dev, "capture clear seq #%u\n", |
322 | pps->clear_sequence, source); | 213 | pps->clear_sequence); |
323 | 214 | ||
324 | captured = ~0; | 215 | captured = ~0; |
325 | } | 216 | } |
326 | 217 | ||
327 | /* Wake up iif captured somthing */ | 218 | pps_kc_event(pps, ts, event); |
219 | |||
220 | /* Wake up if captured something */ | ||
328 | if (captured) { | 221 | if (captured) { |
329 | pps->go = ~0; | 222 | pps->last_ev++; |
330 | wake_up_interruptible(&pps->queue); | 223 | wake_up_interruptible_all(&pps->queue); |
331 | 224 | ||
332 | kill_fasync(&pps->async_queue, SIGIO, POLL_IN); | 225 | kill_fasync(&pps->async_queue, SIGIO, POLL_IN); |
333 | } | 226 | } |
334 | 227 | ||
335 | spin_unlock_irqrestore(&pps->lock, flags); | 228 | spin_unlock_irqrestore(&pps->lock, flags); |
336 | |||
337 | /* Now we can release the PPS source for (possible) deregistration */ | ||
338 | pps_put_source(pps); | ||
339 | } | 229 | } |
340 | EXPORT_SYMBOL(pps_event); | 230 | EXPORT_SYMBOL(pps_event); |
diff --git a/drivers/pps/kc.c b/drivers/pps/kc.c new file mode 100644 index 00000000000..079e930b193 --- /dev/null +++ b/drivers/pps/kc.c | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * PPS kernel consumer API | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Alexander Gordeev <lasaine@lvk.cs.msu.su> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/pps_kernel.h> | ||
29 | |||
30 | #include "kc.h" | ||
31 | |||
32 | /* | ||
33 | * Global variables | ||
34 | */ | ||
35 | |||
36 | /* state variables to bind kernel consumer */ | ||
37 | DEFINE_SPINLOCK(pps_kc_hardpps_lock); | ||
38 | /* PPS API (RFC 2783): current source and mode for kernel consumer */ | ||
39 | struct pps_device *pps_kc_hardpps_dev; /* unique pointer to device */ | ||
40 | int pps_kc_hardpps_mode; /* mode bits for kernel consumer */ | ||
41 | |||
42 | /* pps_kc_bind - control PPS kernel consumer binding | ||
43 | * @pps: the PPS source | ||
44 | * @bind_args: kernel consumer bind parameters | ||
45 | * | ||
46 | * This function is used to bind or unbind PPS kernel consumer according to | ||
47 | * supplied parameters. Should not be called in interrupt context. | ||
48 | */ | ||
49 | int pps_kc_bind(struct pps_device *pps, struct pps_bind_args *bind_args) | ||
50 | { | ||
51 | /* Check if another consumer is already bound */ | ||
52 | spin_lock_irq(&pps_kc_hardpps_lock); | ||
53 | |||
54 | if (bind_args->edge == 0) | ||
55 | if (pps_kc_hardpps_dev == pps) { | ||
56 | pps_kc_hardpps_mode = 0; | ||
57 | pps_kc_hardpps_dev = NULL; | ||
58 | spin_unlock_irq(&pps_kc_hardpps_lock); | ||
59 | dev_info(pps->dev, "unbound kernel" | ||
60 | " consumer\n"); | ||
61 | } else { | ||
62 | spin_unlock_irq(&pps_kc_hardpps_lock); | ||
63 | dev_err(pps->dev, "selected kernel consumer" | ||
64 | " is not bound\n"); | ||
65 | return -EINVAL; | ||
66 | } | ||
67 | else | ||
68 | if (pps_kc_hardpps_dev == NULL || | ||
69 | pps_kc_hardpps_dev == pps) { | ||
70 | pps_kc_hardpps_mode = bind_args->edge; | ||
71 | pps_kc_hardpps_dev = pps; | ||
72 | spin_unlock_irq(&pps_kc_hardpps_lock); | ||
73 | dev_info(pps->dev, "bound kernel consumer: " | ||
74 | "edge=0x%x\n", bind_args->edge); | ||
75 | } else { | ||
76 | spin_unlock_irq(&pps_kc_hardpps_lock); | ||
77 | dev_err(pps->dev, "another kernel consumer" | ||
78 | " is already bound\n"); | ||
79 | return -EINVAL; | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /* pps_kc_remove - unbind kernel consumer on PPS source removal | ||
86 | * @pps: the PPS source | ||
87 | * | ||
88 | * This function is used to disable kernel consumer on PPS source removal | ||
89 | * if this source was bound to PPS kernel consumer. Can be called on any | ||
90 | * source safely. Should not be called in interrupt context. | ||
91 | */ | ||
92 | void pps_kc_remove(struct pps_device *pps) | ||
93 | { | ||
94 | spin_lock_irq(&pps_kc_hardpps_lock); | ||
95 | if (pps == pps_kc_hardpps_dev) { | ||
96 | pps_kc_hardpps_mode = 0; | ||
97 | pps_kc_hardpps_dev = NULL; | ||
98 | spin_unlock_irq(&pps_kc_hardpps_lock); | ||
99 | dev_info(pps->dev, "unbound kernel consumer" | ||
100 | " on device removal\n"); | ||
101 | } else | ||
102 | spin_unlock_irq(&pps_kc_hardpps_lock); | ||
103 | } | ||
104 | |||
105 | /* pps_kc_event - call hardpps() on PPS event | ||
106 | * @pps: the PPS source | ||
107 | * @ts: PPS event timestamp | ||
108 | * @event: PPS event edge | ||
109 | * | ||
110 | * This function calls hardpps() when an event from bound PPS source occurs. | ||
111 | */ | ||
112 | void pps_kc_event(struct pps_device *pps, struct pps_event_time *ts, | ||
113 | int event) | ||
114 | { | ||
115 | unsigned long flags; | ||
116 | |||
117 | /* Pass some events to kernel consumer if activated */ | ||
118 | spin_lock_irqsave(&pps_kc_hardpps_lock, flags); | ||
119 | if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode) | ||
120 | hardpps(&ts->ts_real, &ts->ts_raw); | ||
121 | spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags); | ||
122 | } | ||
diff --git a/drivers/pps/kc.h b/drivers/pps/kc.h new file mode 100644 index 00000000000..d296fcd0a17 --- /dev/null +++ b/drivers/pps/kc.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * PPS kernel consumer API header | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Alexander Gordeev <lasaine@lvk.cs.msu.su> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef LINUX_PPS_KC_H | ||
22 | #define LINUX_PPS_KC_H | ||
23 | |||
24 | #include <linux/errno.h> | ||
25 | #include <linux/pps_kernel.h> | ||
26 | |||
27 | #ifdef CONFIG_NTP_PPS | ||
28 | |||
29 | extern int pps_kc_bind(struct pps_device *pps, | ||
30 | struct pps_bind_args *bind_args); | ||
31 | extern void pps_kc_remove(struct pps_device *pps); | ||
32 | extern void pps_kc_event(struct pps_device *pps, | ||
33 | struct pps_event_time *ts, int event); | ||
34 | |||
35 | |||
36 | #else /* CONFIG_NTP_PPS */ | ||
37 | |||
38 | static inline int pps_kc_bind(struct pps_device *pps, | ||
39 | struct pps_bind_args *bind_args) { return -EOPNOTSUPP; } | ||
40 | static inline void pps_kc_remove(struct pps_device *pps) {} | ||
41 | static inline void pps_kc_event(struct pps_device *pps, | ||
42 | struct pps_event_time *ts, int event) {} | ||
43 | |||
44 | #endif /* CONFIG_NTP_PPS */ | ||
45 | |||
46 | #endif /* LINUX_PPS_KC_H */ | ||
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index ca5183bdad8..2baadd21b7a 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | 23 | ||
23 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
@@ -26,9 +27,13 @@ | |||
26 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
27 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
28 | #include <linux/idr.h> | 29 | #include <linux/idr.h> |
30 | #include <linux/mutex.h> | ||
29 | #include <linux/cdev.h> | 31 | #include <linux/cdev.h> |
30 | #include <linux/poll.h> | 32 | #include <linux/poll.h> |
31 | #include <linux/pps_kernel.h> | 33 | #include <linux/pps_kernel.h> |
34 | #include <linux/slab.h> | ||
35 | |||
36 | #include "kc.h" | ||
32 | 37 | ||
33 | /* | 38 | /* |
34 | * Local variables | 39 | * Local variables |
@@ -37,6 +42,9 @@ | |||
37 | static dev_t pps_devt; | 42 | static dev_t pps_devt; |
38 | static struct class *pps_class; | 43 | static struct class *pps_class; |
39 | 44 | ||
45 | static DEFINE_MUTEX(pps_idr_lock); | ||
46 | static DEFINE_IDR(pps_idr); | ||
47 | |||
40 | /* | 48 | /* |
41 | * Char device methods | 49 | * Char device methods |
42 | */ | 50 | */ |
@@ -61,15 +69,13 @@ static long pps_cdev_ioctl(struct file *file, | |||
61 | { | 69 | { |
62 | struct pps_device *pps = file->private_data; | 70 | struct pps_device *pps = file->private_data; |
63 | struct pps_kparams params; | 71 | struct pps_kparams params; |
64 | struct pps_fdata fdata; | ||
65 | unsigned long ticks; | ||
66 | void __user *uarg = (void __user *) arg; | 72 | void __user *uarg = (void __user *) arg; |
67 | int __user *iuarg = (int __user *) arg; | 73 | int __user *iuarg = (int __user *) arg; |
68 | int err; | 74 | int err; |
69 | 75 | ||
70 | switch (cmd) { | 76 | switch (cmd) { |
71 | case PPS_GETPARAMS: | 77 | case PPS_GETPARAMS: |
72 | pr_debug("PPS_GETPARAMS: source %d\n", pps->id); | 78 | dev_dbg(pps->dev, "PPS_GETPARAMS\n"); |
73 | 79 | ||
74 | spin_lock_irq(&pps->lock); | 80 | spin_lock_irq(&pps->lock); |
75 | 81 | ||
@@ -85,7 +91,7 @@ static long pps_cdev_ioctl(struct file *file, | |||
85 | break; | 91 | break; |
86 | 92 | ||
87 | case PPS_SETPARAMS: | 93 | case PPS_SETPARAMS: |
88 | pr_debug("PPS_SETPARAMS: source %d\n", pps->id); | 94 | dev_dbg(pps->dev, "PPS_SETPARAMS\n"); |
89 | 95 | ||
90 | /* Check the capabilities */ | 96 | /* Check the capabilities */ |
91 | if (!capable(CAP_SYS_TIME)) | 97 | if (!capable(CAP_SYS_TIME)) |
@@ -95,14 +101,14 @@ static long pps_cdev_ioctl(struct file *file, | |||
95 | if (err) | 101 | if (err) |
96 | return -EFAULT; | 102 | return -EFAULT; |
97 | if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) { | 103 | if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) { |
98 | pr_debug("capture mode unspecified (%x)\n", | 104 | dev_dbg(pps->dev, "capture mode unspecified (%x)\n", |
99 | params.mode); | 105 | params.mode); |
100 | return -EINVAL; | 106 | return -EINVAL; |
101 | } | 107 | } |
102 | 108 | ||
103 | /* Check for supported capabilities */ | 109 | /* Check for supported capabilities */ |
104 | if ((params.mode & ~pps->info.mode) != 0) { | 110 | if ((params.mode & ~pps->info.mode) != 0) { |
105 | pr_debug("unsupported capabilities (%x)\n", | 111 | dev_dbg(pps->dev, "unsupported capabilities (%x)\n", |
106 | params.mode); | 112 | params.mode); |
107 | return -EINVAL; | 113 | return -EINVAL; |
108 | } | 114 | } |
@@ -115,7 +121,7 @@ static long pps_cdev_ioctl(struct file *file, | |||
115 | /* Restore the read only parameters */ | 121 | /* Restore the read only parameters */ |
116 | if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { | 122 | if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { |
117 | /* section 3.3 of RFC 2783 interpreted */ | 123 | /* section 3.3 of RFC 2783 interpreted */ |
118 | pr_debug("time format unspecified (%x)\n", | 124 | dev_dbg(pps->dev, "time format unspecified (%x)\n", |
119 | params.mode); | 125 | params.mode); |
120 | pps->params.mode |= PPS_TSFMT_TSPEC; | 126 | pps->params.mode |= PPS_TSFMT_TSPEC; |
121 | } | 127 | } |
@@ -128,7 +134,7 @@ static long pps_cdev_ioctl(struct file *file, | |||
128 | break; | 134 | break; |
129 | 135 | ||
130 | case PPS_GETCAP: | 136 | case PPS_GETCAP: |
131 | pr_debug("PPS_GETCAP: source %d\n", pps->id); | 137 | dev_dbg(pps->dev, "PPS_GETCAP\n"); |
132 | 138 | ||
133 | err = put_user(pps->info.mode, iuarg); | 139 | err = put_user(pps->info.mode, iuarg); |
134 | if (err) | 140 | if (err) |
@@ -136,20 +142,26 @@ static long pps_cdev_ioctl(struct file *file, | |||
136 | 142 | ||
137 | break; | 143 | break; |
138 | 144 | ||
139 | case PPS_FETCH: | 145 | case PPS_FETCH: { |
140 | pr_debug("PPS_FETCH: source %d\n", pps->id); | 146 | struct pps_fdata fdata; |
147 | unsigned int ev; | ||
148 | |||
149 | dev_dbg(pps->dev, "PPS_FETCH\n"); | ||
141 | 150 | ||
142 | err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata)); | 151 | err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata)); |
143 | if (err) | 152 | if (err) |
144 | return -EFAULT; | 153 | return -EFAULT; |
145 | 154 | ||
146 | pps->go = 0; | 155 | ev = pps->last_ev; |
147 | 156 | ||
148 | /* Manage the timeout */ | 157 | /* Manage the timeout */ |
149 | if (fdata.timeout.flags & PPS_TIME_INVALID) | 158 | if (fdata.timeout.flags & PPS_TIME_INVALID) |
150 | err = wait_event_interruptible(pps->queue, pps->go); | 159 | err = wait_event_interruptible(pps->queue, |
160 | ev != pps->last_ev); | ||
151 | else { | 161 | else { |
152 | pr_debug("timeout %lld.%09d\n", | 162 | unsigned long ticks; |
163 | |||
164 | dev_dbg(pps->dev, "timeout %lld.%09d\n", | ||
153 | (long long) fdata.timeout.sec, | 165 | (long long) fdata.timeout.sec, |
154 | fdata.timeout.nsec); | 166 | fdata.timeout.nsec); |
155 | ticks = fdata.timeout.sec * HZ; | 167 | ticks = fdata.timeout.sec * HZ; |
@@ -157,7 +169,9 @@ static long pps_cdev_ioctl(struct file *file, | |||
157 | 169 | ||
158 | if (ticks != 0) { | 170 | if (ticks != 0) { |
159 | err = wait_event_interruptible_timeout( | 171 | err = wait_event_interruptible_timeout( |
160 | pps->queue, pps->go, ticks); | 172 | pps->queue, |
173 | ev != pps->last_ev, | ||
174 | ticks); | ||
161 | if (err == 0) | 175 | if (err == 0) |
162 | return -ETIMEDOUT; | 176 | return -ETIMEDOUT; |
163 | } | 177 | } |
@@ -165,7 +179,7 @@ static long pps_cdev_ioctl(struct file *file, | |||
165 | 179 | ||
166 | /* Check for pending signals */ | 180 | /* Check for pending signals */ |
167 | if (err == -ERESTARTSYS) { | 181 | if (err == -ERESTARTSYS) { |
168 | pr_debug("pending signal caught\n"); | 182 | dev_dbg(pps->dev, "pending signal caught\n"); |
169 | return -EINTR; | 183 | return -EINTR; |
170 | } | 184 | } |
171 | 185 | ||
@@ -185,10 +199,44 @@ static long pps_cdev_ioctl(struct file *file, | |||
185 | return -EFAULT; | 199 | return -EFAULT; |
186 | 200 | ||
187 | break; | 201 | break; |
202 | } | ||
203 | case PPS_KC_BIND: { | ||
204 | struct pps_bind_args bind_args; | ||
205 | |||
206 | dev_dbg(pps->dev, "PPS_KC_BIND\n"); | ||
207 | |||
208 | /* Check the capabilities */ | ||
209 | if (!capable(CAP_SYS_TIME)) | ||
210 | return -EPERM; | ||
211 | |||
212 | if (copy_from_user(&bind_args, uarg, | ||
213 | sizeof(struct pps_bind_args))) | ||
214 | return -EFAULT; | ||
188 | 215 | ||
216 | /* Check for supported capabilities */ | ||
217 | if ((bind_args.edge & ~pps->info.mode) != 0) { | ||
218 | dev_err(pps->dev, "unsupported capabilities (%x)\n", | ||
219 | bind_args.edge); | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | |||
223 | /* Validate parameters roughly */ | ||
224 | if (bind_args.tsformat != PPS_TSFMT_TSPEC || | ||
225 | (bind_args.edge & ~PPS_CAPTUREBOTH) != 0 || | ||
226 | bind_args.consumer != PPS_KC_HARDPPS) { | ||
227 | dev_err(pps->dev, "invalid kernel consumer bind" | ||
228 | " parameters (%x)\n", bind_args.edge); | ||
229 | return -EINVAL; | ||
230 | } | ||
231 | |||
232 | err = pps_kc_bind(pps, &bind_args); | ||
233 | if (err < 0) | ||
234 | return err; | ||
235 | |||
236 | break; | ||
237 | } | ||
189 | default: | 238 | default: |
190 | return -ENOTTY; | 239 | return -ENOTTY; |
191 | break; | ||
192 | } | 240 | } |
193 | 241 | ||
194 | return 0; | 242 | return 0; |
@@ -198,12 +246,6 @@ static int pps_cdev_open(struct inode *inode, struct file *file) | |||
198 | { | 246 | { |
199 | struct pps_device *pps = container_of(inode->i_cdev, | 247 | struct pps_device *pps = container_of(inode->i_cdev, |
200 | struct pps_device, cdev); | 248 | struct pps_device, cdev); |
201 | int found; | ||
202 | |||
203 | found = pps_get_source(pps->id) != 0; | ||
204 | if (!found) | ||
205 | return -ENODEV; | ||
206 | |||
207 | file->private_data = pps; | 249 | file->private_data = pps; |
208 | 250 | ||
209 | return 0; | 251 | return 0; |
@@ -211,11 +253,6 @@ static int pps_cdev_open(struct inode *inode, struct file *file) | |||
211 | 253 | ||
212 | static int pps_cdev_release(struct inode *inode, struct file *file) | 254 | static int pps_cdev_release(struct inode *inode, struct file *file) |
213 | { | 255 | { |
214 | struct pps_device *pps = file->private_data; | ||
215 | |||
216 | /* Free the PPS source and wake up (possible) deregistration */ | ||
217 | pps_put_source(pps); | ||
218 | |||
219 | return 0; | 256 | return 0; |
220 | } | 257 | } |
221 | 258 | ||
@@ -233,25 +270,67 @@ static const struct file_operations pps_cdev_fops = { | |||
233 | .release = pps_cdev_release, | 270 | .release = pps_cdev_release, |
234 | }; | 271 | }; |
235 | 272 | ||
273 | static void pps_device_destruct(struct device *dev) | ||
274 | { | ||
275 | struct pps_device *pps = dev_get_drvdata(dev); | ||
276 | |||
277 | /* release id here to protect others from using it while it's | ||
278 | * still in use */ | ||
279 | mutex_lock(&pps_idr_lock); | ||
280 | idr_remove(&pps_idr, pps->id); | ||
281 | mutex_unlock(&pps_idr_lock); | ||
282 | |||
283 | kfree(dev); | ||
284 | kfree(pps); | ||
285 | } | ||
286 | |||
236 | int pps_register_cdev(struct pps_device *pps) | 287 | int pps_register_cdev(struct pps_device *pps) |
237 | { | 288 | { |
238 | int err; | 289 | int err; |
290 | dev_t devt; | ||
291 | |||
292 | mutex_lock(&pps_idr_lock); | ||
293 | /* Get new ID for the new PPS source */ | ||
294 | if (idr_pre_get(&pps_idr, GFP_KERNEL) == 0) { | ||
295 | mutex_unlock(&pps_idr_lock); | ||
296 | return -ENOMEM; | ||
297 | } | ||
298 | |||
299 | /* Now really allocate the PPS source. | ||
300 | * After idr_get_new() calling the new source will be freely available | ||
301 | * into the kernel. | ||
302 | */ | ||
303 | err = idr_get_new(&pps_idr, pps, &pps->id); | ||
304 | mutex_unlock(&pps_idr_lock); | ||
305 | |||
306 | if (err < 0) | ||
307 | return err; | ||
308 | |||
309 | pps->id &= MAX_ID_MASK; | ||
310 | if (pps->id >= PPS_MAX_SOURCES) { | ||
311 | pr_err("%s: too many PPS sources in the system\n", | ||
312 | pps->info.name); | ||
313 | err = -EBUSY; | ||
314 | goto free_idr; | ||
315 | } | ||
316 | |||
317 | devt = MKDEV(MAJOR(pps_devt), pps->id); | ||
239 | 318 | ||
240 | pps->devno = MKDEV(MAJOR(pps_devt), pps->id); | ||
241 | cdev_init(&pps->cdev, &pps_cdev_fops); | 319 | cdev_init(&pps->cdev, &pps_cdev_fops); |
242 | pps->cdev.owner = pps->info.owner; | 320 | pps->cdev.owner = pps->info.owner; |
243 | 321 | ||
244 | err = cdev_add(&pps->cdev, pps->devno, 1); | 322 | err = cdev_add(&pps->cdev, devt, 1); |
245 | if (err) { | 323 | if (err) { |
246 | printk(KERN_ERR "pps: %s: failed to add char device %d:%d\n", | 324 | pr_err("%s: failed to add char device %d:%d\n", |
247 | pps->info.name, MAJOR(pps_devt), pps->id); | 325 | pps->info.name, MAJOR(pps_devt), pps->id); |
248 | return err; | 326 | goto free_idr; |
249 | } | 327 | } |
250 | pps->dev = device_create(pps_class, pps->info.dev, pps->devno, NULL, | 328 | pps->dev = device_create(pps_class, pps->info.dev, devt, pps, |
251 | "pps%d", pps->id); | 329 | "pps%d", pps->id); |
252 | if (IS_ERR(pps->dev)) | 330 | if (IS_ERR(pps->dev)) |
253 | goto del_cdev; | 331 | goto del_cdev; |
254 | dev_set_drvdata(pps->dev, pps); | 332 | |
333 | pps->dev->release = pps_device_destruct; | ||
255 | 334 | ||
256 | pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, | 335 | pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, |
257 | MAJOR(pps_devt), pps->id); | 336 | MAJOR(pps_devt), pps->id); |
@@ -261,12 +340,17 @@ int pps_register_cdev(struct pps_device *pps) | |||
261 | del_cdev: | 340 | del_cdev: |
262 | cdev_del(&pps->cdev); | 341 | cdev_del(&pps->cdev); |
263 | 342 | ||
343 | free_idr: | ||
344 | mutex_lock(&pps_idr_lock); | ||
345 | idr_remove(&pps_idr, pps->id); | ||
346 | mutex_unlock(&pps_idr_lock); | ||
347 | |||
264 | return err; | 348 | return err; |
265 | } | 349 | } |
266 | 350 | ||
267 | void pps_unregister_cdev(struct pps_device *pps) | 351 | void pps_unregister_cdev(struct pps_device *pps) |
268 | { | 352 | { |
269 | device_destroy(pps_class, pps->devno); | 353 | device_destroy(pps_class, pps->dev->devt); |
270 | cdev_del(&pps->cdev); | 354 | cdev_del(&pps->cdev); |
271 | } | 355 | } |
272 | 356 | ||
@@ -286,14 +370,14 @@ static int __init pps_init(void) | |||
286 | 370 | ||
287 | pps_class = class_create(THIS_MODULE, "pps"); | 371 | pps_class = class_create(THIS_MODULE, "pps"); |
288 | if (!pps_class) { | 372 | if (!pps_class) { |
289 | printk(KERN_ERR "pps: failed to allocate class\n"); | 373 | pr_err("failed to allocate class\n"); |
290 | return -ENOMEM; | 374 | return -ENOMEM; |
291 | } | 375 | } |
292 | pps_class->dev_attrs = pps_attrs; | 376 | pps_class->dev_attrs = pps_attrs; |
293 | 377 | ||
294 | err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); | 378 | err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); |
295 | if (err < 0) { | 379 | if (err < 0) { |
296 | printk(KERN_ERR "pps: failed to allocate char device region\n"); | 380 | pr_err("failed to allocate char device region\n"); |
297 | goto remove_class; | 381 | goto remove_class; |
298 | } | 382 | } |
299 | 383 | ||
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 1eb82c4c712..467e82bd092 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -46,7 +46,6 @@ static void rio_init_em(struct rio_dev *rdev); | |||
46 | DEFINE_SPINLOCK(rio_global_list_lock); | 46 | DEFINE_SPINLOCK(rio_global_list_lock); |
47 | 47 | ||
48 | static int next_destid = 0; | 48 | static int next_destid = 0; |
49 | static int next_switchid = 0; | ||
50 | static int next_net = 0; | 49 | static int next_net = 0; |
51 | static int next_comptag = 1; | 50 | static int next_comptag = 1; |
52 | 51 | ||
@@ -378,12 +377,30 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
378 | struct rio_dev *rdev; | 377 | struct rio_dev *rdev; |
379 | struct rio_switch *rswitch = NULL; | 378 | struct rio_switch *rswitch = NULL; |
380 | int result, rdid; | 379 | int result, rdid; |
380 | size_t size; | ||
381 | u32 swpinfo = 0; | ||
381 | 382 | ||
382 | rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL); | 383 | size = sizeof(struct rio_dev); |
384 | if (rio_mport_read_config_32(port, destid, hopcount, | ||
385 | RIO_PEF_CAR, &result)) | ||
386 | return NULL; | ||
387 | |||
388 | if (result & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) { | ||
389 | rio_mport_read_config_32(port, destid, hopcount, | ||
390 | RIO_SWP_INFO_CAR, &swpinfo); | ||
391 | if (result & RIO_PEF_SWITCH) { | ||
392 | size += (RIO_GET_TOTAL_PORTS(swpinfo) * | ||
393 | sizeof(rswitch->nextdev[0])) + sizeof(*rswitch); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | rdev = kzalloc(size, GFP_KERNEL); | ||
383 | if (!rdev) | 398 | if (!rdev) |
384 | return NULL; | 399 | return NULL; |
385 | 400 | ||
386 | rdev->net = net; | 401 | rdev->net = net; |
402 | rdev->pef = result; | ||
403 | rdev->swpinfo = swpinfo; | ||
387 | rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR, | 404 | rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR, |
388 | &result); | 405 | &result); |
389 | rdev->did = result >> 16; | 406 | rdev->did = result >> 16; |
@@ -397,8 +414,6 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
397 | rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR, | 414 | rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR, |
398 | &result); | 415 | &result); |
399 | rdev->asm_rev = result >> 16; | 416 | rdev->asm_rev = result >> 16; |
400 | rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR, | ||
401 | &rdev->pef); | ||
402 | if (rdev->pef & RIO_PEF_EXT_FEATURES) { | 417 | if (rdev->pef & RIO_PEF_EXT_FEATURES) { |
403 | rdev->efptr = result & 0xffff; | 418 | rdev->efptr = result & 0xffff; |
404 | rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid, | 419 | rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid, |
@@ -408,11 +423,6 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
408 | hopcount, RIO_EFB_ERR_MGMNT); | 423 | hopcount, RIO_EFB_ERR_MGMNT); |
409 | } | 424 | } |
410 | 425 | ||
411 | if (rdev->pef & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) { | ||
412 | rio_mport_read_config_32(port, destid, hopcount, | ||
413 | RIO_SWP_INFO_CAR, &rdev->swpinfo); | ||
414 | } | ||
415 | |||
416 | rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, | 426 | rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, |
417 | &rdev->src_ops); | 427 | &rdev->src_ops); |
418 | rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, | 428 | rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, |
@@ -427,6 +437,10 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
427 | rio_mport_write_config_32(port, destid, hopcount, | 437 | rio_mport_write_config_32(port, destid, hopcount, |
428 | RIO_COMPONENT_TAG_CSR, next_comptag); | 438 | RIO_COMPONENT_TAG_CSR, next_comptag); |
429 | rdev->comp_tag = next_comptag++; | 439 | rdev->comp_tag = next_comptag++; |
440 | } else { | ||
441 | rio_mport_read_config_32(port, destid, hopcount, | ||
442 | RIO_COMPONENT_TAG_CSR, | ||
443 | &rdev->comp_tag); | ||
430 | } | 444 | } |
431 | 445 | ||
432 | if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { | 446 | if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { |
@@ -437,21 +451,20 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
437 | next_destid++; | 451 | next_destid++; |
438 | } else | 452 | } else |
439 | rdev->destid = rio_get_device_id(port, destid, hopcount); | 453 | rdev->destid = rio_get_device_id(port, destid, hopcount); |
440 | } else | 454 | |
441 | /* Switch device has an associated destID */ | 455 | rdev->hopcount = 0xff; |
442 | rdev->destid = RIO_INVALID_DESTID; | 456 | } else { |
457 | /* Switch device has an associated destID which | ||
458 | * will be adjusted later | ||
459 | */ | ||
460 | rdev->destid = destid; | ||
461 | rdev->hopcount = hopcount; | ||
462 | } | ||
443 | 463 | ||
444 | /* If a PE has both switch and other functions, show it as a switch */ | 464 | /* If a PE has both switch and other functions, show it as a switch */ |
445 | if (rio_is_switch(rdev)) { | 465 | if (rio_is_switch(rdev)) { |
446 | rswitch = kzalloc(sizeof(*rswitch) + | 466 | rswitch = rdev->rswitch; |
447 | RIO_GET_TOTAL_PORTS(rdev->swpinfo) * | 467 | rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID; |
448 | sizeof(rswitch->nextdev[0]), | ||
449 | GFP_KERNEL); | ||
450 | if (!rswitch) | ||
451 | goto cleanup; | ||
452 | rswitch->switchid = next_switchid; | ||
453 | rswitch->hopcount = hopcount; | ||
454 | rswitch->destid = destid; | ||
455 | rswitch->port_ok = 0; | 468 | rswitch->port_ok = 0; |
456 | rswitch->route_table = kzalloc(sizeof(u8)* | 469 | rswitch->route_table = kzalloc(sizeof(u8)* |
457 | RIO_MAX_ROUTE_ENTRIES(port->sys_size), | 470 | RIO_MAX_ROUTE_ENTRIES(port->sys_size), |
@@ -462,15 +475,13 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
462 | for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size); | 475 | for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size); |
463 | rdid++) | 476 | rdid++) |
464 | rswitch->route_table[rdid] = RIO_INVALID_ROUTE; | 477 | rswitch->route_table[rdid] = RIO_INVALID_ROUTE; |
465 | rdev->rswitch = rswitch; | ||
466 | rswitch->rdev = rdev; | ||
467 | dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, | 478 | dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, |
468 | rdev->rswitch->switchid); | 479 | rswitch->switchid); |
469 | rio_switch_init(rdev, do_enum); | 480 | rio_switch_init(rdev, do_enum); |
470 | 481 | ||
471 | if (do_enum && rdev->rswitch->clr_table) | 482 | if (do_enum && rswitch->clr_table) |
472 | rdev->rswitch->clr_table(port, destid, hopcount, | 483 | rswitch->clr_table(port, destid, hopcount, |
473 | RIO_GLOBAL_TABLE); | 484 | RIO_GLOBAL_TABLE); |
474 | 485 | ||
475 | list_add_tail(&rswitch->node, &rio_switches); | 486 | list_add_tail(&rswitch->node, &rio_switches); |
476 | 487 | ||
@@ -506,10 +517,9 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
506 | return rdev; | 517 | return rdev; |
507 | 518 | ||
508 | cleanup: | 519 | cleanup: |
509 | if (rswitch) { | 520 | if (rswitch->route_table) |
510 | kfree(rswitch->route_table); | 521 | kfree(rswitch->route_table); |
511 | kfree(rswitch); | 522 | |
512 | } | ||
513 | kfree(rdev); | 523 | kfree(rdev); |
514 | return NULL; | 524 | return NULL; |
515 | } | 525 | } |
@@ -632,8 +642,7 @@ rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount) | |||
632 | 642 | ||
633 | /** | 643 | /** |
634 | * rio_route_add_entry- Add a route entry to a switch routing table | 644 | * rio_route_add_entry- Add a route entry to a switch routing table |
635 | * @mport: Master port to send transaction | 645 | * @rdev: RIO device |
636 | * @rswitch: Switch device | ||
637 | * @table: Routing table ID | 646 | * @table: Routing table ID |
638 | * @route_destid: Destination ID to be routed | 647 | * @route_destid: Destination ID to be routed |
639 | * @route_port: Port number to be routed | 648 | * @route_port: Port number to be routed |
@@ -647,31 +656,31 @@ rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount) | |||
647 | * on failure. | 656 | * on failure. |
648 | */ | 657 | */ |
649 | static int | 658 | static int |
650 | rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch, | 659 | rio_route_add_entry(struct rio_dev *rdev, |
651 | u16 table, u16 route_destid, u8 route_port, int lock) | 660 | u16 table, u16 route_destid, u8 route_port, int lock) |
652 | { | 661 | { |
653 | int rc; | 662 | int rc; |
654 | 663 | ||
655 | if (lock) { | 664 | if (lock) { |
656 | rc = rio_lock_device(mport, rswitch->destid, | 665 | rc = rio_lock_device(rdev->net->hport, rdev->destid, |
657 | rswitch->hopcount, 1000); | 666 | rdev->hopcount, 1000); |
658 | if (rc) | 667 | if (rc) |
659 | return rc; | 668 | return rc; |
660 | } | 669 | } |
661 | 670 | ||
662 | rc = rswitch->add_entry(mport, rswitch->destid, | 671 | rc = rdev->rswitch->add_entry(rdev->net->hport, rdev->destid, |
663 | rswitch->hopcount, table, | 672 | rdev->hopcount, table, |
664 | route_destid, route_port); | 673 | route_destid, route_port); |
665 | if (lock) | 674 | if (lock) |
666 | rio_unlock_device(mport, rswitch->destid, rswitch->hopcount); | 675 | rio_unlock_device(rdev->net->hport, rdev->destid, |
676 | rdev->hopcount); | ||
667 | 677 | ||
668 | return rc; | 678 | return rc; |
669 | } | 679 | } |
670 | 680 | ||
671 | /** | 681 | /** |
672 | * rio_route_get_entry- Read a route entry in a switch routing table | 682 | * rio_route_get_entry- Read a route entry in a switch routing table |
673 | * @mport: Master port to send transaction | 683 | * @rdev: RIO device |
674 | * @rswitch: Switch device | ||
675 | * @table: Routing table ID | 684 | * @table: Routing table ID |
676 | * @route_destid: Destination ID to be routed | 685 | * @route_destid: Destination ID to be routed |
677 | * @route_port: Pointer to read port number into | 686 | * @route_port: Pointer to read port number into |
@@ -685,23 +694,24 @@ rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch, | |||
685 | * on failure. | 694 | * on failure. |
686 | */ | 695 | */ |
687 | static int | 696 | static int |
688 | rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table, | 697 | rio_route_get_entry(struct rio_dev *rdev, u16 table, |
689 | u16 route_destid, u8 *route_port, int lock) | 698 | u16 route_destid, u8 *route_port, int lock) |
690 | { | 699 | { |
691 | int rc; | 700 | int rc; |
692 | 701 | ||
693 | if (lock) { | 702 | if (lock) { |
694 | rc = rio_lock_device(mport, rswitch->destid, | 703 | rc = rio_lock_device(rdev->net->hport, rdev->destid, |
695 | rswitch->hopcount, 1000); | 704 | rdev->hopcount, 1000); |
696 | if (rc) | 705 | if (rc) |
697 | return rc; | 706 | return rc; |
698 | } | 707 | } |
699 | 708 | ||
700 | rc = rswitch->get_entry(mport, rswitch->destid, | 709 | rc = rdev->rswitch->get_entry(rdev->net->hport, rdev->destid, |
701 | rswitch->hopcount, table, | 710 | rdev->hopcount, table, |
702 | route_destid, route_port); | 711 | route_destid, route_port); |
703 | if (lock) | 712 | if (lock) |
704 | rio_unlock_device(mport, rswitch->destid, rswitch->hopcount); | 713 | rio_unlock_device(rdev->net->hport, rdev->destid, |
714 | rdev->hopcount); | ||
705 | 715 | ||
706 | return rc; | 716 | return rc; |
707 | } | 717 | } |
@@ -809,16 +819,15 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
809 | return -1; | 819 | return -1; |
810 | 820 | ||
811 | if (rio_is_switch(rdev)) { | 821 | if (rio_is_switch(rdev)) { |
812 | next_switchid++; | ||
813 | sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo); | 822 | sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo); |
814 | rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, | 823 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, |
815 | port->host_deviceid, sw_inport, 0); | 824 | port->host_deviceid, sw_inport, 0); |
816 | rdev->rswitch->route_table[port->host_deviceid] = sw_inport; | 825 | rdev->rswitch->route_table[port->host_deviceid] = sw_inport; |
817 | 826 | ||
818 | for (destid = 0; destid < next_destid; destid++) { | 827 | for (destid = 0; destid < next_destid; destid++) { |
819 | if (destid == port->host_deviceid) | 828 | if (destid == port->host_deviceid) |
820 | continue; | 829 | continue; |
821 | rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, | 830 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, |
822 | destid, sw_inport, 0); | 831 | destid, sw_inport, 0); |
823 | rdev->rswitch->route_table[destid] = sw_inport; | 832 | rdev->rswitch->route_table[destid] = sw_inport; |
824 | } | 833 | } |
@@ -850,8 +859,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
850 | "RIO: scanning device on port %d\n", | 859 | "RIO: scanning device on port %d\n", |
851 | port_num); | 860 | port_num); |
852 | rdev->rswitch->port_ok |= (1 << port_num); | 861 | rdev->rswitch->port_ok |= (1 << port_num); |
853 | rio_route_add_entry(port, rdev->rswitch, | 862 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, |
854 | RIO_GLOBAL_TABLE, | ||
855 | RIO_ANY_DESTID(port->sys_size), | 863 | RIO_ANY_DESTID(port->sys_size), |
856 | port_num, 0); | 864 | port_num, 0); |
857 | 865 | ||
@@ -865,7 +873,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
865 | destid < next_destid; destid++) { | 873 | destid < next_destid; destid++) { |
866 | if (destid == port->host_deviceid) | 874 | if (destid == port->host_deviceid) |
867 | continue; | 875 | continue; |
868 | rio_route_add_entry(port, rdev->rswitch, | 876 | rio_route_add_entry(rdev, |
869 | RIO_GLOBAL_TABLE, | 877 | RIO_GLOBAL_TABLE, |
870 | destid, | 878 | destid, |
871 | port_num, | 879 | port_num, |
@@ -904,7 +912,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
904 | next_destid++; | 912 | next_destid++; |
905 | } | 913 | } |
906 | 914 | ||
907 | rdev->rswitch->destid = sw_destid; | 915 | rdev->destid = sw_destid; |
908 | } else | 916 | } else |
909 | pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n", | 917 | pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n", |
910 | rio_name(rdev), rdev->vid, rdev->did); | 918 | rio_name(rdev), rdev->vid, rdev->did); |
@@ -941,7 +949,7 @@ static int rio_enum_complete(struct rio_mport *port) | |||
941 | */ | 949 | */ |
942 | static int __devinit | 950 | static int __devinit |
943 | rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | 951 | rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, |
944 | u8 hopcount) | 952 | u8 hopcount, struct rio_dev *prev, int prev_port) |
945 | { | 953 | { |
946 | u8 port_num, route_port; | 954 | u8 port_num, route_port; |
947 | struct rio_dev *rdev; | 955 | struct rio_dev *rdev; |
@@ -951,14 +959,15 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | |||
951 | if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) { | 959 | if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) { |
952 | /* Add device to the global and bus/net specific list. */ | 960 | /* Add device to the global and bus/net specific list. */ |
953 | list_add_tail(&rdev->net_list, &net->devices); | 961 | list_add_tail(&rdev->net_list, &net->devices); |
962 | rdev->prev = prev; | ||
963 | if (prev && rio_is_switch(prev)) | ||
964 | prev->rswitch->nextdev[prev_port] = rdev; | ||
954 | } else | 965 | } else |
955 | return -1; | 966 | return -1; |
956 | 967 | ||
957 | if (rio_is_switch(rdev)) { | 968 | if (rio_is_switch(rdev)) { |
958 | next_switchid++; | ||
959 | |||
960 | /* Associated destid is how we accessed this switch */ | 969 | /* Associated destid is how we accessed this switch */ |
961 | rdev->rswitch->destid = destid; | 970 | rdev->destid = destid; |
962 | 971 | ||
963 | pr_debug( | 972 | pr_debug( |
964 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", | 973 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", |
@@ -981,7 +990,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | |||
981 | for (ndestid = 0; | 990 | for (ndestid = 0; |
982 | ndestid < RIO_ANY_DESTID(port->sys_size); | 991 | ndestid < RIO_ANY_DESTID(port->sys_size); |
983 | ndestid++) { | 992 | ndestid++) { |
984 | rio_route_get_entry(port, rdev->rswitch, | 993 | rio_route_get_entry(rdev, |
985 | RIO_GLOBAL_TABLE, | 994 | RIO_GLOBAL_TABLE, |
986 | ndestid, | 995 | ndestid, |
987 | &route_port, 0); | 996 | &route_port, 0); |
@@ -992,8 +1001,8 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | |||
992 | if (ndestid == RIO_ANY_DESTID(port->sys_size)) | 1001 | if (ndestid == RIO_ANY_DESTID(port->sys_size)) |
993 | continue; | 1002 | continue; |
994 | rio_unlock_device(port, destid, hopcount); | 1003 | rio_unlock_device(port, destid, hopcount); |
995 | if (rio_disc_peer | 1004 | if (rio_disc_peer(net, port, ndestid, |
996 | (net, port, ndestid, hopcount + 1) < 0) | 1005 | hopcount + 1, rdev, port_num) < 0) |
997 | return -1; | 1006 | return -1; |
998 | } | 1007 | } |
999 | } | 1008 | } |
@@ -1069,14 +1078,14 @@ static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port) | |||
1069 | */ | 1078 | */ |
1070 | static void rio_update_route_tables(struct rio_mport *port) | 1079 | static void rio_update_route_tables(struct rio_mport *port) |
1071 | { | 1080 | { |
1072 | struct rio_dev *rdev; | 1081 | struct rio_dev *rdev, *swrdev; |
1073 | struct rio_switch *rswitch; | 1082 | struct rio_switch *rswitch; |
1074 | u8 sport; | 1083 | u8 sport; |
1075 | u16 destid; | 1084 | u16 destid; |
1076 | 1085 | ||
1077 | list_for_each_entry(rdev, &rio_devices, global_list) { | 1086 | list_for_each_entry(rdev, &rio_devices, global_list) { |
1078 | 1087 | ||
1079 | destid = (rio_is_switch(rdev))?rdev->rswitch->destid:rdev->destid; | 1088 | destid = rdev->destid; |
1080 | 1089 | ||
1081 | list_for_each_entry(rswitch, &rio_switches, node) { | 1090 | list_for_each_entry(rswitch, &rio_switches, node) { |
1082 | 1091 | ||
@@ -1084,14 +1093,16 @@ static void rio_update_route_tables(struct rio_mport *port) | |||
1084 | continue; | 1093 | continue; |
1085 | 1094 | ||
1086 | if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) { | 1095 | if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) { |
1096 | swrdev = sw_to_rio_dev(rswitch); | ||
1097 | |||
1087 | /* Skip if destid ends in empty switch*/ | 1098 | /* Skip if destid ends in empty switch*/ |
1088 | if (rswitch->destid == destid) | 1099 | if (swrdev->destid == destid) |
1089 | continue; | 1100 | continue; |
1090 | 1101 | ||
1091 | sport = RIO_GET_PORT_NUM(rswitch->rdev->swpinfo); | 1102 | sport = RIO_GET_PORT_NUM(swrdev->swpinfo); |
1092 | 1103 | ||
1093 | if (rswitch->add_entry) { | 1104 | if (rswitch->add_entry) { |
1094 | rio_route_add_entry(port, rswitch, | 1105 | rio_route_add_entry(swrdev, |
1095 | RIO_GLOBAL_TABLE, destid, | 1106 | RIO_GLOBAL_TABLE, destid, |
1096 | sport, 0); | 1107 | sport, 0); |
1097 | rswitch->route_table[destid] = sport; | 1108 | rswitch->route_table[destid] = sport; |
@@ -1203,21 +1214,20 @@ static void rio_build_route_tables(void) | |||
1203 | 1214 | ||
1204 | list_for_each_entry(rdev, &rio_devices, global_list) | 1215 | list_for_each_entry(rdev, &rio_devices, global_list) |
1205 | if (rio_is_switch(rdev)) { | 1216 | if (rio_is_switch(rdev)) { |
1206 | rio_lock_device(rdev->net->hport, rdev->rswitch->destid, | 1217 | rio_lock_device(rdev->net->hport, rdev->destid, |
1207 | rdev->rswitch->hopcount, 1000); | 1218 | rdev->hopcount, 1000); |
1208 | for (i = 0; | 1219 | for (i = 0; |
1209 | i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size); | 1220 | i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size); |
1210 | i++) { | 1221 | i++) { |
1211 | if (rio_route_get_entry | 1222 | if (rio_route_get_entry(rdev, |
1212 | (rdev->net->hport, rdev->rswitch, | 1223 | RIO_GLOBAL_TABLE, i, &sport, 0) < 0) |
1213 | RIO_GLOBAL_TABLE, i, &sport, 0) < 0) | ||
1214 | continue; | 1224 | continue; |
1215 | rdev->rswitch->route_table[i] = sport; | 1225 | rdev->rswitch->route_table[i] = sport; |
1216 | } | 1226 | } |
1217 | 1227 | ||
1218 | rio_unlock_device(rdev->net->hport, | 1228 | rio_unlock_device(rdev->net->hport, |
1219 | rdev->rswitch->destid, | 1229 | rdev->destid, |
1220 | rdev->rswitch->hopcount); | 1230 | rdev->hopcount); |
1221 | } | 1231 | } |
1222 | } | 1232 | } |
1223 | 1233 | ||
@@ -1284,7 +1294,7 @@ int __devinit rio_disc_mport(struct rio_mport *mport) | |||
1284 | mport->host_deviceid); | 1294 | mport->host_deviceid); |
1285 | 1295 | ||
1286 | if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size), | 1296 | if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size), |
1287 | 0) < 0) { | 1297 | 0, NULL, 0) < 0) { |
1288 | printk(KERN_INFO | 1298 | printk(KERN_INFO |
1289 | "RIO: master port %d device has failed discovery\n", | 1299 | "RIO: master port %d device has failed discovery\n", |
1290 | mport->id); | 1300 | mport->id); |
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 137ed93ee33..76b41853a87 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c | |||
@@ -217,7 +217,7 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev) | |||
217 | 217 | ||
218 | err = device_create_bin_file(&rdev->dev, &rio_config_attr); | 218 | err = device_create_bin_file(&rdev->dev, &rio_config_attr); |
219 | 219 | ||
220 | if (!err && rdev->rswitch) { | 220 | if (!err && (rdev->pef & RIO_PEF_SWITCH)) { |
221 | err = device_create_file(&rdev->dev, &dev_attr_routes); | 221 | err = device_create_file(&rdev->dev, &dev_attr_routes); |
222 | if (!err && rdev->rswitch->sw_sysfs) | 222 | if (!err && rdev->rswitch->sw_sysfs) |
223 | err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE); | 223 | err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE); |
@@ -239,7 +239,7 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev) | |||
239 | void rio_remove_sysfs_dev_files(struct rio_dev *rdev) | 239 | void rio_remove_sysfs_dev_files(struct rio_dev *rdev) |
240 | { | 240 | { |
241 | device_remove_bin_file(&rdev->dev, &rio_config_attr); | 241 | device_remove_bin_file(&rdev->dev, &rio_config_attr); |
242 | if (rdev->rswitch) { | 242 | if (rdev->pef & RIO_PEF_SWITCH) { |
243 | device_remove_file(&rdev->dev, &dev_attr_routes); | 243 | device_remove_file(&rdev->dev, &dev_attr_routes); |
244 | if (rdev->rswitch->sw_sysfs) | 244 | if (rdev->rswitch->sw_sysfs) |
245 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); | 245 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 7b5080c4556..cc2a3b74d0f 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -471,16 +471,9 @@ exit: | |||
471 | */ | 471 | */ |
472 | int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) | 472 | int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) |
473 | { | 473 | { |
474 | u8 hopcount = 0xff; | ||
475 | u16 destid = rdev->destid; | ||
476 | u32 regval; | 474 | u32 regval; |
477 | 475 | ||
478 | if (rdev->rswitch) { | 476 | rio_read_config_32(rdev, |
479 | destid = rdev->rswitch->destid; | ||
480 | hopcount = rdev->rswitch->hopcount; | ||
481 | } | ||
482 | |||
483 | rio_mport_read_config_32(rdev->net->hport, destid, hopcount, | ||
484 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(pnum), | 477 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(pnum), |
485 | ®val); | 478 | ®val); |
486 | if (lock) | 479 | if (lock) |
@@ -488,7 +481,7 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) | |||
488 | else | 481 | else |
489 | regval &= ~RIO_PORT_N_CTL_LOCKOUT; | 482 | regval &= ~RIO_PORT_N_CTL_LOCKOUT; |
490 | 483 | ||
491 | rio_mport_write_config_32(rdev->net->hport, destid, hopcount, | 484 | rio_write_config_32(rdev, |
492 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(pnum), | 485 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(pnum), |
493 | regval); | 486 | regval); |
494 | return 0; | 487 | return 0; |
@@ -507,7 +500,7 @@ static int | |||
507 | rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) | 500 | rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) |
508 | { | 501 | { |
509 | u32 result; | 502 | u32 result; |
510 | int p_port, dstid, rc = -EIO; | 503 | int p_port, rc = -EIO; |
511 | struct rio_dev *prev = NULL; | 504 | struct rio_dev *prev = NULL; |
512 | 505 | ||
513 | /* Find switch with failed RIO link */ | 506 | /* Find switch with failed RIO link */ |
@@ -522,9 +515,7 @@ rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) | |||
522 | if (prev == NULL) | 515 | if (prev == NULL) |
523 | goto err_out; | 516 | goto err_out; |
524 | 517 | ||
525 | dstid = (rdev->pef & RIO_PEF_SWITCH) ? | 518 | p_port = prev->rswitch->route_table[rdev->destid]; |
526 | rdev->rswitch->destid : rdev->destid; | ||
527 | p_port = prev->rswitch->route_table[dstid]; | ||
528 | 519 | ||
529 | if (p_port != RIO_INVALID_ROUTE) { | 520 | if (p_port != RIO_INVALID_ROUTE) { |
530 | pr_debug("RIO: link failed on [%s]-P%d\n", | 521 | pr_debug("RIO: link failed on [%s]-P%d\n", |
@@ -567,15 +558,8 @@ rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount) | |||
567 | */ | 558 | */ |
568 | static int rio_chk_dev_access(struct rio_dev *rdev) | 559 | static int rio_chk_dev_access(struct rio_dev *rdev) |
569 | { | 560 | { |
570 | u8 hopcount = 0xff; | 561 | return rio_mport_chk_dev_access(rdev->net->hport, |
571 | u16 destid = rdev->destid; | 562 | rdev->destid, rdev->hopcount); |
572 | |||
573 | if (rdev->rswitch) { | ||
574 | destid = rdev->rswitch->destid; | ||
575 | hopcount = rdev->rswitch->hopcount; | ||
576 | } | ||
577 | |||
578 | return rio_mport_chk_dev_access(rdev->net->hport, destid, hopcount); | ||
579 | } | 563 | } |
580 | 564 | ||
581 | /** | 565 | /** |
@@ -588,23 +572,20 @@ static int rio_chk_dev_access(struct rio_dev *rdev) | |||
588 | static int | 572 | static int |
589 | rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) | 573 | rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) |
590 | { | 574 | { |
591 | struct rio_mport *mport = rdev->net->hport; | ||
592 | u16 destid = rdev->rswitch->destid; | ||
593 | u8 hopcount = rdev->rswitch->hopcount; | ||
594 | u32 regval; | 575 | u32 regval; |
595 | int checkcount; | 576 | int checkcount; |
596 | 577 | ||
597 | if (lnkresp) { | 578 | if (lnkresp) { |
598 | /* Read from link maintenance response register | 579 | /* Read from link maintenance response register |
599 | * to clear valid bit */ | 580 | * to clear valid bit */ |
600 | rio_mport_read_config_32(mport, destid, hopcount, | 581 | rio_read_config_32(rdev, |
601 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), | 582 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), |
602 | ®val); | 583 | ®val); |
603 | udelay(50); | 584 | udelay(50); |
604 | } | 585 | } |
605 | 586 | ||
606 | /* Issue Input-status command */ | 587 | /* Issue Input-status command */ |
607 | rio_mport_write_config_32(mport, destid, hopcount, | 588 | rio_write_config_32(rdev, |
608 | rdev->phys_efptr + RIO_PORT_N_MNT_REQ_CSR(pnum), | 589 | rdev->phys_efptr + RIO_PORT_N_MNT_REQ_CSR(pnum), |
609 | RIO_MNT_REQ_CMD_IS); | 590 | RIO_MNT_REQ_CMD_IS); |
610 | 591 | ||
@@ -615,7 +596,7 @@ rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) | |||
615 | checkcount = 3; | 596 | checkcount = 3; |
616 | while (checkcount--) { | 597 | while (checkcount--) { |
617 | udelay(50); | 598 | udelay(50); |
618 | rio_mport_read_config_32(mport, destid, hopcount, | 599 | rio_read_config_32(rdev, |
619 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), | 600 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), |
620 | ®val); | 601 | ®val); |
621 | if (regval & RIO_PORT_N_MNT_RSP_RVAL) { | 602 | if (regval & RIO_PORT_N_MNT_RSP_RVAL) { |
@@ -635,15 +616,12 @@ rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) | |||
635 | */ | 616 | */ |
636 | static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | 617 | static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) |
637 | { | 618 | { |
638 | struct rio_mport *mport = rdev->net->hport; | ||
639 | u16 destid = rdev->rswitch->destid; | ||
640 | u8 hopcount = rdev->rswitch->hopcount; | ||
641 | struct rio_dev *nextdev = rdev->rswitch->nextdev[pnum]; | 619 | struct rio_dev *nextdev = rdev->rswitch->nextdev[pnum]; |
642 | u32 regval; | 620 | u32 regval; |
643 | u32 far_ackid, far_linkstat, near_ackid; | 621 | u32 far_ackid, far_linkstat, near_ackid; |
644 | 622 | ||
645 | if (err_status == 0) | 623 | if (err_status == 0) |
646 | rio_mport_read_config_32(mport, destid, hopcount, | 624 | rio_read_config_32(rdev, |
647 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | 625 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), |
648 | &err_status); | 626 | &err_status); |
649 | 627 | ||
@@ -661,7 +639,7 @@ static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | |||
661 | pnum, regval); | 639 | pnum, regval); |
662 | far_ackid = (regval & RIO_PORT_N_MNT_RSP_ASTAT) >> 5; | 640 | far_ackid = (regval & RIO_PORT_N_MNT_RSP_ASTAT) >> 5; |
663 | far_linkstat = regval & RIO_PORT_N_MNT_RSP_LSTAT; | 641 | far_linkstat = regval & RIO_PORT_N_MNT_RSP_LSTAT; |
664 | rio_mport_read_config_32(mport, destid, hopcount, | 642 | rio_read_config_32(rdev, |
665 | rdev->phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum), | 643 | rdev->phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum), |
666 | ®val); | 644 | ®val); |
667 | pr_debug("RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n", pnum, regval); | 645 | pr_debug("RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n", pnum, regval); |
@@ -679,9 +657,8 @@ static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | |||
679 | /* Align near outstanding/outbound ackIDs with | 657 | /* Align near outstanding/outbound ackIDs with |
680 | * far inbound. | 658 | * far inbound. |
681 | */ | 659 | */ |
682 | rio_mport_write_config_32(mport, destid, | 660 | rio_write_config_32(rdev, |
683 | hopcount, rdev->phys_efptr + | 661 | rdev->phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum), |
684 | RIO_PORT_N_ACK_STS_CSR(pnum), | ||
685 | (near_ackid << 24) | | 662 | (near_ackid << 24) | |
686 | (far_ackid << 8) | far_ackid); | 663 | (far_ackid << 8) | far_ackid); |
687 | /* Align far outstanding/outbound ackIDs with | 664 | /* Align far outstanding/outbound ackIDs with |
@@ -698,7 +675,7 @@ static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | |||
698 | pr_debug("RIO_EM: Invalid nextdev pointer (NULL)\n"); | 675 | pr_debug("RIO_EM: Invalid nextdev pointer (NULL)\n"); |
699 | } | 676 | } |
700 | rd_err: | 677 | rd_err: |
701 | rio_mport_read_config_32(mport, destid, hopcount, | 678 | rio_read_config_32(rdev, |
702 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | 679 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), |
703 | &err_status); | 680 | &err_status); |
704 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); | 681 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); |
@@ -710,7 +687,7 @@ rd_err: | |||
710 | RIO_GET_PORT_NUM(nextdev->swpinfo), NULL); | 687 | RIO_GET_PORT_NUM(nextdev->swpinfo), NULL); |
711 | udelay(50); | 688 | udelay(50); |
712 | 689 | ||
713 | rio_mport_read_config_32(mport, destid, hopcount, | 690 | rio_read_config_32(rdev, |
714 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | 691 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), |
715 | &err_status); | 692 | &err_status); |
716 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); | 693 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); |
@@ -730,13 +707,10 @@ rd_err: | |||
730 | int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | 707 | int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) |
731 | { | 708 | { |
732 | struct rio_dev *rdev; | 709 | struct rio_dev *rdev; |
733 | struct rio_mport *mport; | ||
734 | u8 hopcount; | ||
735 | u16 destid; | ||
736 | u32 err_status, em_perrdet, em_ltlerrdet; | 710 | u32 err_status, em_perrdet, em_ltlerrdet; |
737 | int rc, portnum; | 711 | int rc, portnum; |
738 | 712 | ||
739 | rdev = rio_get_comptag(pw_msg->em.comptag, NULL); | 713 | rdev = rio_get_comptag((pw_msg->em.comptag & RIO_CTAG_UDEVID), NULL); |
740 | if (rdev == NULL) { | 714 | if (rdev == NULL) { |
741 | /* Device removed or enumeration error */ | 715 | /* Device removed or enumeration error */ |
742 | pr_debug("RIO: %s No matching device for CTag 0x%08x\n", | 716 | pr_debug("RIO: %s No matching device for CTag 0x%08x\n", |
@@ -800,17 +774,13 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
800 | return 0; | 774 | return 0; |
801 | } | 775 | } |
802 | 776 | ||
803 | mport = rdev->net->hport; | ||
804 | destid = rdev->rswitch->destid; | ||
805 | hopcount = rdev->rswitch->hopcount; | ||
806 | |||
807 | /* | 777 | /* |
808 | * Process the port-write notification from switch | 778 | * Process the port-write notification from switch |
809 | */ | 779 | */ |
810 | if (rdev->rswitch->em_handle) | 780 | if (rdev->rswitch->em_handle) |
811 | rdev->rswitch->em_handle(rdev, portnum); | 781 | rdev->rswitch->em_handle(rdev, portnum); |
812 | 782 | ||
813 | rio_mport_read_config_32(mport, destid, hopcount, | 783 | rio_read_config_32(rdev, |
814 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 784 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), |
815 | &err_status); | 785 | &err_status); |
816 | pr_debug("RIO_PW: SP%d_ERR_STS_CSR=0x%08x\n", portnum, err_status); | 786 | pr_debug("RIO_PW: SP%d_ERR_STS_CSR=0x%08x\n", portnum, err_status); |
@@ -840,7 +810,7 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
840 | rdev->rswitch->port_ok &= ~(1 << portnum); | 810 | rdev->rswitch->port_ok &= ~(1 << portnum); |
841 | rio_set_port_lockout(rdev, portnum, 1); | 811 | rio_set_port_lockout(rdev, portnum, 1); |
842 | 812 | ||
843 | rio_mport_write_config_32(mport, destid, hopcount, | 813 | rio_write_config_32(rdev, |
844 | rdev->phys_efptr + | 814 | rdev->phys_efptr + |
845 | RIO_PORT_N_ACK_STS_CSR(portnum), | 815 | RIO_PORT_N_ACK_STS_CSR(portnum), |
846 | RIO_PORT_N_ACK_CLEAR); | 816 | RIO_PORT_N_ACK_CLEAR); |
@@ -851,28 +821,28 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
851 | } | 821 | } |
852 | } | 822 | } |
853 | 823 | ||
854 | rio_mport_read_config_32(mport, destid, hopcount, | 824 | rio_read_config_32(rdev, |
855 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet); | 825 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet); |
856 | if (em_perrdet) { | 826 | if (em_perrdet) { |
857 | pr_debug("RIO_PW: RIO_EM_P%d_ERR_DETECT=0x%08x\n", | 827 | pr_debug("RIO_PW: RIO_EM_P%d_ERR_DETECT=0x%08x\n", |
858 | portnum, em_perrdet); | 828 | portnum, em_perrdet); |
859 | /* Clear EM Port N Error Detect CSR */ | 829 | /* Clear EM Port N Error Detect CSR */ |
860 | rio_mport_write_config_32(mport, destid, hopcount, | 830 | rio_write_config_32(rdev, |
861 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), 0); | 831 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), 0); |
862 | } | 832 | } |
863 | 833 | ||
864 | rio_mport_read_config_32(mport, destid, hopcount, | 834 | rio_read_config_32(rdev, |
865 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet); | 835 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet); |
866 | if (em_ltlerrdet) { | 836 | if (em_ltlerrdet) { |
867 | pr_debug("RIO_PW: RIO_EM_LTL_ERR_DETECT=0x%08x\n", | 837 | pr_debug("RIO_PW: RIO_EM_LTL_ERR_DETECT=0x%08x\n", |
868 | em_ltlerrdet); | 838 | em_ltlerrdet); |
869 | /* Clear EM L/T Layer Error Detect CSR */ | 839 | /* Clear EM L/T Layer Error Detect CSR */ |
870 | rio_mport_write_config_32(mport, destid, hopcount, | 840 | rio_write_config_32(rdev, |
871 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, 0); | 841 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, 0); |
872 | } | 842 | } |
873 | 843 | ||
874 | /* Clear remaining error bits and Port-Write Pending bit */ | 844 | /* Clear remaining error bits and Port-Write Pending bit */ |
875 | rio_mport_write_config_32(mport, destid, hopcount, | 845 | rio_write_config_32(rdev, |
876 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 846 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), |
877 | err_status); | 847 | err_status); |
878 | 848 | ||
diff --git a/drivers/rapidio/switches/idt_gen2.c b/drivers/rapidio/switches/idt_gen2.c index 0bb871cb5c4..095016a9dec 100644 --- a/drivers/rapidio/switches/idt_gen2.c +++ b/drivers/rapidio/switches/idt_gen2.c | |||
@@ -209,9 +209,6 @@ idtg2_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
209 | static int | 209 | static int |
210 | idtg2_em_init(struct rio_dev *rdev) | 210 | idtg2_em_init(struct rio_dev *rdev) |
211 | { | 211 | { |
212 | struct rio_mport *mport = rdev->net->hport; | ||
213 | u16 destid = rdev->rswitch->destid; | ||
214 | u8 hopcount = rdev->rswitch->hopcount; | ||
215 | u32 regval; | 212 | u32 regval; |
216 | int i, tmp; | 213 | int i, tmp; |
217 | 214 | ||
@@ -220,29 +217,25 @@ idtg2_em_init(struct rio_dev *rdev) | |||
220 | * All standard EM configuration should be performed at upper level. | 217 | * All standard EM configuration should be performed at upper level. |
221 | */ | 218 | */ |
222 | 219 | ||
223 | pr_debug("RIO: %s [%d:%d]\n", __func__, destid, hopcount); | 220 | pr_debug("RIO: %s [%d:%d]\n", __func__, rdev->destid, rdev->hopcount); |
224 | 221 | ||
225 | /* Set Port-Write info CSR: PRIO=3 and CRF=1 */ | 222 | /* Set Port-Write info CSR: PRIO=3 and CRF=1 */ |
226 | rio_mport_write_config_32(mport, destid, hopcount, | 223 | rio_write_config_32(rdev, IDT_PW_INFO_CSR, 0x0000e000); |
227 | IDT_PW_INFO_CSR, 0x0000e000); | ||
228 | 224 | ||
229 | /* | 225 | /* |
230 | * Configure LT LAYER error reporting. | 226 | * Configure LT LAYER error reporting. |
231 | */ | 227 | */ |
232 | 228 | ||
233 | /* Enable standard (RIO.p8) error reporting */ | 229 | /* Enable standard (RIO.p8) error reporting */ |
234 | rio_mport_write_config_32(mport, destid, hopcount, | 230 | rio_write_config_32(rdev, IDT_LT_ERR_REPORT_EN, |
235 | IDT_LT_ERR_REPORT_EN, | ||
236 | REM_LTL_ERR_ILLTRAN | REM_LTL_ERR_UNSOLR | | 231 | REM_LTL_ERR_ILLTRAN | REM_LTL_ERR_UNSOLR | |
237 | REM_LTL_ERR_UNSUPTR); | 232 | REM_LTL_ERR_UNSUPTR); |
238 | 233 | ||
239 | /* Use Port-Writes for LT layer error reporting. | 234 | /* Use Port-Writes for LT layer error reporting. |
240 | * Enable per-port reset | 235 | * Enable per-port reset |
241 | */ | 236 | */ |
242 | rio_mport_read_config_32(mport, destid, hopcount, | 237 | rio_read_config_32(rdev, IDT_DEV_CTRL_1, ®val); |
243 | IDT_DEV_CTRL_1, ®val); | 238 | rio_write_config_32(rdev, IDT_DEV_CTRL_1, |
244 | rio_mport_write_config_32(mport, destid, hopcount, | ||
245 | IDT_DEV_CTRL_1, | ||
246 | regval | IDT_DEV_CTRL_1_GENPW | IDT_DEV_CTRL_1_PRSTBEH); | 239 | regval | IDT_DEV_CTRL_1_GENPW | IDT_DEV_CTRL_1_PRSTBEH); |
247 | 240 | ||
248 | /* | 241 | /* |
@@ -250,45 +243,40 @@ idtg2_em_init(struct rio_dev *rdev) | |||
250 | */ | 243 | */ |
251 | 244 | ||
252 | /* Report all RIO.p8 errors supported by device */ | 245 | /* Report all RIO.p8 errors supported by device */ |
253 | rio_mport_write_config_32(mport, destid, hopcount, | 246 | rio_write_config_32(rdev, IDT_PORT_ERR_REPORT_EN_BC, 0x807e8037); |
254 | IDT_PORT_ERR_REPORT_EN_BC, 0x807e8037); | ||
255 | 247 | ||
256 | /* Configure reporting of implementation specific errors/events */ | 248 | /* Configure reporting of implementation specific errors/events */ |
257 | rio_mport_write_config_32(mport, destid, hopcount, | 249 | rio_write_config_32(rdev, IDT_PORT_ISERR_REPORT_EN_BC, |
258 | IDT_PORT_ISERR_REPORT_EN_BC, IDT_PORT_INIT_TX_ACQUIRED); | 250 | IDT_PORT_INIT_TX_ACQUIRED); |
259 | 251 | ||
260 | /* Use Port-Writes for port error reporting and enable error logging */ | 252 | /* Use Port-Writes for port error reporting and enable error logging */ |
261 | tmp = RIO_GET_TOTAL_PORTS(rdev->swpinfo); | 253 | tmp = RIO_GET_TOTAL_PORTS(rdev->swpinfo); |
262 | for (i = 0; i < tmp; i++) { | 254 | for (i = 0; i < tmp; i++) { |
263 | rio_mport_read_config_32(mport, destid, hopcount, | 255 | rio_read_config_32(rdev, IDT_PORT_OPS(i), ®val); |
264 | IDT_PORT_OPS(i), ®val); | 256 | rio_write_config_32(rdev, |
265 | rio_mport_write_config_32(mport, destid, hopcount, | ||
266 | IDT_PORT_OPS(i), regval | IDT_PORT_OPS_GENPW | | 257 | IDT_PORT_OPS(i), regval | IDT_PORT_OPS_GENPW | |
267 | IDT_PORT_OPS_PL_ELOG | | 258 | IDT_PORT_OPS_PL_ELOG | |
268 | IDT_PORT_OPS_LL_ELOG | | 259 | IDT_PORT_OPS_LL_ELOG | |
269 | IDT_PORT_OPS_LT_ELOG); | 260 | IDT_PORT_OPS_LT_ELOG); |
270 | } | 261 | } |
271 | /* Overwrite error log if full */ | 262 | /* Overwrite error log if full */ |
272 | rio_mport_write_config_32(mport, destid, hopcount, | 263 | rio_write_config_32(rdev, IDT_ERR_CAP, IDT_ERR_CAP_LOG_OVERWR); |
273 | IDT_ERR_CAP, IDT_ERR_CAP_LOG_OVERWR); | ||
274 | 264 | ||
275 | /* | 265 | /* |
276 | * Configure LANE error reporting. | 266 | * Configure LANE error reporting. |
277 | */ | 267 | */ |
278 | 268 | ||
279 | /* Disable line error reporting */ | 269 | /* Disable line error reporting */ |
280 | rio_mport_write_config_32(mport, destid, hopcount, | 270 | rio_write_config_32(rdev, IDT_LANE_ERR_REPORT_EN_BC, 0); |
281 | IDT_LANE_ERR_REPORT_EN_BC, 0); | ||
282 | 271 | ||
283 | /* Use Port-Writes for lane error reporting (when enabled) | 272 | /* Use Port-Writes for lane error reporting (when enabled) |
284 | * (do per-lane update because lanes may have different configuration) | 273 | * (do per-lane update because lanes may have different configuration) |
285 | */ | 274 | */ |
286 | tmp = (rdev->did == RIO_DID_IDTCPS1848) ? 48 : 16; | 275 | tmp = (rdev->did == RIO_DID_IDTCPS1848) ? 48 : 16; |
287 | for (i = 0; i < tmp; i++) { | 276 | for (i = 0; i < tmp; i++) { |
288 | rio_mport_read_config_32(mport, destid, hopcount, | 277 | rio_read_config_32(rdev, IDT_LANE_CTRL(i), ®val); |
289 | IDT_LANE_CTRL(i), ®val); | 278 | rio_write_config_32(rdev, IDT_LANE_CTRL(i), |
290 | rio_mport_write_config_32(mport, destid, hopcount, | 279 | regval | IDT_LANE_CTRL_GENPW); |
291 | IDT_LANE_CTRL(i), regval | IDT_LANE_CTRL_GENPW); | ||
292 | } | 280 | } |
293 | 281 | ||
294 | /* | 282 | /* |
@@ -296,41 +284,32 @@ idtg2_em_init(struct rio_dev *rdev) | |||
296 | */ | 284 | */ |
297 | 285 | ||
298 | /* Disable JTAG and I2C Error capture */ | 286 | /* Disable JTAG and I2C Error capture */ |
299 | rio_mport_write_config_32(mport, destid, hopcount, | 287 | rio_write_config_32(rdev, IDT_AUX_PORT_ERR_CAP_EN, 0); |
300 | IDT_AUX_PORT_ERR_CAP_EN, 0); | ||
301 | 288 | ||
302 | /* Disable JTAG and I2C Error reporting/logging */ | 289 | /* Disable JTAG and I2C Error reporting/logging */ |
303 | rio_mport_write_config_32(mport, destid, hopcount, | 290 | rio_write_config_32(rdev, IDT_AUX_ERR_REPORT_EN, 0); |
304 | IDT_AUX_ERR_REPORT_EN, 0); | ||
305 | 291 | ||
306 | /* Disable Port-Write notification from JTAG */ | 292 | /* Disable Port-Write notification from JTAG */ |
307 | rio_mport_write_config_32(mport, destid, hopcount, | 293 | rio_write_config_32(rdev, IDT_JTAG_CTRL, 0); |
308 | IDT_JTAG_CTRL, 0); | ||
309 | 294 | ||
310 | /* Disable Port-Write notification from I2C */ | 295 | /* Disable Port-Write notification from I2C */ |
311 | rio_mport_read_config_32(mport, destid, hopcount, | 296 | rio_read_config_32(rdev, IDT_I2C_MCTRL, ®val); |
312 | IDT_I2C_MCTRL, ®val); | 297 | rio_write_config_32(rdev, IDT_I2C_MCTRL, regval & ~IDT_I2C_MCTRL_GENPW); |
313 | rio_mport_write_config_32(mport, destid, hopcount, | ||
314 | IDT_I2C_MCTRL, | ||
315 | regval & ~IDT_I2C_MCTRL_GENPW); | ||
316 | 298 | ||
317 | /* | 299 | /* |
318 | * Configure CFG_BLK error reporting. | 300 | * Configure CFG_BLK error reporting. |
319 | */ | 301 | */ |
320 | 302 | ||
321 | /* Disable Configuration Block error capture */ | 303 | /* Disable Configuration Block error capture */ |
322 | rio_mport_write_config_32(mport, destid, hopcount, | 304 | rio_write_config_32(rdev, IDT_CFGBLK_ERR_CAPTURE_EN, 0); |
323 | IDT_CFGBLK_ERR_CAPTURE_EN, 0); | ||
324 | 305 | ||
325 | /* Disable Port-Writes for Configuration Block error reporting */ | 306 | /* Disable Port-Writes for Configuration Block error reporting */ |
326 | rio_mport_read_config_32(mport, destid, hopcount, | 307 | rio_read_config_32(rdev, IDT_CFGBLK_ERR_REPORT, ®val); |
327 | IDT_CFGBLK_ERR_REPORT, ®val); | 308 | rio_write_config_32(rdev, IDT_CFGBLK_ERR_REPORT, |
328 | rio_mport_write_config_32(mport, destid, hopcount, | 309 | regval & ~IDT_CFGBLK_ERR_REPORT_GENPW); |
329 | IDT_CFGBLK_ERR_REPORT, | ||
330 | regval & ~IDT_CFGBLK_ERR_REPORT_GENPW); | ||
331 | 310 | ||
332 | /* set TVAL = ~50us */ | 311 | /* set TVAL = ~50us */ |
333 | rio_mport_write_config_32(mport, destid, hopcount, | 312 | rio_write_config_32(rdev, |
334 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); | 313 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); |
335 | 314 | ||
336 | return 0; | 315 | return 0; |
@@ -339,18 +318,15 @@ idtg2_em_init(struct rio_dev *rdev) | |||
339 | static int | 318 | static int |
340 | idtg2_em_handler(struct rio_dev *rdev, u8 portnum) | 319 | idtg2_em_handler(struct rio_dev *rdev, u8 portnum) |
341 | { | 320 | { |
342 | struct rio_mport *mport = rdev->net->hport; | ||
343 | u16 destid = rdev->rswitch->destid; | ||
344 | u8 hopcount = rdev->rswitch->hopcount; | ||
345 | u32 regval, em_perrdet, em_ltlerrdet; | 321 | u32 regval, em_perrdet, em_ltlerrdet; |
346 | 322 | ||
347 | rio_mport_read_config_32(mport, destid, hopcount, | 323 | rio_read_config_32(rdev, |
348 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet); | 324 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet); |
349 | if (em_ltlerrdet) { | 325 | if (em_ltlerrdet) { |
350 | /* Service Logical/Transport Layer Error(s) */ | 326 | /* Service Logical/Transport Layer Error(s) */ |
351 | if (em_ltlerrdet & REM_LTL_ERR_IMPSPEC) { | 327 | if (em_ltlerrdet & REM_LTL_ERR_IMPSPEC) { |
352 | /* Implementation specific error reported */ | 328 | /* Implementation specific error reported */ |
353 | rio_mport_read_config_32(mport, destid, hopcount, | 329 | rio_read_config_32(rdev, |
354 | IDT_ISLTL_ADDRESS_CAP, ®val); | 330 | IDT_ISLTL_ADDRESS_CAP, ®val); |
355 | 331 | ||
356 | pr_debug("RIO: %s Implementation Specific LTL errors" \ | 332 | pr_debug("RIO: %s Implementation Specific LTL errors" \ |
@@ -358,13 +334,12 @@ idtg2_em_handler(struct rio_dev *rdev, u8 portnum) | |||
358 | rio_name(rdev), em_ltlerrdet, regval); | 334 | rio_name(rdev), em_ltlerrdet, regval); |
359 | 335 | ||
360 | /* Clear implementation specific address capture CSR */ | 336 | /* Clear implementation specific address capture CSR */ |
361 | rio_mport_write_config_32(mport, destid, hopcount, | 337 | rio_write_config_32(rdev, IDT_ISLTL_ADDRESS_CAP, 0); |
362 | IDT_ISLTL_ADDRESS_CAP, 0); | ||
363 | 338 | ||
364 | } | 339 | } |
365 | } | 340 | } |
366 | 341 | ||
367 | rio_mport_read_config_32(mport, destid, hopcount, | 342 | rio_read_config_32(rdev, |
368 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet); | 343 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet); |
369 | if (em_perrdet) { | 344 | if (em_perrdet) { |
370 | /* Service Port-Level Error(s) */ | 345 | /* Service Port-Level Error(s) */ |
@@ -372,14 +347,14 @@ idtg2_em_handler(struct rio_dev *rdev, u8 portnum) | |||
372 | /* Implementation Specific port error reported */ | 347 | /* Implementation Specific port error reported */ |
373 | 348 | ||
374 | /* Get IS errors reported */ | 349 | /* Get IS errors reported */ |
375 | rio_mport_read_config_32(mport, destid, hopcount, | 350 | rio_read_config_32(rdev, |
376 | IDT_PORT_ISERR_DET(portnum), ®val); | 351 | IDT_PORT_ISERR_DET(portnum), ®val); |
377 | 352 | ||
378 | pr_debug("RIO: %s Implementation Specific Port" \ | 353 | pr_debug("RIO: %s Implementation Specific Port" \ |
379 | " errors 0x%x\n", rio_name(rdev), regval); | 354 | " errors 0x%x\n", rio_name(rdev), regval); |
380 | 355 | ||
381 | /* Clear all implementation specific events */ | 356 | /* Clear all implementation specific events */ |
382 | rio_mport_write_config_32(mport, destid, hopcount, | 357 | rio_write_config_32(rdev, |
383 | IDT_PORT_ISERR_DET(portnum), 0); | 358 | IDT_PORT_ISERR_DET(portnum), 0); |
384 | } | 359 | } |
385 | } | 360 | } |
@@ -391,14 +366,10 @@ static ssize_t | |||
391 | idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf) | 366 | idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf) |
392 | { | 367 | { |
393 | struct rio_dev *rdev = to_rio_dev(dev); | 368 | struct rio_dev *rdev = to_rio_dev(dev); |
394 | struct rio_mport *mport = rdev->net->hport; | ||
395 | u16 destid = rdev->rswitch->destid; | ||
396 | u8 hopcount = rdev->rswitch->hopcount; | ||
397 | ssize_t len = 0; | 369 | ssize_t len = 0; |
398 | u32 regval; | 370 | u32 regval; |
399 | 371 | ||
400 | while (!rio_mport_read_config_32(mport, destid, hopcount, | 372 | while (!rio_read_config_32(rdev, IDT_ERR_RD, ®val)) { |
401 | IDT_ERR_RD, ®val)) { | ||
402 | if (!regval) /* 0 = end of log */ | 373 | if (!regval) /* 0 = end of log */ |
403 | break; | 374 | break; |
404 | len += snprintf(buf + len, PAGE_SIZE - len, | 375 | len += snprintf(buf + len, PAGE_SIZE - len, |
@@ -445,3 +416,5 @@ static int idtg2_switch_init(struct rio_dev *rdev, int do_enum) | |||
445 | 416 | ||
446 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1848, idtg2_switch_init); | 417 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1848, idtg2_switch_init); |
447 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init); | 418 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init); |
419 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTVPS1616, idtg2_switch_init); | ||
420 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTSPS1616, idtg2_switch_init); | ||
diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c index fc9f6374f75..3a971077e7b 100644 --- a/drivers/rapidio/switches/idtcps.c +++ b/drivers/rapidio/switches/idtcps.c | |||
@@ -117,10 +117,6 @@ idtcps_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
117 | 117 | ||
118 | static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) | 118 | static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) |
119 | { | 119 | { |
120 | struct rio_mport *mport = rdev->net->hport; | ||
121 | u16 destid = rdev->rswitch->destid; | ||
122 | u8 hopcount = rdev->rswitch->hopcount; | ||
123 | |||
124 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); | 120 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
125 | rdev->rswitch->add_entry = idtcps_route_add_entry; | 121 | rdev->rswitch->add_entry = idtcps_route_add_entry; |
126 | rdev->rswitch->get_entry = idtcps_route_get_entry; | 122 | rdev->rswitch->get_entry = idtcps_route_get_entry; |
@@ -132,7 +128,7 @@ static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) | |||
132 | 128 | ||
133 | if (do_enum) { | 129 | if (do_enum) { |
134 | /* set TVAL = ~50us */ | 130 | /* set TVAL = ~50us */ |
135 | rio_mport_write_config_32(mport, destid, hopcount, | 131 | rio_write_config_32(rdev, |
136 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); | 132 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); |
137 | } | 133 | } |
138 | 134 | ||
diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c index b9a389b9f81..3994c00aa01 100644 --- a/drivers/rapidio/switches/tsi568.c +++ b/drivers/rapidio/switches/tsi568.c | |||
@@ -113,22 +113,17 @@ tsi568_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
113 | static int | 113 | static int |
114 | tsi568_em_init(struct rio_dev *rdev) | 114 | tsi568_em_init(struct rio_dev *rdev) |
115 | { | 115 | { |
116 | struct rio_mport *mport = rdev->net->hport; | ||
117 | u16 destid = rdev->rswitch->destid; | ||
118 | u8 hopcount = rdev->rswitch->hopcount; | ||
119 | u32 regval; | 116 | u32 regval; |
120 | int portnum; | 117 | int portnum; |
121 | 118 | ||
122 | pr_debug("TSI568 %s [%d:%d]\n", __func__, destid, hopcount); | 119 | pr_debug("TSI568 %s [%d:%d]\n", __func__, rdev->destid, rdev->hopcount); |
123 | 120 | ||
124 | /* Make sure that Port-Writes are disabled (for all ports) */ | 121 | /* Make sure that Port-Writes are disabled (for all ports) */ |
125 | for (portnum = 0; | 122 | for (portnum = 0; |
126 | portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) { | 123 | portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) { |
127 | rio_mport_read_config_32(mport, destid, hopcount, | 124 | rio_read_config_32(rdev, TSI568_SP_MODE(portnum), ®val); |
128 | TSI568_SP_MODE(portnum), ®val); | 125 | rio_write_config_32(rdev, TSI568_SP_MODE(portnum), |
129 | rio_mport_write_config_32(mport, destid, hopcount, | 126 | regval | TSI568_SP_MODE_PW_DIS); |
130 | TSI568_SP_MODE(portnum), | ||
131 | regval | TSI568_SP_MODE_PW_DIS); | ||
132 | } | 127 | } |
133 | 128 | ||
134 | return 0; | 129 | return 0; |
diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c index 2003fb63c40..1a62934bfeb 100644 --- a/drivers/rapidio/switches/tsi57x.c +++ b/drivers/rapidio/switches/tsi57x.c | |||
@@ -158,48 +158,45 @@ tsi57x_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
158 | static int | 158 | static int |
159 | tsi57x_em_init(struct rio_dev *rdev) | 159 | tsi57x_em_init(struct rio_dev *rdev) |
160 | { | 160 | { |
161 | struct rio_mport *mport = rdev->net->hport; | ||
162 | u16 destid = rdev->rswitch->destid; | ||
163 | u8 hopcount = rdev->rswitch->hopcount; | ||
164 | u32 regval; | 161 | u32 regval; |
165 | int portnum; | 162 | int portnum; |
166 | 163 | ||
167 | pr_debug("TSI578 %s [%d:%d]\n", __func__, destid, hopcount); | 164 | pr_debug("TSI578 %s [%d:%d]\n", __func__, rdev->destid, rdev->hopcount); |
168 | 165 | ||
169 | for (portnum = 0; | 166 | for (portnum = 0; |
170 | portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) { | 167 | portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) { |
171 | /* Make sure that Port-Writes are enabled (for all ports) */ | 168 | /* Make sure that Port-Writes are enabled (for all ports) */ |
172 | rio_mport_read_config_32(mport, destid, hopcount, | 169 | rio_read_config_32(rdev, |
173 | TSI578_SP_MODE(portnum), ®val); | 170 | TSI578_SP_MODE(portnum), ®val); |
174 | rio_mport_write_config_32(mport, destid, hopcount, | 171 | rio_write_config_32(rdev, |
175 | TSI578_SP_MODE(portnum), | 172 | TSI578_SP_MODE(portnum), |
176 | regval & ~TSI578_SP_MODE_PW_DIS); | 173 | regval & ~TSI578_SP_MODE_PW_DIS); |
177 | 174 | ||
178 | /* Clear all pending interrupts */ | 175 | /* Clear all pending interrupts */ |
179 | rio_mport_read_config_32(mport, destid, hopcount, | 176 | rio_read_config_32(rdev, |
180 | rdev->phys_efptr + | 177 | rdev->phys_efptr + |
181 | RIO_PORT_N_ERR_STS_CSR(portnum), | 178 | RIO_PORT_N_ERR_STS_CSR(portnum), |
182 | ®val); | 179 | ®val); |
183 | rio_mport_write_config_32(mport, destid, hopcount, | 180 | rio_write_config_32(rdev, |
184 | rdev->phys_efptr + | 181 | rdev->phys_efptr + |
185 | RIO_PORT_N_ERR_STS_CSR(portnum), | 182 | RIO_PORT_N_ERR_STS_CSR(portnum), |
186 | regval & 0x07120214); | 183 | regval & 0x07120214); |
187 | 184 | ||
188 | rio_mport_read_config_32(mport, destid, hopcount, | 185 | rio_read_config_32(rdev, |
189 | TSI578_SP_INT_STATUS(portnum), ®val); | 186 | TSI578_SP_INT_STATUS(portnum), ®val); |
190 | rio_mport_write_config_32(mport, destid, hopcount, | 187 | rio_write_config_32(rdev, |
191 | TSI578_SP_INT_STATUS(portnum), | 188 | TSI578_SP_INT_STATUS(portnum), |
192 | regval & 0x000700bd); | 189 | regval & 0x000700bd); |
193 | 190 | ||
194 | /* Enable all interrupts to allow ports to send a port-write */ | 191 | /* Enable all interrupts to allow ports to send a port-write */ |
195 | rio_mport_read_config_32(mport, destid, hopcount, | 192 | rio_read_config_32(rdev, |
196 | TSI578_SP_CTL_INDEP(portnum), ®val); | 193 | TSI578_SP_CTL_INDEP(portnum), ®val); |
197 | rio_mport_write_config_32(mport, destid, hopcount, | 194 | rio_write_config_32(rdev, |
198 | TSI578_SP_CTL_INDEP(portnum), | 195 | TSI578_SP_CTL_INDEP(portnum), |
199 | regval | 0x000b0000); | 196 | regval | 0x000b0000); |
200 | 197 | ||
201 | /* Skip next (odd) port if the current port is in x4 mode */ | 198 | /* Skip next (odd) port if the current port is in x4 mode */ |
202 | rio_mport_read_config_32(mport, destid, hopcount, | 199 | rio_read_config_32(rdev, |
203 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), | 200 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), |
204 | ®val); | 201 | ®val); |
205 | if ((regval & RIO_PORT_N_CTL_PWIDTH) == RIO_PORT_N_CTL_PWIDTH_4) | 202 | if ((regval & RIO_PORT_N_CTL_PWIDTH) == RIO_PORT_N_CTL_PWIDTH_4) |
@@ -207,7 +204,7 @@ tsi57x_em_init(struct rio_dev *rdev) | |||
207 | } | 204 | } |
208 | 205 | ||
209 | /* set TVAL = ~50us */ | 206 | /* set TVAL = ~50us */ |
210 | rio_mport_write_config_32(mport, destid, hopcount, | 207 | rio_write_config_32(rdev, |
211 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x9a << 8); | 208 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x9a << 8); |
212 | 209 | ||
213 | return 0; | 210 | return 0; |
@@ -217,14 +214,12 @@ static int | |||
217 | tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) | 214 | tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) |
218 | { | 215 | { |
219 | struct rio_mport *mport = rdev->net->hport; | 216 | struct rio_mport *mport = rdev->net->hport; |
220 | u16 destid = rdev->rswitch->destid; | ||
221 | u8 hopcount = rdev->rswitch->hopcount; | ||
222 | u32 intstat, err_status; | 217 | u32 intstat, err_status; |
223 | int sendcount, checkcount; | 218 | int sendcount, checkcount; |
224 | u8 route_port; | 219 | u8 route_port; |
225 | u32 regval; | 220 | u32 regval; |
226 | 221 | ||
227 | rio_mport_read_config_32(mport, destid, hopcount, | 222 | rio_read_config_32(rdev, |
228 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 223 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), |
229 | &err_status); | 224 | &err_status); |
230 | 225 | ||
@@ -232,15 +227,15 @@ tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) | |||
232 | (err_status & (RIO_PORT_N_ERR_STS_PW_OUT_ES | | 227 | (err_status & (RIO_PORT_N_ERR_STS_PW_OUT_ES | |
233 | RIO_PORT_N_ERR_STS_PW_INP_ES))) { | 228 | RIO_PORT_N_ERR_STS_PW_INP_ES))) { |
234 | /* Remove any queued packets by locking/unlocking port */ | 229 | /* Remove any queued packets by locking/unlocking port */ |
235 | rio_mport_read_config_32(mport, destid, hopcount, | 230 | rio_read_config_32(rdev, |
236 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), | 231 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), |
237 | ®val); | 232 | ®val); |
238 | if (!(regval & RIO_PORT_N_CTL_LOCKOUT)) { | 233 | if (!(regval & RIO_PORT_N_CTL_LOCKOUT)) { |
239 | rio_mport_write_config_32(mport, destid, hopcount, | 234 | rio_write_config_32(rdev, |
240 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), | 235 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), |
241 | regval | RIO_PORT_N_CTL_LOCKOUT); | 236 | regval | RIO_PORT_N_CTL_LOCKOUT); |
242 | udelay(50); | 237 | udelay(50); |
243 | rio_mport_write_config_32(mport, destid, hopcount, | 238 | rio_write_config_32(rdev, |
244 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), | 239 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), |
245 | regval); | 240 | regval); |
246 | } | 241 | } |
@@ -248,7 +243,7 @@ tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) | |||
248 | /* Read from link maintenance response register to clear | 243 | /* Read from link maintenance response register to clear |
249 | * valid bit | 244 | * valid bit |
250 | */ | 245 | */ |
251 | rio_mport_read_config_32(mport, destid, hopcount, | 246 | rio_read_config_32(rdev, |
252 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(portnum), | 247 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(portnum), |
253 | ®val); | 248 | ®val); |
254 | 249 | ||
@@ -257,13 +252,12 @@ tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) | |||
257 | */ | 252 | */ |
258 | sendcount = 3; | 253 | sendcount = 3; |
259 | while (sendcount) { | 254 | while (sendcount) { |
260 | rio_mport_write_config_32(mport, destid, hopcount, | 255 | rio_write_config_32(rdev, |
261 | TSI578_SP_CS_TX(portnum), 0x40fc8000); | 256 | TSI578_SP_CS_TX(portnum), 0x40fc8000); |
262 | checkcount = 3; | 257 | checkcount = 3; |
263 | while (checkcount--) { | 258 | while (checkcount--) { |
264 | udelay(50); | 259 | udelay(50); |
265 | rio_mport_read_config_32( | 260 | rio_read_config_32(rdev, |
266 | mport, destid, hopcount, | ||
267 | rdev->phys_efptr + | 261 | rdev->phys_efptr + |
268 | RIO_PORT_N_MNT_RSP_CSR(portnum), | 262 | RIO_PORT_N_MNT_RSP_CSR(portnum), |
269 | ®val); | 263 | ®val); |
@@ -277,25 +271,23 @@ tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) | |||
277 | 271 | ||
278 | exit_es: | 272 | exit_es: |
279 | /* Clear implementation specific error status bits */ | 273 | /* Clear implementation specific error status bits */ |
280 | rio_mport_read_config_32(mport, destid, hopcount, | 274 | rio_read_config_32(rdev, TSI578_SP_INT_STATUS(portnum), &intstat); |
281 | TSI578_SP_INT_STATUS(portnum), &intstat); | ||
282 | pr_debug("TSI578[%x:%x] SP%d_INT_STATUS=0x%08x\n", | 275 | pr_debug("TSI578[%x:%x] SP%d_INT_STATUS=0x%08x\n", |
283 | destid, hopcount, portnum, intstat); | 276 | rdev->destid, rdev->hopcount, portnum, intstat); |
284 | 277 | ||
285 | if (intstat & 0x10000) { | 278 | if (intstat & 0x10000) { |
286 | rio_mport_read_config_32(mport, destid, hopcount, | 279 | rio_read_config_32(rdev, |
287 | TSI578_SP_LUT_PEINF(portnum), ®val); | 280 | TSI578_SP_LUT_PEINF(portnum), ®val); |
288 | regval = (mport->sys_size) ? (regval >> 16) : (regval >> 24); | 281 | regval = (mport->sys_size) ? (regval >> 16) : (regval >> 24); |
289 | route_port = rdev->rswitch->route_table[regval]; | 282 | route_port = rdev->rswitch->route_table[regval]; |
290 | pr_debug("RIO: TSI578[%s] P%d LUT Parity Error (destID=%d)\n", | 283 | pr_debug("RIO: TSI578[%s] P%d LUT Parity Error (destID=%d)\n", |
291 | rio_name(rdev), portnum, regval); | 284 | rio_name(rdev), portnum, regval); |
292 | tsi57x_route_add_entry(mport, destid, hopcount, | 285 | tsi57x_route_add_entry(mport, rdev->destid, rdev->hopcount, |
293 | RIO_GLOBAL_TABLE, regval, route_port); | 286 | RIO_GLOBAL_TABLE, regval, route_port); |
294 | } | 287 | } |
295 | 288 | ||
296 | rio_mport_write_config_32(mport, destid, hopcount, | 289 | rio_write_config_32(rdev, TSI578_SP_INT_STATUS(portnum), |
297 | TSI578_SP_INT_STATUS(portnum), | 290 | intstat & 0x000700bd); |
298 | intstat & 0x000700bd); | ||
299 | 291 | ||
300 | return 0; | 292 | return 0; |
301 | } | 293 | } |
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 2ce2eb71d0f..dd6308499bd 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
@@ -249,7 +249,7 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
249 | } | 249 | } |
250 | 250 | ||
251 | static int pm8607_set_voltage(struct regulator_dev *rdev, | 251 | static int pm8607_set_voltage(struct regulator_dev *rdev, |
252 | int min_uV, int max_uV) | 252 | int min_uV, int max_uV, unsigned *selector) |
253 | { | 253 | { |
254 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 254 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
255 | uint8_t val, mask; | 255 | uint8_t val, mask; |
@@ -263,6 +263,7 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, | |||
263 | ret = choose_voltage(rdev, min_uV, max_uV); | 263 | ret = choose_voltage(rdev, min_uV, max_uV); |
264 | if (ret < 0) | 264 | if (ret < 0) |
265 | return -EINVAL; | 265 | return -EINVAL; |
266 | *selector = ret; | ||
266 | val = (uint8_t)(ret << info->vol_shift); | 267 | val = (uint8_t)(ret << info->vol_shift); |
267 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 268 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
268 | 269 | ||
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index dd30e883d4a..e1d943619ab 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -186,13 +186,25 @@ config REGULATOR_PCAP | |||
186 | This driver provides support for the voltage regulators of the | 186 | This driver provides support for the voltage regulators of the |
187 | PCAP2 PMIC. | 187 | PCAP2 PMIC. |
188 | 188 | ||
189 | config REGULATOR_MC13XXX_CORE | ||
190 | tristate | ||
191 | |||
189 | config REGULATOR_MC13783 | 192 | config REGULATOR_MC13783 |
190 | tristate "Support regulators on Freescale MC13783 PMIC" | 193 | tristate "Support regulators on Freescale MC13783 PMIC" |
191 | depends on MFD_MC13783 | 194 | depends on MFD_MC13783 |
195 | select REGULATOR_MC13XXX_CORE | ||
192 | help | 196 | help |
193 | Say y here to support the regulators found on the Freescale MC13783 | 197 | Say y here to support the regulators found on the Freescale MC13783 |
194 | PMIC. | 198 | PMIC. |
195 | 199 | ||
200 | config REGULATOR_MC13892 | ||
201 | tristate "Support regulators on Freescale MC13892 PMIC" | ||
202 | depends on MFD_MC13XXX | ||
203 | select REGULATOR_MC13XXX_CORE | ||
204 | help | ||
205 | Say y here to support the regulators found on the Freescale MC13892 | ||
206 | PMIC. | ||
207 | |||
196 | config REGULATOR_AB3100 | 208 | config REGULATOR_AB3100 |
197 | tristate "ST-Ericsson AB3100 Regulator functions" | 209 | tristate "ST-Ericsson AB3100 Regulator functions" |
198 | depends on AB3100_CORE | 210 | depends on AB3100_CORE |
@@ -250,5 +262,15 @@ config REGULATOR_TPS6586X | |||
250 | help | 262 | help |
251 | This driver supports TPS6586X voltage regulator chips. | 263 | This driver supports TPS6586X voltage regulator chips. |
252 | 264 | ||
265 | config REGULATOR_TPS6524X | ||
266 | tristate "TI TPS6524X Power regulators" | ||
267 | depends on SPI | ||
268 | help | ||
269 | This driver supports TPS6524X voltage regulator chips. TPS6524X | ||
270 | provides three step-down converters and two general-purpose LDO | ||
271 | voltage regulators. This device is interfaced using a customized | ||
272 | serial interface currently supported on the sequencer serial | ||
273 | port controller. | ||
274 | |||
253 | endif | 275 | endif |
254 | 276 | ||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index bff81573678..0b5e88c2b8d 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -30,10 +30,13 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | |||
30 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | 30 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o |
31 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | 31 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
32 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o | 32 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o |
33 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o | ||
34 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o | ||
33 | obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o | 35 | obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o |
34 | 36 | ||
35 | obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o | 37 | obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o |
36 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o | 38 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o |
39 | obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o | ||
37 | obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o | 40 | obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o |
38 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o | 41 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o |
39 | obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o | 42 | obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index b349266a43d..ed6feaf9398 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
@@ -362,7 +362,8 @@ static int ab3100_get_best_voltage_index(struct regulator_dev *reg, | |||
362 | } | 362 | } |
363 | 363 | ||
364 | static int ab3100_set_voltage_regulator(struct regulator_dev *reg, | 364 | static int ab3100_set_voltage_regulator(struct regulator_dev *reg, |
365 | int min_uV, int max_uV) | 365 | int min_uV, int max_uV, |
366 | unsigned *selector) | ||
366 | { | 367 | { |
367 | struct ab3100_regulator *abreg = reg->reg_data; | 368 | struct ab3100_regulator *abreg = reg->reg_data; |
368 | u8 regval; | 369 | u8 regval; |
@@ -373,6 +374,8 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg, | |||
373 | if (bestindex < 0) | 374 | if (bestindex < 0) |
374 | return bestindex; | 375 | return bestindex; |
375 | 376 | ||
377 | *selector = bestindex; | ||
378 | |||
376 | err = abx500_get_register_interruptible(abreg->dev, 0, | 379 | err = abx500_get_register_interruptible(abreg->dev, 0, |
377 | abreg->regreg, ®val); | 380 | abreg->regreg, ®val); |
378 | if (err) { | 381 | if (err) { |
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index db6b70f2051..d9a052c53ae 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
@@ -3,18 +3,13 @@ | |||
3 | * | 3 | * |
4 | * License Terms: GNU General Public License v2 | 4 | * License Terms: GNU General Public License v2 |
5 | * | 5 | * |
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | 6 | * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson |
7 | * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson | ||
7 | * | 8 | * |
8 | * AB8500 peripheral regulators | 9 | * AB8500 peripheral regulators |
9 | * | 10 | * |
10 | * AB8500 supports the following regulators, | 11 | * AB8500 supports the following regulators: |
11 | * LDOs - VAUDIO, VANAMIC2/2, VDIGMIC, VINTCORE12, VTVOUT, | 12 | * VAUX1/2/3, VINTCORE, VTVOUT, VAUDIO, VAMIC1/2, VDMIC, VANA |
12 | * VAUX1/2/3, VANA | ||
13 | * | ||
14 | * for DB8500 cut 1.0 and previous versions of the silicon, all accesses | ||
15 | * to registers are through the DB8500 SPI. In cut 1.1 onwards, these | ||
16 | * accesses are through the DB8500 PRCMU I2C | ||
17 | * | ||
18 | */ | 13 | */ |
19 | #include <linux/init.h> | 14 | #include <linux/init.h> |
20 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
@@ -28,38 +23,37 @@ | |||
28 | 23 | ||
29 | /** | 24 | /** |
30 | * struct ab8500_regulator_info - ab8500 regulator information | 25 | * struct ab8500_regulator_info - ab8500 regulator information |
26 | * @dev: device pointer | ||
31 | * @desc: regulator description | 27 | * @desc: regulator description |
32 | * @ab8500: ab8500 parent | ||
33 | * @regulator_dev: regulator device | 28 | * @regulator_dev: regulator device |
34 | * @max_uV: maximum voltage (for variable voltage supplies) | 29 | * @max_uV: maximum voltage (for variable voltage supplies) |
35 | * @min_uV: minimum voltage (for variable voltage supplies) | 30 | * @min_uV: minimum voltage (for variable voltage supplies) |
36 | * @fixed_uV: typical voltage (for fixed voltage supplies) | 31 | * @fixed_uV: typical voltage (for fixed voltage supplies) |
37 | * @update_bank: bank to control on/off | 32 | * @update_bank: bank to control on/off |
38 | * @update_reg: register to control on/off | 33 | * @update_reg: register to control on/off |
39 | * @mask: mask to enable/disable regulator | 34 | * @update_mask: mask to enable/disable regulator |
40 | * @enable: bits to enable the regulator in normal(high power) mode | 35 | * @update_val_enable: bits to enable the regulator in normal (high power) mode |
41 | * @voltage_bank: bank to control regulator voltage | 36 | * @voltage_bank: bank to control regulator voltage |
42 | * @voltage_reg: register to control regulator voltage | 37 | * @voltage_reg: register to control regulator voltage |
43 | * @voltage_mask: mask to control regulator voltage | 38 | * @voltage_mask: mask to control regulator voltage |
44 | * @supported_voltages: supported voltage table | 39 | * @voltages: supported voltage table |
45 | * @voltages_len: number of supported voltages for the regulator | 40 | * @voltages_len: number of supported voltages for the regulator |
46 | */ | 41 | */ |
47 | struct ab8500_regulator_info { | 42 | struct ab8500_regulator_info { |
48 | struct device *dev; | 43 | struct device *dev; |
49 | struct regulator_desc desc; | 44 | struct regulator_desc desc; |
50 | struct ab8500 *ab8500; | ||
51 | struct regulator_dev *regulator; | 45 | struct regulator_dev *regulator; |
52 | int max_uV; | 46 | int max_uV; |
53 | int min_uV; | 47 | int min_uV; |
54 | int fixed_uV; | 48 | int fixed_uV; |
55 | u8 update_bank; | 49 | u8 update_bank; |
56 | u8 update_reg; | 50 | u8 update_reg; |
57 | u8 mask; | 51 | u8 update_mask; |
58 | u8 enable; | 52 | u8 update_val_enable; |
59 | u8 voltage_bank; | 53 | u8 voltage_bank; |
60 | u8 voltage_reg; | 54 | u8 voltage_reg; |
61 | u8 voltage_mask; | 55 | u8 voltage_mask; |
62 | int const *supported_voltages; | 56 | int const *voltages; |
63 | int voltages_len; | 57 | int voltages_len; |
64 | }; | 58 | }; |
65 | 59 | ||
@@ -83,6 +77,17 @@ static const int ldo_vauxn_voltages[] = { | |||
83 | 3300000, | 77 | 3300000, |
84 | }; | 78 | }; |
85 | 79 | ||
80 | static const int ldo_vaux3_voltages[] = { | ||
81 | 1200000, | ||
82 | 1500000, | ||
83 | 1800000, | ||
84 | 2100000, | ||
85 | 2500000, | ||
86 | 2750000, | ||
87 | 2790000, | ||
88 | 2910000, | ||
89 | }; | ||
90 | |||
86 | static const int ldo_vintcore_voltages[] = { | 91 | static const int ldo_vintcore_voltages[] = { |
87 | 1200000, | 92 | 1200000, |
88 | 1225000, | 93 | 1225000, |
@@ -95,57 +100,80 @@ static const int ldo_vintcore_voltages[] = { | |||
95 | 100 | ||
96 | static int ab8500_regulator_enable(struct regulator_dev *rdev) | 101 | static int ab8500_regulator_enable(struct regulator_dev *rdev) |
97 | { | 102 | { |
98 | int regulator_id, ret; | 103 | int ret; |
99 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | 104 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); |
100 | 105 | ||
101 | regulator_id = rdev_get_id(rdev); | 106 | if (info == NULL) { |
102 | if (regulator_id >= AB8500_NUM_REGULATORS) | 107 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); |
103 | return -EINVAL; | 108 | return -EINVAL; |
109 | } | ||
104 | 110 | ||
105 | ret = abx500_mask_and_set_register_interruptible(info->dev, | 111 | ret = abx500_mask_and_set_register_interruptible(info->dev, |
106 | info->update_bank, info->update_reg, info->mask, info->enable); | 112 | info->update_bank, info->update_reg, |
113 | info->update_mask, info->update_val_enable); | ||
107 | if (ret < 0) | 114 | if (ret < 0) |
108 | dev_err(rdev_get_dev(rdev), | 115 | dev_err(rdev_get_dev(rdev), |
109 | "couldn't set enable bits for regulator\n"); | 116 | "couldn't set enable bits for regulator\n"); |
117 | |||
118 | dev_vdbg(rdev_get_dev(rdev), | ||
119 | "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", | ||
120 | info->desc.name, info->update_bank, info->update_reg, | ||
121 | info->update_mask, info->update_val_enable); | ||
122 | |||
110 | return ret; | 123 | return ret; |
111 | } | 124 | } |
112 | 125 | ||
113 | static int ab8500_regulator_disable(struct regulator_dev *rdev) | 126 | static int ab8500_regulator_disable(struct regulator_dev *rdev) |
114 | { | 127 | { |
115 | int regulator_id, ret; | 128 | int ret; |
116 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | 129 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); |
117 | 130 | ||
118 | regulator_id = rdev_get_id(rdev); | 131 | if (info == NULL) { |
119 | if (regulator_id >= AB8500_NUM_REGULATORS) | 132 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); |
120 | return -EINVAL; | 133 | return -EINVAL; |
134 | } | ||
121 | 135 | ||
122 | ret = abx500_mask_and_set_register_interruptible(info->dev, | 136 | ret = abx500_mask_and_set_register_interruptible(info->dev, |
123 | info->update_bank, info->update_reg, info->mask, 0x0); | 137 | info->update_bank, info->update_reg, |
138 | info->update_mask, 0x0); | ||
124 | if (ret < 0) | 139 | if (ret < 0) |
125 | dev_err(rdev_get_dev(rdev), | 140 | dev_err(rdev_get_dev(rdev), |
126 | "couldn't set disable bits for regulator\n"); | 141 | "couldn't set disable bits for regulator\n"); |
142 | |||
143 | dev_vdbg(rdev_get_dev(rdev), | ||
144 | "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", | ||
145 | info->desc.name, info->update_bank, info->update_reg, | ||
146 | info->update_mask, 0x0); | ||
147 | |||
127 | return ret; | 148 | return ret; |
128 | } | 149 | } |
129 | 150 | ||
130 | static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) | 151 | static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) |
131 | { | 152 | { |
132 | int regulator_id, ret; | 153 | int ret; |
133 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | 154 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); |
134 | u8 value; | 155 | u8 regval; |
135 | 156 | ||
136 | regulator_id = rdev_get_id(rdev); | 157 | if (info == NULL) { |
137 | if (regulator_id >= AB8500_NUM_REGULATORS) | 158 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); |
138 | return -EINVAL; | 159 | return -EINVAL; |
160 | } | ||
139 | 161 | ||
140 | ret = abx500_get_register_interruptible(info->dev, | 162 | ret = abx500_get_register_interruptible(info->dev, |
141 | info->update_bank, info->update_reg, &value); | 163 | info->update_bank, info->update_reg, ®val); |
142 | if (ret < 0) { | 164 | if (ret < 0) { |
143 | dev_err(rdev_get_dev(rdev), | 165 | dev_err(rdev_get_dev(rdev), |
144 | "couldn't read 0x%x register\n", info->update_reg); | 166 | "couldn't read 0x%x register\n", info->update_reg); |
145 | return ret; | 167 | return ret; |
146 | } | 168 | } |
147 | 169 | ||
148 | if (value & info->mask) | 170 | dev_vdbg(rdev_get_dev(rdev), |
171 | "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," | ||
172 | " 0x%x\n", | ||
173 | info->desc.name, info->update_bank, info->update_reg, | ||
174 | info->update_mask, regval); | ||
175 | |||
176 | if (regval & info->update_mask) | ||
149 | return true; | 177 | return true; |
150 | else | 178 | else |
151 | return false; | 179 | return false; |
@@ -153,12 +181,12 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) | |||
153 | 181 | ||
154 | static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) | 182 | static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) |
155 | { | 183 | { |
156 | int regulator_id; | ||
157 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | 184 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); |
158 | 185 | ||
159 | regulator_id = rdev_get_id(rdev); | 186 | if (info == NULL) { |
160 | if (regulator_id >= AB8500_NUM_REGULATORS) | 187 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); |
161 | return -EINVAL; | 188 | return -EINVAL; |
189 | } | ||
162 | 190 | ||
163 | /* return the uV for the fixed regulators */ | 191 | /* return the uV for the fixed regulators */ |
164 | if (info->fixed_uV) | 192 | if (info->fixed_uV) |
@@ -167,33 +195,40 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) | |||
167 | if (selector >= info->voltages_len) | 195 | if (selector >= info->voltages_len) |
168 | return -EINVAL; | 196 | return -EINVAL; |
169 | 197 | ||
170 | return info->supported_voltages[selector]; | 198 | return info->voltages[selector]; |
171 | } | 199 | } |
172 | 200 | ||
173 | static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) | 201 | static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) |
174 | { | 202 | { |
175 | int regulator_id, ret; | 203 | int ret, val; |
176 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | 204 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); |
177 | u8 value; | 205 | u8 regval; |
178 | 206 | ||
179 | regulator_id = rdev_get_id(rdev); | 207 | if (info == NULL) { |
180 | if (regulator_id >= AB8500_NUM_REGULATORS) | 208 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); |
181 | return -EINVAL; | 209 | return -EINVAL; |
210 | } | ||
182 | 211 | ||
183 | ret = abx500_get_register_interruptible(info->dev, info->voltage_bank, | 212 | ret = abx500_get_register_interruptible(info->dev, |
184 | info->voltage_reg, &value); | 213 | info->voltage_bank, info->voltage_reg, ®val); |
185 | if (ret < 0) { | 214 | if (ret < 0) { |
186 | dev_err(rdev_get_dev(rdev), | 215 | dev_err(rdev_get_dev(rdev), |
187 | "couldn't read voltage reg for regulator\n"); | 216 | "couldn't read voltage reg for regulator\n"); |
188 | return ret; | 217 | return ret; |
189 | } | 218 | } |
190 | 219 | ||
220 | dev_vdbg(rdev_get_dev(rdev), | ||
221 | "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," | ||
222 | " 0x%x\n", | ||
223 | info->desc.name, info->voltage_bank, info->voltage_reg, | ||
224 | info->voltage_mask, regval); | ||
225 | |||
191 | /* vintcore has a different layout */ | 226 | /* vintcore has a different layout */ |
192 | value &= info->voltage_mask; | 227 | val = regval & info->voltage_mask; |
193 | if (regulator_id == AB8500_LDO_INTCORE) | 228 | if (info->desc.id == AB8500_LDO_INTCORE) |
194 | ret = info->supported_voltages[value >> 0x3]; | 229 | ret = info->voltages[val >> 0x3]; |
195 | else | 230 | else |
196 | ret = info->supported_voltages[value]; | 231 | ret = info->voltages[val]; |
197 | 232 | ||
198 | return ret; | 233 | return ret; |
199 | } | 234 | } |
@@ -206,8 +241,8 @@ static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, | |||
206 | 241 | ||
207 | /* check the supported voltage */ | 242 | /* check the supported voltage */ |
208 | for (i = 0; i < info->voltages_len; i++) { | 243 | for (i = 0; i < info->voltages_len; i++) { |
209 | if ((info->supported_voltages[i] >= min_uV) && | 244 | if ((info->voltages[i] >= min_uV) && |
210 | (info->supported_voltages[i] <= max_uV)) | 245 | (info->voltages[i] <= max_uV)) |
211 | return i; | 246 | return i; |
212 | } | 247 | } |
213 | 248 | ||
@@ -215,14 +250,17 @@ static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, | |||
215 | } | 250 | } |
216 | 251 | ||
217 | static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, | 252 | static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, |
218 | int min_uV, int max_uV) | 253 | int min_uV, int max_uV, |
254 | unsigned *selector) | ||
219 | { | 255 | { |
220 | int regulator_id, ret; | 256 | int ret; |
221 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | 257 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); |
258 | u8 regval; | ||
222 | 259 | ||
223 | regulator_id = rdev_get_id(rdev); | 260 | if (info == NULL) { |
224 | if (regulator_id >= AB8500_NUM_REGULATORS) | 261 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); |
225 | return -EINVAL; | 262 | return -EINVAL; |
263 | } | ||
226 | 264 | ||
227 | /* get the appropriate voltages within the range */ | 265 | /* get the appropriate voltages within the range */ |
228 | ret = ab8500_get_best_voltage_index(rdev, min_uV, max_uV); | 266 | ret = ab8500_get_best_voltage_index(rdev, min_uV, max_uV); |
@@ -232,14 +270,23 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, | |||
232 | return ret; | 270 | return ret; |
233 | } | 271 | } |
234 | 272 | ||
273 | *selector = ret; | ||
274 | |||
235 | /* set the registers for the request */ | 275 | /* set the registers for the request */ |
276 | regval = (u8)ret; | ||
236 | ret = abx500_mask_and_set_register_interruptible(info->dev, | 277 | ret = abx500_mask_and_set_register_interruptible(info->dev, |
237 | info->voltage_bank, info->voltage_reg, | 278 | info->voltage_bank, info->voltage_reg, |
238 | info->voltage_mask, (u8)ret); | 279 | info->voltage_mask, regval); |
239 | if (ret < 0) | 280 | if (ret < 0) |
240 | dev_err(rdev_get_dev(rdev), | 281 | dev_err(rdev_get_dev(rdev), |
241 | "couldn't set voltage reg for regulator\n"); | 282 | "couldn't set voltage reg for regulator\n"); |
242 | 283 | ||
284 | dev_vdbg(rdev_get_dev(rdev), | ||
285 | "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," | ||
286 | " 0x%x\n", | ||
287 | info->desc.name, info->voltage_bank, info->voltage_reg, | ||
288 | info->voltage_mask, regval); | ||
289 | |||
243 | return ret; | 290 | return ret; |
244 | } | 291 | } |
245 | 292 | ||
@@ -254,17 +301,17 @@ static struct regulator_ops ab8500_regulator_ops = { | |||
254 | 301 | ||
255 | static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) | 302 | static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) |
256 | { | 303 | { |
257 | int regulator_id; | ||
258 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | 304 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); |
259 | 305 | ||
260 | regulator_id = rdev_get_id(rdev); | 306 | if (info == NULL) { |
261 | if (regulator_id >= AB8500_NUM_REGULATORS) | 307 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); |
262 | return -EINVAL; | 308 | return -EINVAL; |
309 | } | ||
263 | 310 | ||
264 | return info->fixed_uV; | 311 | return info->fixed_uV; |
265 | } | 312 | } |
266 | 313 | ||
267 | static struct regulator_ops ab8500_ldo_fixed_ops = { | 314 | static struct regulator_ops ab8500_regulator_fixed_ops = { |
268 | .enable = ab8500_regulator_enable, | 315 | .enable = ab8500_regulator_enable, |
269 | .disable = ab8500_regulator_disable, | 316 | .disable = ab8500_regulator_disable, |
270 | .is_enabled = ab8500_regulator_is_enabled, | 317 | .is_enabled = ab8500_regulator_is_enabled, |
@@ -272,88 +319,197 @@ static struct regulator_ops ab8500_ldo_fixed_ops = { | |||
272 | .list_voltage = ab8500_list_voltage, | 319 | .list_voltage = ab8500_list_voltage, |
273 | }; | 320 | }; |
274 | 321 | ||
275 | #define AB8500_LDO(_id, min, max, bank, reg, reg_mask, \ | 322 | static struct ab8500_regulator_info |
276 | reg_enable, volt_bank, volt_reg, volt_mask, \ | 323 | ab8500_regulator_info[AB8500_NUM_REGULATORS] = { |
277 | voltages, len_volts) \ | ||
278 | { \ | ||
279 | .desc = { \ | ||
280 | .name = "LDO-" #_id, \ | ||
281 | .ops = &ab8500_regulator_ops, \ | ||
282 | .type = REGULATOR_VOLTAGE, \ | ||
283 | .id = AB8500_LDO_##_id, \ | ||
284 | .owner = THIS_MODULE, \ | ||
285 | }, \ | ||
286 | .min_uV = (min) * 1000, \ | ||
287 | .max_uV = (max) * 1000, \ | ||
288 | .update_bank = bank, \ | ||
289 | .update_reg = reg, \ | ||
290 | .mask = reg_mask, \ | ||
291 | .enable = reg_enable, \ | ||
292 | .voltage_bank = volt_bank, \ | ||
293 | .voltage_reg = volt_reg, \ | ||
294 | .voltage_mask = volt_mask, \ | ||
295 | .supported_voltages = voltages, \ | ||
296 | .voltages_len = len_volts, \ | ||
297 | .fixed_uV = 0, \ | ||
298 | } | ||
299 | |||
300 | #define AB8500_FIXED_LDO(_id, fixed, bank, reg, \ | ||
301 | reg_mask, reg_enable) \ | ||
302 | { \ | ||
303 | .desc = { \ | ||
304 | .name = "LDO-" #_id, \ | ||
305 | .ops = &ab8500_ldo_fixed_ops, \ | ||
306 | .type = REGULATOR_VOLTAGE, \ | ||
307 | .id = AB8500_LDO_##_id, \ | ||
308 | .owner = THIS_MODULE, \ | ||
309 | }, \ | ||
310 | .fixed_uV = fixed * 1000, \ | ||
311 | .update_bank = bank, \ | ||
312 | .update_reg = reg, \ | ||
313 | .mask = reg_mask, \ | ||
314 | .enable = reg_enable, \ | ||
315 | } | ||
316 | |||
317 | static struct ab8500_regulator_info ab8500_regulator_info[] = { | ||
318 | /* | 324 | /* |
319 | * Variable Voltage LDOs | 325 | * Variable Voltage Regulators |
320 | * name, min uV, max uV, ctrl bank, ctrl reg, reg mask, enable mask, | 326 | * name, min mV, max mV, |
321 | * volt ctrl bank, volt ctrl reg, volt ctrl mask, volt table, | 327 | * update bank, reg, mask, enable val |
322 | * num supported volts | 328 | * volt bank, reg, mask, table, table length |
323 | */ | 329 | */ |
324 | AB8500_LDO(AUX1, 1100, 3300, 0x04, 0x09, 0x3, 0x1, 0x04, 0x1f, 0xf, | 330 | [AB8500_LDO_AUX1] = { |
325 | ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), | 331 | .desc = { |
326 | AB8500_LDO(AUX2, 1100, 3300, 0x04, 0x09, 0xc, 0x4, 0x04, 0x20, 0xf, | 332 | .name = "LDO-AUX1", |
327 | ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), | 333 | .ops = &ab8500_regulator_ops, |
328 | AB8500_LDO(AUX3, 1100, 3300, 0x04, 0x0a, 0x3, 0x1, 0x04, 0x21, 0xf, | 334 | .type = REGULATOR_VOLTAGE, |
329 | ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), | 335 | .id = AB8500_LDO_AUX1, |
330 | AB8500_LDO(INTCORE, 1100, 3300, 0x03, 0x80, 0x4, 0x4, 0x03, 0x80, 0x38, | 336 | .owner = THIS_MODULE, |
331 | ldo_vintcore_voltages, ARRAY_SIZE(ldo_vintcore_voltages)), | 337 | .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), |
338 | }, | ||
339 | .min_uV = 1100000, | ||
340 | .max_uV = 3300000, | ||
341 | .update_bank = 0x04, | ||
342 | .update_reg = 0x09, | ||
343 | .update_mask = 0x03, | ||
344 | .update_val_enable = 0x01, | ||
345 | .voltage_bank = 0x04, | ||
346 | .voltage_reg = 0x1f, | ||
347 | .voltage_mask = 0x0f, | ||
348 | .voltages = ldo_vauxn_voltages, | ||
349 | .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), | ||
350 | }, | ||
351 | [AB8500_LDO_AUX2] = { | ||
352 | .desc = { | ||
353 | .name = "LDO-AUX2", | ||
354 | .ops = &ab8500_regulator_ops, | ||
355 | .type = REGULATOR_VOLTAGE, | ||
356 | .id = AB8500_LDO_AUX2, | ||
357 | .owner = THIS_MODULE, | ||
358 | .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), | ||
359 | }, | ||
360 | .min_uV = 1100000, | ||
361 | .max_uV = 3300000, | ||
362 | .update_bank = 0x04, | ||
363 | .update_reg = 0x09, | ||
364 | .update_mask = 0x0c, | ||
365 | .update_val_enable = 0x04, | ||
366 | .voltage_bank = 0x04, | ||
367 | .voltage_reg = 0x20, | ||
368 | .voltage_mask = 0x0f, | ||
369 | .voltages = ldo_vauxn_voltages, | ||
370 | .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), | ||
371 | }, | ||
372 | [AB8500_LDO_AUX3] = { | ||
373 | .desc = { | ||
374 | .name = "LDO-AUX3", | ||
375 | .ops = &ab8500_regulator_ops, | ||
376 | .type = REGULATOR_VOLTAGE, | ||
377 | .id = AB8500_LDO_AUX3, | ||
378 | .owner = THIS_MODULE, | ||
379 | .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages), | ||
380 | }, | ||
381 | .min_uV = 1100000, | ||
382 | .max_uV = 3300000, | ||
383 | .update_bank = 0x04, | ||
384 | .update_reg = 0x0a, | ||
385 | .update_mask = 0x03, | ||
386 | .update_val_enable = 0x01, | ||
387 | .voltage_bank = 0x04, | ||
388 | .voltage_reg = 0x21, | ||
389 | .voltage_mask = 0x07, | ||
390 | .voltages = ldo_vaux3_voltages, | ||
391 | .voltages_len = ARRAY_SIZE(ldo_vaux3_voltages), | ||
392 | }, | ||
393 | [AB8500_LDO_INTCORE] = { | ||
394 | .desc = { | ||
395 | .name = "LDO-INTCORE", | ||
396 | .ops = &ab8500_regulator_ops, | ||
397 | .type = REGULATOR_VOLTAGE, | ||
398 | .id = AB8500_LDO_INTCORE, | ||
399 | .owner = THIS_MODULE, | ||
400 | .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), | ||
401 | }, | ||
402 | .min_uV = 1100000, | ||
403 | .max_uV = 3300000, | ||
404 | .update_bank = 0x03, | ||
405 | .update_reg = 0x80, | ||
406 | .update_mask = 0x44, | ||
407 | .update_val_enable = 0x04, | ||
408 | .voltage_bank = 0x03, | ||
409 | .voltage_reg = 0x80, | ||
410 | .voltage_mask = 0x38, | ||
411 | .voltages = ldo_vintcore_voltages, | ||
412 | .voltages_len = ARRAY_SIZE(ldo_vintcore_voltages), | ||
413 | }, | ||
332 | 414 | ||
333 | /* | 415 | /* |
334 | * Fixed Voltage LDOs | 416 | * Fixed Voltage Regulators |
335 | * name, o/p uV, ctrl bank, ctrl reg, enable, disable | 417 | * name, fixed mV, |
418 | * update bank, reg, mask, enable val | ||
336 | */ | 419 | */ |
337 | AB8500_FIXED_LDO(TVOUT, 2000, 0x03, 0x80, 0x2, 0x2), | 420 | [AB8500_LDO_TVOUT] = { |
338 | AB8500_FIXED_LDO(AUDIO, 2000, 0x03, 0x83, 0x2, 0x2), | 421 | .desc = { |
339 | AB8500_FIXED_LDO(ANAMIC1, 2050, 0x03, 0x83, 0x4, 0x4), | 422 | .name = "LDO-TVOUT", |
340 | AB8500_FIXED_LDO(ANAMIC2, 2050, 0x03, 0x83, 0x8, 0x8), | 423 | .ops = &ab8500_regulator_fixed_ops, |
341 | AB8500_FIXED_LDO(DMIC, 1800, 0x03, 0x83, 0x10, 0x10), | 424 | .type = REGULATOR_VOLTAGE, |
342 | AB8500_FIXED_LDO(ANA, 1200, 0x03, 0x83, 0xc, 0x4), | 425 | .id = AB8500_LDO_TVOUT, |
343 | }; | 426 | .owner = THIS_MODULE, |
427 | .n_voltages = 1, | ||
428 | }, | ||
429 | .fixed_uV = 2000000, | ||
430 | .update_bank = 0x03, | ||
431 | .update_reg = 0x80, | ||
432 | .update_mask = 0x82, | ||
433 | .update_val_enable = 0x02, | ||
434 | }, | ||
435 | [AB8500_LDO_AUDIO] = { | ||
436 | .desc = { | ||
437 | .name = "LDO-AUDIO", | ||
438 | .ops = &ab8500_regulator_fixed_ops, | ||
439 | .type = REGULATOR_VOLTAGE, | ||
440 | .id = AB8500_LDO_AUDIO, | ||
441 | .owner = THIS_MODULE, | ||
442 | .n_voltages = 1, | ||
443 | }, | ||
444 | .fixed_uV = 2000000, | ||
445 | .update_bank = 0x03, | ||
446 | .update_reg = 0x83, | ||
447 | .update_mask = 0x02, | ||
448 | .update_val_enable = 0x02, | ||
449 | }, | ||
450 | [AB8500_LDO_ANAMIC1] = { | ||
451 | .desc = { | ||
452 | .name = "LDO-ANAMIC1", | ||
453 | .ops = &ab8500_regulator_fixed_ops, | ||
454 | .type = REGULATOR_VOLTAGE, | ||
455 | .id = AB8500_LDO_ANAMIC1, | ||
456 | .owner = THIS_MODULE, | ||
457 | .n_voltages = 1, | ||
458 | }, | ||
459 | .fixed_uV = 2050000, | ||
460 | .update_bank = 0x03, | ||
461 | .update_reg = 0x83, | ||
462 | .update_mask = 0x08, | ||
463 | .update_val_enable = 0x08, | ||
464 | }, | ||
465 | [AB8500_LDO_ANAMIC2] = { | ||
466 | .desc = { | ||
467 | .name = "LDO-ANAMIC2", | ||
468 | .ops = &ab8500_regulator_fixed_ops, | ||
469 | .type = REGULATOR_VOLTAGE, | ||
470 | .id = AB8500_LDO_ANAMIC2, | ||
471 | .owner = THIS_MODULE, | ||
472 | .n_voltages = 1, | ||
473 | }, | ||
474 | .fixed_uV = 2050000, | ||
475 | .update_bank = 0x03, | ||
476 | .update_reg = 0x83, | ||
477 | .update_mask = 0x10, | ||
478 | .update_val_enable = 0x10, | ||
479 | }, | ||
480 | [AB8500_LDO_DMIC] = { | ||
481 | .desc = { | ||
482 | .name = "LDO-DMIC", | ||
483 | .ops = &ab8500_regulator_fixed_ops, | ||
484 | .type = REGULATOR_VOLTAGE, | ||
485 | .id = AB8500_LDO_DMIC, | ||
486 | .owner = THIS_MODULE, | ||
487 | .n_voltages = 1, | ||
488 | }, | ||
489 | .fixed_uV = 1800000, | ||
490 | .update_bank = 0x03, | ||
491 | .update_reg = 0x83, | ||
492 | .update_mask = 0x04, | ||
493 | .update_val_enable = 0x04, | ||
494 | }, | ||
495 | [AB8500_LDO_ANA] = { | ||
496 | .desc = { | ||
497 | .name = "LDO-ANA", | ||
498 | .ops = &ab8500_regulator_fixed_ops, | ||
499 | .type = REGULATOR_VOLTAGE, | ||
500 | .id = AB8500_LDO_ANA, | ||
501 | .owner = THIS_MODULE, | ||
502 | .n_voltages = 1, | ||
503 | }, | ||
504 | .fixed_uV = 1200000, | ||
505 | .update_bank = 0x04, | ||
506 | .update_reg = 0x06, | ||
507 | .update_mask = 0x0c, | ||
508 | .update_val_enable = 0x04, | ||
509 | }, | ||
344 | 510 | ||
345 | static inline struct ab8500_regulator_info *find_regulator_info(int id) | ||
346 | { | ||
347 | struct ab8500_regulator_info *info; | ||
348 | int i; | ||
349 | 511 | ||
350 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | 512 | }; |
351 | info = &ab8500_regulator_info[i]; | ||
352 | if (info->desc.id == id) | ||
353 | return info; | ||
354 | } | ||
355 | return NULL; | ||
356 | } | ||
357 | 513 | ||
358 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | 514 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) |
359 | { | 515 | { |
@@ -366,6 +522,16 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | |||
366 | return -EINVAL; | 522 | return -EINVAL; |
367 | } | 523 | } |
368 | pdata = dev_get_platdata(ab8500->dev); | 524 | pdata = dev_get_platdata(ab8500->dev); |
525 | if (!pdata) { | ||
526 | dev_err(&pdev->dev, "null pdata\n"); | ||
527 | return -EINVAL; | ||
528 | } | ||
529 | |||
530 | /* make sure the platform data has the correct size */ | ||
531 | if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { | ||
532 | dev_err(&pdev->dev, "platform configuration error\n"); | ||
533 | return -EINVAL; | ||
534 | } | ||
369 | 535 | ||
370 | /* register all regulators */ | 536 | /* register all regulators */ |
371 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | 537 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { |
@@ -374,10 +540,22 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | |||
374 | /* assign per-regulator data */ | 540 | /* assign per-regulator data */ |
375 | info = &ab8500_regulator_info[i]; | 541 | info = &ab8500_regulator_info[i]; |
376 | info->dev = &pdev->dev; | 542 | info->dev = &pdev->dev; |
377 | info->ab8500 = ab8500; | ||
378 | 543 | ||
544 | /* fix for hardware before ab8500v2.0 */ | ||
545 | if (abx500_get_chip_id(info->dev) < 0x20) { | ||
546 | if (info->desc.id == AB8500_LDO_AUX3) { | ||
547 | info->desc.n_voltages = | ||
548 | ARRAY_SIZE(ldo_vauxn_voltages); | ||
549 | info->voltages = ldo_vauxn_voltages; | ||
550 | info->voltages_len = | ||
551 | ARRAY_SIZE(ldo_vauxn_voltages); | ||
552 | info->voltage_mask = 0xf; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | /* register regulator with framework */ | ||
379 | info->regulator = regulator_register(&info->desc, &pdev->dev, | 557 | info->regulator = regulator_register(&info->desc, &pdev->dev, |
380 | pdata->regulator[i], info); | 558 | &pdata->regulator[i], info); |
381 | if (IS_ERR(info->regulator)) { | 559 | if (IS_ERR(info->regulator)) { |
382 | err = PTR_ERR(info->regulator); | 560 | err = PTR_ERR(info->regulator); |
383 | dev_err(&pdev->dev, "failed to register regulator %s\n", | 561 | dev_err(&pdev->dev, "failed to register regulator %s\n", |
@@ -389,6 +567,9 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | |||
389 | } | 567 | } |
390 | return err; | 568 | return err; |
391 | } | 569 | } |
570 | |||
571 | dev_vdbg(rdev_get_dev(info->regulator), | ||
572 | "%s-probed\n", info->desc.name); | ||
392 | } | 573 | } |
393 | 574 | ||
394 | return 0; | 575 | return 0; |
@@ -401,6 +582,10 @@ static __devexit int ab8500_regulator_remove(struct platform_device *pdev) | |||
401 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | 582 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { |
402 | struct ab8500_regulator_info *info = NULL; | 583 | struct ab8500_regulator_info *info = NULL; |
403 | info = &ab8500_regulator_info[i]; | 584 | info = &ab8500_regulator_info[i]; |
585 | |||
586 | dev_vdbg(rdev_get_dev(info->regulator), | ||
587 | "%s-remove\n", info->desc.name); | ||
588 | |||
404 | regulator_unregister(info->regulator); | 589 | regulator_unregister(info->regulator); |
405 | } | 590 | } |
406 | 591 | ||
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ba521f0f0fa..9fa20957847 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -13,8 +13,11 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
17 | |||
16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/debugfs.h> | ||
18 | #include <linux/device.h> | 21 | #include <linux/device.h> |
19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
20 | #include <linux/err.h> | 23 | #include <linux/err.h> |
@@ -25,16 +28,30 @@ | |||
25 | #include <linux/regulator/driver.h> | 28 | #include <linux/regulator/driver.h> |
26 | #include <linux/regulator/machine.h> | 29 | #include <linux/regulator/machine.h> |
27 | 30 | ||
31 | #define CREATE_TRACE_POINTS | ||
32 | #include <trace/events/regulator.h> | ||
33 | |||
28 | #include "dummy.h" | 34 | #include "dummy.h" |
29 | 35 | ||
30 | #define REGULATOR_VERSION "0.5" | 36 | #define rdev_err(rdev, fmt, ...) \ |
37 | pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) | ||
38 | #define rdev_warn(rdev, fmt, ...) \ | ||
39 | pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) | ||
40 | #define rdev_info(rdev, fmt, ...) \ | ||
41 | pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) | ||
42 | #define rdev_dbg(rdev, fmt, ...) \ | ||
43 | pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) | ||
31 | 44 | ||
32 | static DEFINE_MUTEX(regulator_list_mutex); | 45 | static DEFINE_MUTEX(regulator_list_mutex); |
33 | static LIST_HEAD(regulator_list); | 46 | static LIST_HEAD(regulator_list); |
34 | static LIST_HEAD(regulator_map_list); | 47 | static LIST_HEAD(regulator_map_list); |
35 | static int has_full_constraints; | 48 | static bool has_full_constraints; |
36 | static bool board_wants_dummy_regulator; | 49 | static bool board_wants_dummy_regulator; |
37 | 50 | ||
51 | #ifdef CONFIG_DEBUG_FS | ||
52 | static struct dentry *debugfs_root; | ||
53 | #endif | ||
54 | |||
38 | /* | 55 | /* |
39 | * struct regulator_map | 56 | * struct regulator_map |
40 | * | 57 | * |
@@ -71,6 +88,8 @@ static int _regulator_get_current_limit(struct regulator_dev *rdev); | |||
71 | static unsigned int _regulator_get_mode(struct regulator_dev *rdev); | 88 | static unsigned int _regulator_get_mode(struct regulator_dev *rdev); |
72 | static void _notifier_call_chain(struct regulator_dev *rdev, | 89 | static void _notifier_call_chain(struct regulator_dev *rdev, |
73 | unsigned long event, void *data); | 90 | unsigned long event, void *data); |
91 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, | ||
92 | int min_uV, int max_uV); | ||
74 | 93 | ||
75 | static const char *rdev_get_name(struct regulator_dev *rdev) | 94 | static const char *rdev_get_name(struct regulator_dev *rdev) |
76 | { | 95 | { |
@@ -111,13 +130,11 @@ static int regulator_check_voltage(struct regulator_dev *rdev, | |||
111 | BUG_ON(*min_uV > *max_uV); | 130 | BUG_ON(*min_uV > *max_uV); |
112 | 131 | ||
113 | if (!rdev->constraints) { | 132 | if (!rdev->constraints) { |
114 | printk(KERN_ERR "%s: no constraints for %s\n", __func__, | 133 | rdev_err(rdev, "no constraints\n"); |
115 | rdev_get_name(rdev)); | ||
116 | return -ENODEV; | 134 | return -ENODEV; |
117 | } | 135 | } |
118 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { | 136 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { |
119 | printk(KERN_ERR "%s: operation not allowed for %s\n", | 137 | rdev_err(rdev, "operation not allowed\n"); |
120 | __func__, rdev_get_name(rdev)); | ||
121 | return -EPERM; | 138 | return -EPERM; |
122 | } | 139 | } |
123 | 140 | ||
@@ -132,6 +149,27 @@ static int regulator_check_voltage(struct regulator_dev *rdev, | |||
132 | return 0; | 149 | return 0; |
133 | } | 150 | } |
134 | 151 | ||
152 | /* Make sure we select a voltage that suits the needs of all | ||
153 | * regulator consumers | ||
154 | */ | ||
155 | static int regulator_check_consumers(struct regulator_dev *rdev, | ||
156 | int *min_uV, int *max_uV) | ||
157 | { | ||
158 | struct regulator *regulator; | ||
159 | |||
160 | list_for_each_entry(regulator, &rdev->consumer_list, list) { | ||
161 | if (*max_uV > regulator->max_uV) | ||
162 | *max_uV = regulator->max_uV; | ||
163 | if (*min_uV < regulator->min_uV) | ||
164 | *min_uV = regulator->min_uV; | ||
165 | } | ||
166 | |||
167 | if (*min_uV > *max_uV) | ||
168 | return -EINVAL; | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
135 | /* current constraint check */ | 173 | /* current constraint check */ |
136 | static int regulator_check_current_limit(struct regulator_dev *rdev, | 174 | static int regulator_check_current_limit(struct regulator_dev *rdev, |
137 | int *min_uA, int *max_uA) | 175 | int *min_uA, int *max_uA) |
@@ -139,13 +177,11 @@ static int regulator_check_current_limit(struct regulator_dev *rdev, | |||
139 | BUG_ON(*min_uA > *max_uA); | 177 | BUG_ON(*min_uA > *max_uA); |
140 | 178 | ||
141 | if (!rdev->constraints) { | 179 | if (!rdev->constraints) { |
142 | printk(KERN_ERR "%s: no constraints for %s\n", __func__, | 180 | rdev_err(rdev, "no constraints\n"); |
143 | rdev_get_name(rdev)); | ||
144 | return -ENODEV; | 181 | return -ENODEV; |
145 | } | 182 | } |
146 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { | 183 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { |
147 | printk(KERN_ERR "%s: operation not allowed for %s\n", | 184 | rdev_err(rdev, "operation not allowed\n"); |
148 | __func__, rdev_get_name(rdev)); | ||
149 | return -EPERM; | 185 | return -EPERM; |
150 | } | 186 | } |
151 | 187 | ||
@@ -174,18 +210,15 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode) | |||
174 | } | 210 | } |
175 | 211 | ||
176 | if (!rdev->constraints) { | 212 | if (!rdev->constraints) { |
177 | printk(KERN_ERR "%s: no constraints for %s\n", __func__, | 213 | rdev_err(rdev, "no constraints\n"); |
178 | rdev_get_name(rdev)); | ||
179 | return -ENODEV; | 214 | return -ENODEV; |
180 | } | 215 | } |
181 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { | 216 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { |
182 | printk(KERN_ERR "%s: operation not allowed for %s\n", | 217 | rdev_err(rdev, "operation not allowed\n"); |
183 | __func__, rdev_get_name(rdev)); | ||
184 | return -EPERM; | 218 | return -EPERM; |
185 | } | 219 | } |
186 | if (!(rdev->constraints->valid_modes_mask & mode)) { | 220 | if (!(rdev->constraints->valid_modes_mask & mode)) { |
187 | printk(KERN_ERR "%s: invalid mode %x for %s\n", | 221 | rdev_err(rdev, "invalid mode %x\n", mode); |
188 | __func__, mode, rdev_get_name(rdev)); | ||
189 | return -EINVAL; | 222 | return -EINVAL; |
190 | } | 223 | } |
191 | return 0; | 224 | return 0; |
@@ -195,13 +228,11 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode) | |||
195 | static int regulator_check_drms(struct regulator_dev *rdev) | 228 | static int regulator_check_drms(struct regulator_dev *rdev) |
196 | { | 229 | { |
197 | if (!rdev->constraints) { | 230 | if (!rdev->constraints) { |
198 | printk(KERN_ERR "%s: no constraints for %s\n", __func__, | 231 | rdev_err(rdev, "no constraints\n"); |
199 | rdev_get_name(rdev)); | ||
200 | return -ENODEV; | 232 | return -ENODEV; |
201 | } | 233 | } |
202 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { | 234 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { |
203 | printk(KERN_ERR "%s: operation not allowed for %s\n", | 235 | rdev_err(rdev, "operation not allowed\n"); |
204 | __func__, rdev_get_name(rdev)); | ||
205 | return -EPERM; | 236 | return -EPERM; |
206 | } | 237 | } |
207 | return 0; | 238 | return 0; |
@@ -553,18 +584,21 @@ static void drms_uA_update(struct regulator_dev *rdev) | |||
553 | 584 | ||
554 | err = regulator_check_drms(rdev); | 585 | err = regulator_check_drms(rdev); |
555 | if (err < 0 || !rdev->desc->ops->get_optimum_mode || | 586 | if (err < 0 || !rdev->desc->ops->get_optimum_mode || |
556 | !rdev->desc->ops->get_voltage || !rdev->desc->ops->set_mode) | 587 | (!rdev->desc->ops->get_voltage && |
588 | !rdev->desc->ops->get_voltage_sel) || | ||
589 | !rdev->desc->ops->set_mode) | ||
557 | return; | 590 | return; |
558 | 591 | ||
559 | /* get output voltage */ | 592 | /* get output voltage */ |
560 | output_uV = rdev->desc->ops->get_voltage(rdev); | 593 | output_uV = _regulator_get_voltage(rdev); |
561 | if (output_uV <= 0) | 594 | if (output_uV <= 0) |
562 | return; | 595 | return; |
563 | 596 | ||
564 | /* get input voltage */ | 597 | /* get input voltage */ |
565 | if (rdev->supply && rdev->supply->desc->ops->get_voltage) | 598 | input_uV = 0; |
566 | input_uV = rdev->supply->desc->ops->get_voltage(rdev->supply); | 599 | if (rdev->supply) |
567 | else | 600 | input_uV = _regulator_get_voltage(rdev); |
601 | if (input_uV <= 0) | ||
568 | input_uV = rdev->constraints->input_uV; | 602 | input_uV = rdev->constraints->input_uV; |
569 | if (input_uV <= 0) | 603 | if (input_uV <= 0) |
570 | return; | 604 | return; |
@@ -598,20 +632,17 @@ static int suspend_set_state(struct regulator_dev *rdev, | |||
598 | */ | 632 | */ |
599 | if (!rstate->enabled && !rstate->disabled) { | 633 | if (!rstate->enabled && !rstate->disabled) { |
600 | if (can_set_state) | 634 | if (can_set_state) |
601 | printk(KERN_WARNING "%s: No configuration for %s\n", | 635 | rdev_warn(rdev, "No configuration\n"); |
602 | __func__, rdev_get_name(rdev)); | ||
603 | return 0; | 636 | return 0; |
604 | } | 637 | } |
605 | 638 | ||
606 | if (rstate->enabled && rstate->disabled) { | 639 | if (rstate->enabled && rstate->disabled) { |
607 | printk(KERN_ERR "%s: invalid configuration for %s\n", | 640 | rdev_err(rdev, "invalid configuration\n"); |
608 | __func__, rdev_get_name(rdev)); | ||
609 | return -EINVAL; | 641 | return -EINVAL; |
610 | } | 642 | } |
611 | 643 | ||
612 | if (!can_set_state) { | 644 | if (!can_set_state) { |
613 | printk(KERN_ERR "%s: no way to set suspend state\n", | 645 | rdev_err(rdev, "no way to set suspend state\n"); |
614 | __func__); | ||
615 | return -EINVAL; | 646 | return -EINVAL; |
616 | } | 647 | } |
617 | 648 | ||
@@ -620,15 +651,14 @@ static int suspend_set_state(struct regulator_dev *rdev, | |||
620 | else | 651 | else |
621 | ret = rdev->desc->ops->set_suspend_disable(rdev); | 652 | ret = rdev->desc->ops->set_suspend_disable(rdev); |
622 | if (ret < 0) { | 653 | if (ret < 0) { |
623 | printk(KERN_ERR "%s: failed to enabled/disable\n", __func__); | 654 | rdev_err(rdev, "failed to enabled/disable\n"); |
624 | return ret; | 655 | return ret; |
625 | } | 656 | } |
626 | 657 | ||
627 | if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) { | 658 | if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) { |
628 | ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV); | 659 | ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV); |
629 | if (ret < 0) { | 660 | if (ret < 0) { |
630 | printk(KERN_ERR "%s: failed to set voltage\n", | 661 | rdev_err(rdev, "failed to set voltage\n"); |
631 | __func__); | ||
632 | return ret; | 662 | return ret; |
633 | } | 663 | } |
634 | } | 664 | } |
@@ -636,7 +666,7 @@ static int suspend_set_state(struct regulator_dev *rdev, | |||
636 | if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) { | 666 | if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) { |
637 | ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode); | 667 | ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode); |
638 | if (ret < 0) { | 668 | if (ret < 0) { |
639 | printk(KERN_ERR "%s: failed to set mode\n", __func__); | 669 | rdev_err(rdev, "failed to set mode\n"); |
640 | return ret; | 670 | return ret; |
641 | } | 671 | } |
642 | } | 672 | } |
@@ -714,29 +744,27 @@ static void print_constraints(struct regulator_dev *rdev) | |||
714 | if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY) | 744 | if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY) |
715 | count += sprintf(buf + count, "standby"); | 745 | count += sprintf(buf + count, "standby"); |
716 | 746 | ||
717 | printk(KERN_INFO "regulator: %s: %s\n", rdev_get_name(rdev), buf); | 747 | rdev_info(rdev, "%s\n", buf); |
718 | } | 748 | } |
719 | 749 | ||
720 | static int machine_constraints_voltage(struct regulator_dev *rdev, | 750 | static int machine_constraints_voltage(struct regulator_dev *rdev, |
721 | struct regulation_constraints *constraints) | 751 | struct regulation_constraints *constraints) |
722 | { | 752 | { |
723 | struct regulator_ops *ops = rdev->desc->ops; | 753 | struct regulator_ops *ops = rdev->desc->ops; |
724 | const char *name = rdev_get_name(rdev); | ||
725 | int ret; | 754 | int ret; |
726 | 755 | ||
727 | /* do we need to apply the constraint voltage */ | 756 | /* do we need to apply the constraint voltage */ |
728 | if (rdev->constraints->apply_uV && | 757 | if (rdev->constraints->apply_uV && |
729 | rdev->constraints->min_uV == rdev->constraints->max_uV && | 758 | rdev->constraints->min_uV == rdev->constraints->max_uV) { |
730 | ops->set_voltage) { | 759 | ret = _regulator_do_set_voltage(rdev, |
731 | ret = ops->set_voltage(rdev, | 760 | rdev->constraints->min_uV, |
732 | rdev->constraints->min_uV, rdev->constraints->max_uV); | 761 | rdev->constraints->max_uV); |
733 | if (ret < 0) { | 762 | if (ret < 0) { |
734 | printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n", | 763 | rdev_err(rdev, "failed to apply %duV constraint\n", |
735 | __func__, | 764 | rdev->constraints->min_uV); |
736 | rdev->constraints->min_uV, name); | 765 | rdev->constraints = NULL; |
737 | rdev->constraints = NULL; | 766 | return ret; |
738 | return ret; | 767 | } |
739 | } | ||
740 | } | 768 | } |
741 | 769 | ||
742 | /* constrain machine-level voltage specs to fit | 770 | /* constrain machine-level voltage specs to fit |
@@ -765,8 +793,7 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, | |||
765 | 793 | ||
766 | /* else require explicit machine-level constraints */ | 794 | /* else require explicit machine-level constraints */ |
767 | if (cmin <= 0 || cmax <= 0 || cmax < cmin) { | 795 | if (cmin <= 0 || cmax <= 0 || cmax < cmin) { |
768 | pr_err("%s: %s '%s' voltage constraints\n", | 796 | rdev_err(rdev, "invalid voltage constraints\n"); |
769 | __func__, "invalid", name); | ||
770 | return -EINVAL; | 797 | return -EINVAL; |
771 | } | 798 | } |
772 | 799 | ||
@@ -787,22 +814,19 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, | |||
787 | 814 | ||
788 | /* final: [min_uV..max_uV] valid iff constraints valid */ | 815 | /* final: [min_uV..max_uV] valid iff constraints valid */ |
789 | if (max_uV < min_uV) { | 816 | if (max_uV < min_uV) { |
790 | pr_err("%s: %s '%s' voltage constraints\n", | 817 | rdev_err(rdev, "unsupportable voltage constraints\n"); |
791 | __func__, "unsupportable", name); | ||
792 | return -EINVAL; | 818 | return -EINVAL; |
793 | } | 819 | } |
794 | 820 | ||
795 | /* use regulator's subset of machine constraints */ | 821 | /* use regulator's subset of machine constraints */ |
796 | if (constraints->min_uV < min_uV) { | 822 | if (constraints->min_uV < min_uV) { |
797 | pr_debug("%s: override '%s' %s, %d -> %d\n", | 823 | rdev_dbg(rdev, "override min_uV, %d -> %d\n", |
798 | __func__, name, "min_uV", | 824 | constraints->min_uV, min_uV); |
799 | constraints->min_uV, min_uV); | ||
800 | constraints->min_uV = min_uV; | 825 | constraints->min_uV = min_uV; |
801 | } | 826 | } |
802 | if (constraints->max_uV > max_uV) { | 827 | if (constraints->max_uV > max_uV) { |
803 | pr_debug("%s: override '%s' %s, %d -> %d\n", | 828 | rdev_dbg(rdev, "override max_uV, %d -> %d\n", |
804 | __func__, name, "max_uV", | 829 | constraints->max_uV, max_uV); |
805 | constraints->max_uV, max_uV); | ||
806 | constraints->max_uV = max_uV; | 830 | constraints->max_uV = max_uV; |
807 | } | 831 | } |
808 | } | 832 | } |
@@ -822,26 +846,25 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, | |||
822 | * set_mode. | 846 | * set_mode. |
823 | */ | 847 | */ |
824 | static int set_machine_constraints(struct regulator_dev *rdev, | 848 | static int set_machine_constraints(struct regulator_dev *rdev, |
825 | struct regulation_constraints *constraints) | 849 | const struct regulation_constraints *constraints) |
826 | { | 850 | { |
827 | int ret = 0; | 851 | int ret = 0; |
828 | const char *name; | ||
829 | struct regulator_ops *ops = rdev->desc->ops; | 852 | struct regulator_ops *ops = rdev->desc->ops; |
830 | 853 | ||
831 | rdev->constraints = constraints; | 854 | rdev->constraints = kmemdup(constraints, sizeof(*constraints), |
832 | 855 | GFP_KERNEL); | |
833 | name = rdev_get_name(rdev); | 856 | if (!rdev->constraints) |
857 | return -ENOMEM; | ||
834 | 858 | ||
835 | ret = machine_constraints_voltage(rdev, constraints); | 859 | ret = machine_constraints_voltage(rdev, rdev->constraints); |
836 | if (ret != 0) | 860 | if (ret != 0) |
837 | goto out; | 861 | goto out; |
838 | 862 | ||
839 | /* do we need to setup our suspend state */ | 863 | /* do we need to setup our suspend state */ |
840 | if (constraints->initial_state) { | 864 | if (constraints->initial_state) { |
841 | ret = suspend_prepare(rdev, constraints->initial_state); | 865 | ret = suspend_prepare(rdev, rdev->constraints->initial_state); |
842 | if (ret < 0) { | 866 | if (ret < 0) { |
843 | printk(KERN_ERR "%s: failed to set suspend state for %s\n", | 867 | rdev_err(rdev, "failed to set suspend state\n"); |
844 | __func__, name); | ||
845 | rdev->constraints = NULL; | 868 | rdev->constraints = NULL; |
846 | goto out; | 869 | goto out; |
847 | } | 870 | } |
@@ -849,17 +872,14 @@ static int set_machine_constraints(struct regulator_dev *rdev, | |||
849 | 872 | ||
850 | if (constraints->initial_mode) { | 873 | if (constraints->initial_mode) { |
851 | if (!ops->set_mode) { | 874 | if (!ops->set_mode) { |
852 | printk(KERN_ERR "%s: no set_mode operation for %s\n", | 875 | rdev_err(rdev, "no set_mode operation\n"); |
853 | __func__, name); | ||
854 | ret = -EINVAL; | 876 | ret = -EINVAL; |
855 | goto out; | 877 | goto out; |
856 | } | 878 | } |
857 | 879 | ||
858 | ret = ops->set_mode(rdev, constraints->initial_mode); | 880 | ret = ops->set_mode(rdev, rdev->constraints->initial_mode); |
859 | if (ret < 0) { | 881 | if (ret < 0) { |
860 | printk(KERN_ERR | 882 | rdev_err(rdev, "failed to set initial mode: %d\n", ret); |
861 | "%s: failed to set initial mode for %s: %d\n", | ||
862 | __func__, name, ret); | ||
863 | goto out; | 883 | goto out; |
864 | } | 884 | } |
865 | } | 885 | } |
@@ -867,11 +887,11 @@ static int set_machine_constraints(struct regulator_dev *rdev, | |||
867 | /* If the constraints say the regulator should be on at this point | 887 | /* If the constraints say the regulator should be on at this point |
868 | * and we have control then make sure it is enabled. | 888 | * and we have control then make sure it is enabled. |
869 | */ | 889 | */ |
870 | if ((constraints->always_on || constraints->boot_on) && ops->enable) { | 890 | if ((rdev->constraints->always_on || rdev->constraints->boot_on) && |
891 | ops->enable) { | ||
871 | ret = ops->enable(rdev); | 892 | ret = ops->enable(rdev); |
872 | if (ret < 0) { | 893 | if (ret < 0) { |
873 | printk(KERN_ERR "%s: failed to enable %s\n", | 894 | rdev_err(rdev, "failed to enable\n"); |
874 | __func__, name); | ||
875 | rdev->constraints = NULL; | 895 | rdev->constraints = NULL; |
876 | goto out; | 896 | goto out; |
877 | } | 897 | } |
@@ -899,9 +919,8 @@ static int set_supply(struct regulator_dev *rdev, | |||
899 | err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj, | 919 | err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj, |
900 | "supply"); | 920 | "supply"); |
901 | if (err) { | 921 | if (err) { |
902 | printk(KERN_ERR | 922 | rdev_err(rdev, "could not add device link %s err %d\n", |
903 | "%s: could not add device link %s err %d\n", | 923 | supply_rdev->dev.kobj.name, err); |
904 | __func__, supply_rdev->dev.kobj.name, err); | ||
905 | goto out; | 924 | goto out; |
906 | } | 925 | } |
907 | rdev->supply = supply_rdev; | 926 | rdev->supply = supply_rdev; |
@@ -957,10 +976,10 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, | |||
957 | continue; | 976 | continue; |
958 | 977 | ||
959 | dev_dbg(consumer_dev, "%s/%s is '%s' supply; fail %s/%s\n", | 978 | dev_dbg(consumer_dev, "%s/%s is '%s' supply; fail %s/%s\n", |
960 | dev_name(&node->regulator->dev), | 979 | dev_name(&node->regulator->dev), |
961 | node->regulator->desc->name, | 980 | node->regulator->desc->name, |
962 | supply, | 981 | supply, |
963 | dev_name(&rdev->dev), rdev_get_name(rdev)); | 982 | dev_name(&rdev->dev), rdev_get_name(rdev)); |
964 | return -EBUSY; | 983 | return -EBUSY; |
965 | } | 984 | } |
966 | 985 | ||
@@ -1031,8 +1050,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, | |||
1031 | regulator->dev_attr.show = device_requested_uA_show; | 1050 | regulator->dev_attr.show = device_requested_uA_show; |
1032 | err = device_create_file(dev, ®ulator->dev_attr); | 1051 | err = device_create_file(dev, ®ulator->dev_attr); |
1033 | if (err < 0) { | 1052 | if (err < 0) { |
1034 | printk(KERN_WARNING "%s: could not add regulator_dev" | 1053 | rdev_warn(rdev, "could not add regulator_dev requested microamps sysfs entry\n"); |
1035 | " load sysfs\n", __func__); | ||
1036 | goto attr_name_err; | 1054 | goto attr_name_err; |
1037 | } | 1055 | } |
1038 | 1056 | ||
@@ -1049,9 +1067,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, | |||
1049 | err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj, | 1067 | err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj, |
1050 | buf); | 1068 | buf); |
1051 | if (err) { | 1069 | if (err) { |
1052 | printk(KERN_WARNING | 1070 | rdev_warn(rdev, "could not add device link %s err %d\n", |
1053 | "%s: could not add device link %s err %d\n", | 1071 | dev->kobj.name, err); |
1054 | __func__, dev->kobj.name, err); | ||
1055 | goto link_name_err; | 1072 | goto link_name_err; |
1056 | } | 1073 | } |
1057 | } | 1074 | } |
@@ -1088,7 +1105,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1088 | int ret; | 1105 | int ret; |
1089 | 1106 | ||
1090 | if (id == NULL) { | 1107 | if (id == NULL) { |
1091 | printk(KERN_ERR "regulator: get() with no identifier\n"); | 1108 | pr_err("get() with no identifier\n"); |
1092 | return regulator; | 1109 | return regulator; |
1093 | } | 1110 | } |
1094 | 1111 | ||
@@ -1122,8 +1139,8 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1122 | * substitute in a dummy regulator so consumers can continue. | 1139 | * substitute in a dummy regulator so consumers can continue. |
1123 | */ | 1140 | */ |
1124 | if (!has_full_constraints) { | 1141 | if (!has_full_constraints) { |
1125 | pr_warning("%s supply %s not found, using dummy regulator\n", | 1142 | pr_warn("%s supply %s not found, using dummy regulator\n", |
1126 | devname, id); | 1143 | devname, id); |
1127 | rdev = dummy_regulator_rdev; | 1144 | rdev = dummy_regulator_rdev; |
1128 | goto found; | 1145 | goto found; |
1129 | } | 1146 | } |
@@ -1274,8 +1291,7 @@ static int _regulator_enable(struct regulator_dev *rdev) | |||
1274 | ret = _regulator_enable(rdev->supply); | 1291 | ret = _regulator_enable(rdev->supply); |
1275 | mutex_unlock(&rdev->supply->mutex); | 1292 | mutex_unlock(&rdev->supply->mutex); |
1276 | if (ret < 0) { | 1293 | if (ret < 0) { |
1277 | printk(KERN_ERR "%s: failed to enable %s: %d\n", | 1294 | rdev_err(rdev, "failed to enable: %d\n", ret); |
1278 | __func__, rdev_get_name(rdev), ret); | ||
1279 | return ret; | 1295 | return ret; |
1280 | } | 1296 | } |
1281 | } | 1297 | } |
@@ -1302,13 +1318,13 @@ static int _regulator_enable(struct regulator_dev *rdev) | |||
1302 | if (ret >= 0) { | 1318 | if (ret >= 0) { |
1303 | delay = ret; | 1319 | delay = ret; |
1304 | } else { | 1320 | } else { |
1305 | printk(KERN_WARNING | 1321 | rdev_warn(rdev, "enable_time() failed: %d\n", |
1306 | "%s: enable_time() failed for %s: %d\n", | 1322 | ret); |
1307 | __func__, rdev_get_name(rdev), | ||
1308 | ret); | ||
1309 | delay = 0; | 1323 | delay = 0; |
1310 | } | 1324 | } |
1311 | 1325 | ||
1326 | trace_regulator_enable(rdev_get_name(rdev)); | ||
1327 | |||
1312 | /* Allow the regulator to ramp; it would be useful | 1328 | /* Allow the regulator to ramp; it would be useful |
1313 | * to extend this for bulk operations so that the | 1329 | * to extend this for bulk operations so that the |
1314 | * regulators can ramp together. */ | 1330 | * regulators can ramp together. */ |
@@ -1316,6 +1332,8 @@ static int _regulator_enable(struct regulator_dev *rdev) | |||
1316 | if (ret < 0) | 1332 | if (ret < 0) |
1317 | return ret; | 1333 | return ret; |
1318 | 1334 | ||
1335 | trace_regulator_enable_delay(rdev_get_name(rdev)); | ||
1336 | |||
1319 | if (delay >= 1000) { | 1337 | if (delay >= 1000) { |
1320 | mdelay(delay / 1000); | 1338 | mdelay(delay / 1000); |
1321 | udelay(delay % 1000); | 1339 | udelay(delay % 1000); |
@@ -1323,9 +1341,10 @@ static int _regulator_enable(struct regulator_dev *rdev) | |||
1323 | udelay(delay); | 1341 | udelay(delay); |
1324 | } | 1342 | } |
1325 | 1343 | ||
1344 | trace_regulator_enable_complete(rdev_get_name(rdev)); | ||
1345 | |||
1326 | } else if (ret < 0) { | 1346 | } else if (ret < 0) { |
1327 | printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n", | 1347 | rdev_err(rdev, "is_enabled() failed: %d\n", ret); |
1328 | __func__, rdev_get_name(rdev), ret); | ||
1329 | return ret; | 1348 | return ret; |
1330 | } | 1349 | } |
1331 | /* Fallthrough on positive return values - already enabled */ | 1350 | /* Fallthrough on positive return values - already enabled */ |
@@ -1367,8 +1386,7 @@ static int _regulator_disable(struct regulator_dev *rdev, | |||
1367 | *supply_rdev_ptr = NULL; | 1386 | *supply_rdev_ptr = NULL; |
1368 | 1387 | ||
1369 | if (WARN(rdev->use_count <= 0, | 1388 | if (WARN(rdev->use_count <= 0, |
1370 | "unbalanced disables for %s\n", | 1389 | "unbalanced disables for %s\n", rdev_get_name(rdev))) |
1371 | rdev_get_name(rdev))) | ||
1372 | return -EIO; | 1390 | return -EIO; |
1373 | 1391 | ||
1374 | /* are we the last user and permitted to disable ? */ | 1392 | /* are we the last user and permitted to disable ? */ |
@@ -1378,13 +1396,16 @@ static int _regulator_disable(struct regulator_dev *rdev, | |||
1378 | /* we are last user */ | 1396 | /* we are last user */ |
1379 | if (_regulator_can_change_status(rdev) && | 1397 | if (_regulator_can_change_status(rdev) && |
1380 | rdev->desc->ops->disable) { | 1398 | rdev->desc->ops->disable) { |
1399 | trace_regulator_disable(rdev_get_name(rdev)); | ||
1400 | |||
1381 | ret = rdev->desc->ops->disable(rdev); | 1401 | ret = rdev->desc->ops->disable(rdev); |
1382 | if (ret < 0) { | 1402 | if (ret < 0) { |
1383 | printk(KERN_ERR "%s: failed to disable %s\n", | 1403 | rdev_err(rdev, "failed to disable\n"); |
1384 | __func__, rdev_get_name(rdev)); | ||
1385 | return ret; | 1404 | return ret; |
1386 | } | 1405 | } |
1387 | 1406 | ||
1407 | trace_regulator_disable_complete(rdev_get_name(rdev)); | ||
1408 | |||
1388 | _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, | 1409 | _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, |
1389 | NULL); | 1410 | NULL); |
1390 | } | 1411 | } |
@@ -1451,8 +1472,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev, | |||
1451 | /* ah well, who wants to live forever... */ | 1472 | /* ah well, who wants to live forever... */ |
1452 | ret = rdev->desc->ops->disable(rdev); | 1473 | ret = rdev->desc->ops->disable(rdev); |
1453 | if (ret < 0) { | 1474 | if (ret < 0) { |
1454 | printk(KERN_ERR "%s: failed to force disable %s\n", | 1475 | rdev_err(rdev, "failed to force disable\n"); |
1455 | __func__, rdev_get_name(rdev)); | ||
1456 | return ret; | 1476 | return ret; |
1457 | } | 1477 | } |
1458 | /* notify other consumers that power has been forced off */ | 1478 | /* notify other consumers that power has been forced off */ |
@@ -1605,6 +1625,62 @@ int regulator_is_supported_voltage(struct regulator *regulator, | |||
1605 | return 0; | 1625 | return 0; |
1606 | } | 1626 | } |
1607 | 1627 | ||
1628 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, | ||
1629 | int min_uV, int max_uV) | ||
1630 | { | ||
1631 | int ret; | ||
1632 | unsigned int selector; | ||
1633 | |||
1634 | trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); | ||
1635 | |||
1636 | if (rdev->desc->ops->set_voltage) { | ||
1637 | ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, | ||
1638 | &selector); | ||
1639 | |||
1640 | if (rdev->desc->ops->list_voltage) | ||
1641 | selector = rdev->desc->ops->list_voltage(rdev, | ||
1642 | selector); | ||
1643 | else | ||
1644 | selector = -1; | ||
1645 | } else if (rdev->desc->ops->set_voltage_sel) { | ||
1646 | int best_val = INT_MAX; | ||
1647 | int i; | ||
1648 | |||
1649 | selector = 0; | ||
1650 | |||
1651 | /* Find the smallest voltage that falls within the specified | ||
1652 | * range. | ||
1653 | */ | ||
1654 | for (i = 0; i < rdev->desc->n_voltages; i++) { | ||
1655 | ret = rdev->desc->ops->list_voltage(rdev, i); | ||
1656 | if (ret < 0) | ||
1657 | continue; | ||
1658 | |||
1659 | if (ret < best_val && ret >= min_uV && ret <= max_uV) { | ||
1660 | best_val = ret; | ||
1661 | selector = i; | ||
1662 | } | ||
1663 | } | ||
1664 | |||
1665 | if (best_val != INT_MAX) { | ||
1666 | ret = rdev->desc->ops->set_voltage_sel(rdev, selector); | ||
1667 | selector = best_val; | ||
1668 | } else { | ||
1669 | ret = -EINVAL; | ||
1670 | } | ||
1671 | } else { | ||
1672 | ret = -EINVAL; | ||
1673 | } | ||
1674 | |||
1675 | if (ret == 0) | ||
1676 | _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, | ||
1677 | NULL); | ||
1678 | |||
1679 | trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector); | ||
1680 | |||
1681 | return ret; | ||
1682 | } | ||
1683 | |||
1608 | /** | 1684 | /** |
1609 | * regulator_set_voltage - set regulator output voltage | 1685 | * regulator_set_voltage - set regulator output voltage |
1610 | * @regulator: regulator source | 1686 | * @regulator: regulator source |
@@ -1626,12 +1702,20 @@ int regulator_is_supported_voltage(struct regulator *regulator, | |||
1626 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | 1702 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) |
1627 | { | 1703 | { |
1628 | struct regulator_dev *rdev = regulator->rdev; | 1704 | struct regulator_dev *rdev = regulator->rdev; |
1629 | int ret; | 1705 | int ret = 0; |
1630 | 1706 | ||
1631 | mutex_lock(&rdev->mutex); | 1707 | mutex_lock(&rdev->mutex); |
1632 | 1708 | ||
1709 | /* If we're setting the same range as last time the change | ||
1710 | * should be a noop (some cpufreq implementations use the same | ||
1711 | * voltage for multiple frequencies, for example). | ||
1712 | */ | ||
1713 | if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) | ||
1714 | goto out; | ||
1715 | |||
1633 | /* sanity check */ | 1716 | /* sanity check */ |
1634 | if (!rdev->desc->ops->set_voltage) { | 1717 | if (!rdev->desc->ops->set_voltage && |
1718 | !rdev->desc->ops->set_voltage_sel) { | ||
1635 | ret = -EINVAL; | 1719 | ret = -EINVAL; |
1636 | goto out; | 1720 | goto out; |
1637 | } | 1721 | } |
@@ -1642,18 +1726,76 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | |||
1642 | goto out; | 1726 | goto out; |
1643 | regulator->min_uV = min_uV; | 1727 | regulator->min_uV = min_uV; |
1644 | regulator->max_uV = max_uV; | 1728 | regulator->max_uV = max_uV; |
1645 | ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV); | 1729 | |
1730 | ret = regulator_check_consumers(rdev, &min_uV, &max_uV); | ||
1731 | if (ret < 0) | ||
1732 | goto out; | ||
1733 | |||
1734 | ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); | ||
1646 | 1735 | ||
1647 | out: | 1736 | out: |
1648 | _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL); | ||
1649 | mutex_unlock(&rdev->mutex); | 1737 | mutex_unlock(&rdev->mutex); |
1650 | return ret; | 1738 | return ret; |
1651 | } | 1739 | } |
1652 | EXPORT_SYMBOL_GPL(regulator_set_voltage); | 1740 | EXPORT_SYMBOL_GPL(regulator_set_voltage); |
1653 | 1741 | ||
1742 | /** | ||
1743 | * regulator_sync_voltage - re-apply last regulator output voltage | ||
1744 | * @regulator: regulator source | ||
1745 | * | ||
1746 | * Re-apply the last configured voltage. This is intended to be used | ||
1747 | * where some external control source the consumer is cooperating with | ||
1748 | * has caused the configured voltage to change. | ||
1749 | */ | ||
1750 | int regulator_sync_voltage(struct regulator *regulator) | ||
1751 | { | ||
1752 | struct regulator_dev *rdev = regulator->rdev; | ||
1753 | int ret, min_uV, max_uV; | ||
1754 | |||
1755 | mutex_lock(&rdev->mutex); | ||
1756 | |||
1757 | if (!rdev->desc->ops->set_voltage && | ||
1758 | !rdev->desc->ops->set_voltage_sel) { | ||
1759 | ret = -EINVAL; | ||
1760 | goto out; | ||
1761 | } | ||
1762 | |||
1763 | /* This is only going to work if we've had a voltage configured. */ | ||
1764 | if (!regulator->min_uV && !regulator->max_uV) { | ||
1765 | ret = -EINVAL; | ||
1766 | goto out; | ||
1767 | } | ||
1768 | |||
1769 | min_uV = regulator->min_uV; | ||
1770 | max_uV = regulator->max_uV; | ||
1771 | |||
1772 | /* This should be a paranoia check... */ | ||
1773 | ret = regulator_check_voltage(rdev, &min_uV, &max_uV); | ||
1774 | if (ret < 0) | ||
1775 | goto out; | ||
1776 | |||
1777 | ret = regulator_check_consumers(rdev, &min_uV, &max_uV); | ||
1778 | if (ret < 0) | ||
1779 | goto out; | ||
1780 | |||
1781 | ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); | ||
1782 | |||
1783 | out: | ||
1784 | mutex_unlock(&rdev->mutex); | ||
1785 | return ret; | ||
1786 | } | ||
1787 | EXPORT_SYMBOL_GPL(regulator_sync_voltage); | ||
1788 | |||
1654 | static int _regulator_get_voltage(struct regulator_dev *rdev) | 1789 | static int _regulator_get_voltage(struct regulator_dev *rdev) |
1655 | { | 1790 | { |
1656 | /* sanity check */ | 1791 | int sel; |
1792 | |||
1793 | if (rdev->desc->ops->get_voltage_sel) { | ||
1794 | sel = rdev->desc->ops->get_voltage_sel(rdev); | ||
1795 | if (sel < 0) | ||
1796 | return sel; | ||
1797 | return rdev->desc->ops->list_voltage(rdev, sel); | ||
1798 | } | ||
1657 | if (rdev->desc->ops->get_voltage) | 1799 | if (rdev->desc->ops->get_voltage) |
1658 | return rdev->desc->ops->get_voltage(rdev); | 1800 | return rdev->desc->ops->get_voltage(rdev); |
1659 | else | 1801 | else |
@@ -1880,21 +2022,20 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | |||
1880 | goto out; | 2022 | goto out; |
1881 | 2023 | ||
1882 | /* get output voltage */ | 2024 | /* get output voltage */ |
1883 | output_uV = rdev->desc->ops->get_voltage(rdev); | 2025 | output_uV = _regulator_get_voltage(rdev); |
1884 | if (output_uV <= 0) { | 2026 | if (output_uV <= 0) { |
1885 | printk(KERN_ERR "%s: invalid output voltage found for %s\n", | 2027 | rdev_err(rdev, "invalid output voltage found\n"); |
1886 | __func__, rdev_get_name(rdev)); | ||
1887 | goto out; | 2028 | goto out; |
1888 | } | 2029 | } |
1889 | 2030 | ||
1890 | /* get input voltage */ | 2031 | /* get input voltage */ |
1891 | if (rdev->supply && rdev->supply->desc->ops->get_voltage) | 2032 | input_uV = 0; |
1892 | input_uV = rdev->supply->desc->ops->get_voltage(rdev->supply); | 2033 | if (rdev->supply) |
1893 | else | 2034 | input_uV = _regulator_get_voltage(rdev->supply); |
2035 | if (input_uV <= 0) | ||
1894 | input_uV = rdev->constraints->input_uV; | 2036 | input_uV = rdev->constraints->input_uV; |
1895 | if (input_uV <= 0) { | 2037 | if (input_uV <= 0) { |
1896 | printk(KERN_ERR "%s: invalid input voltage found for %s\n", | 2038 | rdev_err(rdev, "invalid input voltage found\n"); |
1897 | __func__, rdev_get_name(rdev)); | ||
1898 | goto out; | 2039 | goto out; |
1899 | } | 2040 | } |
1900 | 2041 | ||
@@ -1907,16 +2048,14 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | |||
1907 | total_uA_load); | 2048 | total_uA_load); |
1908 | ret = regulator_check_mode(rdev, mode); | 2049 | ret = regulator_check_mode(rdev, mode); |
1909 | if (ret < 0) { | 2050 | if (ret < 0) { |
1910 | printk(KERN_ERR "%s: failed to get optimum mode for %s @" | 2051 | rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", |
1911 | " %d uA %d -> %d uV\n", __func__, rdev_get_name(rdev), | 2052 | total_uA_load, input_uV, output_uV); |
1912 | total_uA_load, input_uV, output_uV); | ||
1913 | goto out; | 2053 | goto out; |
1914 | } | 2054 | } |
1915 | 2055 | ||
1916 | ret = rdev->desc->ops->set_mode(rdev, mode); | 2056 | ret = rdev->desc->ops->set_mode(rdev, mode); |
1917 | if (ret < 0) { | 2057 | if (ret < 0) { |
1918 | printk(KERN_ERR "%s: failed to set optimum mode %x for %s\n", | 2058 | rdev_err(rdev, "failed to set optimum mode %x\n", mode); |
1919 | __func__, mode, rdev_get_name(rdev)); | ||
1920 | goto out; | 2059 | goto out; |
1921 | } | 2060 | } |
1922 | ret = mode; | 2061 | ret = mode; |
@@ -2047,7 +2186,7 @@ int regulator_bulk_enable(int num_consumers, | |||
2047 | return 0; | 2186 | return 0; |
2048 | 2187 | ||
2049 | err: | 2188 | err: |
2050 | printk(KERN_ERR "Failed to enable %s: %d\n", consumers[i].supply, ret); | 2189 | pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret); |
2051 | for (--i; i >= 0; --i) | 2190 | for (--i; i >= 0; --i) |
2052 | regulator_disable(consumers[i].consumer); | 2191 | regulator_disable(consumers[i].consumer); |
2053 | 2192 | ||
@@ -2082,8 +2221,7 @@ int regulator_bulk_disable(int num_consumers, | |||
2082 | return 0; | 2221 | return 0; |
2083 | 2222 | ||
2084 | err: | 2223 | err: |
2085 | printk(KERN_ERR "Failed to disable %s: %d\n", consumers[i].supply, | 2224 | pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret); |
2086 | ret); | ||
2087 | for (--i; i >= 0; --i) | 2225 | for (--i; i >= 0; --i) |
2088 | regulator_enable(consumers[i].consumer); | 2226 | regulator_enable(consumers[i].consumer); |
2089 | 2227 | ||
@@ -2166,7 +2304,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev) | |||
2166 | int status = 0; | 2304 | int status = 0; |
2167 | 2305 | ||
2168 | /* some attributes need specific methods to be displayed */ | 2306 | /* some attributes need specific methods to be displayed */ |
2169 | if (ops->get_voltage) { | 2307 | if (ops->get_voltage || ops->get_voltage_sel) { |
2170 | status = device_create_file(dev, &dev_attr_microvolts); | 2308 | status = device_create_file(dev, &dev_attr_microvolts); |
2171 | if (status < 0) | 2309 | if (status < 0) |
2172 | return status; | 2310 | return status; |
@@ -2207,7 +2345,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev) | |||
2207 | return status; | 2345 | return status; |
2208 | 2346 | ||
2209 | /* constraints need specific supporting methods */ | 2347 | /* constraints need specific supporting methods */ |
2210 | if (ops->set_voltage) { | 2348 | if (ops->set_voltage || ops->set_voltage_sel) { |
2211 | status = device_create_file(dev, &dev_attr_min_microvolts); | 2349 | status = device_create_file(dev, &dev_attr_min_microvolts); |
2212 | if (status < 0) | 2350 | if (status < 0) |
2213 | return status; | 2351 | return status; |
@@ -2271,6 +2409,23 @@ static int add_regulator_attributes(struct regulator_dev *rdev) | |||
2271 | return status; | 2409 | return status; |
2272 | } | 2410 | } |
2273 | 2411 | ||
2412 | static void rdev_init_debugfs(struct regulator_dev *rdev) | ||
2413 | { | ||
2414 | #ifdef CONFIG_DEBUG_FS | ||
2415 | rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); | ||
2416 | if (IS_ERR(rdev->debugfs) || !rdev->debugfs) { | ||
2417 | rdev_warn(rdev, "Failed to create debugfs directory\n"); | ||
2418 | rdev->debugfs = NULL; | ||
2419 | return; | ||
2420 | } | ||
2421 | |||
2422 | debugfs_create_u32("use_count", 0444, rdev->debugfs, | ||
2423 | &rdev->use_count); | ||
2424 | debugfs_create_u32("open_count", 0444, rdev->debugfs, | ||
2425 | &rdev->open_count); | ||
2426 | #endif | ||
2427 | } | ||
2428 | |||
2274 | /** | 2429 | /** |
2275 | * regulator_register - register regulator | 2430 | * regulator_register - register regulator |
2276 | * @regulator_desc: regulator to register | 2431 | * @regulator_desc: regulator to register |
@@ -2282,7 +2437,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev) | |||
2282 | * Returns 0 on success. | 2437 | * Returns 0 on success. |
2283 | */ | 2438 | */ |
2284 | struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | 2439 | struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, |
2285 | struct device *dev, struct regulator_init_data *init_data, | 2440 | struct device *dev, const struct regulator_init_data *init_data, |
2286 | void *driver_data) | 2441 | void *driver_data) |
2287 | { | 2442 | { |
2288 | static atomic_t regulator_no = ATOMIC_INIT(0); | 2443 | static atomic_t regulator_no = ATOMIC_INIT(0); |
@@ -2302,6 +2457,22 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2302 | if (!init_data) | 2457 | if (!init_data) |
2303 | return ERR_PTR(-EINVAL); | 2458 | return ERR_PTR(-EINVAL); |
2304 | 2459 | ||
2460 | /* Only one of each should be implemented */ | ||
2461 | WARN_ON(regulator_desc->ops->get_voltage && | ||
2462 | regulator_desc->ops->get_voltage_sel); | ||
2463 | WARN_ON(regulator_desc->ops->set_voltage && | ||
2464 | regulator_desc->ops->set_voltage_sel); | ||
2465 | |||
2466 | /* If we're using selectors we must implement list_voltage. */ | ||
2467 | if (regulator_desc->ops->get_voltage_sel && | ||
2468 | !regulator_desc->ops->list_voltage) { | ||
2469 | return ERR_PTR(-EINVAL); | ||
2470 | } | ||
2471 | if (regulator_desc->ops->set_voltage_sel && | ||
2472 | !regulator_desc->ops->list_voltage) { | ||
2473 | return ERR_PTR(-EINVAL); | ||
2474 | } | ||
2475 | |||
2305 | rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); | 2476 | rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); |
2306 | if (rdev == NULL) | 2477 | if (rdev == NULL) |
2307 | return ERR_PTR(-ENOMEM); | 2478 | return ERR_PTR(-ENOMEM); |
@@ -2399,6 +2570,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2399 | } | 2570 | } |
2400 | 2571 | ||
2401 | list_add(&rdev->list, ®ulator_list); | 2572 | list_add(&rdev->list, ®ulator_list); |
2573 | |||
2574 | rdev_init_debugfs(rdev); | ||
2402 | out: | 2575 | out: |
2403 | mutex_unlock(®ulator_list_mutex); | 2576 | mutex_unlock(®ulator_list_mutex); |
2404 | return rdev; | 2577 | return rdev; |
@@ -2431,12 +2604,16 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
2431 | return; | 2604 | return; |
2432 | 2605 | ||
2433 | mutex_lock(®ulator_list_mutex); | 2606 | mutex_lock(®ulator_list_mutex); |
2607 | #ifdef CONFIG_DEBUG_FS | ||
2608 | debugfs_remove_recursive(rdev->debugfs); | ||
2609 | #endif | ||
2434 | WARN_ON(rdev->open_count); | 2610 | WARN_ON(rdev->open_count); |
2435 | unset_regulator_supplies(rdev); | 2611 | unset_regulator_supplies(rdev); |
2436 | list_del(&rdev->list); | 2612 | list_del(&rdev->list); |
2437 | if (rdev->supply) | 2613 | if (rdev->supply) |
2438 | sysfs_remove_link(&rdev->dev.kobj, "supply"); | 2614 | sysfs_remove_link(&rdev->dev.kobj, "supply"); |
2439 | device_unregister(&rdev->dev); | 2615 | device_unregister(&rdev->dev); |
2616 | kfree(rdev->constraints); | ||
2440 | mutex_unlock(®ulator_list_mutex); | 2617 | mutex_unlock(®ulator_list_mutex); |
2441 | } | 2618 | } |
2442 | EXPORT_SYMBOL_GPL(regulator_unregister); | 2619 | EXPORT_SYMBOL_GPL(regulator_unregister); |
@@ -2465,8 +2642,7 @@ int regulator_suspend_prepare(suspend_state_t state) | |||
2465 | mutex_unlock(&rdev->mutex); | 2642 | mutex_unlock(&rdev->mutex); |
2466 | 2643 | ||
2467 | if (ret < 0) { | 2644 | if (ret < 0) { |
2468 | printk(KERN_ERR "%s: failed to prepare %s\n", | 2645 | rdev_err(rdev, "failed to prepare\n"); |
2469 | __func__, rdev_get_name(rdev)); | ||
2470 | goto out; | 2646 | goto out; |
2471 | } | 2647 | } |
2472 | } | 2648 | } |
@@ -2572,10 +2748,16 @@ static int __init regulator_init(void) | |||
2572 | { | 2748 | { |
2573 | int ret; | 2749 | int ret; |
2574 | 2750 | ||
2575 | printk(KERN_INFO "regulator: core version %s\n", REGULATOR_VERSION); | ||
2576 | |||
2577 | ret = class_register(®ulator_class); | 2751 | ret = class_register(®ulator_class); |
2578 | 2752 | ||
2753 | #ifdef CONFIG_DEBUG_FS | ||
2754 | debugfs_root = debugfs_create_dir("regulator", NULL); | ||
2755 | if (IS_ERR(debugfs_root) || !debugfs_root) { | ||
2756 | pr_warn("regulator: Failed to create debugfs directory\n"); | ||
2757 | debugfs_root = NULL; | ||
2758 | } | ||
2759 | #endif | ||
2760 | |||
2579 | regulator_dummy_init(); | 2761 | regulator_dummy_init(); |
2580 | 2762 | ||
2581 | return ret; | 2763 | return ret; |
@@ -2590,7 +2772,6 @@ static int __init regulator_init_complete(void) | |||
2590 | struct regulator_ops *ops; | 2772 | struct regulator_ops *ops; |
2591 | struct regulation_constraints *c; | 2773 | struct regulation_constraints *c; |
2592 | int enabled, ret; | 2774 | int enabled, ret; |
2593 | const char *name; | ||
2594 | 2775 | ||
2595 | mutex_lock(®ulator_list_mutex); | 2776 | mutex_lock(®ulator_list_mutex); |
2596 | 2777 | ||
@@ -2602,8 +2783,6 @@ static int __init regulator_init_complete(void) | |||
2602 | ops = rdev->desc->ops; | 2783 | ops = rdev->desc->ops; |
2603 | c = rdev->constraints; | 2784 | c = rdev->constraints; |
2604 | 2785 | ||
2605 | name = rdev_get_name(rdev); | ||
2606 | |||
2607 | if (!ops->disable || (c && c->always_on)) | 2786 | if (!ops->disable || (c && c->always_on)) |
2608 | continue; | 2787 | continue; |
2609 | 2788 | ||
@@ -2624,13 +2803,10 @@ static int __init regulator_init_complete(void) | |||
2624 | if (has_full_constraints) { | 2803 | if (has_full_constraints) { |
2625 | /* We log since this may kill the system if it | 2804 | /* We log since this may kill the system if it |
2626 | * goes wrong. */ | 2805 | * goes wrong. */ |
2627 | printk(KERN_INFO "%s: disabling %s\n", | 2806 | rdev_info(rdev, "disabling\n"); |
2628 | __func__, name); | ||
2629 | ret = ops->disable(rdev); | 2807 | ret = ops->disable(rdev); |
2630 | if (ret != 0) { | 2808 | if (ret != 0) { |
2631 | printk(KERN_ERR | 2809 | rdev_err(rdev, "couldn't disable: %d\n", ret); |
2632 | "%s: couldn't disable %s: %d\n", | ||
2633 | __func__, name, ret); | ||
2634 | } | 2810 | } |
2635 | } else { | 2811 | } else { |
2636 | /* The intention is that in future we will | 2812 | /* The intention is that in future we will |
@@ -2638,9 +2814,7 @@ static int __init regulator_init_complete(void) | |||
2638 | * so warn even if we aren't going to do | 2814 | * so warn even if we aren't going to do |
2639 | * anything here. | 2815 | * anything here. |
2640 | */ | 2816 | */ |
2641 | printk(KERN_WARNING | 2817 | rdev_warn(rdev, "incomplete constraints, leaving on\n"); |
2642 | "%s: incomplete constraints, leaving %s on\n", | ||
2643 | __func__, name); | ||
2644 | } | 2818 | } |
2645 | 2819 | ||
2646 | unlock: | 2820 | unlock: |
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index f8c4661a7a8..362e0822108 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c | |||
@@ -107,7 +107,7 @@ static inline int check_range(struct da903x_regulator_info *info, | |||
107 | 107 | ||
108 | /* DA9030/DA9034 common operations */ | 108 | /* DA9030/DA9034 common operations */ |
109 | static int da903x_set_ldo_voltage(struct regulator_dev *rdev, | 109 | static int da903x_set_ldo_voltage(struct regulator_dev *rdev, |
110 | int min_uV, int max_uV) | 110 | int min_uV, int max_uV, unsigned *selector) |
111 | { | 111 | { |
112 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); | 112 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); |
113 | struct device *da9034_dev = to_da903x_dev(rdev); | 113 | struct device *da9034_dev = to_da903x_dev(rdev); |
@@ -119,6 +119,7 @@ static int da903x_set_ldo_voltage(struct regulator_dev *rdev, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 121 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; |
122 | *selector = val; | ||
122 | val <<= info->vol_shift; | 123 | val <<= info->vol_shift; |
123 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 124 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
124 | 125 | ||
@@ -187,7 +188,8 @@ static int da903x_list_voltage(struct regulator_dev *rdev, unsigned selector) | |||
187 | 188 | ||
188 | /* DA9030 specific operations */ | 189 | /* DA9030 specific operations */ |
189 | static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, | 190 | static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, |
190 | int min_uV, int max_uV) | 191 | int min_uV, int max_uV, |
192 | unsigned *selector) | ||
191 | { | 193 | { |
192 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); | 194 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); |
193 | struct device *da903x_dev = to_da903x_dev(rdev); | 195 | struct device *da903x_dev = to_da903x_dev(rdev); |
@@ -200,6 +202,7 @@ static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, | |||
200 | } | 202 | } |
201 | 203 | ||
202 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 204 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; |
205 | *selector = val; | ||
203 | val <<= info->vol_shift; | 206 | val <<= info->vol_shift; |
204 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 207 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
205 | val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */ | 208 | val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */ |
@@ -214,7 +217,8 @@ static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, | |||
214 | } | 217 | } |
215 | 218 | ||
216 | static int da9030_set_ldo14_voltage(struct regulator_dev *rdev, | 219 | static int da9030_set_ldo14_voltage(struct regulator_dev *rdev, |
217 | int min_uV, int max_uV) | 220 | int min_uV, int max_uV, |
221 | unsigned *selector) | ||
218 | { | 222 | { |
219 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); | 223 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); |
220 | struct device *da903x_dev = to_da903x_dev(rdev); | 224 | struct device *da903x_dev = to_da903x_dev(rdev); |
@@ -234,6 +238,7 @@ static int da9030_set_ldo14_voltage(struct regulator_dev *rdev, | |||
234 | val = (min_uV - thresh + info->step_uV - 1) / info->step_uV; | 238 | val = (min_uV - thresh + info->step_uV - 1) / info->step_uV; |
235 | } | 239 | } |
236 | 240 | ||
241 | *selector = val; | ||
237 | val <<= info->vol_shift; | 242 | val <<= info->vol_shift; |
238 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 243 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
239 | 244 | ||
@@ -263,7 +268,7 @@ static int da9030_get_ldo14_voltage(struct regulator_dev *rdev) | |||
263 | 268 | ||
264 | /* DA9034 specific operations */ | 269 | /* DA9034 specific operations */ |
265 | static int da9034_set_dvc_voltage(struct regulator_dev *rdev, | 270 | static int da9034_set_dvc_voltage(struct regulator_dev *rdev, |
266 | int min_uV, int max_uV) | 271 | int min_uV, int max_uV, unsigned *selector) |
267 | { | 272 | { |
268 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); | 273 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); |
269 | struct device *da9034_dev = to_da903x_dev(rdev); | 274 | struct device *da9034_dev = to_da903x_dev(rdev); |
@@ -276,6 +281,7 @@ static int da9034_set_dvc_voltage(struct regulator_dev *rdev, | |||
276 | } | 281 | } |
277 | 282 | ||
278 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 283 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; |
284 | *selector = val; | ||
279 | val <<= info->vol_shift; | 285 | val <<= info->vol_shift; |
280 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 286 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
281 | 287 | ||
@@ -289,7 +295,7 @@ static int da9034_set_dvc_voltage(struct regulator_dev *rdev, | |||
289 | } | 295 | } |
290 | 296 | ||
291 | static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, | 297 | static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, |
292 | int min_uV, int max_uV) | 298 | int min_uV, int max_uV, unsigned *selector) |
293 | { | 299 | { |
294 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); | 300 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); |
295 | struct device *da9034_dev = to_da903x_dev(rdev); | 301 | struct device *da9034_dev = to_da903x_dev(rdev); |
@@ -302,6 +308,7 @@ static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, | |||
302 | 308 | ||
303 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 309 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; |
304 | val = (val >= 20) ? val - 12 : ((val > 7) ? 8 : val); | 310 | val = (val >= 20) ? val - 12 : ((val > 7) ? 8 : val); |
311 | *selector = val; | ||
305 | val <<= info->vol_shift; | 312 | val <<= info->vol_shift; |
306 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 313 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
307 | 314 | ||
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index b8cc6389a54..e4b3592e817 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c | |||
@@ -58,7 +58,9 @@ out: | |||
58 | return data; | 58 | return data; |
59 | } | 59 | } |
60 | 60 | ||
61 | static int isl6271a_set_voltage(struct regulator_dev *dev, int minuV, int maxuV) | 61 | static int isl6271a_set_voltage(struct regulator_dev *dev, |
62 | int minuV, int maxuV, | ||
63 | unsigned *selector) | ||
62 | { | 64 | { |
63 | struct isl_pmic *pmic = rdev_get_drvdata(dev); | 65 | struct isl_pmic *pmic = rdev_get_drvdata(dev); |
64 | int vsel, err, data; | 66 | int vsel, err, data; |
@@ -78,6 +80,8 @@ static int isl6271a_set_voltage(struct regulator_dev *dev, int minuV, int maxuV) | |||
78 | /* Convert the microvolts to data for the chip */ | 80 | /* Convert the microvolts to data for the chip */ |
79 | data = (vsel - ISL6271A_VOLTAGE_MIN) / ISL6271A_VOLTAGE_STEP; | 81 | data = (vsel - ISL6271A_VOLTAGE_MIN) / ISL6271A_VOLTAGE_STEP; |
80 | 82 | ||
83 | *selector = data; | ||
84 | |||
81 | mutex_lock(&pmic->mtx); | 85 | mutex_lock(&pmic->mtx); |
82 | 86 | ||
83 | err = i2c_smbus_write_byte(pmic->client, data); | 87 | err = i2c_smbus_write_byte(pmic->client, data); |
@@ -169,7 +173,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, | |||
169 | init_data, pmic); | 173 | init_data, pmic); |
170 | if (IS_ERR(pmic->rdev[i])) { | 174 | if (IS_ERR(pmic->rdev[i])) { |
171 | dev_err(&i2c->dev, "failed to register %s\n", id->name); | 175 | dev_err(&i2c->dev, "failed to register %s\n", id->name); |
172 | err = PTR_ERR(pmic->rdev); | 176 | err = PTR_ERR(pmic->rdev[i]); |
173 | goto error; | 177 | goto error; |
174 | } | 178 | } |
175 | } | 179 | } |
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 3bb82b624e1..0f22ef12601 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c | |||
@@ -168,7 +168,8 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev) | |||
168 | } | 168 | } |
169 | 169 | ||
170 | static int lp3971_ldo_set_voltage(struct regulator_dev *dev, | 170 | static int lp3971_ldo_set_voltage(struct regulator_dev *dev, |
171 | int min_uV, int max_uV) | 171 | int min_uV, int max_uV, |
172 | unsigned int *selector) | ||
172 | { | 173 | { |
173 | struct lp3971 *lp3971 = rdev_get_drvdata(dev); | 174 | struct lp3971 *lp3971 = rdev_get_drvdata(dev); |
174 | int ldo = rdev_get_id(dev) - LP3971_LDO1; | 175 | int ldo = rdev_get_id(dev) - LP3971_LDO1; |
@@ -187,6 +188,8 @@ static int lp3971_ldo_set_voltage(struct regulator_dev *dev, | |||
187 | if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol) | 188 | if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol) |
188 | return -EINVAL; | 189 | return -EINVAL; |
189 | 190 | ||
191 | *selector = val; | ||
192 | |||
190 | return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo), | 193 | return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo), |
191 | LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), | 194 | LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), |
192 | val << LDO_VOL_CONTR_SHIFT(ldo)); | 195 | val << LDO_VOL_CONTR_SHIFT(ldo)); |
@@ -256,7 +259,8 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev) | |||
256 | } | 259 | } |
257 | 260 | ||
258 | static int lp3971_dcdc_set_voltage(struct regulator_dev *dev, | 261 | static int lp3971_dcdc_set_voltage(struct regulator_dev *dev, |
259 | int min_uV, int max_uV) | 262 | int min_uV, int max_uV, |
263 | unsigned int *selector) | ||
260 | { | 264 | { |
261 | struct lp3971 *lp3971 = rdev_get_drvdata(dev); | 265 | struct lp3971 *lp3971 = rdev_get_drvdata(dev); |
262 | int buck = rdev_get_id(dev) - LP3971_DCDC1; | 266 | int buck = rdev_get_id(dev) - LP3971_DCDC1; |
@@ -277,6 +281,8 @@ static int lp3971_dcdc_set_voltage(struct regulator_dev *dev, | |||
277 | if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol) | 281 | if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol) |
278 | return -EINVAL; | 282 | return -EINVAL; |
279 | 283 | ||
284 | *selector = val; | ||
285 | |||
280 | ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck), | 286 | ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck), |
281 | BUCK_TARGET_VOL_MASK, val); | 287 | BUCK_TARGET_VOL_MASK, val); |
282 | if (ret) | 288 | if (ret) |
diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c index e07062fd0b4..6aa1b506fb5 100644 --- a/drivers/regulator/lp3972.c +++ b/drivers/regulator/lp3972.c | |||
@@ -292,7 +292,8 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev) | |||
292 | } | 292 | } |
293 | 293 | ||
294 | static int lp3972_ldo_set_voltage(struct regulator_dev *dev, | 294 | static int lp3972_ldo_set_voltage(struct regulator_dev *dev, |
295 | int min_uV, int max_uV) | 295 | int min_uV, int max_uV, |
296 | unsigned int *selector) | ||
296 | { | 297 | { |
297 | struct lp3972 *lp3972 = rdev_get_drvdata(dev); | 298 | struct lp3972 *lp3972 = rdev_get_drvdata(dev); |
298 | int ldo = rdev_get_id(dev) - LP3972_LDO1; | 299 | int ldo = rdev_get_id(dev) - LP3972_LDO1; |
@@ -313,6 +314,8 @@ static int lp3972_ldo_set_voltage(struct regulator_dev *dev, | |||
313 | if (val > LP3972_LDO_VOL_MAX_IDX(ldo) || vol_map[val] > max_vol) | 314 | if (val > LP3972_LDO_VOL_MAX_IDX(ldo) || vol_map[val] > max_vol) |
314 | return -EINVAL; | 315 | return -EINVAL; |
315 | 316 | ||
317 | *selector = val; | ||
318 | |||
316 | shift = LP3972_LDO_VOL_CONTR_SHIFT(ldo); | 319 | shift = LP3972_LDO_VOL_CONTR_SHIFT(ldo); |
317 | ret = lp3972_set_bits(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo), | 320 | ret = lp3972_set_bits(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo), |
318 | LP3972_LDO_VOL_MASK(ldo) << shift, val << shift); | 321 | LP3972_LDO_VOL_MASK(ldo) << shift, val << shift); |
@@ -416,7 +419,8 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev) | |||
416 | } | 419 | } |
417 | 420 | ||
418 | static int lp3972_dcdc_set_voltage(struct regulator_dev *dev, | 421 | static int lp3972_dcdc_set_voltage(struct regulator_dev *dev, |
419 | int min_uV, int max_uV) | 422 | int min_uV, int max_uV, |
423 | unsigned int *selector) | ||
420 | { | 424 | { |
421 | struct lp3972 *lp3972 = rdev_get_drvdata(dev); | 425 | struct lp3972 *lp3972 = rdev_get_drvdata(dev); |
422 | int buck = rdev_get_id(dev) - LP3972_DCDC1; | 426 | int buck = rdev_get_id(dev) - LP3972_DCDC1; |
@@ -438,6 +442,8 @@ static int lp3972_dcdc_set_voltage(struct regulator_dev *dev, | |||
438 | vol_map[val] > max_vol) | 442 | vol_map[val] > max_vol) |
439 | return -EINVAL; | 443 | return -EINVAL; |
440 | 444 | ||
445 | *selector = val; | ||
446 | |||
441 | ret = lp3972_set_bits(lp3972, LP3972_BUCK_VOL1_REG(buck), | 447 | ret = lp3972_set_bits(lp3972, LP3972_BUCK_VOL1_REG(buck), |
442 | LP3972_BUCK_VOL_MASK, val); | 448 | LP3972_BUCK_VOL_MASK, val); |
443 | if (ret) | 449 | if (ret) |
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 559cfa271a4..3f49512c513 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c | |||
@@ -63,12 +63,12 @@ static int max1586_v3_calc_voltage(struct max1586_data *max1586, | |||
63 | return max1586->min_uV + (selector * range_uV / MAX1586_V3_MAX_VSEL); | 63 | return max1586->min_uV + (selector * range_uV / MAX1586_V3_MAX_VSEL); |
64 | } | 64 | } |
65 | 65 | ||
66 | static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV) | 66 | static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV, |
67 | unsigned *selector) | ||
67 | { | 68 | { |
68 | struct max1586_data *max1586 = rdev_get_drvdata(rdev); | 69 | struct max1586_data *max1586 = rdev_get_drvdata(rdev); |
69 | struct i2c_client *client = max1586->client; | 70 | struct i2c_client *client = max1586->client; |
70 | unsigned range_uV = max1586->max_uV - max1586->min_uV; | 71 | unsigned range_uV = max1586->max_uV - max1586->min_uV; |
71 | unsigned selector; | ||
72 | u8 v3_prog; | 72 | u8 v3_prog; |
73 | 73 | ||
74 | if (min_uV > max1586->max_uV || max_uV < max1586->min_uV) | 74 | if (min_uV > max1586->max_uV || max_uV < max1586->min_uV) |
@@ -76,15 +76,15 @@ static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
76 | if (min_uV < max1586->min_uV) | 76 | if (min_uV < max1586->min_uV) |
77 | min_uV = max1586->min_uV; | 77 | min_uV = max1586->min_uV; |
78 | 78 | ||
79 | selector = ((min_uV - max1586->min_uV) * MAX1586_V3_MAX_VSEL + | 79 | *selector = ((min_uV - max1586->min_uV) * MAX1586_V3_MAX_VSEL + |
80 | range_uV - 1) / range_uV; | 80 | range_uV - 1) / range_uV; |
81 | if (max1586_v3_calc_voltage(max1586, selector) > max_uV) | 81 | if (max1586_v3_calc_voltage(max1586, *selector) > max_uV) |
82 | return -EINVAL; | 82 | return -EINVAL; |
83 | 83 | ||
84 | dev_dbg(&client->dev, "changing voltage v3 to %dmv\n", | 84 | dev_dbg(&client->dev, "changing voltage v3 to %dmv\n", |
85 | max1586_v3_calc_voltage(max1586, selector) / 1000); | 85 | max1586_v3_calc_voltage(max1586, *selector) / 1000); |
86 | 86 | ||
87 | v3_prog = I2C_V3_SELECT | (u8) selector; | 87 | v3_prog = I2C_V3_SELECT | (u8) *selector; |
88 | return i2c_smbus_write_byte(client, v3_prog); | 88 | return i2c_smbus_write_byte(client, v3_prog); |
89 | } | 89 | } |
90 | 90 | ||
@@ -110,10 +110,10 @@ static int max1586_v6_calc_voltage(unsigned selector) | |||
110 | return voltages_uv[selector]; | 110 | return voltages_uv[selector]; |
111 | } | 111 | } |
112 | 112 | ||
113 | static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV) | 113 | static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV, |
114 | unsigned int *selector) | ||
114 | { | 115 | { |
115 | struct i2c_client *client = rdev_get_drvdata(rdev); | 116 | struct i2c_client *client = rdev_get_drvdata(rdev); |
116 | unsigned selector; | ||
117 | u8 v6_prog; | 117 | u8 v6_prog; |
118 | 118 | ||
119 | if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV) | 119 | if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV) |
@@ -122,21 +122,21 @@ static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
122 | return -EINVAL; | 122 | return -EINVAL; |
123 | 123 | ||
124 | if (min_uV < 1800000) | 124 | if (min_uV < 1800000) |
125 | selector = 0; | 125 | *selector = 0; |
126 | else if (min_uV < 2500000) | 126 | else if (min_uV < 2500000) |
127 | selector = 1; | 127 | *selector = 1; |
128 | else if (min_uV < 3000000) | 128 | else if (min_uV < 3000000) |
129 | selector = 2; | 129 | *selector = 2; |
130 | else if (min_uV >= 3000000) | 130 | else if (min_uV >= 3000000) |
131 | selector = 3; | 131 | *selector = 3; |
132 | 132 | ||
133 | if (max1586_v6_calc_voltage(selector) > max_uV) | 133 | if (max1586_v6_calc_voltage(*selector) > max_uV) |
134 | return -EINVAL; | 134 | return -EINVAL; |
135 | 135 | ||
136 | dev_dbg(&client->dev, "changing voltage v6 to %dmv\n", | 136 | dev_dbg(&client->dev, "changing voltage v6 to %dmv\n", |
137 | max1586_v6_calc_voltage(selector) / 1000); | 137 | max1586_v6_calc_voltage(*selector) / 1000); |
138 | 138 | ||
139 | v6_prog = I2C_V6_SELECT | (u8) selector; | 139 | v6_prog = I2C_V6_SELECT | (u8) *selector; |
140 | return i2c_smbus_write_byte(client, v6_prog); | 140 | return i2c_smbus_write_byte(client, v6_prog); |
141 | } | 141 | } |
142 | 142 | ||
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 6b60a9c0366..30eb9e54f7e 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
@@ -155,7 +155,7 @@ static int max8649_get_voltage(struct regulator_dev *rdev) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | static int max8649_set_voltage(struct regulator_dev *rdev, | 157 | static int max8649_set_voltage(struct regulator_dev *rdev, |
158 | int min_uV, int max_uV) | 158 | int min_uV, int max_uV, unsigned *selector) |
159 | { | 159 | { |
160 | struct max8649_regulator_info *info = rdev_get_drvdata(rdev); | 160 | struct max8649_regulator_info *info = rdev_get_drvdata(rdev); |
161 | unsigned char data, mask; | 161 | unsigned char data, mask; |
@@ -168,6 +168,7 @@ static int max8649_set_voltage(struct regulator_dev *rdev, | |||
168 | data = (min_uV - MAX8649_DCDC_VMIN + MAX8649_DCDC_STEP - 1) | 168 | data = (min_uV - MAX8649_DCDC_VMIN + MAX8649_DCDC_STEP - 1) |
169 | / MAX8649_DCDC_STEP; | 169 | / MAX8649_DCDC_STEP; |
170 | mask = MAX8649_VOL_MASK; | 170 | mask = MAX8649_VOL_MASK; |
171 | *selector = data & mask; | ||
171 | 172 | ||
172 | return max8649_set_bits(info->i2c, info->vol_reg, mask, data); | 173 | return max8649_set_bits(info->i2c, info->vol_reg, mask, data); |
173 | } | 174 | } |
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index c570e6eb0db..33f5d9a492e 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c | |||
@@ -141,7 +141,8 @@ static int max8660_dcdc_get(struct regulator_dev *rdev) | |||
141 | return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; | 141 | return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV) | 144 | static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV, |
145 | unsigned int *s) | ||
145 | { | 146 | { |
146 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 147 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
147 | u8 reg, selector, bits; | 148 | u8 reg, selector, bits; |
@@ -154,6 +155,7 @@ static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
154 | 155 | ||
155 | selector = (min_uV - (MAX8660_DCDC_MIN_UV - MAX8660_DCDC_STEP + 1)) | 156 | selector = (min_uV - (MAX8660_DCDC_MIN_UV - MAX8660_DCDC_STEP + 1)) |
156 | / MAX8660_DCDC_STEP; | 157 | / MAX8660_DCDC_STEP; |
158 | *s = selector; | ||
157 | 159 | ||
158 | ret = max8660_dcdc_list(rdev, selector); | 160 | ret = max8660_dcdc_list(rdev, selector); |
159 | if (ret < 0 || ret > max_uV) | 161 | if (ret < 0 || ret > max_uV) |
@@ -196,7 +198,8 @@ static int max8660_ldo5_get(struct regulator_dev *rdev) | |||
196 | return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; | 198 | return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; |
197 | } | 199 | } |
198 | 200 | ||
199 | static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV) | 201 | static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV, |
202 | unsigned int *s) | ||
200 | { | 203 | { |
201 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 204 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
202 | u8 selector; | 205 | u8 selector; |
@@ -213,6 +216,8 @@ static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
213 | if (ret < 0 || ret > max_uV) | 216 | if (ret < 0 || ret > max_uV) |
214 | return -EINVAL; | 217 | return -EINVAL; |
215 | 218 | ||
219 | *s = selector; | ||
220 | |||
216 | ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector); | 221 | ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector); |
217 | if (ret) | 222 | if (ret) |
218 | return ret; | 223 | return ret; |
@@ -270,7 +275,8 @@ static int max8660_ldo67_get(struct regulator_dev *rdev) | |||
270 | return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP; | 275 | return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP; |
271 | } | 276 | } |
272 | 277 | ||
273 | static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, int max_uV) | 278 | static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, |
279 | int max_uV, unsigned int *s) | ||
274 | { | 280 | { |
275 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 281 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
276 | u8 selector; | 282 | u8 selector; |
@@ -288,6 +294,8 @@ static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
288 | if (ret < 0 || ret > max_uV) | 294 | if (ret < 0 || ret > max_uV) |
289 | return -EINVAL; | 295 | return -EINVAL; |
290 | 296 | ||
297 | *s = selector; | ||
298 | |||
291 | if (rdev_get_id(rdev) == MAX8660_V6) | 299 | if (rdev_get_id(rdev) == MAX8660_V6) |
292 | return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector); | 300 | return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector); |
293 | else | 301 | else |
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 552cad85ae5..8ae147549c6 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c | |||
@@ -55,7 +55,7 @@ static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | static int max8925_set_voltage(struct regulator_dev *rdev, | 57 | static int max8925_set_voltage(struct regulator_dev *rdev, |
58 | int min_uV, int max_uV) | 58 | int min_uV, int max_uV, unsigned int *selector) |
59 | { | 59 | { |
60 | struct max8925_regulator_info *info = rdev_get_drvdata(rdev); | 60 | struct max8925_regulator_info *info = rdev_get_drvdata(rdev); |
61 | unsigned char data, mask; | 61 | unsigned char data, mask; |
@@ -66,6 +66,7 @@ static int max8925_set_voltage(struct regulator_dev *rdev, | |||
66 | return -EINVAL; | 66 | return -EINVAL; |
67 | } | 67 | } |
68 | data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 68 | data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; |
69 | *selector = data; | ||
69 | data <<= info->vol_shift; | 70 | data <<= info->vol_shift; |
70 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 71 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
71 | 72 | ||
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index 0d5dda4fd91..a8f4ecfb084 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c | |||
@@ -133,7 +133,7 @@ static int max8952_get_voltage(struct regulator_dev *rdev) | |||
133 | } | 133 | } |
134 | 134 | ||
135 | static int max8952_set_voltage(struct regulator_dev *rdev, | 135 | static int max8952_set_voltage(struct regulator_dev *rdev, |
136 | int min_uV, int max_uV) | 136 | int min_uV, int max_uV, unsigned *selector) |
137 | { | 137 | { |
138 | struct max8952_data *max8952 = rdev_get_drvdata(rdev); | 138 | struct max8952_data *max8952 = rdev_get_drvdata(rdev); |
139 | s8 vid = -1, i; | 139 | s8 vid = -1, i; |
@@ -156,6 +156,7 @@ static int max8952_set_voltage(struct regulator_dev *rdev, | |||
156 | if (vid >= 0 && vid < MAX8952_NUM_DVS_MODE) { | 156 | if (vid >= 0 && vid < MAX8952_NUM_DVS_MODE) { |
157 | max8952->vid0 = (vid % 2 == 1); | 157 | max8952->vid0 = (vid % 2 == 1); |
158 | max8952->vid1 = (((vid >> 1) % 2) == 1); | 158 | max8952->vid1 = (((vid >> 1) % 2) == 1); |
159 | *selector = vid; | ||
159 | gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0); | 160 | gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0); |
160 | gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1); | 161 | gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1); |
161 | } else | 162 | } else |
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 5c20756db60..7568df6122a 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
@@ -304,7 +304,7 @@ static int max8998_get_voltage(struct regulator_dev *rdev) | |||
304 | } | 304 | } |
305 | 305 | ||
306 | static int max8998_set_voltage_ldo(struct regulator_dev *rdev, | 306 | static int max8998_set_voltage_ldo(struct regulator_dev *rdev, |
307 | int min_uV, int max_uV) | 307 | int min_uV, int max_uV, unsigned *selector) |
308 | { | 308 | { |
309 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | 309 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); |
310 | struct i2c_client *i2c = max8998->iodev->i2c; | 310 | struct i2c_client *i2c = max8998->iodev->i2c; |
@@ -331,6 +331,8 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev, | |||
331 | if (desc->min + desc->step*i > max_vol) | 331 | if (desc->min + desc->step*i > max_vol) |
332 | return -EINVAL; | 332 | return -EINVAL; |
333 | 333 | ||
334 | *selector = i; | ||
335 | |||
334 | ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); | 336 | ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); |
335 | if (ret) | 337 | if (ret) |
336 | return ret; | 338 | return ret; |
@@ -352,7 +354,7 @@ static inline void buck2_gpio_set(int gpio, int v) | |||
352 | } | 354 | } |
353 | 355 | ||
354 | static int max8998_set_voltage_buck(struct regulator_dev *rdev, | 356 | static int max8998_set_voltage_buck(struct regulator_dev *rdev, |
355 | int min_uV, int max_uV) | 357 | int min_uV, int max_uV, unsigned *selector) |
356 | { | 358 | { |
357 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | 359 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); |
358 | struct max8998_platform_data *pdata = | 360 | struct max8998_platform_data *pdata = |
@@ -384,6 +386,8 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, | |||
384 | if (desc->min + desc->step*i > max_vol) | 386 | if (desc->min + desc->step*i > max_vol) |
385 | return -EINVAL; | 387 | return -EINVAL; |
386 | 388 | ||
389 | *selector = i; | ||
390 | |||
387 | ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); | 391 | ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); |
388 | if (ret) | 392 | if (ret) |
389 | return ret; | 393 | return ret; |
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index ecd99f59dba..3e5d0c3b4e5 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Regulator Driver for Freescale MC13783 PMIC | 2 | * Regulator Driver for Freescale MC13783 PMIC |
3 | * | 3 | * |
4 | * Copyright 2010 Yong Shen <yong.shen@linaro.org> | ||
4 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | 5 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> |
5 | * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | 6 | * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> |
6 | * | 7 | * |
@@ -17,6 +18,7 @@ | |||
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include "mc13xxx.h" | ||
20 | 22 | ||
21 | #define MC13783_REG_SWITCHERS5 29 | 23 | #define MC13783_REG_SWITCHERS5 29 |
22 | #define MC13783_REG_SWITCHERS5_SW3EN (1 << 20) | 24 | #define MC13783_REG_SWITCHERS5_SW3EN (1 << 20) |
@@ -89,154 +91,106 @@ | |||
89 | #define MC13783_REG_POWERMISC_PWGTSPI_M (3 << 15) | 91 | #define MC13783_REG_POWERMISC_PWGTSPI_M (3 << 15) |
90 | 92 | ||
91 | 93 | ||
92 | struct mc13783_regulator { | ||
93 | struct regulator_desc desc; | ||
94 | int reg; | ||
95 | int enable_bit; | ||
96 | int vsel_reg; | ||
97 | int vsel_shift; | ||
98 | int vsel_mask; | ||
99 | int const *voltages; | ||
100 | }; | ||
101 | |||
102 | /* Voltage Values */ | 94 | /* Voltage Values */ |
103 | static const int const mc13783_sw3_val[] = { | 95 | static const int mc13783_sw3_val[] = { |
104 | 5000000, 5000000, 5000000, 5500000, | 96 | 5000000, 5000000, 5000000, 5500000, |
105 | }; | 97 | }; |
106 | 98 | ||
107 | static const int const mc13783_vaudio_val[] = { | 99 | static const int mc13783_vaudio_val[] = { |
108 | 2775000, | 100 | 2775000, |
109 | }; | 101 | }; |
110 | 102 | ||
111 | static const int const mc13783_viohi_val[] = { | 103 | static const int mc13783_viohi_val[] = { |
112 | 2775000, | 104 | 2775000, |
113 | }; | 105 | }; |
114 | 106 | ||
115 | static const int const mc13783_violo_val[] = { | 107 | static const int mc13783_violo_val[] = { |
116 | 1200000, 1300000, 1500000, 1800000, | 108 | 1200000, 1300000, 1500000, 1800000, |
117 | }; | 109 | }; |
118 | 110 | ||
119 | static const int const mc13783_vdig_val[] = { | 111 | static const int mc13783_vdig_val[] = { |
120 | 1200000, 1300000, 1500000, 1800000, | 112 | 1200000, 1300000, 1500000, 1800000, |
121 | }; | 113 | }; |
122 | 114 | ||
123 | static const int const mc13783_vgen_val[] = { | 115 | static const int mc13783_vgen_val[] = { |
124 | 1200000, 1300000, 1500000, 1800000, | 116 | 1200000, 1300000, 1500000, 1800000, |
125 | 1100000, 2000000, 2775000, 2400000, | 117 | 1100000, 2000000, 2775000, 2400000, |
126 | }; | 118 | }; |
127 | 119 | ||
128 | static const int const mc13783_vrfdig_val[] = { | 120 | static const int mc13783_vrfdig_val[] = { |
129 | 1200000, 1500000, 1800000, 1875000, | 121 | 1200000, 1500000, 1800000, 1875000, |
130 | }; | 122 | }; |
131 | 123 | ||
132 | static const int const mc13783_vrfref_val[] = { | 124 | static const int mc13783_vrfref_val[] = { |
133 | 2475000, 2600000, 2700000, 2775000, | 125 | 2475000, 2600000, 2700000, 2775000, |
134 | }; | 126 | }; |
135 | 127 | ||
136 | static const int const mc13783_vrfcp_val[] = { | 128 | static const int mc13783_vrfcp_val[] = { |
137 | 2700000, 2775000, | 129 | 2700000, 2775000, |
138 | }; | 130 | }; |
139 | 131 | ||
140 | static const int const mc13783_vsim_val[] = { | 132 | static const int mc13783_vsim_val[] = { |
141 | 1800000, 2900000, 3000000, | 133 | 1800000, 2900000, 3000000, |
142 | }; | 134 | }; |
143 | 135 | ||
144 | static const int const mc13783_vesim_val[] = { | 136 | static const int mc13783_vesim_val[] = { |
145 | 1800000, 2900000, | 137 | 1800000, 2900000, |
146 | }; | 138 | }; |
147 | 139 | ||
148 | static const int const mc13783_vcam_val[] = { | 140 | static const int mc13783_vcam_val[] = { |
149 | 1500000, 1800000, 2500000, 2550000, | 141 | 1500000, 1800000, 2500000, 2550000, |
150 | 2600000, 2750000, 2800000, 3000000, | 142 | 2600000, 2750000, 2800000, 3000000, |
151 | }; | 143 | }; |
152 | 144 | ||
153 | static const int const mc13783_vrfbg_val[] = { | 145 | static const int mc13783_vrfbg_val[] = { |
154 | 1250000, | 146 | 1250000, |
155 | }; | 147 | }; |
156 | 148 | ||
157 | static const int const mc13783_vvib_val[] = { | 149 | static const int mc13783_vvib_val[] = { |
158 | 1300000, 1800000, 2000000, 3000000, | 150 | 1300000, 1800000, 2000000, 3000000, |
159 | }; | 151 | }; |
160 | 152 | ||
161 | static const int const mc13783_vmmc_val[] = { | 153 | static const int mc13783_vmmc_val[] = { |
162 | 1600000, 1800000, 2000000, 2600000, | 154 | 1600000, 1800000, 2000000, 2600000, |
163 | 2700000, 2800000, 2900000, 3000000, | 155 | 2700000, 2800000, 2900000, 3000000, |
164 | }; | 156 | }; |
165 | 157 | ||
166 | static const int const mc13783_vrf_val[] = { | 158 | static const int mc13783_vrf_val[] = { |
167 | 1500000, 1875000, 2700000, 2775000, | 159 | 1500000, 1875000, 2700000, 2775000, |
168 | }; | 160 | }; |
169 | 161 | ||
170 | static const int const mc13783_gpo_val[] = { | 162 | static const int mc13783_gpo_val[] = { |
171 | 3100000, | 163 | 3100000, |
172 | }; | 164 | }; |
173 | 165 | ||
174 | static const int const mc13783_pwgtdrv_val[] = { | 166 | static const int mc13783_pwgtdrv_val[] = { |
175 | 5500000, | 167 | 5500000, |
176 | }; | 168 | }; |
177 | 169 | ||
178 | static struct regulator_ops mc13783_regulator_ops; | ||
179 | static struct regulator_ops mc13783_fixed_regulator_ops; | ||
180 | static struct regulator_ops mc13783_gpo_regulator_ops; | 170 | static struct regulator_ops mc13783_gpo_regulator_ops; |
181 | 171 | ||
182 | #define MC13783_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages) \ | 172 | #define MC13783_DEFINE(prefix, name, reg, vsel_reg, voltages) \ |
183 | [MC13783_ ## prefix ## _ ## _name] = { \ | 173 | MC13xxx_DEFINE(MC13783_REG_, name, reg, vsel_reg, voltages, \ |
184 | .desc = { \ | 174 | mc13xxx_regulator_ops) |
185 | .name = #prefix "_" #_name, \ | ||
186 | .n_voltages = ARRAY_SIZE(_voltages), \ | ||
187 | .ops = &mc13783_regulator_ops, \ | ||
188 | .type = REGULATOR_VOLTAGE, \ | ||
189 | .id = MC13783_ ## prefix ## _ ## _name, \ | ||
190 | .owner = THIS_MODULE, \ | ||
191 | }, \ | ||
192 | .reg = MC13783_REG_ ## _reg, \ | ||
193 | .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ | ||
194 | .vsel_reg = MC13783_REG_ ## _vsel_reg, \ | ||
195 | .vsel_shift = MC13783_REG_ ## _vsel_reg ## _ ## _name ## VSEL,\ | ||
196 | .vsel_mask = MC13783_REG_ ## _vsel_reg ## _ ## _name ## VSEL_M,\ | ||
197 | .voltages = _voltages, \ | ||
198 | } | ||
199 | 175 | ||
200 | #define MC13783_FIXED_DEFINE(prefix, _name, _reg, _voltages) \ | 176 | #define MC13783_FIXED_DEFINE(prefix, name, reg, voltages) \ |
201 | [MC13783_ ## prefix ## _ ## _name] = { \ | 177 | MC13xxx_FIXED_DEFINE(MC13783_REG_, name, reg, voltages, \ |
202 | .desc = { \ | 178 | mc13xxx_fixed_regulator_ops) |
203 | .name = #prefix "_" #_name, \ | ||
204 | .n_voltages = ARRAY_SIZE(_voltages), \ | ||
205 | .ops = &mc13783_fixed_regulator_ops, \ | ||
206 | .type = REGULATOR_VOLTAGE, \ | ||
207 | .id = MC13783_ ## prefix ## _ ## _name, \ | ||
208 | .owner = THIS_MODULE, \ | ||
209 | }, \ | ||
210 | .reg = MC13783_REG_ ## _reg, \ | ||
211 | .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ | ||
212 | .voltages = _voltages, \ | ||
213 | } | ||
214 | 179 | ||
215 | #define MC13783_GPO_DEFINE(prefix, _name, _reg, _voltages) \ | 180 | #define MC13783_GPO_DEFINE(prefix, name, reg, voltages) \ |
216 | [MC13783_ ## prefix ## _ ## _name] = { \ | 181 | MC13xxx_GPO_DEFINE(MC13783_REG_, name, reg, voltages, \ |
217 | .desc = { \ | 182 | mc13783_gpo_regulator_ops) |
218 | .name = #prefix "_" #_name, \ | ||
219 | .n_voltages = ARRAY_SIZE(_voltages), \ | ||
220 | .ops = &mc13783_gpo_regulator_ops, \ | ||
221 | .type = REGULATOR_VOLTAGE, \ | ||
222 | .id = MC13783_ ## prefix ## _ ## _name, \ | ||
223 | .owner = THIS_MODULE, \ | ||
224 | }, \ | ||
225 | .reg = MC13783_REG_ ## _reg, \ | ||
226 | .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ | ||
227 | .voltages = _voltages, \ | ||
228 | } | ||
229 | 183 | ||
230 | #define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages) \ | 184 | #define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages) \ |
231 | MC13783_DEFINE(SW, _name, _reg, _vsel_reg, _voltages) | 185 | MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages) |
232 | #define MC13783_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages) \ | 186 | #define MC13783_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages) \ |
233 | MC13783_DEFINE(REGU, _name, _reg, _vsel_reg, _voltages) | 187 | MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages) |
234 | 188 | ||
235 | static struct mc13783_regulator mc13783_regulators[] = { | 189 | static struct mc13xxx_regulator mc13783_regulators[] = { |
236 | MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val), | 190 | MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val), |
237 | 191 | ||
238 | MC13783_FIXED_DEFINE(REGU, VAUDIO, REGULATORMODE0, mc13783_vaudio_val), | 192 | MC13783_FIXED_DEFINE(REG, VAUDIO, REGULATORMODE0, mc13783_vaudio_val), |
239 | MC13783_FIXED_DEFINE(REGU, VIOHI, REGULATORMODE0, mc13783_viohi_val), | 193 | MC13783_FIXED_DEFINE(REG, VIOHI, REGULATORMODE0, mc13783_viohi_val), |
240 | MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0, REGULATORSETTING0, \ | 194 | MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0, REGULATORSETTING0, \ |
241 | mc13783_violo_val), | 195 | mc13783_violo_val), |
242 | MC13783_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, \ | 196 | MC13783_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, \ |
@@ -255,7 +209,7 @@ static struct mc13783_regulator mc13783_regulators[] = { | |||
255 | mc13783_vesim_val), | 209 | mc13783_vesim_val), |
256 | MC13783_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, \ | 210 | MC13783_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, \ |
257 | mc13783_vcam_val), | 211 | mc13783_vcam_val), |
258 | MC13783_FIXED_DEFINE(REGU, VRFBG, REGULATORMODE1, mc13783_vrfbg_val), | 212 | MC13783_FIXED_DEFINE(REG, VRFBG, REGULATORMODE1, mc13783_vrfbg_val), |
259 | MC13783_DEFINE_REGU(VVIB, REGULATORMODE1, REGULATORSETTING1, \ | 213 | MC13783_DEFINE_REGU(VVIB, REGULATORMODE1, REGULATORSETTING1, \ |
260 | mc13783_vvib_val), | 214 | mc13783_vvib_val), |
261 | MC13783_DEFINE_REGU(VRF1, REGULATORMODE1, REGULATORSETTING1, \ | 215 | MC13783_DEFINE_REGU(VRF1, REGULATORMODE1, REGULATORSETTING1, \ |
@@ -266,215 +220,24 @@ static struct mc13783_regulator mc13783_regulators[] = { | |||
266 | mc13783_vmmc_val), | 220 | mc13783_vmmc_val), |
267 | MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1, \ | 221 | MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1, \ |
268 | mc13783_vmmc_val), | 222 | mc13783_vmmc_val), |
269 | MC13783_GPO_DEFINE(REGU, GPO1, POWERMISC, mc13783_gpo_val), | 223 | MC13783_GPO_DEFINE(REG, GPO1, POWERMISC, mc13783_gpo_val), |
270 | MC13783_GPO_DEFINE(REGU, GPO2, POWERMISC, mc13783_gpo_val), | 224 | MC13783_GPO_DEFINE(REG, GPO2, POWERMISC, mc13783_gpo_val), |
271 | MC13783_GPO_DEFINE(REGU, GPO3, POWERMISC, mc13783_gpo_val), | 225 | MC13783_GPO_DEFINE(REG, GPO3, POWERMISC, mc13783_gpo_val), |
272 | MC13783_GPO_DEFINE(REGU, GPO4, POWERMISC, mc13783_gpo_val), | 226 | MC13783_GPO_DEFINE(REG, GPO4, POWERMISC, mc13783_gpo_val), |
273 | MC13783_GPO_DEFINE(REGU, PWGT1SPI, POWERMISC, mc13783_pwgtdrv_val), | 227 | MC13783_GPO_DEFINE(REG, PWGT1SPI, POWERMISC, mc13783_pwgtdrv_val), |
274 | MC13783_GPO_DEFINE(REGU, PWGT2SPI, POWERMISC, mc13783_pwgtdrv_val), | 228 | MC13783_GPO_DEFINE(REG, PWGT2SPI, POWERMISC, mc13783_pwgtdrv_val), |
275 | }; | ||
276 | |||
277 | struct mc13783_regulator_priv { | ||
278 | struct mc13783 *mc13783; | ||
279 | u32 powermisc_pwgt_state; | ||
280 | struct regulator_dev *regulators[]; | ||
281 | }; | ||
282 | |||
283 | static int mc13783_regulator_enable(struct regulator_dev *rdev) | ||
284 | { | ||
285 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
286 | int id = rdev_get_id(rdev); | ||
287 | int ret; | ||
288 | |||
289 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
290 | |||
291 | mc13783_lock(priv->mc13783); | ||
292 | ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg, | ||
293 | mc13783_regulators[id].enable_bit, | ||
294 | mc13783_regulators[id].enable_bit); | ||
295 | mc13783_unlock(priv->mc13783); | ||
296 | |||
297 | return ret; | ||
298 | } | ||
299 | |||
300 | static int mc13783_regulator_disable(struct regulator_dev *rdev) | ||
301 | { | ||
302 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
303 | int id = rdev_get_id(rdev); | ||
304 | int ret; | ||
305 | |||
306 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
307 | |||
308 | mc13783_lock(priv->mc13783); | ||
309 | ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg, | ||
310 | mc13783_regulators[id].enable_bit, 0); | ||
311 | mc13783_unlock(priv->mc13783); | ||
312 | |||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | static int mc13783_regulator_is_enabled(struct regulator_dev *rdev) | ||
317 | { | ||
318 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
319 | int ret, id = rdev_get_id(rdev); | ||
320 | unsigned int val; | ||
321 | |||
322 | mc13783_lock(priv->mc13783); | ||
323 | ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); | ||
324 | mc13783_unlock(priv->mc13783); | ||
325 | |||
326 | if (ret) | ||
327 | return ret; | ||
328 | |||
329 | return (val & mc13783_regulators[id].enable_bit) != 0; | ||
330 | } | ||
331 | |||
332 | static int mc13783_regulator_list_voltage(struct regulator_dev *rdev, | ||
333 | unsigned selector) | ||
334 | { | ||
335 | int id = rdev_get_id(rdev); | ||
336 | |||
337 | if (selector >= mc13783_regulators[id].desc.n_voltages) | ||
338 | return -EINVAL; | ||
339 | |||
340 | return mc13783_regulators[id].voltages[selector]; | ||
341 | } | ||
342 | |||
343 | static int mc13783_get_best_voltage_index(struct regulator_dev *rdev, | ||
344 | int min_uV, int max_uV) | ||
345 | { | ||
346 | int reg_id = rdev_get_id(rdev); | ||
347 | int i; | ||
348 | int bestmatch; | ||
349 | int bestindex; | ||
350 | |||
351 | /* | ||
352 | * Locate the minimum voltage fitting the criteria on | ||
353 | * this regulator. The switchable voltages are not | ||
354 | * in strict falling order so we need to check them | ||
355 | * all for the best match. | ||
356 | */ | ||
357 | bestmatch = INT_MAX; | ||
358 | bestindex = -1; | ||
359 | for (i = 0; i < mc13783_regulators[reg_id].desc.n_voltages; i++) { | ||
360 | if (mc13783_regulators[reg_id].voltages[i] >= min_uV && | ||
361 | mc13783_regulators[reg_id].voltages[i] < bestmatch) { | ||
362 | bestmatch = mc13783_regulators[reg_id].voltages[i]; | ||
363 | bestindex = i; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | if (bestindex < 0 || bestmatch > max_uV) { | ||
368 | dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n", | ||
369 | min_uV, max_uV); | ||
370 | return -EINVAL; | ||
371 | } | ||
372 | return bestindex; | ||
373 | } | ||
374 | |||
375 | static int mc13783_regulator_set_voltage(struct regulator_dev *rdev, | ||
376 | int min_uV, int max_uV) | ||
377 | { | ||
378 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
379 | int value, id = rdev_get_id(rdev); | ||
380 | int ret; | ||
381 | |||
382 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", | ||
383 | __func__, id, min_uV, max_uV); | ||
384 | |||
385 | /* Find the best index */ | ||
386 | value = mc13783_get_best_voltage_index(rdev, min_uV, max_uV); | ||
387 | dev_dbg(rdev_get_dev(rdev), "%s best value: %d \n", __func__, value); | ||
388 | if (value < 0) | ||
389 | return value; | ||
390 | |||
391 | mc13783_lock(priv->mc13783); | ||
392 | ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].vsel_reg, | ||
393 | mc13783_regulators[id].vsel_mask, | ||
394 | value << mc13783_regulators[id].vsel_shift); | ||
395 | mc13783_unlock(priv->mc13783); | ||
396 | |||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | static int mc13783_regulator_get_voltage(struct regulator_dev *rdev) | ||
401 | { | ||
402 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
403 | int ret, id = rdev_get_id(rdev); | ||
404 | unsigned int val; | ||
405 | |||
406 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
407 | |||
408 | mc13783_lock(priv->mc13783); | ||
409 | ret = mc13783_reg_read(priv->mc13783, | ||
410 | mc13783_regulators[id].vsel_reg, &val); | ||
411 | mc13783_unlock(priv->mc13783); | ||
412 | |||
413 | if (ret) | ||
414 | return ret; | ||
415 | |||
416 | val = (val & mc13783_regulators[id].vsel_mask) | ||
417 | >> mc13783_regulators[id].vsel_shift; | ||
418 | |||
419 | dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); | ||
420 | |||
421 | BUG_ON(val < 0 || val > mc13783_regulators[id].desc.n_voltages); | ||
422 | |||
423 | return mc13783_regulators[id].voltages[val]; | ||
424 | } | ||
425 | |||
426 | static struct regulator_ops mc13783_regulator_ops = { | ||
427 | .enable = mc13783_regulator_enable, | ||
428 | .disable = mc13783_regulator_disable, | ||
429 | .is_enabled = mc13783_regulator_is_enabled, | ||
430 | .list_voltage = mc13783_regulator_list_voltage, | ||
431 | .set_voltage = mc13783_regulator_set_voltage, | ||
432 | .get_voltage = mc13783_regulator_get_voltage, | ||
433 | }; | ||
434 | |||
435 | static int mc13783_fixed_regulator_set_voltage(struct regulator_dev *rdev, | ||
436 | int min_uV, int max_uV) | ||
437 | { | ||
438 | int id = rdev_get_id(rdev); | ||
439 | |||
440 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", | ||
441 | __func__, id, min_uV, max_uV); | ||
442 | |||
443 | if (min_uV >= mc13783_regulators[id].voltages[0] && | ||
444 | max_uV <= mc13783_regulators[id].voltages[0]) | ||
445 | return 0; | ||
446 | else | ||
447 | return -EINVAL; | ||
448 | } | ||
449 | |||
450 | static int mc13783_fixed_regulator_get_voltage(struct regulator_dev *rdev) | ||
451 | { | ||
452 | int id = rdev_get_id(rdev); | ||
453 | |||
454 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
455 | |||
456 | return mc13783_regulators[id].voltages[0]; | ||
457 | } | ||
458 | |||
459 | static struct regulator_ops mc13783_fixed_regulator_ops = { | ||
460 | .enable = mc13783_regulator_enable, | ||
461 | .disable = mc13783_regulator_disable, | ||
462 | .is_enabled = mc13783_regulator_is_enabled, | ||
463 | .list_voltage = mc13783_regulator_list_voltage, | ||
464 | .set_voltage = mc13783_fixed_regulator_set_voltage, | ||
465 | .get_voltage = mc13783_fixed_regulator_get_voltage, | ||
466 | }; | 229 | }; |
467 | 230 | ||
468 | static int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask, | 231 | static int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, |
469 | u32 val) | 232 | u32 val) |
470 | { | 233 | { |
471 | struct mc13783 *mc13783 = priv->mc13783; | 234 | struct mc13xxx *mc13783 = priv->mc13xxx; |
472 | int ret; | 235 | int ret; |
473 | u32 valread; | 236 | u32 valread; |
474 | 237 | ||
475 | BUG_ON(val & ~mask); | 238 | BUG_ON(val & ~mask); |
476 | 239 | ||
477 | ret = mc13783_reg_read(mc13783, MC13783_REG_POWERMISC, &valread); | 240 | ret = mc13xxx_reg_read(mc13783, MC13783_REG_POWERMISC, &valread); |
478 | if (ret) | 241 | if (ret) |
479 | return ret; | 242 | return ret; |
480 | 243 | ||
@@ -489,34 +252,36 @@ static int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask, | |||
489 | valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) | | 252 | valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) | |
490 | priv->powermisc_pwgt_state; | 253 | priv->powermisc_pwgt_state; |
491 | 254 | ||
492 | return mc13783_reg_write(mc13783, MC13783_REG_POWERMISC, valread); | 255 | return mc13xxx_reg_write(mc13783, MC13783_REG_POWERMISC, valread); |
493 | } | 256 | } |
494 | 257 | ||
495 | static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev) | 258 | static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev) |
496 | { | 259 | { |
497 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | 260 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
261 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
498 | int id = rdev_get_id(rdev); | 262 | int id = rdev_get_id(rdev); |
499 | int ret; | 263 | int ret; |
500 | u32 en_val = mc13783_regulators[id].enable_bit; | 264 | u32 en_val = mc13xxx_regulators[id].enable_bit; |
501 | 265 | ||
502 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | 266 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); |
503 | 267 | ||
504 | /* Power Gate enable value is 0 */ | 268 | /* Power Gate enable value is 0 */ |
505 | if (id == MC13783_REGU_PWGT1SPI || | 269 | if (id == MC13783_REG_PWGT1SPI || |
506 | id == MC13783_REGU_PWGT2SPI) | 270 | id == MC13783_REG_PWGT2SPI) |
507 | en_val = 0; | 271 | en_val = 0; |
508 | 272 | ||
509 | mc13783_lock(priv->mc13783); | 273 | mc13xxx_lock(priv->mc13xxx); |
510 | ret = mc13783_powermisc_rmw(priv, mc13783_regulators[id].enable_bit, | 274 | ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit, |
511 | en_val); | 275 | en_val); |
512 | mc13783_unlock(priv->mc13783); | 276 | mc13xxx_unlock(priv->mc13xxx); |
513 | 277 | ||
514 | return ret; | 278 | return ret; |
515 | } | 279 | } |
516 | 280 | ||
517 | static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev) | 281 | static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev) |
518 | { | 282 | { |
519 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | 283 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
284 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
520 | int id = rdev_get_id(rdev); | 285 | int id = rdev_get_id(rdev); |
521 | int ret; | 286 | int ret; |
522 | u32 dis_val = 0; | 287 | u32 dis_val = 0; |
@@ -524,27 +289,28 @@ static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev) | |||
524 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | 289 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); |
525 | 290 | ||
526 | /* Power Gate disable value is 1 */ | 291 | /* Power Gate disable value is 1 */ |
527 | if (id == MC13783_REGU_PWGT1SPI || | 292 | if (id == MC13783_REG_PWGT1SPI || |
528 | id == MC13783_REGU_PWGT2SPI) | 293 | id == MC13783_REG_PWGT2SPI) |
529 | dis_val = mc13783_regulators[id].enable_bit; | 294 | dis_val = mc13xxx_regulators[id].enable_bit; |
530 | 295 | ||
531 | mc13783_lock(priv->mc13783); | 296 | mc13xxx_lock(priv->mc13xxx); |
532 | ret = mc13783_powermisc_rmw(priv, mc13783_regulators[id].enable_bit, | 297 | ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit, |
533 | dis_val); | 298 | dis_val); |
534 | mc13783_unlock(priv->mc13783); | 299 | mc13xxx_unlock(priv->mc13xxx); |
535 | 300 | ||
536 | return ret; | 301 | return ret; |
537 | } | 302 | } |
538 | 303 | ||
539 | static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev) | 304 | static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev) |
540 | { | 305 | { |
541 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | 306 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
307 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
542 | int ret, id = rdev_get_id(rdev); | 308 | int ret, id = rdev_get_id(rdev); |
543 | unsigned int val; | 309 | unsigned int val; |
544 | 310 | ||
545 | mc13783_lock(priv->mc13783); | 311 | mc13xxx_lock(priv->mc13xxx); |
546 | ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); | 312 | ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val); |
547 | mc13783_unlock(priv->mc13783); | 313 | mc13xxx_unlock(priv->mc13xxx); |
548 | 314 | ||
549 | if (ret) | 315 | if (ret) |
550 | return ret; | 316 | return ret; |
@@ -554,22 +320,22 @@ static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev) | |||
554 | val = (val & ~MC13783_REG_POWERMISC_PWGTSPI_M) | | 320 | val = (val & ~MC13783_REG_POWERMISC_PWGTSPI_M) | |
555 | (priv->powermisc_pwgt_state ^ MC13783_REG_POWERMISC_PWGTSPI_M); | 321 | (priv->powermisc_pwgt_state ^ MC13783_REG_POWERMISC_PWGTSPI_M); |
556 | 322 | ||
557 | return (val & mc13783_regulators[id].enable_bit) != 0; | 323 | return (val & mc13xxx_regulators[id].enable_bit) != 0; |
558 | } | 324 | } |
559 | 325 | ||
560 | static struct regulator_ops mc13783_gpo_regulator_ops = { | 326 | static struct regulator_ops mc13783_gpo_regulator_ops = { |
561 | .enable = mc13783_gpo_regulator_enable, | 327 | .enable = mc13783_gpo_regulator_enable, |
562 | .disable = mc13783_gpo_regulator_disable, | 328 | .disable = mc13783_gpo_regulator_disable, |
563 | .is_enabled = mc13783_gpo_regulator_is_enabled, | 329 | .is_enabled = mc13783_gpo_regulator_is_enabled, |
564 | .list_voltage = mc13783_regulator_list_voltage, | 330 | .list_voltage = mc13xxx_regulator_list_voltage, |
565 | .set_voltage = mc13783_fixed_regulator_set_voltage, | 331 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, |
566 | .get_voltage = mc13783_fixed_regulator_get_voltage, | 332 | .get_voltage = mc13xxx_fixed_regulator_get_voltage, |
567 | }; | 333 | }; |
568 | 334 | ||
569 | static int __devinit mc13783_regulator_probe(struct platform_device *pdev) | 335 | static int __devinit mc13783_regulator_probe(struct platform_device *pdev) |
570 | { | 336 | { |
571 | struct mc13783_regulator_priv *priv; | 337 | struct mc13xxx_regulator_priv *priv; |
572 | struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent); | 338 | struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); |
573 | struct mc13783_regulator_platform_data *pdata = | 339 | struct mc13783_regulator_platform_data *pdata = |
574 | dev_get_platdata(&pdev->dev); | 340 | dev_get_platdata(&pdev->dev); |
575 | struct mc13783_regulator_init_data *init_data; | 341 | struct mc13783_regulator_init_data *init_data; |
@@ -583,7 +349,8 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev) | |||
583 | if (!priv) | 349 | if (!priv) |
584 | return -ENOMEM; | 350 | return -ENOMEM; |
585 | 351 | ||
586 | priv->mc13783 = mc13783; | 352 | priv->mc13xxx_regulators = mc13783_regulators; |
353 | priv->mc13xxx = mc13783; | ||
587 | 354 | ||
588 | for (i = 0; i < pdata->num_regulators; i++) { | 355 | for (i = 0; i < pdata->num_regulators; i++) { |
589 | init_data = &pdata->regulators[i]; | 356 | init_data = &pdata->regulators[i]; |
@@ -613,7 +380,7 @@ err: | |||
613 | 380 | ||
614 | static int __devexit mc13783_regulator_remove(struct platform_device *pdev) | 381 | static int __devexit mc13783_regulator_remove(struct platform_device *pdev) |
615 | { | 382 | { |
616 | struct mc13783_regulator_priv *priv = platform_get_drvdata(pdev); | 383 | struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); |
617 | struct mc13783_regulator_platform_data *pdata = | 384 | struct mc13783_regulator_platform_data *pdata = |
618 | dev_get_platdata(&pdev->dev); | 385 | dev_get_platdata(&pdev->dev); |
619 | int i; | 386 | int i; |
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c new file mode 100644 index 00000000000..1b8f7398a4a --- /dev/null +++ b/drivers/regulator/mc13892-regulator.c | |||
@@ -0,0 +1,635 @@ | |||
1 | /* | ||
2 | * Regulator Driver for Freescale MC13892 PMIC | ||
3 | * | ||
4 | * Copyright 2010 Yong Shen <yong.shen@linaro.org> | ||
5 | * | ||
6 | * Based on draft driver from Arnaud Patard <arnaud.patard@rtp-net.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/mfd/mc13892.h> | ||
14 | #include <linux/regulator/machine.h> | ||
15 | #include <linux/regulator/driver.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/err.h> | ||
21 | #include "mc13xxx.h" | ||
22 | |||
23 | #define MC13892_REVISION 7 | ||
24 | |||
25 | #define MC13892_POWERCTL0 13 | ||
26 | #define MC13892_POWERCTL0_USEROFFSPI 3 | ||
27 | #define MC13892_POWERCTL0_VCOINCELLVSEL 20 | ||
28 | #define MC13892_POWERCTL0_VCOINCELLVSEL_M (7<<20) | ||
29 | #define MC13892_POWERCTL0_VCOINCELLEN (1<<23) | ||
30 | |||
31 | #define MC13892_SWITCHERS0_SWxHI (1<<23) | ||
32 | |||
33 | #define MC13892_SWITCHERS0 24 | ||
34 | #define MC13892_SWITCHERS0_SW1VSEL 0 | ||
35 | #define MC13892_SWITCHERS0_SW1VSEL_M (0x1f<<0) | ||
36 | #define MC13892_SWITCHERS0_SW1HI (1<<23) | ||
37 | #define MC13892_SWITCHERS0_SW1EN 0 | ||
38 | |||
39 | #define MC13892_SWITCHERS1 25 | ||
40 | #define MC13892_SWITCHERS1_SW2VSEL 0 | ||
41 | #define MC13892_SWITCHERS1_SW2VSEL_M (0x1f<<0) | ||
42 | #define MC13892_SWITCHERS1_SW2HI (1<<23) | ||
43 | #define MC13892_SWITCHERS1_SW2EN 0 | ||
44 | |||
45 | #define MC13892_SWITCHERS2 26 | ||
46 | #define MC13892_SWITCHERS2_SW3VSEL 0 | ||
47 | #define MC13892_SWITCHERS2_SW3VSEL_M (0x1f<<0) | ||
48 | #define MC13892_SWITCHERS2_SW3HI (1<<23) | ||
49 | #define MC13892_SWITCHERS2_SW3EN 0 | ||
50 | |||
51 | #define MC13892_SWITCHERS3 27 | ||
52 | #define MC13892_SWITCHERS3_SW4VSEL 0 | ||
53 | #define MC13892_SWITCHERS3_SW4VSEL_M (0x1f<<0) | ||
54 | #define MC13892_SWITCHERS3_SW4HI (1<<23) | ||
55 | #define MC13892_SWITCHERS3_SW4EN 0 | ||
56 | |||
57 | #define MC13892_SWITCHERS4 28 | ||
58 | #define MC13892_SWITCHERS4_SW1MODE 0 | ||
59 | #define MC13892_SWITCHERS4_SW1MODE_AUTO (8<<0) | ||
60 | #define MC13892_SWITCHERS4_SW1MODE_M (0xf<<0) | ||
61 | #define MC13892_SWITCHERS4_SW2MODE 10 | ||
62 | #define MC13892_SWITCHERS4_SW2MODE_AUTO (8<<10) | ||
63 | #define MC13892_SWITCHERS4_SW2MODE_M (0xf<<10) | ||
64 | |||
65 | #define MC13892_SWITCHERS5 29 | ||
66 | #define MC13892_SWITCHERS5_SW3MODE 0 | ||
67 | #define MC13892_SWITCHERS5_SW3MODE_AUTO (8<<0) | ||
68 | #define MC13892_SWITCHERS5_SW3MODE_M (0xf<<0) | ||
69 | #define MC13892_SWITCHERS5_SW4MODE 8 | ||
70 | #define MC13892_SWITCHERS5_SW4MODE_AUTO (8<<8) | ||
71 | #define MC13892_SWITCHERS5_SW4MODE_M (0xf<<8) | ||
72 | #define MC13892_SWITCHERS5_SWBSTEN (1<<20) | ||
73 | |||
74 | #define MC13892_REGULATORSETTING0 30 | ||
75 | #define MC13892_REGULATORSETTING0_VGEN1VSEL 0 | ||
76 | #define MC13892_REGULATORSETTING0_VDIGVSEL 4 | ||
77 | #define MC13892_REGULATORSETTING0_VGEN2VSEL 6 | ||
78 | #define MC13892_REGULATORSETTING0_VPLLVSEL 9 | ||
79 | #define MC13892_REGULATORSETTING0_VUSB2VSEL 11 | ||
80 | #define MC13892_REGULATORSETTING0_VGEN3VSEL 14 | ||
81 | #define MC13892_REGULATORSETTING0_VCAMVSEL 16 | ||
82 | |||
83 | #define MC13892_REGULATORSETTING0_VGEN1VSEL_M (3<<0) | ||
84 | #define MC13892_REGULATORSETTING0_VDIGVSEL_M (3<<4) | ||
85 | #define MC13892_REGULATORSETTING0_VGEN2VSEL_M (7<<6) | ||
86 | #define MC13892_REGULATORSETTING0_VPLLVSEL_M (3<<9) | ||
87 | #define MC13892_REGULATORSETTING0_VUSB2VSEL_M (3<<11) | ||
88 | #define MC13892_REGULATORSETTING0_VGEN3VSEL_M (1<<14) | ||
89 | #define MC13892_REGULATORSETTING0_VCAMVSEL_M (3<<16) | ||
90 | |||
91 | #define MC13892_REGULATORSETTING1 31 | ||
92 | #define MC13892_REGULATORSETTING1_VVIDEOVSEL 2 | ||
93 | #define MC13892_REGULATORSETTING1_VAUDIOVSEL 4 | ||
94 | #define MC13892_REGULATORSETTING1_VSDVSEL 6 | ||
95 | |||
96 | #define MC13892_REGULATORSETTING1_VVIDEOVSEL_M (3<<2) | ||
97 | #define MC13892_REGULATORSETTING1_VAUDIOVSEL_M (3<<4) | ||
98 | #define MC13892_REGULATORSETTING1_VSDVSEL_M (7<<6) | ||
99 | |||
100 | #define MC13892_REGULATORMODE0 32 | ||
101 | #define MC13892_REGULATORMODE0_VGEN1EN (1<<0) | ||
102 | #define MC13892_REGULATORMODE0_VGEN1STDBY (1<<1) | ||
103 | #define MC13892_REGULATORMODE0_VGEN1MODE (1<<2) | ||
104 | #define MC13892_REGULATORMODE0_VIOHIEN (1<<3) | ||
105 | #define MC13892_REGULATORMODE0_VIOHISTDBY (1<<4) | ||
106 | #define MC13892_REGULATORMODE0_VIOHIMODE (1<<5) | ||
107 | #define MC13892_REGULATORMODE0_VDIGEN (1<<9) | ||
108 | #define MC13892_REGULATORMODE0_VDIGSTDBY (1<<10) | ||
109 | #define MC13892_REGULATORMODE0_VDIGMODE (1<<11) | ||
110 | #define MC13892_REGULATORMODE0_VGEN2EN (1<<12) | ||
111 | #define MC13892_REGULATORMODE0_VGEN2STDBY (1<<13) | ||
112 | #define MC13892_REGULATORMODE0_VGEN2MODE (1<<14) | ||
113 | #define MC13892_REGULATORMODE0_VPLLEN (1<<15) | ||
114 | #define MC13892_REGULATORMODE0_VPLLSTDBY (1<<16) | ||
115 | #define MC13892_REGULATORMODE0_VPLLMODE (1<<17) | ||
116 | #define MC13892_REGULATORMODE0_VUSB2EN (1<<18) | ||
117 | #define MC13892_REGULATORMODE0_VUSB2STDBY (1<<19) | ||
118 | #define MC13892_REGULATORMODE0_VUSB2MODE (1<<20) | ||
119 | |||
120 | #define MC13892_REGULATORMODE1 33 | ||
121 | #define MC13892_REGULATORMODE1_VGEN3EN (1<<0) | ||
122 | #define MC13892_REGULATORMODE1_VGEN3STDBY (1<<1) | ||
123 | #define MC13892_REGULATORMODE1_VGEN3MODE (1<<2) | ||
124 | #define MC13892_REGULATORMODE1_VCAMEN (1<<6) | ||
125 | #define MC13892_REGULATORMODE1_VCAMSTDBY (1<<7) | ||
126 | #define MC13892_REGULATORMODE1_VCAMMODE (1<<8) | ||
127 | #define MC13892_REGULATORMODE1_VCAMCONFIGEN (1<<9) | ||
128 | #define MC13892_REGULATORMODE1_VVIDEOEN (1<<12) | ||
129 | #define MC13892_REGULATORMODE1_VVIDEOSTDBY (1<<13) | ||
130 | #define MC13892_REGULATORMODE1_VVIDEOMODE (1<<14) | ||
131 | #define MC13892_REGULATORMODE1_VAUDIOEN (1<<15) | ||
132 | #define MC13892_REGULATORMODE1_VAUDIOSTDBY (1<<16) | ||
133 | #define MC13892_REGULATORMODE1_VAUDIOMODE (1<<17) | ||
134 | #define MC13892_REGULATORMODE1_VSDEN (1<<18) | ||
135 | #define MC13892_REGULATORMODE1_VSDSTDBY (1<<19) | ||
136 | #define MC13892_REGULATORMODE1_VSDMODE (1<<20) | ||
137 | |||
138 | #define MC13892_POWERMISC 34 | ||
139 | #define MC13892_POWERMISC_GPO1EN (1<<6) | ||
140 | #define MC13892_POWERMISC_GPO2EN (1<<8) | ||
141 | #define MC13892_POWERMISC_GPO3EN (1<<10) | ||
142 | #define MC13892_POWERMISC_GPO4EN (1<<12) | ||
143 | #define MC13892_POWERMISC_PWGT1SPIEN (1<<15) | ||
144 | #define MC13892_POWERMISC_PWGT2SPIEN (1<<16) | ||
145 | #define MC13892_POWERMISC_GPO4ADINEN (1<<21) | ||
146 | |||
147 | #define MC13892_POWERMISC_PWGTSPI_M (3 << 15) | ||
148 | |||
149 | #define MC13892_USB1 50 | ||
150 | #define MC13892_USB1_VUSBEN (1<<3) | ||
151 | |||
152 | static const int mc13892_vcoincell[] = { | ||
153 | 2500000, 2700000, 2800000, 2900000, 3000000, 3100000, | ||
154 | 3200000, 3300000, | ||
155 | }; | ||
156 | |||
157 | static const int mc13892_sw1[] = { | ||
158 | 600000, 625000, 650000, 675000, 700000, 725000, | ||
159 | 750000, 775000, 800000, 825000, 850000, 875000, | ||
160 | 900000, 925000, 950000, 975000, 1000000, 1025000, | ||
161 | 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, | ||
162 | 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, | ||
163 | 1350000, 1375000 | ||
164 | }; | ||
165 | |||
166 | static const int mc13892_sw[] = { | ||
167 | 600000, 625000, 650000, 675000, 700000, 725000, | ||
168 | 750000, 775000, 800000, 825000, 850000, 875000, | ||
169 | 900000, 925000, 950000, 975000, 1000000, 1025000, | ||
170 | 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, | ||
171 | 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, | ||
172 | 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, | ||
173 | 1500000, 1525000, 1550000, 1575000, 1600000, 1625000, | ||
174 | 1650000, 1675000, 1700000, 1725000, 1750000, 1775000, | ||
175 | 1800000, 1825000, 1850000, 1875000 | ||
176 | }; | ||
177 | |||
178 | static const int mc13892_swbst[] = { | ||
179 | 5000000, | ||
180 | }; | ||
181 | |||
182 | static const int mc13892_viohi[] = { | ||
183 | 2775000, | ||
184 | }; | ||
185 | |||
186 | static const int mc13892_vpll[] = { | ||
187 | 1050000, 1250000, 1650000, 1800000, | ||
188 | }; | ||
189 | |||
190 | static const int mc13892_vdig[] = { | ||
191 | 1050000, 1250000, 1650000, 1800000, | ||
192 | }; | ||
193 | |||
194 | static const int mc13892_vsd[] = { | ||
195 | 1800000, 2000000, 2600000, 2700000, | ||
196 | 2800000, 2900000, 3000000, 3150000, | ||
197 | }; | ||
198 | |||
199 | static const int mc13892_vusb2[] = { | ||
200 | 2400000, 2600000, 2700000, 2775000, | ||
201 | }; | ||
202 | |||
203 | static const int mc13892_vvideo[] = { | ||
204 | 2700000, 2775000, 2500000, 2600000, | ||
205 | }; | ||
206 | |||
207 | static const int mc13892_vaudio[] = { | ||
208 | 2300000, 2500000, 2775000, 3000000, | ||
209 | }; | ||
210 | |||
211 | static const int mc13892_vcam[] = { | ||
212 | 2500000, 2600000, 2750000, 3000000, | ||
213 | }; | ||
214 | |||
215 | static const int mc13892_vgen1[] = { | ||
216 | 1200000, 1500000, 2775000, 3150000, | ||
217 | }; | ||
218 | |||
219 | static const int mc13892_vgen2[] = { | ||
220 | 1200000, 1500000, 1600000, 1800000, | ||
221 | 2700000, 2800000, 3000000, 3150000, | ||
222 | }; | ||
223 | |||
224 | static const int mc13892_vgen3[] = { | ||
225 | 1800000, 2900000, | ||
226 | }; | ||
227 | |||
228 | static const int mc13892_vusb[] = { | ||
229 | 3300000, | ||
230 | }; | ||
231 | |||
232 | static const int mc13892_gpo[] = { | ||
233 | 2750000, | ||
234 | }; | ||
235 | |||
236 | static const int mc13892_pwgtdrv[] = { | ||
237 | 5000000, | ||
238 | }; | ||
239 | |||
240 | static struct regulator_ops mc13892_gpo_regulator_ops; | ||
241 | /* sw regulators need special care due to the "hi bit" */ | ||
242 | static struct regulator_ops mc13892_sw_regulator_ops; | ||
243 | |||
244 | |||
245 | #define MC13892_FIXED_DEFINE(name, reg, voltages) \ | ||
246 | MC13xxx_FIXED_DEFINE(MC13892_, name, reg, voltages, \ | ||
247 | mc13xxx_fixed_regulator_ops) | ||
248 | |||
249 | #define MC13892_GPO_DEFINE(name, reg, voltages) \ | ||
250 | MC13xxx_GPO_DEFINE(MC13892_, name, reg, voltages, \ | ||
251 | mc13892_gpo_regulator_ops) | ||
252 | |||
253 | #define MC13892_SW_DEFINE(name, reg, vsel_reg, voltages) \ | ||
254 | MC13xxx_DEFINE(MC13892_, name, reg, vsel_reg, voltages, \ | ||
255 | mc13892_sw_regulator_ops) | ||
256 | |||
257 | #define MC13892_DEFINE_REGU(name, reg, vsel_reg, voltages) \ | ||
258 | MC13xxx_DEFINE(MC13892_, name, reg, vsel_reg, voltages, \ | ||
259 | mc13xxx_regulator_ops) | ||
260 | |||
261 | static struct mc13xxx_regulator mc13892_regulators[] = { | ||
262 | MC13892_DEFINE_REGU(VCOINCELL, POWERCTL0, POWERCTL0, mc13892_vcoincell), | ||
263 | MC13892_SW_DEFINE(SW1, SWITCHERS0, SWITCHERS0, mc13892_sw1), | ||
264 | MC13892_SW_DEFINE(SW2, SWITCHERS1, SWITCHERS1, mc13892_sw), | ||
265 | MC13892_SW_DEFINE(SW3, SWITCHERS2, SWITCHERS2, mc13892_sw), | ||
266 | MC13892_SW_DEFINE(SW4, SWITCHERS3, SWITCHERS3, mc13892_sw), | ||
267 | MC13892_FIXED_DEFINE(SWBST, SWITCHERS5, mc13892_swbst), | ||
268 | MC13892_FIXED_DEFINE(VIOHI, REGULATORMODE0, mc13892_viohi), | ||
269 | MC13892_DEFINE_REGU(VPLL, REGULATORMODE0, REGULATORSETTING0, \ | ||
270 | mc13892_vpll), | ||
271 | MC13892_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, \ | ||
272 | mc13892_vdig), | ||
273 | MC13892_DEFINE_REGU(VSD, REGULATORMODE1, REGULATORSETTING1, \ | ||
274 | mc13892_vsd), | ||
275 | MC13892_DEFINE_REGU(VUSB2, REGULATORMODE0, REGULATORSETTING0, \ | ||
276 | mc13892_vusb2), | ||
277 | MC13892_DEFINE_REGU(VVIDEO, REGULATORMODE1, REGULATORSETTING1, \ | ||
278 | mc13892_vvideo), | ||
279 | MC13892_DEFINE_REGU(VAUDIO, REGULATORMODE1, REGULATORSETTING1, \ | ||
280 | mc13892_vaudio), | ||
281 | MC13892_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, \ | ||
282 | mc13892_vcam), | ||
283 | MC13892_DEFINE_REGU(VGEN1, REGULATORMODE0, REGULATORSETTING0, \ | ||
284 | mc13892_vgen1), | ||
285 | MC13892_DEFINE_REGU(VGEN2, REGULATORMODE0, REGULATORSETTING0, \ | ||
286 | mc13892_vgen2), | ||
287 | MC13892_DEFINE_REGU(VGEN3, REGULATORMODE1, REGULATORSETTING0, \ | ||
288 | mc13892_vgen3), | ||
289 | MC13892_FIXED_DEFINE(VUSB, USB1, mc13892_vusb), | ||
290 | MC13892_GPO_DEFINE(GPO1, POWERMISC, mc13892_gpo), | ||
291 | MC13892_GPO_DEFINE(GPO2, POWERMISC, mc13892_gpo), | ||
292 | MC13892_GPO_DEFINE(GPO3, POWERMISC, mc13892_gpo), | ||
293 | MC13892_GPO_DEFINE(GPO4, POWERMISC, mc13892_gpo), | ||
294 | MC13892_GPO_DEFINE(PWGT1SPI, POWERMISC, mc13892_pwgtdrv), | ||
295 | MC13892_GPO_DEFINE(PWGT2SPI, POWERMISC, mc13892_pwgtdrv), | ||
296 | }; | ||
297 | |||
298 | static int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, | ||
299 | u32 val) | ||
300 | { | ||
301 | struct mc13xxx *mc13892 = priv->mc13xxx; | ||
302 | int ret; | ||
303 | u32 valread; | ||
304 | |||
305 | BUG_ON(val & ~mask); | ||
306 | |||
307 | ret = mc13xxx_reg_read(mc13892, MC13892_POWERMISC, &valread); | ||
308 | if (ret) | ||
309 | return ret; | ||
310 | |||
311 | /* Update the stored state for Power Gates. */ | ||
312 | priv->powermisc_pwgt_state = | ||
313 | (priv->powermisc_pwgt_state & ~mask) | val; | ||
314 | priv->powermisc_pwgt_state &= MC13892_POWERMISC_PWGTSPI_M; | ||
315 | |||
316 | /* Construct the new register value */ | ||
317 | valread = (valread & ~mask) | val; | ||
318 | /* Overwrite the PWGTxEN with the stored version */ | ||
319 | valread = (valread & ~MC13892_POWERMISC_PWGTSPI_M) | | ||
320 | priv->powermisc_pwgt_state; | ||
321 | |||
322 | return mc13xxx_reg_write(mc13892, MC13892_POWERMISC, valread); | ||
323 | } | ||
324 | |||
325 | static int mc13892_gpo_regulator_enable(struct regulator_dev *rdev) | ||
326 | { | ||
327 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
328 | int id = rdev_get_id(rdev); | ||
329 | int ret; | ||
330 | u32 en_val = mc13892_regulators[id].enable_bit; | ||
331 | u32 mask = mc13892_regulators[id].enable_bit; | ||
332 | |||
333 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
334 | |||
335 | /* Power Gate enable value is 0 */ | ||
336 | if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI) | ||
337 | en_val = 0; | ||
338 | |||
339 | if (id == MC13892_GPO4) | ||
340 | mask |= MC13892_POWERMISC_GPO4ADINEN; | ||
341 | |||
342 | mc13xxx_lock(priv->mc13xxx); | ||
343 | ret = mc13892_powermisc_rmw(priv, mask, en_val); | ||
344 | mc13xxx_unlock(priv->mc13xxx); | ||
345 | |||
346 | return ret; | ||
347 | } | ||
348 | |||
349 | static int mc13892_gpo_regulator_disable(struct regulator_dev *rdev) | ||
350 | { | ||
351 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
352 | int id = rdev_get_id(rdev); | ||
353 | int ret; | ||
354 | u32 dis_val = 0; | ||
355 | |||
356 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
357 | |||
358 | /* Power Gate disable value is 1 */ | ||
359 | if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI) | ||
360 | dis_val = mc13892_regulators[id].enable_bit; | ||
361 | |||
362 | mc13xxx_lock(priv->mc13xxx); | ||
363 | ret = mc13892_powermisc_rmw(priv, mc13892_regulators[id].enable_bit, | ||
364 | dis_val); | ||
365 | mc13xxx_unlock(priv->mc13xxx); | ||
366 | |||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev) | ||
371 | { | ||
372 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
373 | int ret, id = rdev_get_id(rdev); | ||
374 | unsigned int val; | ||
375 | |||
376 | mc13xxx_lock(priv->mc13xxx); | ||
377 | ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val); | ||
378 | mc13xxx_unlock(priv->mc13xxx); | ||
379 | |||
380 | if (ret) | ||
381 | return ret; | ||
382 | |||
383 | /* Power Gates state is stored in powermisc_pwgt_state | ||
384 | * where the meaning of bits is negated */ | ||
385 | val = (val & ~MC13892_POWERMISC_PWGTSPI_M) | | ||
386 | (priv->powermisc_pwgt_state ^ MC13892_POWERMISC_PWGTSPI_M); | ||
387 | |||
388 | return (val & mc13892_regulators[id].enable_bit) != 0; | ||
389 | } | ||
390 | |||
391 | |||
392 | static struct regulator_ops mc13892_gpo_regulator_ops = { | ||
393 | .enable = mc13892_gpo_regulator_enable, | ||
394 | .disable = mc13892_gpo_regulator_disable, | ||
395 | .is_enabled = mc13892_gpo_regulator_is_enabled, | ||
396 | .list_voltage = mc13xxx_regulator_list_voltage, | ||
397 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, | ||
398 | .get_voltage = mc13xxx_fixed_regulator_get_voltage, | ||
399 | }; | ||
400 | |||
401 | static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev) | ||
402 | { | ||
403 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
404 | int ret, id = rdev_get_id(rdev); | ||
405 | unsigned int val, hi; | ||
406 | |||
407 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
408 | |||
409 | mc13xxx_lock(priv->mc13xxx); | ||
410 | ret = mc13xxx_reg_read(priv->mc13xxx, | ||
411 | mc13892_regulators[id].vsel_reg, &val); | ||
412 | mc13xxx_unlock(priv->mc13xxx); | ||
413 | if (ret) | ||
414 | return ret; | ||
415 | |||
416 | hi = val & MC13892_SWITCHERS0_SWxHI; | ||
417 | val = (val & mc13892_regulators[id].vsel_mask) | ||
418 | >> mc13892_regulators[id].vsel_shift; | ||
419 | |||
420 | dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); | ||
421 | |||
422 | if (hi) | ||
423 | val = (25000 * val) + 1100000; | ||
424 | else | ||
425 | val = (25000 * val) + 600000; | ||
426 | |||
427 | return val; | ||
428 | } | ||
429 | |||
430 | static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, | ||
431 | int min_uV, int max_uV, unsigned *selector) | ||
432 | { | ||
433 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
434 | int hi, value, val, mask, id = rdev_get_id(rdev); | ||
435 | int ret; | ||
436 | |||
437 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", | ||
438 | __func__, id, min_uV, max_uV); | ||
439 | |||
440 | /* Find the best index */ | ||
441 | value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV); | ||
442 | dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value); | ||
443 | if (value < 0) | ||
444 | return value; | ||
445 | |||
446 | value = mc13892_regulators[id].voltages[value]; | ||
447 | |||
448 | mc13xxx_lock(priv->mc13xxx); | ||
449 | ret = mc13xxx_reg_read(priv->mc13xxx, | ||
450 | mc13892_regulators[id].vsel_reg, &val); | ||
451 | if (ret) | ||
452 | goto err; | ||
453 | |||
454 | hi = val & MC13892_SWITCHERS0_SWxHI; | ||
455 | if (value > 1375) | ||
456 | hi = 1; | ||
457 | if (value < 1100) | ||
458 | hi = 0; | ||
459 | |||
460 | if (hi) { | ||
461 | value = (value - 1100000) / 25000; | ||
462 | value |= MC13892_SWITCHERS0_SWxHI; | ||
463 | } else | ||
464 | value = (value - 600000) / 25000; | ||
465 | |||
466 | mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI; | ||
467 | ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg, | ||
468 | mask, value << mc13892_regulators[id].vsel_shift); | ||
469 | err: | ||
470 | mc13xxx_unlock(priv->mc13xxx); | ||
471 | |||
472 | return ret; | ||
473 | } | ||
474 | |||
475 | static struct regulator_ops mc13892_sw_regulator_ops = { | ||
476 | .is_enabled = mc13xxx_sw_regulator_is_enabled, | ||
477 | .list_voltage = mc13xxx_regulator_list_voltage, | ||
478 | .set_voltage = mc13892_sw_regulator_set_voltage, | ||
479 | .get_voltage = mc13892_sw_regulator_get_voltage, | ||
480 | }; | ||
481 | |||
482 | static int mc13892_vcam_set_mode(struct regulator_dev *rdev, unsigned int mode) | ||
483 | { | ||
484 | unsigned int en_val = 0; | ||
485 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
486 | int ret, id = rdev_get_id(rdev); | ||
487 | |||
488 | if (mode == REGULATOR_MODE_FAST) | ||
489 | en_val = MC13892_REGULATORMODE1_VCAMCONFIGEN; | ||
490 | |||
491 | mc13xxx_lock(priv->mc13xxx); | ||
492 | ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].reg, | ||
493 | MC13892_REGULATORMODE1_VCAMCONFIGEN, en_val); | ||
494 | mc13xxx_unlock(priv->mc13xxx); | ||
495 | |||
496 | return ret; | ||
497 | } | ||
498 | |||
499 | static unsigned int mc13892_vcam_get_mode(struct regulator_dev *rdev) | ||
500 | { | ||
501 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
502 | int ret, id = rdev_get_id(rdev); | ||
503 | unsigned int val; | ||
504 | |||
505 | mc13xxx_lock(priv->mc13xxx); | ||
506 | ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val); | ||
507 | mc13xxx_unlock(priv->mc13xxx); | ||
508 | |||
509 | if (ret) | ||
510 | return ret; | ||
511 | |||
512 | if (val & MC13892_REGULATORMODE1_VCAMCONFIGEN) | ||
513 | return REGULATOR_MODE_FAST; | ||
514 | |||
515 | return REGULATOR_MODE_NORMAL; | ||
516 | } | ||
517 | |||
518 | |||
519 | static int __devinit mc13892_regulator_probe(struct platform_device *pdev) | ||
520 | { | ||
521 | struct mc13xxx_regulator_priv *priv; | ||
522 | struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); | ||
523 | struct mc13xxx_regulator_platform_data *pdata = | ||
524 | dev_get_platdata(&pdev->dev); | ||
525 | struct mc13xxx_regulator_init_data *init_data; | ||
526 | int i, ret; | ||
527 | u32 val; | ||
528 | |||
529 | priv = kzalloc(sizeof(*priv) + | ||
530 | pdata->num_regulators * sizeof(priv->regulators[0]), | ||
531 | GFP_KERNEL); | ||
532 | if (!priv) | ||
533 | return -ENOMEM; | ||
534 | |||
535 | priv->mc13xxx_regulators = mc13892_regulators; | ||
536 | priv->mc13xxx = mc13892; | ||
537 | |||
538 | mc13xxx_lock(mc13892); | ||
539 | ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val); | ||
540 | if (ret) | ||
541 | goto err_free; | ||
542 | |||
543 | /* enable switch auto mode */ | ||
544 | if ((val & 0x0000FFFF) == 0x45d0) { | ||
545 | ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS4, | ||
546 | MC13892_SWITCHERS4_SW1MODE_M | | ||
547 | MC13892_SWITCHERS4_SW2MODE_M, | ||
548 | MC13892_SWITCHERS4_SW1MODE_AUTO | | ||
549 | MC13892_SWITCHERS4_SW2MODE_AUTO); | ||
550 | if (ret) | ||
551 | goto err_free; | ||
552 | |||
553 | ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS5, | ||
554 | MC13892_SWITCHERS5_SW3MODE_M | | ||
555 | MC13892_SWITCHERS5_SW4MODE_M, | ||
556 | MC13892_SWITCHERS5_SW3MODE_AUTO | | ||
557 | MC13892_SWITCHERS5_SW4MODE_AUTO); | ||
558 | if (ret) | ||
559 | goto err_free; | ||
560 | } | ||
561 | mc13xxx_unlock(mc13892); | ||
562 | |||
563 | mc13892_regulators[MC13892_VCAM].desc.ops->set_mode | ||
564 | = mc13892_vcam_set_mode; | ||
565 | mc13892_regulators[MC13892_VCAM].desc.ops->get_mode | ||
566 | = mc13892_vcam_get_mode; | ||
567 | for (i = 0; i < pdata->num_regulators; i++) { | ||
568 | init_data = &pdata->regulators[i]; | ||
569 | priv->regulators[i] = regulator_register( | ||
570 | &mc13892_regulators[init_data->id].desc, | ||
571 | &pdev->dev, init_data->init_data, priv); | ||
572 | |||
573 | if (IS_ERR(priv->regulators[i])) { | ||
574 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
575 | mc13892_regulators[i].desc.name); | ||
576 | ret = PTR_ERR(priv->regulators[i]); | ||
577 | goto err; | ||
578 | } | ||
579 | } | ||
580 | |||
581 | platform_set_drvdata(pdev, priv); | ||
582 | |||
583 | return 0; | ||
584 | err: | ||
585 | while (--i >= 0) | ||
586 | regulator_unregister(priv->regulators[i]); | ||
587 | |||
588 | err_free: | ||
589 | mc13xxx_unlock(mc13892); | ||
590 | kfree(priv); | ||
591 | |||
592 | return ret; | ||
593 | } | ||
594 | |||
595 | static int __devexit mc13892_regulator_remove(struct platform_device *pdev) | ||
596 | { | ||
597 | struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); | ||
598 | struct mc13xxx_regulator_platform_data *pdata = | ||
599 | dev_get_platdata(&pdev->dev); | ||
600 | int i; | ||
601 | |||
602 | platform_set_drvdata(pdev, NULL); | ||
603 | |||
604 | for (i = 0; i < pdata->num_regulators; i++) | ||
605 | regulator_unregister(priv->regulators[i]); | ||
606 | |||
607 | kfree(priv); | ||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static struct platform_driver mc13892_regulator_driver = { | ||
612 | .driver = { | ||
613 | .name = "mc13892-regulator", | ||
614 | .owner = THIS_MODULE, | ||
615 | }, | ||
616 | .remove = __devexit_p(mc13892_regulator_remove), | ||
617 | .probe = mc13892_regulator_probe, | ||
618 | }; | ||
619 | |||
620 | static int __init mc13892_regulator_init(void) | ||
621 | { | ||
622 | return platform_driver_register(&mc13892_regulator_driver); | ||
623 | } | ||
624 | subsys_initcall(mc13892_regulator_init); | ||
625 | |||
626 | static void __exit mc13892_regulator_exit(void) | ||
627 | { | ||
628 | platform_driver_unregister(&mc13892_regulator_driver); | ||
629 | } | ||
630 | module_exit(mc13892_regulator_exit); | ||
631 | |||
632 | MODULE_LICENSE("GPL v2"); | ||
633 | MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>"); | ||
634 | MODULE_DESCRIPTION("Regulator Driver for Freescale MC13892 PMIC"); | ||
635 | MODULE_ALIAS("platform:mc13892-regulator"); | ||
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c new file mode 100644 index 00000000000..f53d31b950d --- /dev/null +++ b/drivers/regulator/mc13xxx-regulator-core.c | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | * Regulator Driver for Freescale MC13xxx PMIC | ||
3 | * | ||
4 | * Copyright 2010 Yong Shen <yong.shen@linaro.org> | ||
5 | * | ||
6 | * Based on mc13783 regulator driver : | ||
7 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | ||
8 | * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * Regs infos taken from mc13xxx drivers from freescale and mc13xxx.pdf file | ||
15 | * from freescale | ||
16 | */ | ||
17 | |||
18 | #include <linux/mfd/mc13xxx.h> | ||
19 | #include <linux/regulator/machine.h> | ||
20 | #include <linux/regulator/driver.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/err.h> | ||
26 | #include "mc13xxx.h" | ||
27 | |||
28 | static int mc13xxx_regulator_enable(struct regulator_dev *rdev) | ||
29 | { | ||
30 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
31 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
32 | int id = rdev_get_id(rdev); | ||
33 | int ret; | ||
34 | |||
35 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
36 | |||
37 | mc13xxx_lock(priv->mc13xxx); | ||
38 | ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, | ||
39 | mc13xxx_regulators[id].enable_bit, | ||
40 | mc13xxx_regulators[id].enable_bit); | ||
41 | mc13xxx_unlock(priv->mc13xxx); | ||
42 | |||
43 | return ret; | ||
44 | } | ||
45 | |||
46 | static int mc13xxx_regulator_disable(struct regulator_dev *rdev) | ||
47 | { | ||
48 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
49 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
50 | int id = rdev_get_id(rdev); | ||
51 | int ret; | ||
52 | |||
53 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
54 | |||
55 | mc13xxx_lock(priv->mc13xxx); | ||
56 | ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, | ||
57 | mc13xxx_regulators[id].enable_bit, 0); | ||
58 | mc13xxx_unlock(priv->mc13xxx); | ||
59 | |||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev) | ||
64 | { | ||
65 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
66 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
67 | int ret, id = rdev_get_id(rdev); | ||
68 | unsigned int val; | ||
69 | |||
70 | mc13xxx_lock(priv->mc13xxx); | ||
71 | ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val); | ||
72 | mc13xxx_unlock(priv->mc13xxx); | ||
73 | |||
74 | if (ret) | ||
75 | return ret; | ||
76 | |||
77 | return (val & mc13xxx_regulators[id].enable_bit) != 0; | ||
78 | } | ||
79 | |||
80 | int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, | ||
81 | unsigned selector) | ||
82 | { | ||
83 | int id = rdev_get_id(rdev); | ||
84 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
85 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
86 | |||
87 | if (selector >= mc13xxx_regulators[id].desc.n_voltages) | ||
88 | return -EINVAL; | ||
89 | |||
90 | return mc13xxx_regulators[id].voltages[selector]; | ||
91 | } | ||
92 | EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage); | ||
93 | |||
94 | int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev, | ||
95 | int min_uV, int max_uV) | ||
96 | { | ||
97 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
98 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
99 | int reg_id = rdev_get_id(rdev); | ||
100 | int i; | ||
101 | int bestmatch; | ||
102 | int bestindex; | ||
103 | |||
104 | /* | ||
105 | * Locate the minimum voltage fitting the criteria on | ||
106 | * this regulator. The switchable voltages are not | ||
107 | * in strict falling order so we need to check them | ||
108 | * all for the best match. | ||
109 | */ | ||
110 | bestmatch = INT_MAX; | ||
111 | bestindex = -1; | ||
112 | for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) { | ||
113 | if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV && | ||
114 | mc13xxx_regulators[reg_id].voltages[i] < bestmatch) { | ||
115 | bestmatch = mc13xxx_regulators[reg_id].voltages[i]; | ||
116 | bestindex = i; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | if (bestindex < 0 || bestmatch > max_uV) { | ||
121 | dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n", | ||
122 | min_uV, max_uV); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | return bestindex; | ||
126 | } | ||
127 | EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index); | ||
128 | |||
129 | static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, | ||
130 | int max_uV, unsigned *selector) | ||
131 | { | ||
132 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
133 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
134 | int value, id = rdev_get_id(rdev); | ||
135 | int ret; | ||
136 | |||
137 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", | ||
138 | __func__, id, min_uV, max_uV); | ||
139 | |||
140 | /* Find the best index */ | ||
141 | value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV); | ||
142 | dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value); | ||
143 | if (value < 0) | ||
144 | return value; | ||
145 | |||
146 | mc13xxx_lock(priv->mc13xxx); | ||
147 | ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg, | ||
148 | mc13xxx_regulators[id].vsel_mask, | ||
149 | value << mc13xxx_regulators[id].vsel_shift); | ||
150 | mc13xxx_unlock(priv->mc13xxx); | ||
151 | |||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) | ||
156 | { | ||
157 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
158 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
159 | int ret, id = rdev_get_id(rdev); | ||
160 | unsigned int val; | ||
161 | |||
162 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
163 | |||
164 | mc13xxx_lock(priv->mc13xxx); | ||
165 | ret = mc13xxx_reg_read(priv->mc13xxx, | ||
166 | mc13xxx_regulators[id].vsel_reg, &val); | ||
167 | mc13xxx_unlock(priv->mc13xxx); | ||
168 | |||
169 | if (ret) | ||
170 | return ret; | ||
171 | |||
172 | val = (val & mc13xxx_regulators[id].vsel_mask) | ||
173 | >> mc13xxx_regulators[id].vsel_shift; | ||
174 | |||
175 | dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); | ||
176 | |||
177 | BUG_ON(val < 0 || val > mc13xxx_regulators[id].desc.n_voltages); | ||
178 | |||
179 | return mc13xxx_regulators[id].voltages[val]; | ||
180 | } | ||
181 | |||
182 | struct regulator_ops mc13xxx_regulator_ops = { | ||
183 | .enable = mc13xxx_regulator_enable, | ||
184 | .disable = mc13xxx_regulator_disable, | ||
185 | .is_enabled = mc13xxx_regulator_is_enabled, | ||
186 | .list_voltage = mc13xxx_regulator_list_voltage, | ||
187 | .set_voltage = mc13xxx_regulator_set_voltage, | ||
188 | .get_voltage = mc13xxx_regulator_get_voltage, | ||
189 | }; | ||
190 | EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops); | ||
191 | |||
192 | int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, | ||
193 | int max_uV, unsigned *selector) | ||
194 | { | ||
195 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
196 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
197 | int id = rdev_get_id(rdev); | ||
198 | |||
199 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", | ||
200 | __func__, id, min_uV, max_uV); | ||
201 | |||
202 | if (min_uV >= mc13xxx_regulators[id].voltages[0] && | ||
203 | max_uV <= mc13xxx_regulators[id].voltages[0]) | ||
204 | return 0; | ||
205 | else | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage); | ||
209 | |||
210 | int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev) | ||
211 | { | ||
212 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | ||
213 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | ||
214 | int id = rdev_get_id(rdev); | ||
215 | |||
216 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
217 | |||
218 | return mc13xxx_regulators[id].voltages[0]; | ||
219 | } | ||
220 | EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage); | ||
221 | |||
222 | struct regulator_ops mc13xxx_fixed_regulator_ops = { | ||
223 | .enable = mc13xxx_regulator_enable, | ||
224 | .disable = mc13xxx_regulator_disable, | ||
225 | .is_enabled = mc13xxx_regulator_is_enabled, | ||
226 | .list_voltage = mc13xxx_regulator_list_voltage, | ||
227 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, | ||
228 | .get_voltage = mc13xxx_fixed_regulator_get_voltage, | ||
229 | }; | ||
230 | EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops); | ||
231 | |||
232 | int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev) | ||
233 | { | ||
234 | return 1; | ||
235 | } | ||
236 | EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled); | ||
237 | |||
238 | MODULE_LICENSE("GPL v2"); | ||
239 | MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>"); | ||
240 | MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC"); | ||
241 | MODULE_ALIAS("mc13xxx-regulator-core"); | ||
diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h new file mode 100644 index 00000000000..27758267e12 --- /dev/null +++ b/drivers/regulator/mc13xxx.h | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * mc13xxx.h - regulators for the Freescale mc13xxx PMIC | ||
3 | * | ||
4 | * Copyright (C) 2010 Yong Shen <yong.shen@linaro.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef __LINUX_REGULATOR_MC13XXX_H | ||
13 | #define __LINUX_REGULATOR_MC13XXX_H | ||
14 | |||
15 | #include <linux/regulator/driver.h> | ||
16 | |||
17 | struct mc13xxx_regulator { | ||
18 | struct regulator_desc desc; | ||
19 | int reg; | ||
20 | int enable_bit; | ||
21 | int vsel_reg; | ||
22 | int vsel_shift; | ||
23 | int vsel_mask; | ||
24 | int hi_bit; | ||
25 | int const *voltages; | ||
26 | }; | ||
27 | |||
28 | struct mc13xxx_regulator_priv { | ||
29 | struct mc13xxx *mc13xxx; | ||
30 | u32 powermisc_pwgt_state; | ||
31 | struct mc13xxx_regulator *mc13xxx_regulators; | ||
32 | struct regulator_dev *regulators[]; | ||
33 | }; | ||
34 | |||
35 | extern int mc13xxx_sw_regulator(struct regulator_dev *rdev); | ||
36 | extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev); | ||
37 | extern int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev, | ||
38 | int min_uV, int max_uV); | ||
39 | extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, | ||
40 | unsigned selector); | ||
41 | extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, | ||
42 | int min_uV, int max_uV, unsigned *selector); | ||
43 | extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev); | ||
44 | |||
45 | extern struct regulator_ops mc13xxx_regulator_ops; | ||
46 | extern struct regulator_ops mc13xxx_fixed_regulator_ops; | ||
47 | |||
48 | #define MC13xxx_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages, _ops) \ | ||
49 | [prefix ## _name] = { \ | ||
50 | .desc = { \ | ||
51 | .name = #prefix "_" #_name, \ | ||
52 | .n_voltages = ARRAY_SIZE(_voltages), \ | ||
53 | .ops = &_ops, \ | ||
54 | .type = REGULATOR_VOLTAGE, \ | ||
55 | .id = prefix ## _name, \ | ||
56 | .owner = THIS_MODULE, \ | ||
57 | }, \ | ||
58 | .reg = prefix ## _reg, \ | ||
59 | .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ | ||
60 | .vsel_reg = prefix ## _vsel_reg, \ | ||
61 | .vsel_shift = prefix ## _vsel_reg ## _ ## _name ## VSEL,\ | ||
62 | .vsel_mask = prefix ## _vsel_reg ## _ ## _name ## VSEL_M,\ | ||
63 | .voltages = _voltages, \ | ||
64 | } | ||
65 | |||
66 | #define MC13xxx_FIXED_DEFINE(prefix, _name, _reg, _voltages, _ops) \ | ||
67 | [prefix ## _name] = { \ | ||
68 | .desc = { \ | ||
69 | .name = #prefix "_" #_name, \ | ||
70 | .n_voltages = ARRAY_SIZE(_voltages), \ | ||
71 | .ops = &_ops, \ | ||
72 | .type = REGULATOR_VOLTAGE, \ | ||
73 | .id = prefix ## _name, \ | ||
74 | .owner = THIS_MODULE, \ | ||
75 | }, \ | ||
76 | .reg = prefix ## _reg, \ | ||
77 | .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ | ||
78 | .voltages = _voltages, \ | ||
79 | } | ||
80 | |||
81 | #define MC13xxx_GPO_DEFINE(prefix, _name, _reg, _voltages, _ops) \ | ||
82 | [prefix ## _name] = { \ | ||
83 | .desc = { \ | ||
84 | .name = #prefix "_" #_name, \ | ||
85 | .n_voltages = ARRAY_SIZE(_voltages), \ | ||
86 | .ops = &_ops, \ | ||
87 | .type = REGULATOR_VOLTAGE, \ | ||
88 | .id = prefix ## _name, \ | ||
89 | .owner = THIS_MODULE, \ | ||
90 | }, \ | ||
91 | .reg = prefix ## _reg, \ | ||
92 | .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ | ||
93 | .voltages = _voltages, \ | ||
94 | } | ||
95 | |||
96 | #define MC13xxx_DEFINE_SW(_name, _reg, _vsel_reg, _voltages, ops) \ | ||
97 | MC13xxx_DEFINE(SW, _name, _reg, _vsel_reg, _voltages, ops) | ||
98 | #define MC13xxx_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages, ops) \ | ||
99 | MC13xxx_DEFINE(REGU, _name, _reg, _vsel_reg, _voltages, ops) | ||
100 | |||
101 | #endif | ||
diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c index 29d0566379a..31f6e11a7f1 100644 --- a/drivers/regulator/pcap-regulator.c +++ b/drivers/regulator/pcap-regulator.c | |||
@@ -151,7 +151,8 @@ static struct pcap_regulator vreg_table[] = { | |||
151 | }; | 151 | }; |
152 | 152 | ||
153 | static int pcap_regulator_set_voltage(struct regulator_dev *rdev, | 153 | static int pcap_regulator_set_voltage(struct regulator_dev *rdev, |
154 | int min_uV, int max_uV) | 154 | int min_uV, int max_uV, |
155 | unsigned *selector) | ||
155 | { | 156 | { |
156 | struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)]; | 157 | struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)]; |
157 | void *pcap = rdev_get_drvdata(rdev); | 158 | void *pcap = rdev_get_drvdata(rdev); |
@@ -170,10 +171,12 @@ static int pcap_regulator_set_voltage(struct regulator_dev *rdev, | |||
170 | i = 0; | 171 | i = 0; |
171 | 172 | ||
172 | uV = vreg->voltage_table[i] * 1000; | 173 | uV = vreg->voltage_table[i] * 1000; |
173 | if (min_uV <= uV && uV <= max_uV) | 174 | if (min_uV <= uV && uV <= max_uV) { |
175 | *selector = i; | ||
174 | return ezx_pcap_set_bits(pcap, vreg->reg, | 176 | return ezx_pcap_set_bits(pcap, vreg->reg, |
175 | (vreg->n_voltages - 1) << vreg->index, | 177 | (vreg->n_voltages - 1) << vreg->index, |
176 | i << vreg->index); | 178 | i << vreg->index); |
179 | } | ||
177 | 180 | ||
178 | if (i == 0 && rdev_get_id(rdev) == V1) | 181 | if (i == 0 && rdev_get_id(rdev) == V1) |
179 | i = vreg->n_voltages - 1; | 182 | i = vreg->n_voltages - 1; |
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index c8f41dc05b7..69a11d9dd87 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c | |||
@@ -108,7 +108,8 @@ static unsigned int ldo_voltage_value(u8 bits) | |||
108 | } | 108 | } |
109 | 109 | ||
110 | static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, | 110 | static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, |
111 | int min_uV, int max_uV) | 111 | int min_uV, int max_uV, |
112 | unsigned *selector) | ||
112 | { | 113 | { |
113 | struct pcf50633 *pcf; | 114 | struct pcf50633 *pcf; |
114 | int regulator_id, millivolts; | 115 | int regulator_id, millivolts; |
@@ -147,6 +148,8 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, | |||
147 | return -EINVAL; | 148 | return -EINVAL; |
148 | } | 149 | } |
149 | 150 | ||
151 | *selector = volt_bits; | ||
152 | |||
150 | return pcf50633_reg_write(pcf, regnr, volt_bits); | 153 | return pcf50633_reg_write(pcf, regnr, volt_bits); |
151 | } | 154 | } |
152 | 155 | ||
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index cd6d4fc9d74..60a7ca5409e 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c | |||
@@ -321,7 +321,8 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) | |||
321 | } | 321 | } |
322 | 322 | ||
323 | static int tps65023_dcdc_set_voltage(struct regulator_dev *dev, | 323 | static int tps65023_dcdc_set_voltage(struct regulator_dev *dev, |
324 | int min_uV, int max_uV) | 324 | int min_uV, int max_uV, |
325 | unsigned *selector) | ||
325 | { | 326 | { |
326 | struct tps_pmic *tps = rdev_get_drvdata(dev); | 327 | struct tps_pmic *tps = rdev_get_drvdata(dev); |
327 | int dcdc = rdev_get_id(dev); | 328 | int dcdc = rdev_get_id(dev); |
@@ -346,6 +347,8 @@ static int tps65023_dcdc_set_voltage(struct regulator_dev *dev, | |||
346 | break; | 347 | break; |
347 | } | 348 | } |
348 | 349 | ||
350 | *selector = vsel; | ||
351 | |||
349 | /* write to the register in case we found a match */ | 352 | /* write to the register in case we found a match */ |
350 | if (vsel == tps->info[dcdc]->table_len) | 353 | if (vsel == tps->info[dcdc]->table_len) |
351 | return -EINVAL; | 354 | return -EINVAL; |
@@ -371,7 +374,7 @@ static int tps65023_ldo_get_voltage(struct regulator_dev *dev) | |||
371 | } | 374 | } |
372 | 375 | ||
373 | static int tps65023_ldo_set_voltage(struct regulator_dev *dev, | 376 | static int tps65023_ldo_set_voltage(struct regulator_dev *dev, |
374 | int min_uV, int max_uV) | 377 | int min_uV, int max_uV, unsigned *selector) |
375 | { | 378 | { |
376 | struct tps_pmic *tps = rdev_get_drvdata(dev); | 379 | struct tps_pmic *tps = rdev_get_drvdata(dev); |
377 | int data, vsel, ldo = rdev_get_id(dev); | 380 | int data, vsel, ldo = rdev_get_id(dev); |
@@ -396,6 +399,8 @@ static int tps65023_ldo_set_voltage(struct regulator_dev *dev, | |||
396 | if (vsel == tps->info[ldo]->table_len) | 399 | if (vsel == tps->info[ldo]->table_len) |
397 | return -EINVAL; | 400 | return -EINVAL; |
398 | 401 | ||
402 | *selector = vsel; | ||
403 | |||
399 | data = tps_65023_reg_read(tps, TPS65023_REG_LDO_CTRL); | 404 | data = tps_65023_reg_read(tps, TPS65023_REG_LDO_CTRL); |
400 | if (data < 0) | 405 | if (data < 0) |
401 | return data; | 406 | return data; |
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 020f5878d7f..06475529059 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c | |||
@@ -369,7 +369,8 @@ static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev) | |||
369 | } | 369 | } |
370 | 370 | ||
371 | static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev, | 371 | static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev, |
372 | int min_uV, int max_uV) | 372 | int min_uV, int max_uV, |
373 | unsigned *selector) | ||
373 | { | 374 | { |
374 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 375 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); |
375 | int data, vsel, dcdc = rdev_get_id(dev); | 376 | int data, vsel, dcdc = rdev_get_id(dev); |
@@ -415,6 +416,8 @@ static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev, | |||
415 | if (vsel == tps->info[dcdc]->table_len) | 416 | if (vsel == tps->info[dcdc]->table_len) |
416 | return -EINVAL; | 417 | return -EINVAL; |
417 | 418 | ||
419 | *selector = vsel; | ||
420 | |||
418 | data = tps6507x_pmic_reg_read(tps, reg); | 421 | data = tps6507x_pmic_reg_read(tps, reg); |
419 | if (data < 0) | 422 | if (data < 0) |
420 | return data; | 423 | return data; |
@@ -450,7 +453,8 @@ static int tps6507x_pmic_ldo_get_voltage(struct regulator_dev *dev) | |||
450 | } | 453 | } |
451 | 454 | ||
452 | static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev, | 455 | static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev, |
453 | int min_uV, int max_uV) | 456 | int min_uV, int max_uV, |
457 | unsigned *selector) | ||
454 | { | 458 | { |
455 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 459 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); |
456 | int data, vsel, ldo = rdev_get_id(dev); | 460 | int data, vsel, ldo = rdev_get_id(dev); |
@@ -483,6 +487,8 @@ static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev, | |||
483 | if (vsel == tps->info[ldo]->table_len) | 487 | if (vsel == tps->info[ldo]->table_len) |
484 | return -EINVAL; | 488 | return -EINVAL; |
485 | 489 | ||
490 | *selector = vsel; | ||
491 | |||
486 | data = tps6507x_pmic_reg_read(tps, reg); | 492 | data = tps6507x_pmic_reg_read(tps, reg); |
487 | if (data < 0) | 493 | if (data < 0) |
488 | return data; | 494 | return data; |
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c new file mode 100644 index 00000000000..176a6be5a8c --- /dev/null +++ b/drivers/regulator/tps6524x-regulator.c | |||
@@ -0,0 +1,693 @@ | |||
1 | /* | ||
2 | * Regulator driver for TPS6524x PMIC | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
11 | * whether express or implied; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/spi/spi.h> | ||
22 | #include <linux/regulator/driver.h> | ||
23 | #include <linux/regulator/machine.h> | ||
24 | |||
25 | #define REG_LDO_SET 0x0 | ||
26 | #define LDO_ILIM_MASK 1 /* 0 = 400-800, 1 = 900-1500 */ | ||
27 | #define LDO_VSEL_MASK 0x0f | ||
28 | #define LDO2_ILIM_SHIFT 12 | ||
29 | #define LDO2_VSEL_SHIFT 4 | ||
30 | #define LDO1_ILIM_SHIFT 8 | ||
31 | #define LDO1_VSEL_SHIFT 0 | ||
32 | |||
33 | #define REG_BLOCK_EN 0x1 | ||
34 | #define BLOCK_MASK 1 | ||
35 | #define BLOCK_LDO1_SHIFT 0 | ||
36 | #define BLOCK_LDO2_SHIFT 1 | ||
37 | #define BLOCK_LCD_SHIFT 2 | ||
38 | #define BLOCK_USB_SHIFT 3 | ||
39 | |||
40 | #define REG_DCDC_SET 0x2 | ||
41 | #define DCDC_VDCDC_MASK 0x1f | ||
42 | #define DCDC_VDCDC1_SHIFT 0 | ||
43 | #define DCDC_VDCDC2_SHIFT 5 | ||
44 | #define DCDC_VDCDC3_SHIFT 10 | ||
45 | |||
46 | #define REG_DCDC_EN 0x3 | ||
47 | #define DCDCDCDC_EN_MASK 0x1 | ||
48 | #define DCDCDCDC1_EN_SHIFT 0 | ||
49 | #define DCDCDCDC1_PG_MSK BIT(1) | ||
50 | #define DCDCDCDC2_EN_SHIFT 2 | ||
51 | #define DCDCDCDC2_PG_MSK BIT(3) | ||
52 | #define DCDCDCDC3_EN_SHIFT 4 | ||
53 | #define DCDCDCDC3_PG_MSK BIT(5) | ||
54 | |||
55 | #define REG_USB 0x4 | ||
56 | #define USB_ILIM_SHIFT 0 | ||
57 | #define USB_ILIM_MASK 0x3 | ||
58 | #define USB_TSD_SHIFT 2 | ||
59 | #define USB_TSD_MASK 0x3 | ||
60 | #define USB_TWARN_SHIFT 4 | ||
61 | #define USB_TWARN_MASK 0x3 | ||
62 | #define USB_IWARN_SD BIT(6) | ||
63 | #define USB_FAST_LOOP BIT(7) | ||
64 | |||
65 | #define REG_ALARM 0x5 | ||
66 | #define ALARM_LDO1 BIT(0) | ||
67 | #define ALARM_DCDC1 BIT(1) | ||
68 | #define ALARM_DCDC2 BIT(2) | ||
69 | #define ALARM_DCDC3 BIT(3) | ||
70 | #define ALARM_LDO2 BIT(4) | ||
71 | #define ALARM_USB_WARN BIT(5) | ||
72 | #define ALARM_USB_ALARM BIT(6) | ||
73 | #define ALARM_LCD BIT(9) | ||
74 | #define ALARM_TEMP_WARM BIT(10) | ||
75 | #define ALARM_TEMP_HOT BIT(11) | ||
76 | #define ALARM_NRST BIT(14) | ||
77 | #define ALARM_POWERUP BIT(15) | ||
78 | |||
79 | #define REG_INT_ENABLE 0x6 | ||
80 | #define INT_LDO1 BIT(0) | ||
81 | #define INT_DCDC1 BIT(1) | ||
82 | #define INT_DCDC2 BIT(2) | ||
83 | #define INT_DCDC3 BIT(3) | ||
84 | #define INT_LDO2 BIT(4) | ||
85 | #define INT_USB_WARN BIT(5) | ||
86 | #define INT_USB_ALARM BIT(6) | ||
87 | #define INT_LCD BIT(9) | ||
88 | #define INT_TEMP_WARM BIT(10) | ||
89 | #define INT_TEMP_HOT BIT(11) | ||
90 | #define INT_GLOBAL_EN BIT(15) | ||
91 | |||
92 | #define REG_INT_STATUS 0x7 | ||
93 | #define STATUS_LDO1 BIT(0) | ||
94 | #define STATUS_DCDC1 BIT(1) | ||
95 | #define STATUS_DCDC2 BIT(2) | ||
96 | #define STATUS_DCDC3 BIT(3) | ||
97 | #define STATUS_LDO2 BIT(4) | ||
98 | #define STATUS_USB_WARN BIT(5) | ||
99 | #define STATUS_USB_ALARM BIT(6) | ||
100 | #define STATUS_LCD BIT(9) | ||
101 | #define STATUS_TEMP_WARM BIT(10) | ||
102 | #define STATUS_TEMP_HOT BIT(11) | ||
103 | |||
104 | #define REG_SOFTWARE_RESET 0xb | ||
105 | #define REG_WRITE_ENABLE 0xd | ||
106 | #define REG_REV_ID 0xf | ||
107 | |||
108 | #define N_DCDC 3 | ||
109 | #define N_LDO 2 | ||
110 | #define N_SWITCH 2 | ||
111 | #define N_REGULATORS (3 /* DCDC */ + \ | ||
112 | 2 /* LDO */ + \ | ||
113 | 2 /* switch */) | ||
114 | |||
115 | #define FIXED_ILIMSEL BIT(0) | ||
116 | #define FIXED_VOLTAGE BIT(1) | ||
117 | |||
118 | #define CMD_READ(reg) ((reg) << 6) | ||
119 | #define CMD_WRITE(reg) (BIT(5) | (reg) << 6) | ||
120 | #define STAT_CLK BIT(3) | ||
121 | #define STAT_WRITE BIT(2) | ||
122 | #define STAT_INVALID BIT(1) | ||
123 | #define STAT_WP BIT(0) | ||
124 | |||
125 | struct field { | ||
126 | int reg; | ||
127 | int shift; | ||
128 | int mask; | ||
129 | }; | ||
130 | |||
131 | struct supply_info { | ||
132 | const char *name; | ||
133 | int n_voltages; | ||
134 | const int *voltages; | ||
135 | int fixed_voltage; | ||
136 | int n_ilimsels; | ||
137 | const int *ilimsels; | ||
138 | int fixed_ilimsel; | ||
139 | int flags; | ||
140 | struct field enable, voltage, ilimsel; | ||
141 | }; | ||
142 | |||
143 | struct tps6524x { | ||
144 | struct device *dev; | ||
145 | struct spi_device *spi; | ||
146 | struct mutex lock; | ||
147 | struct regulator_desc desc[N_REGULATORS]; | ||
148 | struct regulator_dev *rdev[N_REGULATORS]; | ||
149 | }; | ||
150 | |||
151 | static int __read_reg(struct tps6524x *hw, int reg) | ||
152 | { | ||
153 | int error = 0; | ||
154 | u16 cmd = CMD_READ(reg), in; | ||
155 | u8 status; | ||
156 | struct spi_message m; | ||
157 | struct spi_transfer t[3]; | ||
158 | |||
159 | spi_message_init(&m); | ||
160 | memset(t, 0, sizeof(t)); | ||
161 | |||
162 | t[0].tx_buf = &cmd; | ||
163 | t[0].len = 2; | ||
164 | t[0].bits_per_word = 12; | ||
165 | spi_message_add_tail(&t[0], &m); | ||
166 | |||
167 | t[1].rx_buf = ∈ | ||
168 | t[1].len = 2; | ||
169 | t[1].bits_per_word = 16; | ||
170 | spi_message_add_tail(&t[1], &m); | ||
171 | |||
172 | t[2].rx_buf = &status; | ||
173 | t[2].len = 1; | ||
174 | t[2].bits_per_word = 4; | ||
175 | spi_message_add_tail(&t[2], &m); | ||
176 | |||
177 | error = spi_sync(hw->spi, &m); | ||
178 | if (error < 0) | ||
179 | return error; | ||
180 | |||
181 | dev_dbg(hw->dev, "read reg %d, data %x, status %x\n", | ||
182 | reg, in, status); | ||
183 | |||
184 | if (!(status & STAT_CLK) || (status & STAT_WRITE)) | ||
185 | return -EIO; | ||
186 | |||
187 | if (status & STAT_INVALID) | ||
188 | return -EINVAL; | ||
189 | |||
190 | return in; | ||
191 | } | ||
192 | |||
193 | static int read_reg(struct tps6524x *hw, int reg) | ||
194 | { | ||
195 | int ret; | ||
196 | |||
197 | mutex_lock(&hw->lock); | ||
198 | ret = __read_reg(hw, reg); | ||
199 | mutex_unlock(&hw->lock); | ||
200 | |||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | static int __write_reg(struct tps6524x *hw, int reg, int val) | ||
205 | { | ||
206 | int error = 0; | ||
207 | u16 cmd = CMD_WRITE(reg), out = val; | ||
208 | u8 status; | ||
209 | struct spi_message m; | ||
210 | struct spi_transfer t[3]; | ||
211 | |||
212 | spi_message_init(&m); | ||
213 | memset(t, 0, sizeof(t)); | ||
214 | |||
215 | t[0].tx_buf = &cmd; | ||
216 | t[0].len = 2; | ||
217 | t[0].bits_per_word = 12; | ||
218 | spi_message_add_tail(&t[0], &m); | ||
219 | |||
220 | t[1].tx_buf = &out; | ||
221 | t[1].len = 2; | ||
222 | t[1].bits_per_word = 16; | ||
223 | spi_message_add_tail(&t[1], &m); | ||
224 | |||
225 | t[2].rx_buf = &status; | ||
226 | t[2].len = 1; | ||
227 | t[2].bits_per_word = 4; | ||
228 | spi_message_add_tail(&t[2], &m); | ||
229 | |||
230 | error = spi_sync(hw->spi, &m); | ||
231 | if (error < 0) | ||
232 | return error; | ||
233 | |||
234 | dev_dbg(hw->dev, "wrote reg %d, data %x, status %x\n", | ||
235 | reg, out, status); | ||
236 | |||
237 | if (!(status & STAT_CLK) || !(status & STAT_WRITE)) | ||
238 | return -EIO; | ||
239 | |||
240 | if (status & (STAT_INVALID | STAT_WP)) | ||
241 | return -EINVAL; | ||
242 | |||
243 | return error; | ||
244 | } | ||
245 | |||
246 | static int __rmw_reg(struct tps6524x *hw, int reg, int mask, int val) | ||
247 | { | ||
248 | int ret; | ||
249 | |||
250 | ret = __read_reg(hw, reg); | ||
251 | if (ret < 0) | ||
252 | return ret; | ||
253 | |||
254 | ret &= ~mask; | ||
255 | ret |= val; | ||
256 | |||
257 | ret = __write_reg(hw, reg, ret); | ||
258 | |||
259 | return (ret < 0) ? ret : 0; | ||
260 | } | ||
261 | |||
262 | static int rmw_protect(struct tps6524x *hw, int reg, int mask, int val) | ||
263 | { | ||
264 | int ret; | ||
265 | |||
266 | mutex_lock(&hw->lock); | ||
267 | |||
268 | ret = __write_reg(hw, REG_WRITE_ENABLE, 1); | ||
269 | if (ret) { | ||
270 | dev_err(hw->dev, "failed to set write enable\n"); | ||
271 | goto error; | ||
272 | } | ||
273 | |||
274 | ret = __rmw_reg(hw, reg, mask, val); | ||
275 | if (ret) | ||
276 | dev_err(hw->dev, "failed to rmw register %d\n", reg); | ||
277 | |||
278 | ret = __write_reg(hw, REG_WRITE_ENABLE, 0); | ||
279 | if (ret) { | ||
280 | dev_err(hw->dev, "failed to clear write enable\n"); | ||
281 | goto error; | ||
282 | } | ||
283 | |||
284 | error: | ||
285 | mutex_unlock(&hw->lock); | ||
286 | |||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | static int read_field(struct tps6524x *hw, const struct field *field) | ||
291 | { | ||
292 | int tmp; | ||
293 | |||
294 | tmp = read_reg(hw, field->reg); | ||
295 | if (tmp < 0) | ||
296 | return tmp; | ||
297 | |||
298 | return (tmp >> field->shift) & field->mask; | ||
299 | } | ||
300 | |||
301 | static int write_field(struct tps6524x *hw, const struct field *field, | ||
302 | int val) | ||
303 | { | ||
304 | if (val & ~field->mask) | ||
305 | return -EOVERFLOW; | ||
306 | |||
307 | return rmw_protect(hw, field->reg, | ||
308 | field->mask << field->shift, | ||
309 | val << field->shift); | ||
310 | } | ||
311 | |||
312 | static const int dcdc1_voltages[] = { | ||
313 | 800000, 825000, 850000, 875000, | ||
314 | 900000, 925000, 950000, 975000, | ||
315 | 1000000, 1025000, 1050000, 1075000, | ||
316 | 1100000, 1125000, 1150000, 1175000, | ||
317 | 1200000, 1225000, 1250000, 1275000, | ||
318 | 1300000, 1325000, 1350000, 1375000, | ||
319 | 1400000, 1425000, 1450000, 1475000, | ||
320 | 1500000, 1525000, 1550000, 1575000, | ||
321 | }; | ||
322 | |||
323 | static const int dcdc2_voltages[] = { | ||
324 | 1400000, 1450000, 1500000, 1550000, | ||
325 | 1600000, 1650000, 1700000, 1750000, | ||
326 | 1800000, 1850000, 1900000, 1950000, | ||
327 | 2000000, 2050000, 2100000, 2150000, | ||
328 | 2200000, 2250000, 2300000, 2350000, | ||
329 | 2400000, 2450000, 2500000, 2550000, | ||
330 | 2600000, 2650000, 2700000, 2750000, | ||
331 | 2800000, 2850000, 2900000, 2950000, | ||
332 | }; | ||
333 | |||
334 | static const int dcdc3_voltages[] = { | ||
335 | 2400000, 2450000, 2500000, 2550000, 2600000, | ||
336 | 2650000, 2700000, 2750000, 2800000, 2850000, | ||
337 | 2900000, 2950000, 3000000, 3050000, 3100000, | ||
338 | 3150000, 3200000, 3250000, 3300000, 3350000, | ||
339 | 3400000, 3450000, 3500000, 3550000, 3600000, | ||
340 | }; | ||
341 | |||
342 | static const int ldo1_voltages[] = { | ||
343 | 4300000, 4350000, 4400000, 4450000, | ||
344 | 4500000, 4550000, 4600000, 4650000, | ||
345 | 4700000, 4750000, 4800000, 4850000, | ||
346 | 4900000, 4950000, 5000000, 5050000, | ||
347 | }; | ||
348 | |||
349 | static const int ldo2_voltages[] = { | ||
350 | 1100000, 1150000, 1200000, 1250000, | ||
351 | 1300000, 1700000, 1750000, 1800000, | ||
352 | 1850000, 1900000, 3150000, 3200000, | ||
353 | 3250000, 3300000, 3350000, 3400000, | ||
354 | }; | ||
355 | |||
356 | static const int ldo_ilimsel[] = { | ||
357 | 400000, 1500000 | ||
358 | }; | ||
359 | |||
360 | static const int usb_ilimsel[] = { | ||
361 | 200000, 400000, 800000, 1000000 | ||
362 | }; | ||
363 | |||
364 | #define __MK_FIELD(_reg, _mask, _shift) \ | ||
365 | { .reg = (_reg), .mask = (_mask), .shift = (_shift), } | ||
366 | |||
367 | static const struct supply_info supply_info[N_REGULATORS] = { | ||
368 | { | ||
369 | .name = "DCDC1", | ||
370 | .flags = FIXED_ILIMSEL, | ||
371 | .n_voltages = ARRAY_SIZE(dcdc1_voltages), | ||
372 | .voltages = dcdc1_voltages, | ||
373 | .fixed_ilimsel = 2400000, | ||
374 | .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, | ||
375 | DCDCDCDC1_EN_SHIFT), | ||
376 | .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, | ||
377 | DCDC_VDCDC1_SHIFT), | ||
378 | }, | ||
379 | { | ||
380 | .name = "DCDC2", | ||
381 | .flags = FIXED_ILIMSEL, | ||
382 | .n_voltages = ARRAY_SIZE(dcdc2_voltages), | ||
383 | .voltages = dcdc2_voltages, | ||
384 | .fixed_ilimsel = 1200000, | ||
385 | .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, | ||
386 | DCDCDCDC2_EN_SHIFT), | ||
387 | .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, | ||
388 | DCDC_VDCDC2_SHIFT), | ||
389 | }, | ||
390 | { | ||
391 | .name = "DCDC3", | ||
392 | .flags = FIXED_ILIMSEL, | ||
393 | .n_voltages = ARRAY_SIZE(dcdc3_voltages), | ||
394 | .voltages = dcdc3_voltages, | ||
395 | .fixed_ilimsel = 1200000, | ||
396 | .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, | ||
397 | DCDCDCDC3_EN_SHIFT), | ||
398 | .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, | ||
399 | DCDC_VDCDC3_SHIFT), | ||
400 | }, | ||
401 | { | ||
402 | .name = "LDO1", | ||
403 | .n_voltages = ARRAY_SIZE(ldo1_voltages), | ||
404 | .voltages = ldo1_voltages, | ||
405 | .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), | ||
406 | .ilimsels = ldo_ilimsel, | ||
407 | .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, | ||
408 | BLOCK_LDO1_SHIFT), | ||
409 | .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, | ||
410 | LDO1_VSEL_SHIFT), | ||
411 | .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, | ||
412 | LDO1_ILIM_SHIFT), | ||
413 | }, | ||
414 | { | ||
415 | .name = "LDO2", | ||
416 | .n_voltages = ARRAY_SIZE(ldo2_voltages), | ||
417 | .voltages = ldo2_voltages, | ||
418 | .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), | ||
419 | .ilimsels = ldo_ilimsel, | ||
420 | .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, | ||
421 | BLOCK_LDO2_SHIFT), | ||
422 | .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, | ||
423 | LDO2_VSEL_SHIFT), | ||
424 | .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, | ||
425 | LDO2_ILIM_SHIFT), | ||
426 | }, | ||
427 | { | ||
428 | .name = "USB", | ||
429 | .flags = FIXED_VOLTAGE, | ||
430 | .fixed_voltage = 5000000, | ||
431 | .n_ilimsels = ARRAY_SIZE(usb_ilimsel), | ||
432 | .ilimsels = usb_ilimsel, | ||
433 | .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, | ||
434 | BLOCK_USB_SHIFT), | ||
435 | .ilimsel = __MK_FIELD(REG_USB, USB_ILIM_MASK, | ||
436 | USB_ILIM_SHIFT), | ||
437 | }, | ||
438 | { | ||
439 | .name = "LCD", | ||
440 | .flags = FIXED_VOLTAGE | FIXED_ILIMSEL, | ||
441 | .fixed_voltage = 5000000, | ||
442 | .fixed_ilimsel = 400000, | ||
443 | .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, | ||
444 | BLOCK_LCD_SHIFT), | ||
445 | }, | ||
446 | }; | ||
447 | |||
448 | static int list_voltage(struct regulator_dev *rdev, unsigned selector) | ||
449 | { | ||
450 | const struct supply_info *info; | ||
451 | struct tps6524x *hw; | ||
452 | |||
453 | hw = rdev_get_drvdata(rdev); | ||
454 | info = &supply_info[rdev_get_id(rdev)]; | ||
455 | |||
456 | if (info->flags & FIXED_VOLTAGE) | ||
457 | return selector ? -EINVAL : info->fixed_voltage; | ||
458 | |||
459 | return ((selector < info->n_voltages) ? | ||
460 | info->voltages[selector] : -EINVAL); | ||
461 | } | ||
462 | |||
463 | static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | ||
464 | unsigned *selector) | ||
465 | { | ||
466 | const struct supply_info *info; | ||
467 | struct tps6524x *hw; | ||
468 | unsigned i; | ||
469 | |||
470 | hw = rdev_get_drvdata(rdev); | ||
471 | info = &supply_info[rdev_get_id(rdev)]; | ||
472 | |||
473 | if (info->flags & FIXED_VOLTAGE) | ||
474 | return -EINVAL; | ||
475 | |||
476 | for (i = 0; i < info->n_voltages; i++) | ||
477 | if (min_uV <= info->voltages[i] && | ||
478 | max_uV >= info->voltages[i]) | ||
479 | break; | ||
480 | |||
481 | if (i >= info->n_voltages) | ||
482 | i = info->n_voltages - 1; | ||
483 | |||
484 | *selector = info->voltages[i]; | ||
485 | |||
486 | return write_field(hw, &info->voltage, i); | ||
487 | } | ||
488 | |||
489 | static int get_voltage(struct regulator_dev *rdev) | ||
490 | { | ||
491 | const struct supply_info *info; | ||
492 | struct tps6524x *hw; | ||
493 | int ret; | ||
494 | |||
495 | hw = rdev_get_drvdata(rdev); | ||
496 | info = &supply_info[rdev_get_id(rdev)]; | ||
497 | |||
498 | if (info->flags & FIXED_VOLTAGE) | ||
499 | return info->fixed_voltage; | ||
500 | |||
501 | ret = read_field(hw, &info->voltage); | ||
502 | if (ret < 0) | ||
503 | return ret; | ||
504 | if (WARN_ON(ret >= info->n_voltages)) | ||
505 | return -EIO; | ||
506 | |||
507 | return info->voltages[ret]; | ||
508 | } | ||
509 | |||
510 | static int set_current_limit(struct regulator_dev *rdev, int min_uA, | ||
511 | int max_uA) | ||
512 | { | ||
513 | const struct supply_info *info; | ||
514 | struct tps6524x *hw; | ||
515 | int i; | ||
516 | |||
517 | hw = rdev_get_drvdata(rdev); | ||
518 | info = &supply_info[rdev_get_id(rdev)]; | ||
519 | |||
520 | if (info->flags & FIXED_ILIMSEL) | ||
521 | return -EINVAL; | ||
522 | |||
523 | for (i = 0; i < info->n_ilimsels; i++) | ||
524 | if (min_uA <= info->ilimsels[i] && | ||
525 | max_uA >= info->ilimsels[i]) | ||
526 | break; | ||
527 | |||
528 | if (i >= info->n_ilimsels) | ||
529 | return -EINVAL; | ||
530 | |||
531 | return write_field(hw, &info->ilimsel, i); | ||
532 | } | ||
533 | |||
534 | static int get_current_limit(struct regulator_dev *rdev) | ||
535 | { | ||
536 | const struct supply_info *info; | ||
537 | struct tps6524x *hw; | ||
538 | int ret; | ||
539 | |||
540 | hw = rdev_get_drvdata(rdev); | ||
541 | info = &supply_info[rdev_get_id(rdev)]; | ||
542 | |||
543 | if (info->flags & FIXED_ILIMSEL) | ||
544 | return info->fixed_ilimsel; | ||
545 | |||
546 | ret = read_field(hw, &info->ilimsel); | ||
547 | if (ret < 0) | ||
548 | return ret; | ||
549 | if (WARN_ON(ret >= info->n_ilimsels)) | ||
550 | return -EIO; | ||
551 | |||
552 | return info->ilimsels[ret]; | ||
553 | } | ||
554 | |||
555 | static int enable_supply(struct regulator_dev *rdev) | ||
556 | { | ||
557 | const struct supply_info *info; | ||
558 | struct tps6524x *hw; | ||
559 | |||
560 | hw = rdev_get_drvdata(rdev); | ||
561 | info = &supply_info[rdev_get_id(rdev)]; | ||
562 | |||
563 | return write_field(hw, &info->enable, 1); | ||
564 | } | ||
565 | |||
566 | static int disable_supply(struct regulator_dev *rdev) | ||
567 | { | ||
568 | const struct supply_info *info; | ||
569 | struct tps6524x *hw; | ||
570 | |||
571 | hw = rdev_get_drvdata(rdev); | ||
572 | info = &supply_info[rdev_get_id(rdev)]; | ||
573 | |||
574 | return write_field(hw, &info->enable, 0); | ||
575 | } | ||
576 | |||
577 | static int is_supply_enabled(struct regulator_dev *rdev) | ||
578 | { | ||
579 | const struct supply_info *info; | ||
580 | struct tps6524x *hw; | ||
581 | |||
582 | hw = rdev_get_drvdata(rdev); | ||
583 | info = &supply_info[rdev_get_id(rdev)]; | ||
584 | |||
585 | return read_field(hw, &info->enable); | ||
586 | } | ||
587 | |||
588 | static struct regulator_ops regulator_ops = { | ||
589 | .is_enabled = is_supply_enabled, | ||
590 | .enable = enable_supply, | ||
591 | .disable = disable_supply, | ||
592 | .get_voltage = get_voltage, | ||
593 | .set_voltage = set_voltage, | ||
594 | .list_voltage = list_voltage, | ||
595 | .set_current_limit = set_current_limit, | ||
596 | .get_current_limit = get_current_limit, | ||
597 | }; | ||
598 | |||
599 | static int __devexit pmic_remove(struct spi_device *spi) | ||
600 | { | ||
601 | struct tps6524x *hw = spi_get_drvdata(spi); | ||
602 | int i; | ||
603 | |||
604 | if (!hw) | ||
605 | return 0; | ||
606 | for (i = 0; i < N_REGULATORS; i++) { | ||
607 | if (hw->rdev[i]) | ||
608 | regulator_unregister(hw->rdev[i]); | ||
609 | hw->rdev[i] = NULL; | ||
610 | } | ||
611 | spi_set_drvdata(spi, NULL); | ||
612 | kfree(hw); | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static int __devinit pmic_probe(struct spi_device *spi) | ||
617 | { | ||
618 | struct tps6524x *hw; | ||
619 | struct device *dev = &spi->dev; | ||
620 | const struct supply_info *info = supply_info; | ||
621 | struct regulator_init_data *init_data; | ||
622 | int ret = 0, i; | ||
623 | |||
624 | init_data = dev->platform_data; | ||
625 | if (!init_data) { | ||
626 | dev_err(dev, "could not find regulator platform data\n"); | ||
627 | return -EINVAL; | ||
628 | } | ||
629 | |||
630 | hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL); | ||
631 | if (!hw) { | ||
632 | dev_err(dev, "cannot allocate regulator private data\n"); | ||
633 | return -ENOMEM; | ||
634 | } | ||
635 | spi_set_drvdata(spi, hw); | ||
636 | |||
637 | memset(hw, 0, sizeof(struct tps6524x)); | ||
638 | hw->dev = dev; | ||
639 | hw->spi = spi_dev_get(spi); | ||
640 | mutex_init(&hw->lock); | ||
641 | |||
642 | for (i = 0; i < N_REGULATORS; i++, info++, init_data++) { | ||
643 | hw->desc[i].name = info->name; | ||
644 | hw->desc[i].id = i; | ||
645 | hw->desc[i].n_voltages = info->n_voltages; | ||
646 | hw->desc[i].ops = ®ulator_ops; | ||
647 | hw->desc[i].type = REGULATOR_VOLTAGE; | ||
648 | hw->desc[i].owner = THIS_MODULE; | ||
649 | |||
650 | if (info->flags & FIXED_VOLTAGE) | ||
651 | hw->desc[i].n_voltages = 1; | ||
652 | |||
653 | hw->rdev[i] = regulator_register(&hw->desc[i], dev, | ||
654 | init_data, hw); | ||
655 | if (IS_ERR(hw->rdev[i])) { | ||
656 | ret = PTR_ERR(hw->rdev[i]); | ||
657 | hw->rdev[i] = NULL; | ||
658 | goto fail; | ||
659 | } | ||
660 | } | ||
661 | |||
662 | return 0; | ||
663 | |||
664 | fail: | ||
665 | pmic_remove(spi); | ||
666 | return ret; | ||
667 | } | ||
668 | |||
669 | static struct spi_driver pmic_driver = { | ||
670 | .probe = pmic_probe, | ||
671 | .remove = __devexit_p(pmic_remove), | ||
672 | .driver = { | ||
673 | .name = "tps6524x", | ||
674 | .owner = THIS_MODULE, | ||
675 | }, | ||
676 | }; | ||
677 | |||
678 | static int __init pmic_driver_init(void) | ||
679 | { | ||
680 | return spi_register_driver(&pmic_driver); | ||
681 | } | ||
682 | module_init(pmic_driver_init); | ||
683 | |||
684 | static void __exit pmic_driver_exit(void) | ||
685 | { | ||
686 | spi_unregister_driver(&pmic_driver); | ||
687 | } | ||
688 | module_exit(pmic_driver_exit); | ||
689 | |||
690 | MODULE_DESCRIPTION("TPS6524X PMIC Driver"); | ||
691 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
692 | MODULE_LICENSE("GPL"); | ||
693 | MODULE_ALIAS("spi:tps6524x"); | ||
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 6d20b0454a1..bb04a75a4c9 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -85,7 +85,8 @@ static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev, | |||
85 | 85 | ||
86 | static int __tps6586x_ldo_set_voltage(struct device *parent, | 86 | static int __tps6586x_ldo_set_voltage(struct device *parent, |
87 | struct tps6586x_regulator *ri, | 87 | struct tps6586x_regulator *ri, |
88 | int min_uV, int max_uV) | 88 | int min_uV, int max_uV, |
89 | unsigned *selector) | ||
89 | { | 90 | { |
90 | int val, uV; | 91 | int val, uV; |
91 | uint8_t mask; | 92 | uint8_t mask; |
@@ -100,6 +101,8 @@ static int __tps6586x_ldo_set_voltage(struct device *parent, | |||
100 | /* use the first in-range value */ | 101 | /* use the first in-range value */ |
101 | if (min_uV <= uV && uV <= max_uV) { | 102 | if (min_uV <= uV && uV <= max_uV) { |
102 | 103 | ||
104 | *selector = val; | ||
105 | |||
103 | val <<= ri->volt_shift; | 106 | val <<= ri->volt_shift; |
104 | mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; | 107 | mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; |
105 | 108 | ||
@@ -111,12 +114,13 @@ static int __tps6586x_ldo_set_voltage(struct device *parent, | |||
111 | } | 114 | } |
112 | 115 | ||
113 | static int tps6586x_ldo_set_voltage(struct regulator_dev *rdev, | 116 | static int tps6586x_ldo_set_voltage(struct regulator_dev *rdev, |
114 | int min_uV, int max_uV) | 117 | int min_uV, int max_uV, unsigned *selector) |
115 | { | 118 | { |
116 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | 119 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); |
117 | struct device *parent = to_tps6586x_dev(rdev); | 120 | struct device *parent = to_tps6586x_dev(rdev); |
118 | 121 | ||
119 | return __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV); | 122 | return __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV, |
123 | selector); | ||
120 | } | 124 | } |
121 | 125 | ||
122 | static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev) | 126 | static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev) |
@@ -140,13 +144,14 @@ static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev) | |||
140 | } | 144 | } |
141 | 145 | ||
142 | static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev, | 146 | static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev, |
143 | int min_uV, int max_uV) | 147 | int min_uV, int max_uV, unsigned *selector) |
144 | { | 148 | { |
145 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | 149 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); |
146 | struct device *parent = to_tps6586x_dev(rdev); | 150 | struct device *parent = to_tps6586x_dev(rdev); |
147 | int ret; | 151 | int ret; |
148 | 152 | ||
149 | ret = __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV); | 153 | ret = __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV, |
154 | selector); | ||
150 | if (ret) | 155 | if (ret) |
151 | return ret; | 156 | return ret; |
152 | 157 | ||
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index a57262a4fa6..bd332cf1cc3 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -329,7 +329,8 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
329 | } | 329 | } |
330 | 330 | ||
331 | static int | 331 | static int |
332 | twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | 332 | twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, |
333 | unsigned *selector) | ||
333 | { | 334 | { |
334 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 335 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
335 | int vsel; | 336 | int vsel; |
@@ -345,9 +346,11 @@ twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
345 | /* REVISIT for VAUX2, first match may not be best/lowest */ | 346 | /* REVISIT for VAUX2, first match may not be best/lowest */ |
346 | 347 | ||
347 | /* use the first in-range value */ | 348 | /* use the first in-range value */ |
348 | if (min_uV <= uV && uV <= max_uV) | 349 | if (min_uV <= uV && uV <= max_uV) { |
350 | *selector = vsel; | ||
349 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, | 351 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, |
350 | VREG_VOLTAGE, vsel); | 352 | VREG_VOLTAGE, vsel); |
353 | } | ||
351 | } | 354 | } |
352 | 355 | ||
353 | return -EDOM; | 356 | return -EDOM; |
@@ -389,7 +392,8 @@ static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
389 | } | 392 | } |
390 | 393 | ||
391 | static int | 394 | static int |
392 | twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | 395 | twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, |
396 | unsigned *selector) | ||
393 | { | 397 | { |
394 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 398 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
395 | int vsel; | 399 | int vsel; |
@@ -402,6 +406,7 @@ twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
402 | * mV = 1000mv + 100mv * (vsel - 1) | 406 | * mV = 1000mv + 100mv * (vsel - 1) |
403 | */ | 407 | */ |
404 | vsel = (min_uV/1000 - 1000)/100 + 1; | 408 | vsel = (min_uV/1000 - 1000)/100 + 1; |
409 | *selector = vsel; | ||
405 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel); | 410 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel); |
406 | 411 | ||
407 | } | 412 | } |
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index dbfaf5945e4..8b0d2c4bde9 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c | |||
@@ -302,7 +302,7 @@ static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) | |||
302 | } | 302 | } |
303 | 303 | ||
304 | static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, | 304 | static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, |
305 | int min_uV, int max_uV) | 305 | int min_uV, int max_uV, unsigned *selector) |
306 | { | 306 | { |
307 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); | 307 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); |
308 | struct wm831x *wm831x = dcdc->wm831x; | 308 | struct wm831x *wm831x = dcdc->wm831x; |
@@ -314,6 +314,8 @@ static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, | |||
314 | if (vsel < 0) | 314 | if (vsel < 0) |
315 | return vsel; | 315 | return vsel; |
316 | 316 | ||
317 | *selector = vsel; | ||
318 | |||
317 | /* If this value is already set then do a GPIO update if we can */ | 319 | /* If this value is already set then do a GPIO update if we can */ |
318 | if (dcdc->dvs_gpio && dcdc->on_vsel == vsel) | 320 | if (dcdc->dvs_gpio && dcdc->on_vsel == vsel) |
319 | return wm831x_buckv_set_dvs(rdev, 0); | 321 | return wm831x_buckv_set_dvs(rdev, 0); |
@@ -375,14 +377,14 @@ static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev, | |||
375 | return wm831x_set_bits(wm831x, reg, WM831X_DC1_SLP_VSEL_MASK, vsel); | 377 | return wm831x_set_bits(wm831x, reg, WM831X_DC1_SLP_VSEL_MASK, vsel); |
376 | } | 378 | } |
377 | 379 | ||
378 | static int wm831x_buckv_get_voltage(struct regulator_dev *rdev) | 380 | static int wm831x_buckv_get_voltage_sel(struct regulator_dev *rdev) |
379 | { | 381 | { |
380 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); | 382 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); |
381 | 383 | ||
382 | if (dcdc->dvs_gpio && dcdc->dvs_gpio_state) | 384 | if (dcdc->dvs_gpio && dcdc->dvs_gpio_state) |
383 | return wm831x_buckv_list_voltage(rdev, dcdc->dvs_vsel); | 385 | return dcdc->dvs_vsel; |
384 | else | 386 | else |
385 | return wm831x_buckv_list_voltage(rdev, dcdc->on_vsel); | 387 | return dcdc->on_vsel; |
386 | } | 388 | } |
387 | 389 | ||
388 | /* Current limit options */ | 390 | /* Current limit options */ |
@@ -424,7 +426,7 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) | |||
424 | 426 | ||
425 | static struct regulator_ops wm831x_buckv_ops = { | 427 | static struct regulator_ops wm831x_buckv_ops = { |
426 | .set_voltage = wm831x_buckv_set_voltage, | 428 | .set_voltage = wm831x_buckv_set_voltage, |
427 | .get_voltage = wm831x_buckv_get_voltage, | 429 | .get_voltage_sel = wm831x_buckv_get_voltage_sel, |
428 | .list_voltage = wm831x_buckv_list_voltage, | 430 | .list_voltage = wm831x_buckv_list_voltage, |
429 | .set_suspend_voltage = wm831x_buckv_set_suspend_voltage, | 431 | .set_suspend_voltage = wm831x_buckv_set_suspend_voltage, |
430 | .set_current_limit = wm831x_buckv_set_current_limit, | 432 | .set_current_limit = wm831x_buckv_set_current_limit, |
@@ -636,7 +638,7 @@ static int wm831x_buckp_list_voltage(struct regulator_dev *rdev, | |||
636 | } | 638 | } |
637 | 639 | ||
638 | static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg, | 640 | static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg, |
639 | int min_uV, int max_uV) | 641 | int min_uV, int max_uV, int *selector) |
640 | { | 642 | { |
641 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); | 643 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); |
642 | struct wm831x *wm831x = dcdc->wm831x; | 644 | struct wm831x *wm831x = dcdc->wm831x; |
@@ -650,16 +652,20 @@ static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg, | |||
650 | if (wm831x_buckp_list_voltage(rdev, vsel) > max_uV) | 652 | if (wm831x_buckp_list_voltage(rdev, vsel) > max_uV) |
651 | return -EINVAL; | 653 | return -EINVAL; |
652 | 654 | ||
655 | *selector = vsel; | ||
656 | |||
653 | return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, vsel); | 657 | return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, vsel); |
654 | } | 658 | } |
655 | 659 | ||
656 | static int wm831x_buckp_set_voltage(struct regulator_dev *rdev, | 660 | static int wm831x_buckp_set_voltage(struct regulator_dev *rdev, |
657 | int min_uV, int max_uV) | 661 | int min_uV, int max_uV, |
662 | unsigned *selector) | ||
658 | { | 663 | { |
659 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); | 664 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); |
660 | u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; | 665 | u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; |
661 | 666 | ||
662 | return wm831x_buckp_set_voltage_int(rdev, reg, min_uV, max_uV); | 667 | return wm831x_buckp_set_voltage_int(rdev, reg, min_uV, max_uV, |
668 | selector); | ||
663 | } | 669 | } |
664 | 670 | ||
665 | static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, | 671 | static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, |
@@ -667,11 +673,12 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, | |||
667 | { | 673 | { |
668 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); | 674 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); |
669 | u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; | 675 | u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; |
676 | unsigned selector; | ||
670 | 677 | ||
671 | return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV); | 678 | return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV, &selector); |
672 | } | 679 | } |
673 | 680 | ||
674 | static int wm831x_buckp_get_voltage(struct regulator_dev *rdev) | 681 | static int wm831x_buckp_get_voltage_sel(struct regulator_dev *rdev) |
675 | { | 682 | { |
676 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); | 683 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); |
677 | struct wm831x *wm831x = dcdc->wm831x; | 684 | struct wm831x *wm831x = dcdc->wm831x; |
@@ -682,12 +689,12 @@ static int wm831x_buckp_get_voltage(struct regulator_dev *rdev) | |||
682 | if (val < 0) | 689 | if (val < 0) |
683 | return val; | 690 | return val; |
684 | 691 | ||
685 | return wm831x_buckp_list_voltage(rdev, val & WM831X_DC3_ON_VSEL_MASK); | 692 | return val & WM831X_DC3_ON_VSEL_MASK; |
686 | } | 693 | } |
687 | 694 | ||
688 | static struct regulator_ops wm831x_buckp_ops = { | 695 | static struct regulator_ops wm831x_buckp_ops = { |
689 | .set_voltage = wm831x_buckp_set_voltage, | 696 | .set_voltage = wm831x_buckp_set_voltage, |
690 | .get_voltage = wm831x_buckp_get_voltage, | 697 | .get_voltage_sel = wm831x_buckp_get_voltage_sel, |
691 | .list_voltage = wm831x_buckp_list_voltage, | 698 | .list_voltage = wm831x_buckp_list_voltage, |
692 | .set_suspend_voltage = wm831x_buckp_set_suspend_voltage, | 699 | .set_suspend_voltage = wm831x_buckp_set_suspend_voltage, |
693 | 700 | ||
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 9edf8f69234..c94fc5b7cd5 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c | |||
@@ -113,7 +113,8 @@ static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev, | |||
113 | } | 113 | } |
114 | 114 | ||
115 | static int wm831x_gp_ldo_set_voltage_int(struct regulator_dev *rdev, int reg, | 115 | static int wm831x_gp_ldo_set_voltage_int(struct regulator_dev *rdev, int reg, |
116 | int min_uV, int max_uV) | 116 | int min_uV, int max_uV, |
117 | unsigned *selector) | ||
117 | { | 118 | { |
118 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 119 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
119 | struct wm831x *wm831x = ldo->wm831x; | 120 | struct wm831x *wm831x = ldo->wm831x; |
@@ -133,16 +134,20 @@ static int wm831x_gp_ldo_set_voltage_int(struct regulator_dev *rdev, int reg, | |||
133 | if (ret < min_uV || ret > max_uV) | 134 | if (ret < min_uV || ret > max_uV) |
134 | return -EINVAL; | 135 | return -EINVAL; |
135 | 136 | ||
137 | *selector = vsel; | ||
138 | |||
136 | return wm831x_set_bits(wm831x, reg, WM831X_LDO1_ON_VSEL_MASK, vsel); | 139 | return wm831x_set_bits(wm831x, reg, WM831X_LDO1_ON_VSEL_MASK, vsel); |
137 | } | 140 | } |
138 | 141 | ||
139 | static int wm831x_gp_ldo_set_voltage(struct regulator_dev *rdev, | 142 | static int wm831x_gp_ldo_set_voltage(struct regulator_dev *rdev, |
140 | int min_uV, int max_uV) | 143 | int min_uV, int max_uV, |
144 | unsigned *selector) | ||
141 | { | 145 | { |
142 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 146 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
143 | int reg = ldo->base + WM831X_LDO_ON_CONTROL; | 147 | int reg = ldo->base + WM831X_LDO_ON_CONTROL; |
144 | 148 | ||
145 | return wm831x_gp_ldo_set_voltage_int(rdev, reg, min_uV, max_uV); | 149 | return wm831x_gp_ldo_set_voltage_int(rdev, reg, min_uV, max_uV, |
150 | selector); | ||
146 | } | 151 | } |
147 | 152 | ||
148 | static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev, | 153 | static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev, |
@@ -150,11 +155,12 @@ static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev, | |||
150 | { | 155 | { |
151 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 156 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
152 | int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; | 157 | int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; |
158 | unsigned int selector; | ||
153 | 159 | ||
154 | return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV); | 160 | return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV, &selector); |
155 | } | 161 | } |
156 | 162 | ||
157 | static int wm831x_gp_ldo_get_voltage(struct regulator_dev *rdev) | 163 | static int wm831x_gp_ldo_get_voltage_sel(struct regulator_dev *rdev) |
158 | { | 164 | { |
159 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 165 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
160 | struct wm831x *wm831x = ldo->wm831x; | 166 | struct wm831x *wm831x = ldo->wm831x; |
@@ -167,7 +173,7 @@ static int wm831x_gp_ldo_get_voltage(struct regulator_dev *rdev) | |||
167 | 173 | ||
168 | ret &= WM831X_LDO1_ON_VSEL_MASK; | 174 | ret &= WM831X_LDO1_ON_VSEL_MASK; |
169 | 175 | ||
170 | return wm831x_gp_ldo_list_voltage(rdev, ret); | 176 | return ret; |
171 | } | 177 | } |
172 | 178 | ||
173 | static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev) | 179 | static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev) |
@@ -287,7 +293,7 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev, | |||
287 | 293 | ||
288 | static struct regulator_ops wm831x_gp_ldo_ops = { | 294 | static struct regulator_ops wm831x_gp_ldo_ops = { |
289 | .list_voltage = wm831x_gp_ldo_list_voltage, | 295 | .list_voltage = wm831x_gp_ldo_list_voltage, |
290 | .get_voltage = wm831x_gp_ldo_get_voltage, | 296 | .get_voltage_sel = wm831x_gp_ldo_get_voltage_sel, |
291 | .set_voltage = wm831x_gp_ldo_set_voltage, | 297 | .set_voltage = wm831x_gp_ldo_set_voltage, |
292 | .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage, | 298 | .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage, |
293 | .get_mode = wm831x_gp_ldo_get_mode, | 299 | .get_mode = wm831x_gp_ldo_get_mode, |
@@ -413,7 +419,8 @@ static int wm831x_aldo_list_voltage(struct regulator_dev *rdev, | |||
413 | } | 419 | } |
414 | 420 | ||
415 | static int wm831x_aldo_set_voltage_int(struct regulator_dev *rdev, int reg, | 421 | static int wm831x_aldo_set_voltage_int(struct regulator_dev *rdev, int reg, |
416 | int min_uV, int max_uV) | 422 | int min_uV, int max_uV, |
423 | unsigned *selector) | ||
417 | { | 424 | { |
418 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 425 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
419 | struct wm831x *wm831x = ldo->wm831x; | 426 | struct wm831x *wm831x = ldo->wm831x; |
@@ -433,16 +440,19 @@ static int wm831x_aldo_set_voltage_int(struct regulator_dev *rdev, int reg, | |||
433 | if (ret < min_uV || ret > max_uV) | 440 | if (ret < min_uV || ret > max_uV) |
434 | return -EINVAL; | 441 | return -EINVAL; |
435 | 442 | ||
443 | *selector = vsel; | ||
444 | |||
436 | return wm831x_set_bits(wm831x, reg, WM831X_LDO7_ON_VSEL_MASK, vsel); | 445 | return wm831x_set_bits(wm831x, reg, WM831X_LDO7_ON_VSEL_MASK, vsel); |
437 | } | 446 | } |
438 | 447 | ||
439 | static int wm831x_aldo_set_voltage(struct regulator_dev *rdev, | 448 | static int wm831x_aldo_set_voltage(struct regulator_dev *rdev, |
440 | int min_uV, int max_uV) | 449 | int min_uV, int max_uV, unsigned *selector) |
441 | { | 450 | { |
442 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 451 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
443 | int reg = ldo->base + WM831X_LDO_ON_CONTROL; | 452 | int reg = ldo->base + WM831X_LDO_ON_CONTROL; |
444 | 453 | ||
445 | return wm831x_aldo_set_voltage_int(rdev, reg, min_uV, max_uV); | 454 | return wm831x_aldo_set_voltage_int(rdev, reg, min_uV, max_uV, |
455 | selector); | ||
446 | } | 456 | } |
447 | 457 | ||
448 | static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev, | 458 | static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev, |
@@ -450,11 +460,12 @@ static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev, | |||
450 | { | 460 | { |
451 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 461 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
452 | int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; | 462 | int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; |
463 | unsigned int selector; | ||
453 | 464 | ||
454 | return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV); | 465 | return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV, &selector); |
455 | } | 466 | } |
456 | 467 | ||
457 | static int wm831x_aldo_get_voltage(struct regulator_dev *rdev) | 468 | static int wm831x_aldo_get_voltage_sel(struct regulator_dev *rdev) |
458 | { | 469 | { |
459 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 470 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
460 | struct wm831x *wm831x = ldo->wm831x; | 471 | struct wm831x *wm831x = ldo->wm831x; |
@@ -467,7 +478,7 @@ static int wm831x_aldo_get_voltage(struct regulator_dev *rdev) | |||
467 | 478 | ||
468 | ret &= WM831X_LDO7_ON_VSEL_MASK; | 479 | ret &= WM831X_LDO7_ON_VSEL_MASK; |
469 | 480 | ||
470 | return wm831x_aldo_list_voltage(rdev, ret); | 481 | return ret; |
471 | } | 482 | } |
472 | 483 | ||
473 | static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev) | 484 | static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev) |
@@ -548,7 +559,7 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev) | |||
548 | 559 | ||
549 | static struct regulator_ops wm831x_aldo_ops = { | 560 | static struct regulator_ops wm831x_aldo_ops = { |
550 | .list_voltage = wm831x_aldo_list_voltage, | 561 | .list_voltage = wm831x_aldo_list_voltage, |
551 | .get_voltage = wm831x_aldo_get_voltage, | 562 | .get_voltage_sel = wm831x_aldo_get_voltage_sel, |
552 | .set_voltage = wm831x_aldo_set_voltage, | 563 | .set_voltage = wm831x_aldo_set_voltage, |
553 | .set_suspend_voltage = wm831x_aldo_set_suspend_voltage, | 564 | .set_suspend_voltage = wm831x_aldo_set_suspend_voltage, |
554 | .get_mode = wm831x_aldo_get_mode, | 565 | .get_mode = wm831x_aldo_get_mode, |
@@ -666,7 +677,8 @@ static int wm831x_alive_ldo_list_voltage(struct regulator_dev *rdev, | |||
666 | 677 | ||
667 | static int wm831x_alive_ldo_set_voltage_int(struct regulator_dev *rdev, | 678 | static int wm831x_alive_ldo_set_voltage_int(struct regulator_dev *rdev, |
668 | int reg, | 679 | int reg, |
669 | int min_uV, int max_uV) | 680 | int min_uV, int max_uV, |
681 | unsigned *selector) | ||
670 | { | 682 | { |
671 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 683 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
672 | struct wm831x *wm831x = ldo->wm831x; | 684 | struct wm831x *wm831x = ldo->wm831x; |
@@ -680,16 +692,20 @@ static int wm831x_alive_ldo_set_voltage_int(struct regulator_dev *rdev, | |||
680 | if (ret < min_uV || ret > max_uV) | 692 | if (ret < min_uV || ret > max_uV) |
681 | return -EINVAL; | 693 | return -EINVAL; |
682 | 694 | ||
695 | *selector = vsel; | ||
696 | |||
683 | return wm831x_set_bits(wm831x, reg, WM831X_LDO11_ON_VSEL_MASK, vsel); | 697 | return wm831x_set_bits(wm831x, reg, WM831X_LDO11_ON_VSEL_MASK, vsel); |
684 | } | 698 | } |
685 | 699 | ||
686 | static int wm831x_alive_ldo_set_voltage(struct regulator_dev *rdev, | 700 | static int wm831x_alive_ldo_set_voltage(struct regulator_dev *rdev, |
687 | int min_uV, int max_uV) | 701 | int min_uV, int max_uV, |
702 | unsigned *selector) | ||
688 | { | 703 | { |
689 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 704 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
690 | int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL; | 705 | int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL; |
691 | 706 | ||
692 | return wm831x_alive_ldo_set_voltage_int(rdev, reg, min_uV, max_uV); | 707 | return wm831x_alive_ldo_set_voltage_int(rdev, reg, min_uV, max_uV, |
708 | selector); | ||
693 | } | 709 | } |
694 | 710 | ||
695 | static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev, | 711 | static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev, |
@@ -697,11 +713,12 @@ static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev, | |||
697 | { | 713 | { |
698 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 714 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
699 | int reg = ldo->base + WM831X_ALIVE_LDO_SLEEP_CONTROL; | 715 | int reg = ldo->base + WM831X_ALIVE_LDO_SLEEP_CONTROL; |
716 | unsigned selector; | ||
700 | 717 | ||
701 | return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV); | 718 | return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV, &selector); |
702 | } | 719 | } |
703 | 720 | ||
704 | static int wm831x_alive_ldo_get_voltage(struct regulator_dev *rdev) | 721 | static int wm831x_alive_ldo_get_voltage_sel(struct regulator_dev *rdev) |
705 | { | 722 | { |
706 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); | 723 | struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); |
707 | struct wm831x *wm831x = ldo->wm831x; | 724 | struct wm831x *wm831x = ldo->wm831x; |
@@ -714,7 +731,7 @@ static int wm831x_alive_ldo_get_voltage(struct regulator_dev *rdev) | |||
714 | 731 | ||
715 | ret &= WM831X_LDO11_ON_VSEL_MASK; | 732 | ret &= WM831X_LDO11_ON_VSEL_MASK; |
716 | 733 | ||
717 | return wm831x_alive_ldo_list_voltage(rdev, ret); | 734 | return ret; |
718 | } | 735 | } |
719 | 736 | ||
720 | static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) | 737 | static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) |
@@ -736,7 +753,7 @@ static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) | |||
736 | 753 | ||
737 | static struct regulator_ops wm831x_alive_ldo_ops = { | 754 | static struct regulator_ops wm831x_alive_ldo_ops = { |
738 | .list_voltage = wm831x_alive_ldo_list_voltage, | 755 | .list_voltage = wm831x_alive_ldo_list_voltage, |
739 | .get_voltage = wm831x_alive_ldo_get_voltage, | 756 | .get_voltage_sel = wm831x_alive_ldo_get_voltage_sel, |
740 | .set_voltage = wm831x_alive_ldo_set_voltage, | 757 | .set_voltage = wm831x_alive_ldo_set_voltage, |
741 | .set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage, | 758 | .set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage, |
742 | .get_status = wm831x_alive_ldo_get_status, | 759 | .get_status = wm831x_alive_ldo_get_status, |
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index fe4b8a8a9df..1bcb22c4409 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c | |||
@@ -360,7 +360,7 @@ int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode, | |||
360 | EXPORT_SYMBOL_GPL(wm8350_isink_set_flash); | 360 | EXPORT_SYMBOL_GPL(wm8350_isink_set_flash); |
361 | 361 | ||
362 | static int wm8350_dcdc_set_voltage(struct regulator_dev *rdev, int min_uV, | 362 | static int wm8350_dcdc_set_voltage(struct regulator_dev *rdev, int min_uV, |
363 | int max_uV) | 363 | int max_uV, unsigned *selector) |
364 | { | 364 | { |
365 | struct wm8350 *wm8350 = rdev_get_drvdata(rdev); | 365 | struct wm8350 *wm8350 = rdev_get_drvdata(rdev); |
366 | int volt_reg, dcdc = rdev_get_id(rdev), mV, | 366 | int volt_reg, dcdc = rdev_get_id(rdev), mV, |
@@ -397,17 +397,18 @@ static int wm8350_dcdc_set_voltage(struct regulator_dev *rdev, int min_uV, | |||
397 | return -EINVAL; | 397 | return -EINVAL; |
398 | } | 398 | } |
399 | 399 | ||
400 | *selector = mV; | ||
401 | |||
400 | /* all DCDCs have same mV bits */ | 402 | /* all DCDCs have same mV bits */ |
401 | val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; | 403 | val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; |
402 | wm8350_reg_write(wm8350, volt_reg, val | mV); | 404 | wm8350_reg_write(wm8350, volt_reg, val | mV); |
403 | return 0; | 405 | return 0; |
404 | } | 406 | } |
405 | 407 | ||
406 | static int wm8350_dcdc_get_voltage(struct regulator_dev *rdev) | 408 | static int wm8350_dcdc_get_voltage_sel(struct regulator_dev *rdev) |
407 | { | 409 | { |
408 | struct wm8350 *wm8350 = rdev_get_drvdata(rdev); | 410 | struct wm8350 *wm8350 = rdev_get_drvdata(rdev); |
409 | int volt_reg, dcdc = rdev_get_id(rdev); | 411 | int volt_reg, dcdc = rdev_get_id(rdev); |
410 | u16 val; | ||
411 | 412 | ||
412 | switch (dcdc) { | 413 | switch (dcdc) { |
413 | case WM8350_DCDC_1: | 414 | case WM8350_DCDC_1: |
@@ -429,8 +430,7 @@ static int wm8350_dcdc_get_voltage(struct regulator_dev *rdev) | |||
429 | } | 430 | } |
430 | 431 | ||
431 | /* all DCDCs have same mV bits */ | 432 | /* all DCDCs have same mV bits */ |
432 | val = wm8350_reg_read(wm8350, volt_reg) & WM8350_DC1_VSEL_MASK; | 433 | return wm8350_reg_read(wm8350, volt_reg) & WM8350_DC1_VSEL_MASK; |
433 | return wm8350_dcdc_val_to_mvolts(val) * 1000; | ||
434 | } | 434 | } |
435 | 435 | ||
436 | static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev, | 436 | static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev, |
@@ -754,7 +754,7 @@ static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev) | |||
754 | } | 754 | } |
755 | 755 | ||
756 | static int wm8350_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, | 756 | static int wm8350_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, |
757 | int max_uV) | 757 | int max_uV, unsigned *selector) |
758 | { | 758 | { |
759 | struct wm8350 *wm8350 = rdev_get_drvdata(rdev); | 759 | struct wm8350 *wm8350 = rdev_get_drvdata(rdev); |
760 | int volt_reg, ldo = rdev_get_id(rdev), mV, min_mV = min_uV / 1000, | 760 | int volt_reg, ldo = rdev_get_id(rdev), mV, min_mV = min_uV / 1000, |
@@ -797,17 +797,18 @@ static int wm8350_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, | |||
797 | return -EINVAL; | 797 | return -EINVAL; |
798 | } | 798 | } |
799 | 799 | ||
800 | *selector = mV; | ||
801 | |||
800 | /* all LDOs have same mV bits */ | 802 | /* all LDOs have same mV bits */ |
801 | val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; | 803 | val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; |
802 | wm8350_reg_write(wm8350, volt_reg, val | mV); | 804 | wm8350_reg_write(wm8350, volt_reg, val | mV); |
803 | return 0; | 805 | return 0; |
804 | } | 806 | } |
805 | 807 | ||
806 | static int wm8350_ldo_get_voltage(struct regulator_dev *rdev) | 808 | static int wm8350_ldo_get_voltage_sel(struct regulator_dev *rdev) |
807 | { | 809 | { |
808 | struct wm8350 *wm8350 = rdev_get_drvdata(rdev); | 810 | struct wm8350 *wm8350 = rdev_get_drvdata(rdev); |
809 | int volt_reg, ldo = rdev_get_id(rdev); | 811 | int volt_reg, ldo = rdev_get_id(rdev); |
810 | u16 val; | ||
811 | 812 | ||
812 | switch (ldo) { | 813 | switch (ldo) { |
813 | case WM8350_LDO_1: | 814 | case WM8350_LDO_1: |
@@ -827,8 +828,7 @@ static int wm8350_ldo_get_voltage(struct regulator_dev *rdev) | |||
827 | } | 828 | } |
828 | 829 | ||
829 | /* all LDOs have same mV bits */ | 830 | /* all LDOs have same mV bits */ |
830 | val = wm8350_reg_read(wm8350, volt_reg) & WM8350_LDO1_VSEL_MASK; | 831 | return wm8350_reg_read(wm8350, volt_reg) & WM8350_LDO1_VSEL_MASK; |
831 | return wm8350_ldo_val_to_mvolts(val) * 1000; | ||
832 | } | 832 | } |
833 | 833 | ||
834 | static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, | 834 | static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, |
@@ -1225,7 +1225,7 @@ static int wm8350_ldo_is_enabled(struct regulator_dev *rdev) | |||
1225 | 1225 | ||
1226 | static struct regulator_ops wm8350_dcdc_ops = { | 1226 | static struct regulator_ops wm8350_dcdc_ops = { |
1227 | .set_voltage = wm8350_dcdc_set_voltage, | 1227 | .set_voltage = wm8350_dcdc_set_voltage, |
1228 | .get_voltage = wm8350_dcdc_get_voltage, | 1228 | .get_voltage_sel = wm8350_dcdc_get_voltage_sel, |
1229 | .list_voltage = wm8350_dcdc_list_voltage, | 1229 | .list_voltage = wm8350_dcdc_list_voltage, |
1230 | .enable = wm8350_dcdc_enable, | 1230 | .enable = wm8350_dcdc_enable, |
1231 | .disable = wm8350_dcdc_disable, | 1231 | .disable = wm8350_dcdc_disable, |
@@ -1249,7 +1249,7 @@ static struct regulator_ops wm8350_dcdc2_5_ops = { | |||
1249 | 1249 | ||
1250 | static struct regulator_ops wm8350_ldo_ops = { | 1250 | static struct regulator_ops wm8350_ldo_ops = { |
1251 | .set_voltage = wm8350_ldo_set_voltage, | 1251 | .set_voltage = wm8350_ldo_set_voltage, |
1252 | .get_voltage = wm8350_ldo_get_voltage, | 1252 | .get_voltage_sel = wm8350_ldo_get_voltage_sel, |
1253 | .list_voltage = wm8350_ldo_list_voltage, | 1253 | .list_voltage = wm8350_ldo_list_voltage, |
1254 | .enable = wm8350_ldo_enable, | 1254 | .enable = wm8350_ldo_enable, |
1255 | .disable = wm8350_ldo_disable, | 1255 | .disable = wm8350_ldo_disable, |
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 924c7eb29ee..b42d01cef35 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c | |||
@@ -67,7 +67,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | static int wm8400_ldo_set_voltage(struct regulator_dev *dev, | 69 | static int wm8400_ldo_set_voltage(struct regulator_dev *dev, |
70 | int min_uV, int max_uV) | 70 | int min_uV, int max_uV, unsigned *selector) |
71 | { | 71 | { |
72 | struct wm8400 *wm8400 = rdev_get_drvdata(dev); | 72 | struct wm8400 *wm8400 = rdev_get_drvdata(dev); |
73 | u16 val; | 73 | u16 val; |
@@ -93,6 +93,8 @@ static int wm8400_ldo_set_voltage(struct regulator_dev *dev, | |||
93 | val += 0xf; | 93 | val += 0xf; |
94 | } | 94 | } |
95 | 95 | ||
96 | *selector = val; | ||
97 | |||
96 | return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), | 98 | return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), |
97 | WM8400_LDO1_VSEL_MASK, val); | 99 | WM8400_LDO1_VSEL_MASK, val); |
98 | } | 100 | } |
@@ -156,7 +158,7 @@ static int wm8400_dcdc_get_voltage(struct regulator_dev *dev) | |||
156 | } | 158 | } |
157 | 159 | ||
158 | static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, | 160 | static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, |
159 | int min_uV, int max_uV) | 161 | int min_uV, int max_uV, unsigned *selector) |
160 | { | 162 | { |
161 | struct wm8400 *wm8400 = rdev_get_drvdata(dev); | 163 | struct wm8400 *wm8400 = rdev_get_drvdata(dev); |
162 | u16 val; | 164 | u16 val; |
@@ -171,6 +173,8 @@ static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, | |||
171 | return -EINVAL; | 173 | return -EINVAL; |
172 | BUG_ON(850000 + (25000 * val) < min_uV); | 174 | BUG_ON(850000 + (25000 * val) < min_uV); |
173 | 175 | ||
176 | *selector = val; | ||
177 | |||
174 | return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, | 178 | return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, |
175 | WM8400_DC1_VSEL_MASK, val); | 179 | WM8400_DC1_VSEL_MASK, val); |
176 | } | 180 | } |
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 03713bc66e4..594f88eb60c 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c | |||
@@ -86,7 +86,7 @@ static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev, | |||
86 | return (selector * 100000) + 2400000; | 86 | return (selector * 100000) + 2400000; |
87 | } | 87 | } |
88 | 88 | ||
89 | static int wm8994_ldo1_get_voltage(struct regulator_dev *rdev) | 89 | static int wm8994_ldo1_get_voltage_sel(struct regulator_dev *rdev) |
90 | { | 90 | { |
91 | struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); | 91 | struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); |
92 | int val; | 92 | int val; |
@@ -95,13 +95,11 @@ static int wm8994_ldo1_get_voltage(struct regulator_dev *rdev) | |||
95 | if (val < 0) | 95 | if (val < 0) |
96 | return val; | 96 | return val; |
97 | 97 | ||
98 | val = (val & WM8994_LDO1_VSEL_MASK) >> WM8994_LDO1_VSEL_SHIFT; | 98 | return (val & WM8994_LDO1_VSEL_MASK) >> WM8994_LDO1_VSEL_SHIFT; |
99 | |||
100 | return wm8994_ldo1_list_voltage(rdev, val); | ||
101 | } | 99 | } |
102 | 100 | ||
103 | static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev, | 101 | static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev, |
104 | int min_uV, int max_uV) | 102 | int min_uV, int max_uV, unsigned *s) |
105 | { | 103 | { |
106 | struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); | 104 | struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); |
107 | int selector, v; | 105 | int selector, v; |
@@ -111,6 +109,7 @@ static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev, | |||
111 | if (v < 0 || v > max_uV) | 109 | if (v < 0 || v > max_uV) |
112 | return -EINVAL; | 110 | return -EINVAL; |
113 | 111 | ||
112 | *s = selector; | ||
114 | selector <<= WM8994_LDO1_VSEL_SHIFT; | 113 | selector <<= WM8994_LDO1_VSEL_SHIFT; |
115 | 114 | ||
116 | return wm8994_set_bits(ldo->wm8994, WM8994_LDO_1, | 115 | return wm8994_set_bits(ldo->wm8994, WM8994_LDO_1, |
@@ -124,7 +123,7 @@ static struct regulator_ops wm8994_ldo1_ops = { | |||
124 | .enable_time = wm8994_ldo_enable_time, | 123 | .enable_time = wm8994_ldo_enable_time, |
125 | 124 | ||
126 | .list_voltage = wm8994_ldo1_list_voltage, | 125 | .list_voltage = wm8994_ldo1_list_voltage, |
127 | .get_voltage = wm8994_ldo1_get_voltage, | 126 | .get_voltage_sel = wm8994_ldo1_get_voltage_sel, |
128 | .set_voltage = wm8994_ldo1_set_voltage, | 127 | .set_voltage = wm8994_ldo1_set_voltage, |
129 | }; | 128 | }; |
130 | 129 | ||
@@ -137,7 +136,7 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev, | |||
137 | return (selector * 100000) + 900000; | 136 | return (selector * 100000) + 900000; |
138 | } | 137 | } |
139 | 138 | ||
140 | static int wm8994_ldo2_get_voltage(struct regulator_dev *rdev) | 139 | static int wm8994_ldo2_get_voltage_sel(struct regulator_dev *rdev) |
141 | { | 140 | { |
142 | struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); | 141 | struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); |
143 | int val; | 142 | int val; |
@@ -146,13 +145,11 @@ static int wm8994_ldo2_get_voltage(struct regulator_dev *rdev) | |||
146 | if (val < 0) | 145 | if (val < 0) |
147 | return val; | 146 | return val; |
148 | 147 | ||
149 | val = (val & WM8994_LDO2_VSEL_MASK) >> WM8994_LDO2_VSEL_SHIFT; | 148 | return (val & WM8994_LDO2_VSEL_MASK) >> WM8994_LDO2_VSEL_SHIFT; |
150 | |||
151 | return wm8994_ldo2_list_voltage(rdev, val); | ||
152 | } | 149 | } |
153 | 150 | ||
154 | static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev, | 151 | static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev, |
155 | int min_uV, int max_uV) | 152 | int min_uV, int max_uV, unsigned *s) |
156 | { | 153 | { |
157 | struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); | 154 | struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); |
158 | int selector, v; | 155 | int selector, v; |
@@ -162,6 +159,7 @@ static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev, | |||
162 | if (v < 0 || v > max_uV) | 159 | if (v < 0 || v > max_uV) |
163 | return -EINVAL; | 160 | return -EINVAL; |
164 | 161 | ||
162 | *s = selector; | ||
165 | selector <<= WM8994_LDO2_VSEL_SHIFT; | 163 | selector <<= WM8994_LDO2_VSEL_SHIFT; |
166 | 164 | ||
167 | return wm8994_set_bits(ldo->wm8994, WM8994_LDO_2, | 165 | return wm8994_set_bits(ldo->wm8994, WM8994_LDO_2, |
@@ -175,7 +173,7 @@ static struct regulator_ops wm8994_ldo2_ops = { | |||
175 | .enable_time = wm8994_ldo_enable_time, | 173 | .enable_time = wm8994_ldo_enable_time, |
176 | 174 | ||
177 | .list_voltage = wm8994_ldo2_list_voltage, | 175 | .list_voltage = wm8994_ldo2_list_voltage, |
178 | .get_voltage = wm8994_ldo2_get_voltage, | 176 | .get_voltage_sel = wm8994_ldo2_get_voltage_sel, |
179 | .set_voltage = wm8994_ldo2_set_voltage, | 177 | .set_voltage = wm8994_ldo2_set_voltage, |
180 | }; | 178 | }; |
181 | 179 | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 7e6ce626b7f..c7ff8df347e 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/mod_devicetable.h> | 37 | #include <linux/mod_devicetable.h> |
38 | #include <linux/log2.h> | 38 | #include <linux/log2.h> |
39 | #include <linux/pm.h> | ||
39 | 40 | ||
40 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 41 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
41 | #include <asm-generic/rtc.h> | 42 | #include <asm-generic/rtc.h> |
@@ -851,7 +852,7 @@ static void __exit cmos_do_remove(struct device *dev) | |||
851 | 852 | ||
852 | #ifdef CONFIG_PM | 853 | #ifdef CONFIG_PM |
853 | 854 | ||
854 | static int cmos_suspend(struct device *dev, pm_message_t mesg) | 855 | static int cmos_suspend(struct device *dev) |
855 | { | 856 | { |
856 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 857 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
857 | unsigned char tmp; | 858 | unsigned char tmp; |
@@ -899,7 +900,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) | |||
899 | */ | 900 | */ |
900 | static inline int cmos_poweroff(struct device *dev) | 901 | static inline int cmos_poweroff(struct device *dev) |
901 | { | 902 | { |
902 | return cmos_suspend(dev, PMSG_HIBERNATE); | 903 | return cmos_suspend(dev); |
903 | } | 904 | } |
904 | 905 | ||
905 | static int cmos_resume(struct device *dev) | 906 | static int cmos_resume(struct device *dev) |
@@ -946,9 +947,9 @@ static int cmos_resume(struct device *dev) | |||
946 | return 0; | 947 | return 0; |
947 | } | 948 | } |
948 | 949 | ||
950 | static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume); | ||
951 | |||
949 | #else | 952 | #else |
950 | #define cmos_suspend NULL | ||
951 | #define cmos_resume NULL | ||
952 | 953 | ||
953 | static inline int cmos_poweroff(struct device *dev) | 954 | static inline int cmos_poweroff(struct device *dev) |
954 | { | 955 | { |
@@ -1078,7 +1079,7 @@ static void __exit cmos_pnp_remove(struct pnp_dev *pnp) | |||
1078 | 1079 | ||
1079 | static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg) | 1080 | static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg) |
1080 | { | 1081 | { |
1081 | return cmos_suspend(&pnp->dev, mesg); | 1082 | return cmos_suspend(&pnp->dev); |
1082 | } | 1083 | } |
1083 | 1084 | ||
1084 | static int cmos_pnp_resume(struct pnp_dev *pnp) | 1085 | static int cmos_pnp_resume(struct pnp_dev *pnp) |
@@ -1158,8 +1159,9 @@ static struct platform_driver cmos_platform_driver = { | |||
1158 | .shutdown = cmos_platform_shutdown, | 1159 | .shutdown = cmos_platform_shutdown, |
1159 | .driver = { | 1160 | .driver = { |
1160 | .name = (char *) driver_name, | 1161 | .name = (char *) driver_name, |
1161 | .suspend = cmos_suspend, | 1162 | #ifdef CONFIG_PM |
1162 | .resume = cmos_resume, | 1163 | .pm = &cmos_pm_ops, |
1164 | #endif | ||
1163 | } | 1165 | } |
1164 | }; | 1166 | }; |
1165 | 1167 | ||
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 657403ebd54..0ec3f588a25 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
@@ -139,12 +139,13 @@ static int __devinit max6902_probe(struct spi_device *spi) | |||
139 | if (IS_ERR(rtc)) | 139 | if (IS_ERR(rtc)) |
140 | return PTR_ERR(rtc); | 140 | return PTR_ERR(rtc); |
141 | 141 | ||
142 | dev_set_drvdata(&spi->dev, rtc); | ||
142 | return 0; | 143 | return 0; |
143 | } | 144 | } |
144 | 145 | ||
145 | static int __devexit max6902_remove(struct spi_device *spi) | 146 | static int __devexit max6902_remove(struct spi_device *spi) |
146 | { | 147 | { |
147 | struct rtc_device *rtc = platform_get_drvdata(spi); | 148 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); |
148 | 149 | ||
149 | rtc_device_unregister(rtc); | 150 | rtc_device_unregister(rtc); |
150 | return 0; | 151 | return 0; |
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 73377b0d65d..e72b523c79a 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -429,13 +429,14 @@ fail1: | |||
429 | fail0: | 429 | fail0: |
430 | iounmap(rtc_base); | 430 | iounmap(rtc_base); |
431 | fail: | 431 | fail: |
432 | release_resource(mem); | 432 | release_mem_region(mem->start, resource_size(mem)); |
433 | return -EIO; | 433 | return -EIO; |
434 | } | 434 | } |
435 | 435 | ||
436 | static int __exit omap_rtc_remove(struct platform_device *pdev) | 436 | static int __exit omap_rtc_remove(struct platform_device *pdev) |
437 | { | 437 | { |
438 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 438 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
439 | struct resource *mem = dev_get_drvdata(&rtc->dev); | ||
439 | 440 | ||
440 | device_init_wakeup(&pdev->dev, 0); | 441 | device_init_wakeup(&pdev->dev, 0); |
441 | 442 | ||
@@ -447,8 +448,9 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
447 | if (omap_rtc_timer != omap_rtc_alarm) | 448 | if (omap_rtc_timer != omap_rtc_alarm) |
448 | free_irq(omap_rtc_alarm, rtc); | 449 | free_irq(omap_rtc_alarm, rtc); |
449 | 450 | ||
450 | release_resource(dev_get_drvdata(&rtc->dev)); | ||
451 | rtc_device_unregister(rtc); | 451 | rtc_device_unregister(rtc); |
452 | iounmap(rtc_base); | ||
453 | release_mem_region(mem->start, resource_size(mem)); | ||
452 | return 0; | 454 | return 0; |
453 | } | 455 | } |
454 | 456 | ||
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 09e7a053c84..30b2a820e67 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -841,7 +841,7 @@ lcs_notify_lancmd_waiters(struct lcs_card *card, struct lcs_cmd *cmd) | |||
841 | } | 841 | } |
842 | 842 | ||
843 | /** | 843 | /** |
844 | * Emit buffer of a lan comand. | 844 | * Emit buffer of a lan command. |
845 | */ | 845 | */ |
846 | static void | 846 | static void |
847 | lcs_lancmd_timeout(unsigned long data) | 847 | lcs_lancmd_timeout(unsigned long data) |
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 46342fee394..303dde09d29 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c | |||
@@ -317,7 +317,7 @@ static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) | |||
317 | 317 | ||
318 | /** | 318 | /** |
319 | * zfcp_cfdc_port_denied - Process "access denied" for port | 319 | * zfcp_cfdc_port_denied - Process "access denied" for port |
320 | * @port: The port where the acces has been denied | 320 | * @port: The port where the access has been denied |
321 | * @qual: The FSF status qualifier for the access denied FSF status | 321 | * @qual: The FSF status qualifier for the access denied FSF status |
322 | */ | 322 | */ |
323 | void zfcp_cfdc_port_denied(struct zfcp_port *port, | 323 | void zfcp_cfdc_port_denied(struct zfcp_port *port, |
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index dc5ac6e528c..a391090a17c 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c | |||
@@ -416,7 +416,7 @@ static u8 orc_load_firmware(struct orc_host * host) | |||
416 | /* Go back and check they match */ | 416 | /* Go back and check they match */ |
417 | 417 | ||
418 | outb(PRGMRST | DOWNLOAD, host->base + ORC_RISCCTL); /* Reset program count 0 */ | 418 | outb(PRGMRST | DOWNLOAD, host->base + ORC_RISCCTL); /* Reset program count 0 */ |
419 | bios_addr -= 0x1000; /* Reset the BIOS adddress */ | 419 | bios_addr -= 0x1000; /* Reset the BIOS address */ |
420 | for (i = 0, data32_ptr = (u8 *) & data32; /* Check the code */ | 420 | for (i = 0, data32_ptr = (u8 *) & data32; /* Check the code */ |
421 | i < 0x1000; /* Firmware code size = 4K */ | 421 | i < 0x1000; /* Firmware code size = 4K */ |
422 | i++, bios_addr++) { | 422 | i++, bios_addr++) { |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index afc9aeba5ed..060ac4bd5a1 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -91,7 +91,7 @@ void aac_fib_map_free(struct aac_dev *dev) | |||
91 | * aac_fib_setup - setup the fibs | 91 | * aac_fib_setup - setup the fibs |
92 | * @dev: Adapter to set up | 92 | * @dev: Adapter to set up |
93 | * | 93 | * |
94 | * Allocate the PCI space for the fibs, map it and then intialise the | 94 | * Allocate the PCI space for the fibs, map it and then initialise the |
95 | * fib area, the unmapped fib data and also the free list | 95 | * fib area, the unmapped fib data and also the free list |
96 | */ | 96 | */ |
97 | 97 | ||
diff --git a/drivers/scsi/aic7xxx_old/aic7xxx.seq b/drivers/scsi/aic7xxx_old/aic7xxx.seq index 5997e7c3a19..1565be9ebd4 100644 --- a/drivers/scsi/aic7xxx_old/aic7xxx.seq +++ b/drivers/scsi/aic7xxx_old/aic7xxx.seq | |||
@@ -1178,7 +1178,7 @@ notFound: | |||
1178 | /* | 1178 | /* |
1179 | * Retrieve an SCB by SCBID first searching the disconnected list falling | 1179 | * Retrieve an SCB by SCBID first searching the disconnected list falling |
1180 | * back to DMA'ing the SCB down from the host. This routine assumes that | 1180 | * back to DMA'ing the SCB down from the host. This routine assumes that |
1181 | * ARG_1 is the SCBID of interrest and that SINDEX is the position in the | 1181 | * ARG_1 is the SCBID of interest and that SINDEX is the position in the |
1182 | * disconnected list to start the search from. If SINDEX is SCB_LIST_NULL, | 1182 | * disconnected list to start the search from. If SINDEX is SCB_LIST_NULL, |
1183 | * we go directly to the host for the SCB. | 1183 | * we go directly to the host for the SCB. |
1184 | */ | 1184 | */ |
diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h index 28aaf349c11..40273a747d2 100644 --- a/drivers/scsi/aic94xx/aic94xx_reg_def.h +++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h | |||
@@ -1689,7 +1689,7 @@ | |||
1689 | #define PHY_START_CAL 0x01 | 1689 | #define PHY_START_CAL 0x01 |
1690 | 1690 | ||
1691 | /* | 1691 | /* |
1692 | * HST_PCIX2 Registers, Addresss Range: (0x00-0xFC) | 1692 | * HST_PCIX2 Registers, Address Range: (0x00-0xFC) |
1693 | */ | 1693 | */ |
1694 | #define PCIX_REG_BASE_ADR 0xB8040000 | 1694 | #define PCIX_REG_BASE_ADR 0xB8040000 |
1695 | 1695 | ||
@@ -1802,7 +1802,7 @@ | |||
1802 | #define PCIC_TP_CTRL 0xFC | 1802 | #define PCIC_TP_CTRL 0xFC |
1803 | 1803 | ||
1804 | /* | 1804 | /* |
1805 | * EXSI Registers, Addresss Range: (0x00-0xFC) | 1805 | * EXSI Registers, Address Range: (0x00-0xFC) |
1806 | */ | 1806 | */ |
1807 | #define EXSI_REG_BASE_ADR REG_BASE_ADDR_EXSI | 1807 | #define EXSI_REG_BASE_ADR REG_BASE_ADDR_EXSI |
1808 | 1808 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index c43698b1cb6..29593275201 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c | |||
@@ -867,7 +867,7 @@ void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id, | |||
867 | * resources they have with this SCB, and then call this one at the | 867 | * resources they have with this SCB, and then call this one at the |
868 | * end of their timeout function. To do this, one should initialize | 868 | * end of their timeout function. To do this, one should initialize |
869 | * the ascb->timer.{function, data, expires} prior to calling the post | 869 | * the ascb->timer.{function, data, expires} prior to calling the post |
870 | * funcion. The timer is started by the post function. | 870 | * function. The timer is started by the post function. |
871 | */ | 871 | */ |
872 | void asd_ascb_timedout(unsigned long data) | 872 | void asd_ascb_timedout(unsigned long data) |
873 | { | 873 | { |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index 74374618010..390168f62a1 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c | |||
@@ -797,7 +797,7 @@ static void asd_init_lseq_mdp(struct asd_ha_struct *asd_ha, int lseq) | |||
797 | int j; | 797 | int j; |
798 | /* Start from Page 1 of Mode 0 and 1. */ | 798 | /* Start from Page 1 of Mode 0 and 1. */ |
799 | moffs = LSEQ_PAGE_SIZE + i*LSEQ_MODE_SCRATCH_SIZE; | 799 | moffs = LSEQ_PAGE_SIZE + i*LSEQ_MODE_SCRATCH_SIZE; |
800 | /* All the fields of page 1 can be intialized to 0. */ | 800 | /* All the fields of page 1 can be initialized to 0. */ |
801 | for (j = 0; j < LSEQ_PAGE_SIZE; j += 4) | 801 | for (j = 0; j < LSEQ_PAGE_SIZE; j += 4) |
802 | asd_write_reg_dword(asd_ha, LmSCRATCH(lseq)+moffs+j,0); | 802 | asd_write_reg_dword(asd_ha, LmSCRATCH(lseq)+moffs+j,0); |
803 | } | 803 | } |
@@ -938,7 +938,7 @@ static void asd_init_cseq_cio(struct asd_ha_struct *asd_ha) | |||
938 | asd_write_reg_dword(asd_ha, SCBPRO, 0); | 938 | asd_write_reg_dword(asd_ha, SCBPRO, 0); |
939 | asd_write_reg_dword(asd_ha, CSEQCON, 0); | 939 | asd_write_reg_dword(asd_ha, CSEQCON, 0); |
940 | 940 | ||
941 | /* Intialize CSEQ Mode 11 Interrupt Vectors. | 941 | /* Initialize CSEQ Mode 11 Interrupt Vectors. |
942 | * The addresses are 16 bit wide and in dword units. | 942 | * The addresses are 16 bit wide and in dword units. |
943 | * The values of their macros are in byte units. | 943 | * The values of their macros are in byte units. |
944 | * Thus we have to divide by 4. */ | 944 | * Thus we have to divide by 4. */ |
@@ -961,7 +961,7 @@ static void asd_init_cseq_cio(struct asd_ha_struct *asd_ha) | |||
961 | asd_write_reg_word(asd_ha, CPRGMCNT, cseq_idle_loop); | 961 | asd_write_reg_word(asd_ha, CPRGMCNT, cseq_idle_loop); |
962 | 962 | ||
963 | for (i = 0; i < 8; i++) { | 963 | for (i = 0; i < 8; i++) { |
964 | /* Intialize Mode n Link m Interrupt Enable. */ | 964 | /* Initialize Mode n Link m Interrupt Enable. */ |
965 | asd_write_reg_dword(asd_ha, CMnINTEN(i), EN_CMnRSPMBXF); | 965 | asd_write_reg_dword(asd_ha, CMnINTEN(i), EN_CMnRSPMBXF); |
966 | /* Initialize Mode n Request Mailbox. */ | 966 | /* Initialize Mode n Request Mailbox. */ |
967 | asd_write_reg_dword(asd_ha, CMnREQMBX(i), 0); | 967 | asd_write_reg_dword(asd_ha, CMnREQMBX(i), 0); |
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index 9c410b21db6..c0353cdca92 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c | |||
@@ -1838,7 +1838,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
1838 | 1838 | ||
1839 | case BFA_IOIM_SM_ABORT: | 1839 | case BFA_IOIM_SM_ABORT: |
1840 | /* | 1840 | /* |
1841 | * IO is alraedy being cleaned up implicitly | 1841 | * IO is already being cleaned up implicitly |
1842 | */ | 1842 | */ |
1843 | ioim->io_cbfn = __bfa_cb_ioim_abort; | 1843 | ioim->io_cbfn = __bfa_cb_ioim_abort; |
1844 | break; | 1844 | break; |
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 4e2eb92ba02..43fa986bb58 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c | |||
@@ -5646,7 +5646,7 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) | |||
5646 | switch (status) { | 5646 | switch (status) { |
5647 | case BFA_STATUS_OK: | 5647 | case BFA_STATUS_OK: |
5648 | /* | 5648 | /* |
5649 | * Initialiaze the V-Port fields | 5649 | * Initialize the V-Port fields |
5650 | */ | 5650 | */ |
5651 | __vport_fcid(vport) = vport->lps->lp_pid; | 5651 | __vport_fcid(vport) = vport->lps->lp_pid; |
5652 | vport->vport_stats.fdisc_accepts++; | 5652 | vport->vport_stats.fdisc_accepts++; |
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 8f1b5c8bf90..b0f8523e665 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c | |||
@@ -3796,7 +3796,7 @@ static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, | |||
3796 | * adapter_add_device - Adds the device instance to the adaptor instance. | 3796 | * adapter_add_device - Adds the device instance to the adaptor instance. |
3797 | * | 3797 | * |
3798 | * @acb: The adapter device to be updated | 3798 | * @acb: The adapter device to be updated |
3799 | * @dcb: A newly created and intialised device instance to add. | 3799 | * @dcb: A newly created and initialised device instance to add. |
3800 | **/ | 3800 | **/ |
3801 | static void adapter_add_device(struct AdapterCtlBlk *acb, | 3801 | static void adapter_add_device(struct AdapterCtlBlk *acb, |
3802 | struct DeviceCtlBlk *dcb) | 3802 | struct DeviceCtlBlk *dcb) |
@@ -4498,7 +4498,7 @@ static void __devinit adapter_init_chip(struct AdapterCtlBlk *acb) | |||
4498 | * init_adapter - Grab the resource for the card, setup the adapter | 4498 | * init_adapter - Grab the resource for the card, setup the adapter |
4499 | * information, set the card into a known state, create the various | 4499 | * information, set the card into a known state, create the various |
4500 | * tables etc etc. This basically gets all adapter information all up | 4500 | * tables etc etc. This basically gets all adapter information all up |
4501 | * to date, intialised and gets the chip in sync with it. | 4501 | * to date, initialised and gets the chip in sync with it. |
4502 | * | 4502 | * |
4503 | * @host: This hosts adapter structure | 4503 | * @host: This hosts adapter structure |
4504 | * @io_port: The base I/O port | 4504 | * @io_port: The base I/O port |
@@ -4789,7 +4789,7 @@ static void banner_display(void) | |||
4789 | * that it finds in the system. The pci_dev strcuture indicates which | 4789 | * that it finds in the system. The pci_dev strcuture indicates which |
4790 | * instance we are being called from. | 4790 | * instance we are being called from. |
4791 | * | 4791 | * |
4792 | * @dev: The PCI device to intialize. | 4792 | * @dev: The PCI device to initialize. |
4793 | * @id: Looks like a pointer to the entry in our pci device table | 4793 | * @id: Looks like a pointer to the entry in our pci device table |
4794 | * that was actually matched by the PCI subsystem. | 4794 | * that was actually matched by the PCI subsystem. |
4795 | * | 4795 | * |
@@ -4860,7 +4860,7 @@ fail: | |||
4860 | * dc395x_remove_one - Called to remove a single instance of the | 4860 | * dc395x_remove_one - Called to remove a single instance of the |
4861 | * adapter. | 4861 | * adapter. |
4862 | * | 4862 | * |
4863 | * @dev: The PCI device to intialize. | 4863 | * @dev: The PCI device to initialize. |
4864 | **/ | 4864 | **/ |
4865 | static void __devexit dc395x_remove_one(struct pci_dev *dev) | 4865 | static void __devexit dc395x_remove_one(struct pci_dev *dev) |
4866 | { | 4866 | { |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index cdc06cda76e..5962d1a5a67 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
@@ -1250,7 +1250,7 @@ static void fc_lun_reset_send(unsigned long data) | |||
1250 | /** | 1250 | /** |
1251 | * fc_lun_reset() - Send a LUN RESET command to a device | 1251 | * fc_lun_reset() - Send a LUN RESET command to a device |
1252 | * and wait for the reply | 1252 | * and wait for the reply |
1253 | * @lport: The local port to sent the comand on | 1253 | * @lport: The local port to sent the command on |
1254 | * @fsp: The FCP packet that identifies the LUN to be reset | 1254 | * @fsp: The FCP packet that identifies the LUN to be reset |
1255 | * @id: The SCSI command ID | 1255 | * @id: The SCSI command ID |
1256 | * @lun: The LUN ID to be reset | 1256 | * @lun: The LUN ID to be reset |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index c06491b5862..3512abb8a58 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1335,7 +1335,7 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ | |||
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | /** | 1337 | /** |
1338 | * lpfc_param_init - Intializes a cfg attribute | 1338 | * lpfc_param_init - Initializes a cfg attribute |
1339 | * | 1339 | * |
1340 | * Description: | 1340 | * Description: |
1341 | * Macro that given an attr e.g. hba_queue_depth expands | 1341 | * Macro that given an attr e.g. hba_queue_depth expands |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f9f160ab2ee..bb015960dbc 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -2852,7 +2852,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) | |||
2852 | if (unlikely(!fcf_record)) { | 2852 | if (unlikely(!fcf_record)) { |
2853 | lpfc_printf_log(phba, KERN_ERR, | 2853 | lpfc_printf_log(phba, KERN_ERR, |
2854 | LOG_MBOX | LOG_SLI, | 2854 | LOG_MBOX | LOG_SLI, |
2855 | "2554 Could not allocate memmory for " | 2855 | "2554 Could not allocate memory for " |
2856 | "fcf record\n"); | 2856 | "fcf record\n"); |
2857 | rc = -ENODEV; | 2857 | rc = -ENODEV; |
2858 | goto out; | 2858 | goto out; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 462242dcdd0..6d0b36aa338 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -8071,7 +8071,7 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
8071 | * the HBA. | 8071 | * the HBA. |
8072 | */ | 8072 | */ |
8073 | 8073 | ||
8074 | /* HBA interrupt will be diabled after this call */ | 8074 | /* HBA interrupt will be disabled after this call */ |
8075 | lpfc_sli_hba_down(phba); | 8075 | lpfc_sli_hba_down(phba); |
8076 | /* Stop kthread signal shall trigger work_done one more time */ | 8076 | /* Stop kthread signal shall trigger work_done one more time */ |
8077 | kthread_stop(phba->worker_thread); | 8077 | kthread_stop(phba->worker_thread); |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 634b2fea9c4..a359d2b873c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -10172,7 +10172,7 @@ lpfc_sli4_intr_handler(int irq, void *dev_id) | |||
10172 | * lpfc_sli4_queue_free - free a queue structure and associated memory | 10172 | * lpfc_sli4_queue_free - free a queue structure and associated memory |
10173 | * @queue: The queue structure to free. | 10173 | * @queue: The queue structure to free. |
10174 | * | 10174 | * |
10175 | * This function frees a queue structure and the DMAable memeory used for | 10175 | * This function frees a queue structure and the DMAable memory used for |
10176 | * the host resident queue. This function must be called after destroying the | 10176 | * the host resident queue. This function must be called after destroying the |
10177 | * queue on the HBA. | 10177 | * queue on the HBA. |
10178 | **/ | 10178 | **/ |
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index f5644745e24..853411911b2 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | /* | 15 | /* |
16 | * Comand coalescing - This feature allows the driver to be able to combine | 16 | * Command coalescing - This feature allows the driver to be able to combine |
17 | * two or more commands and issue as one command in order to boost I/O | 17 | * two or more commands and issue as one command in order to boost I/O |
18 | * performance. Useful if the nature of the I/O is sequential. It is not very | 18 | * performance. Useful if the nature of the I/O is sequential. It is not very |
19 | * useful for random natured I/Os. | 19 | * useful for random natured I/Os. |
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index a7008c0c24f..25506c77738 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c | |||
@@ -224,7 +224,7 @@ mraid_mm_unlocked_ioctl(struct file *filep, unsigned int cmd, | |||
224 | { | 224 | { |
225 | int err; | 225 | int err; |
226 | 226 | ||
227 | /* inconsistant: mraid_mm_compat_ioctl doesn't take the BKL */ | 227 | /* inconsistent: mraid_mm_compat_ioctl doesn't take the BKL */ |
228 | mutex_lock(&mraid_mm_mutex); | 228 | mutex_lock(&mraid_mm_mutex); |
229 | err = mraid_mm_ioctl(filep, cmd, arg); | 229 | err = mraid_mm_ioctl(filep, cmd, arg); |
230 | mutex_unlock(&mraid_mm_mutex); | 230 | mutex_unlock(&mraid_mm_mutex); |
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index f8c86b28f03..b95285f3383 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c | |||
@@ -603,7 +603,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) | |||
603 | #endif | 603 | #endif |
604 | 604 | ||
605 | intx: | 605 | intx: |
606 | /* intialize the INT-X interrupt */ | 606 | /* initialize the INT-X interrupt */ |
607 | rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED, DRV_NAME, | 607 | rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED, DRV_NAME, |
608 | SHOST_TO_SAS_HA(pm8001_ha->shost)); | 608 | SHOST_TO_SAS_HA(pm8001_ha->shost)); |
609 | return rc; | 609 | return rc; |
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index d53e6503c6d..a2ed201885a 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c | |||
@@ -477,7 +477,7 @@ EXPORT_SYMBOL_GPL(scsi_nl_remove_driver); | |||
477 | 477 | ||
478 | 478 | ||
479 | /** | 479 | /** |
480 | * scsi_netlink_init - Called by SCSI subsystem to intialize | 480 | * scsi_netlink_init - Called by SCSI subsystem to initialize |
481 | * the SCSI transport netlink interface | 481 | * the SCSI transport netlink interface |
482 | * | 482 | * |
483 | **/ | 483 | **/ |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 4c68d36f9ac..490ce213204 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -864,13 +864,15 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
864 | 864 | ||
865 | error = device_add(&sdev->sdev_gendev); | 865 | error = device_add(&sdev->sdev_gendev); |
866 | if (error) { | 866 | if (error) { |
867 | printk(KERN_INFO "error 1\n"); | 867 | sdev_printk(KERN_INFO, sdev, |
868 | "failed to add device: %d\n", error); | ||
868 | return error; | 869 | return error; |
869 | } | 870 | } |
870 | device_enable_async_suspend(&sdev->sdev_dev); | 871 | device_enable_async_suspend(&sdev->sdev_dev); |
871 | error = device_add(&sdev->sdev_dev); | 872 | error = device_add(&sdev->sdev_dev); |
872 | if (error) { | 873 | if (error) { |
873 | printk(KERN_INFO "error 2\n"); | 874 | sdev_printk(KERN_INFO, sdev, |
875 | "failed to add class device: %d\n", error); | ||
874 | device_del(&sdev->sdev_gendev); | 876 | device_del(&sdev->sdev_gendev); |
875 | return error; | 877 | return error; |
876 | } | 878 | } |
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 6b97ded9d45..b4543f575f4 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c | |||
@@ -1866,7 +1866,7 @@ static pci_ers_result_t sym2_io_slot_dump(struct pci_dev *pdev) | |||
1866 | * | 1866 | * |
1867 | * This routine is similar to sym_set_workarounds(), except | 1867 | * This routine is similar to sym_set_workarounds(), except |
1868 | * that, at this point, we already know that the device was | 1868 | * that, at this point, we already know that the device was |
1869 | * successfully intialized at least once before, and so most | 1869 | * successfully initialized at least once before, and so most |
1870 | * of the steps taken there are un-needed here. | 1870 | * of the steps taken there are un-needed here. |
1871 | */ | 1871 | */ |
1872 | static void sym2_reset_workarounds(struct pci_dev *pdev) | 1872 | static void sym2_reset_workarounds(struct pci_dev *pdev) |
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index a067046c9da..1a478bf88c9 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
@@ -341,9 +341,9 @@ static void atmel_spi_next_message(struct spi_master *master) | |||
341 | /* | 341 | /* |
342 | * For DMA, tx_buf/tx_dma have the same relationship as rx_buf/rx_dma: | 342 | * For DMA, tx_buf/tx_dma have the same relationship as rx_buf/rx_dma: |
343 | * - The buffer is either valid for CPU access, else NULL | 343 | * - The buffer is either valid for CPU access, else NULL |
344 | * - If the buffer is valid, so is its DMA addresss | 344 | * - If the buffer is valid, so is its DMA address |
345 | * | 345 | * |
346 | * This driver manages the dma addresss unless message->is_dma_mapped. | 346 | * This driver manages the dma address unless message->is_dma_mapped. |
347 | */ | 347 | */ |
348 | static int | 348 | static int |
349 | atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) | 349 | atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 4e6245e6799..603428213d2 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | 39 | ||
40 | /* | 40 | /* |
41 | * This supports acccess to SPI devices using normal userspace I/O calls. | 41 | * This supports access to SPI devices using normal userspace I/O calls. |
42 | * Note that while traditional UNIX/POSIX I/O semantics are half duplex, | 42 | * Note that while traditional UNIX/POSIX I/O semantics are half duplex, |
43 | * and often mask message boundaries, full SPI support requires full duplex | 43 | * and often mask message boundaries, full SPI support requires full duplex |
44 | * transfers. There are several kinds of internal message boundaries to | 44 | * transfers. There are several kinds of internal message boundaries to |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e2d58690343..5c8fcfc42c3 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -123,6 +123,8 @@ source "drivers/staging/sep/Kconfig" | |||
123 | 123 | ||
124 | source "drivers/staging/iio/Kconfig" | 124 | source "drivers/staging/iio/Kconfig" |
125 | 125 | ||
126 | source "drivers/staging/cs5535_gpio/Kconfig" | ||
127 | |||
126 | source "drivers/staging/zram/Kconfig" | 128 | source "drivers/staging/zram/Kconfig" |
127 | 129 | ||
128 | source "drivers/staging/wlags49_h2/Kconfig" | 130 | source "drivers/staging/wlags49_h2/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c7d222413c0..d5388631782 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -44,6 +44,7 @@ obj-$(CONFIG_VME_BUS) += vme/ | |||
44 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ | 44 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ |
45 | obj-$(CONFIG_DX_SEP) += sep/ | 45 | obj-$(CONFIG_DX_SEP) += sep/ |
46 | obj-$(CONFIG_IIO) += iio/ | 46 | obj-$(CONFIG_IIO) += iio/ |
47 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio/ | ||
47 | obj-$(CONFIG_ZRAM) += zram/ | 48 | obj-$(CONFIG_ZRAM) += zram/ |
48 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ | 49 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ |
49 | obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ | 50 | obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ |
diff --git a/drivers/staging/cs5535_gpio/Kconfig b/drivers/staging/cs5535_gpio/Kconfig new file mode 100644 index 00000000000..a1b3a8d2b86 --- /dev/null +++ b/drivers/staging/cs5535_gpio/Kconfig | |||
@@ -0,0 +1,11 @@ | |||
1 | config CS5535_GPIO | ||
2 | tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)" | ||
3 | depends on X86_32 | ||
4 | help | ||
5 | Note: this driver is DEPRECATED. Please use the cs5535-gpio module | ||
6 | in the GPIO section instead (CONFIG_GPIO_CS5535). | ||
7 | |||
8 | Give userspace access to the GPIO pins on the AMD CS5535 and | ||
9 | CS5536 Geode companion devices. | ||
10 | |||
11 | If compiled as a module, it will be called cs5535_gpio. | ||
diff --git a/drivers/staging/cs5535_gpio/Makefile b/drivers/staging/cs5535_gpio/Makefile new file mode 100644 index 00000000000..d67c4b85f19 --- /dev/null +++ b/drivers/staging/cs5535_gpio/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o | |||
diff --git a/drivers/staging/cs5535_gpio/TODO b/drivers/staging/cs5535_gpio/TODO new file mode 100644 index 00000000000..98d1cd1e236 --- /dev/null +++ b/drivers/staging/cs5535_gpio/TODO | |||
@@ -0,0 +1,6 @@ | |||
1 | This is an obsolete driver for some the CS5535 and CS5536 southbridge GPIOs. | ||
2 | It has been replaced by a driver that makes use of the Linux GPIO subsystem. | ||
3 | Please switch to that driver, and let dilinger@queued.net know if there's | ||
4 | anything missing from the new driver. | ||
5 | |||
6 | This driver is scheduled for removal in 2.6.40. | ||
diff --git a/drivers/char/cs5535_gpio.c b/drivers/staging/cs5535_gpio/cs5535_gpio.c index 0cf1e5fad9a..0cf1e5fad9a 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/staging/cs5535_gpio/cs5535_gpio.c | |||
diff --git a/drivers/staging/msm/msm_fb_bl.c b/drivers/staging/msm/msm_fb_bl.c index 033fc9486e0..2a8077511fc 100644 --- a/drivers/staging/msm/msm_fb_bl.c +++ b/drivers/staging/msm/msm_fb_bl.c | |||
@@ -42,7 +42,7 @@ static int msm_fb_bl_update_status(struct backlight_device *pbd) | |||
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | static struct backlight_ops msm_fb_bl_ops = { | 45 | static const struct backlight_ops msm_fb_bl_ops = { |
46 | .get_brightness = msm_fb_bl_get_brightness, | 46 | .get_brightness = msm_fb_bl_get_brightness, |
47 | .update_status = msm_fb_bl_update_status, | 47 | .update_status = msm_fb_bl_update_status, |
48 | }; | 48 | }; |
diff --git a/drivers/staging/olpc_dcon/TODO b/drivers/staging/olpc_dcon/TODO index ac2d3d02371..35f9cda7be1 100644 --- a/drivers/staging/olpc_dcon/TODO +++ b/drivers/staging/olpc_dcon/TODO | |||
@@ -1,6 +1,5 @@ | |||
1 | TODO: | 1 | TODO: |
2 | - checkpatch.pl cleanups | 2 | - checkpatch.pl cleanups |
3 | - port geode gpio calls to newer cs5535 API | ||
4 | - see if vx855 gpio API can be made similar enough to cs5535 so we can | 3 | - see if vx855 gpio API can be made similar enough to cs5535 so we can |
5 | share more code | 4 | share more code |
6 | - allow simultaneous XO-1 and XO-1.5 support | 5 | - allow simultaneous XO-1 and XO-1.5 support |
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 4ca45ec7fd8..9f26dc9408b 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #include <linux/reboot.h> | 29 | #include <linux/reboot.h> |
30 | #include <linux/gpio.h> | ||
31 | #include <asm/tsc.h> | 30 | #include <asm/tsc.h> |
32 | #include <asm/olpc.h> | 31 | #include <asm/olpc.h> |
33 | 32 | ||
@@ -49,7 +48,7 @@ struct dcon_platform_data { | |||
49 | int (*init)(void); | 48 | int (*init)(void); |
50 | void (*bus_stabilize_wiggle)(void); | 49 | void (*bus_stabilize_wiggle)(void); |
51 | void (*set_dconload)(int); | 50 | void (*set_dconload)(int); |
52 | int (*read_status)(void); | 51 | u8 (*read_status)(void); |
53 | }; | 52 | }; |
54 | 53 | ||
55 | static struct dcon_platform_data *pdata; | 54 | static struct dcon_platform_data *pdata; |
@@ -615,7 +614,7 @@ static struct device_attribute dcon_device_files[] = { | |||
615 | __ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store), | 614 | __ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store), |
616 | }; | 615 | }; |
617 | 616 | ||
618 | static struct backlight_ops dcon_bl_ops = { | 617 | static const struct backlight_ops dcon_bl_ops = { |
619 | .get_brightness = dconbl_get, | 618 | .get_brightness = dconbl_get, |
620 | .update_status = dconbl_set | 619 | .update_status = dconbl_set |
621 | }; | 620 | }; |
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index 6453ca4ba0e..e566d213da2 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h | |||
@@ -29,26 +29,6 @@ | |||
29 | #define DCON_REG_SCAN_INT 9 | 29 | #define DCON_REG_SCAN_INT 9 |
30 | #define DCON_REG_BRIGHT 10 | 30 | #define DCON_REG_BRIGHT 10 |
31 | 31 | ||
32 | /* GPIO registers (CS5536) */ | ||
33 | |||
34 | #define MSR_LBAR_GPIO 0x5140000C | ||
35 | |||
36 | #define GPIOx_OUT_VAL 0x00 | ||
37 | #define GPIOx_OUT_EN 0x04 | ||
38 | #define GPIOx_IN_EN 0x20 | ||
39 | #define GPIOx_INV_EN 0x24 | ||
40 | #define GPIOx_IN_FLTR_EN 0x28 | ||
41 | #define GPIOx_EVNTCNT_EN 0x2C | ||
42 | #define GPIOx_READ_BACK 0x30 | ||
43 | #define GPIOx_EVNT_EN 0x38 | ||
44 | #define GPIOx_NEGEDGE_EN 0x44 | ||
45 | #define GPIOx_NEGEDGE_STS 0x4C | ||
46 | #define GPIO_FLT7_AMNT 0xD8 | ||
47 | #define GPIO_MAP_X 0xE0 | ||
48 | #define GPIO_MAP_Y 0xE4 | ||
49 | #define GPIO_FE7_SEL 0xF7 | ||
50 | |||
51 | |||
52 | /* Status values */ | 32 | /* Status values */ |
53 | 33 | ||
54 | #define DCONSTAT_SCANINT 0 | 34 | #define DCONSTAT_SCANINT 0 |
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index 779fb7d7b30..043198dc6ff 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c | |||
@@ -10,54 +10,70 @@ | |||
10 | * modify it under the terms of version 2 of the GNU General Public | 10 | * modify it under the terms of version 2 of the GNU General Public |
11 | * License as published by the Free Software Foundation. | 11 | * License as published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | #include <linux/cs5535.h> | |
14 | #include <linux/gpio.h> | ||
14 | #include <asm/olpc.h> | 15 | #include <asm/olpc.h> |
15 | 16 | ||
16 | #include "olpc_dcon.h" | 17 | #include "olpc_dcon.h" |
17 | 18 | ||
18 | /* Base address of the GPIO registers */ | ||
19 | static unsigned long gpio_base; | ||
20 | |||
21 | /* | ||
22 | * List of GPIOs that we care about: | ||
23 | * (in) GPIO12 -- DCONBLANK | ||
24 | * (in) GPIO[56] -- DCONSTAT[01] | ||
25 | * (out) GPIO11 -- DCONLOAD | ||
26 | */ | ||
27 | |||
28 | #define IN_GPIOS ((1<<5) | (1<<6) | (1<<7) | (1<<12)) | ||
29 | #define OUT_GPIOS (1<<11) | ||
30 | |||
31 | static int dcon_init_xo_1(void) | 19 | static int dcon_init_xo_1(void) |
32 | { | 20 | { |
33 | unsigned long lo, hi; | ||
34 | unsigned char lob; | 21 | unsigned char lob; |
35 | 22 | ||
36 | rdmsr(MSR_LBAR_GPIO, lo, hi); | 23 | if (gpio_request(OLPC_GPIO_DCON_STAT0, "OLPC-DCON")) { |
37 | 24 | printk(KERN_ERR "olpc-dcon: failed to request STAT0 GPIO\n"); | |
38 | /* Check the mask and whether GPIO is enabled (sanity check) */ | 25 | return -EIO; |
39 | if (hi != 0x0000f001) { | 26 | } |
40 | printk(KERN_ERR "GPIO not enabled -- cannot use DCON\n"); | 27 | if (gpio_request(OLPC_GPIO_DCON_STAT1, "OLPC-DCON")) { |
41 | return -ENODEV; | 28 | printk(KERN_ERR "olpc-dcon: failed to request STAT1 GPIO\n"); |
29 | goto err_gp_stat1; | ||
30 | } | ||
31 | if (gpio_request(OLPC_GPIO_DCON_IRQ, "OLPC-DCON")) { | ||
32 | printk(KERN_ERR "olpc-dcon: failed to request IRQ GPIO\n"); | ||
33 | goto err_gp_irq; | ||
34 | } | ||
35 | if (gpio_request(OLPC_GPIO_DCON_LOAD, "OLPC-DCON")) { | ||
36 | printk(KERN_ERR "olpc-dcon: failed to request LOAD GPIO\n"); | ||
37 | goto err_gp_load; | ||
38 | } | ||
39 | if (gpio_request(OLPC_GPIO_DCON_BLANK, "OLPC-DCON")) { | ||
40 | printk(KERN_ERR "olpc-dcon: failed to request BLANK GPIO\n"); | ||
41 | goto err_gp_blank; | ||
42 | } | 42 | } |
43 | |||
44 | /* Mask off the IO base address */ | ||
45 | gpio_base = lo & 0x0000ff00; | ||
46 | 43 | ||
47 | /* Turn off the event enable for GPIO7 just to be safe */ | 44 | /* Turn off the event enable for GPIO7 just to be safe */ |
48 | outl(1 << (16+7), gpio_base + GPIOx_EVNT_EN); | 45 | cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_EVENTS_ENABLE); |
46 | |||
47 | /* | ||
48 | * Determine the current state by reading the GPIO bit; earlier | ||
49 | * stages of the boot process have established the state. | ||
50 | * | ||
51 | * Note that we read GPIO_OUPUT_VAL rather than GPIO_READ_BACK here; | ||
52 | * this is because OFW will disable input for the pin and set a value.. | ||
53 | * READ_BACK will only contain a valid value if input is enabled and | ||
54 | * then a value is set. So, future readings of the pin can use | ||
55 | * READ_BACK, but the first one cannot. Awesome, huh? | ||
56 | */ | ||
57 | dcon_source = cs5535_gpio_isset(OLPC_GPIO_DCON_LOAD, GPIO_OUTPUT_VAL) | ||
58 | ? DCON_SOURCE_CPU | ||
59 | : DCON_SOURCE_DCON; | ||
60 | dcon_pending = dcon_source; | ||
49 | 61 | ||
50 | /* Set the directions for the GPIO pins */ | 62 | /* Set the directions for the GPIO pins */ |
51 | outl(OUT_GPIOS | (IN_GPIOS << 16), gpio_base + GPIOx_OUT_EN); | 63 | gpio_direction_input(OLPC_GPIO_DCON_STAT0); |
52 | outl(IN_GPIOS | (OUT_GPIOS << 16), gpio_base + GPIOx_IN_EN); | 64 | gpio_direction_input(OLPC_GPIO_DCON_STAT1); |
65 | gpio_direction_input(OLPC_GPIO_DCON_IRQ); | ||
66 | gpio_direction_input(OLPC_GPIO_DCON_BLANK); | ||
67 | gpio_direction_output(OLPC_GPIO_DCON_LOAD, | ||
68 | dcon_source == DCON_SOURCE_CPU); | ||
53 | 69 | ||
54 | /* Set up the interrupt mappings */ | 70 | /* Set up the interrupt mappings */ |
55 | 71 | ||
56 | /* Set the IRQ to pair 2 */ | 72 | /* Set the IRQ to pair 2 */ |
57 | geode_gpio_event_irq(OLPC_GPIO_DCON_IRQ, 2); | 73 | cs5535_gpio_setup_event(OLPC_GPIO_DCON_IRQ, 2, 0); |
58 | 74 | ||
59 | /* Enable group 2 to trigger the DCON interrupt */ | 75 | /* Enable group 2 to trigger the DCON interrupt */ |
60 | geode_gpio_set_irq(2, DCON_IRQ); | 76 | cs5535_gpio_set_irq(2, DCON_IRQ); |
61 | 77 | ||
62 | /* Select edge level for interrupt (in PIC) */ | 78 | /* Select edge level for interrupt (in PIC) */ |
63 | lob = inb(0x4d0); | 79 | lob = inb(0x4d0); |
@@ -65,52 +81,61 @@ static int dcon_init_xo_1(void) | |||
65 | outb(lob, 0x4d0); | 81 | outb(lob, 0x4d0); |
66 | 82 | ||
67 | /* Register the interupt handler */ | 83 | /* Register the interupt handler */ |
68 | if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", &dcon_driver)) | 84 | if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", &dcon_driver)) { |
69 | return -EIO; | 85 | printk(KERN_ERR "olpc-dcon: failed to request DCON's irq\n"); |
86 | goto err_req_irq; | ||
87 | } | ||
70 | 88 | ||
71 | /* Clear INV_EN for GPIO7 (DCONIRQ) */ | 89 | /* Clear INV_EN for GPIO7 (DCONIRQ) */ |
72 | outl((1<<(16+7)), gpio_base + GPIOx_INV_EN); | 90 | cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_INVERT); |
73 | 91 | ||
74 | /* Enable filter for GPIO12 (DCONBLANK) */ | 92 | /* Enable filter for GPIO12 (DCONBLANK) */ |
75 | outl(1<<(12), gpio_base + GPIOx_IN_FLTR_EN); | 93 | cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_INPUT_FILTER); |
76 | 94 | ||
77 | /* Disable filter for GPIO7 */ | 95 | /* Disable filter for GPIO7 */ |
78 | outl(1<<(16+7), gpio_base + GPIOx_IN_FLTR_EN); | 96 | cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_FILTER); |
79 | 97 | ||
80 | /* Disable event counter for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */ | 98 | /* Disable event counter for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */ |
81 | 99 | cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_EVENT_COUNT); | |
82 | outl(1<<(16+7), gpio_base + GPIOx_EVNTCNT_EN); | 100 | cs5535_gpio_clear(OLPC_GPIO_DCON_BLANK, GPIO_INPUT_EVENT_COUNT); |
83 | outl(1<<(16+12), gpio_base + GPIOx_EVNTCNT_EN); | ||
84 | 101 | ||
85 | /* Add GPIO12 to the Filter Event Pair #7 */ | 102 | /* Add GPIO12 to the Filter Event Pair #7 */ |
86 | outb(12, gpio_base + GPIO_FE7_SEL); | 103 | cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_FE7_SEL); |
87 | 104 | ||
88 | /* Turn off negative Edge Enable for GPIO12 */ | 105 | /* Turn off negative Edge Enable for GPIO12 */ |
89 | outl(1<<(16+12), gpio_base + GPIOx_NEGEDGE_EN); | 106 | cs5535_gpio_clear(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_EN); |
90 | 107 | ||
91 | /* Enable negative Edge Enable for GPIO7 */ | 108 | /* Enable negative Edge Enable for GPIO7 */ |
92 | outl(1<<7, gpio_base + GPIOx_NEGEDGE_EN); | 109 | cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_EN); |
93 | 110 | ||
94 | /* Zero the filter amount for Filter Event Pair #7 */ | 111 | /* Zero the filter amount for Filter Event Pair #7 */ |
95 | outw(0, gpio_base + GPIO_FLT7_AMNT); | 112 | cs5535_gpio_set(0, GPIO_FLTR7_AMOUNT); |
96 | 113 | ||
97 | /* Clear the negative edge status for GPIO7 and GPIO12 */ | 114 | /* Clear the negative edge status for GPIO7 and GPIO12 */ |
98 | outl((1<<7) | (1<<12), gpio_base+0x4c); | 115 | cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS); |
116 | cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_STS); | ||
99 | 117 | ||
100 | /* FIXME: Clear the posiitive status as well, just to be sure */ | 118 | /* FIXME: Clear the posiitive status as well, just to be sure */ |
101 | outl((1<<7) | (1<<12), gpio_base+0x48); | 119 | cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_POSITIVE_EDGE_STS); |
120 | cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_POSITIVE_EDGE_STS); | ||
102 | 121 | ||
103 | /* Enable events for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */ | 122 | /* Enable events for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */ |
104 | outl((1<<(7))|(1<<12), gpio_base + GPIOx_EVNT_EN); | 123 | cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_EVENTS_ENABLE); |
105 | 124 | cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_EVENTS_ENABLE); | |
106 | /* Determine the current state by reading the GPIO bit */ | ||
107 | /* Earlier stages of the boot process have established the state */ | ||
108 | dcon_source = inl(gpio_base + GPIOx_OUT_VAL) & (1<<11) | ||
109 | ? DCON_SOURCE_CPU | ||
110 | : DCON_SOURCE_DCON; | ||
111 | dcon_pending = dcon_source; | ||
112 | 125 | ||
113 | return 0; | 126 | return 0; |
127 | |||
128 | err_req_irq: | ||
129 | gpio_free(OLPC_GPIO_DCON_BLANK); | ||
130 | err_gp_blank: | ||
131 | gpio_free(OLPC_GPIO_DCON_LOAD); | ||
132 | err_gp_load: | ||
133 | gpio_free(OLPC_GPIO_DCON_IRQ); | ||
134 | err_gp_irq: | ||
135 | gpio_free(OLPC_GPIO_DCON_STAT1); | ||
136 | err_gp_stat1: | ||
137 | gpio_free(OLPC_GPIO_DCON_STAT0); | ||
138 | return -EIO; | ||
114 | } | 139 | } |
115 | 140 | ||
116 | static void dcon_wiggle_xo_1(void) | 141 | static void dcon_wiggle_xo_1(void) |
@@ -128,37 +153,44 @@ static void dcon_wiggle_xo_1(void) | |||
128 | * simultaneously set AUX1 IN/OUT to GPIO14; ditto for SMB_DATA and | 153 | * simultaneously set AUX1 IN/OUT to GPIO14; ditto for SMB_DATA and |
129 | * GPIO15. | 154 | * GPIO15. |
130 | */ | 155 | */ |
131 | geode_gpio_set(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_VAL); | 156 | cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); |
132 | geode_gpio_set(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_ENABLE); | 157 | cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_VAL); |
133 | geode_gpio_clear(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1); | 158 | cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_ENABLE); |
134 | geode_gpio_clear(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX2); | 159 | cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_ENABLE); |
135 | geode_gpio_clear(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1); | 160 | cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX1); |
161 | cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1); | ||
162 | cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX2); | ||
163 | cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX2); | ||
164 | cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_INPUT_AUX1); | ||
165 | cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1); | ||
136 | 166 | ||
137 | for (x = 0; x < 16; x++) { | 167 | for (x = 0; x < 16; x++) { |
138 | udelay(5); | 168 | udelay(5); |
139 | geode_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); | 169 | cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); |
140 | udelay(5); | 170 | udelay(5); |
141 | geode_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); | 171 | cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); |
142 | } | 172 | } |
143 | udelay(5); | 173 | udelay(5); |
144 | geode_gpio_set(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1); | 174 | cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX1); |
145 | geode_gpio_set(OLPC_GPIO_SMB_CLK|OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1); | 175 | cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1); |
176 | cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_INPUT_AUX1); | ||
177 | cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1); | ||
146 | } | 178 | } |
147 | 179 | ||
148 | static void dcon_set_dconload_1(int val) | 180 | static void dcon_set_dconload_1(int val) |
149 | { | 181 | { |
150 | if (val) | 182 | gpio_set_value(OLPC_GPIO_DCON_LOAD, val); |
151 | outl(1<<11, gpio_base + GPIOx_OUT_VAL); | ||
152 | else | ||
153 | outl(1<<(11 + 16), gpio_base + GPIOx_OUT_VAL); | ||
154 | } | 183 | } |
155 | 184 | ||
156 | static int dcon_read_status_xo_1(void) | 185 | static u8 dcon_read_status_xo_1(void) |
157 | { | 186 | { |
158 | int status = inl(gpio_base + GPIOx_READ_BACK) >> 5; | 187 | u8 status; |
159 | 188 | ||
189 | status = gpio_get_value(OLPC_GPIO_DCON_STAT0); | ||
190 | status |= gpio_get_value(OLPC_GPIO_DCON_STAT1) << 1; | ||
191 | |||
160 | /* Clear the negative edge status for GPIO7 */ | 192 | /* Clear the negative edge status for GPIO7 */ |
161 | outl(1 << 7, gpio_base + GPIOx_NEGEDGE_STS); | 193 | cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS); |
162 | 194 | ||
163 | return status; | 195 | return status; |
164 | } | 196 | } |
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c index cca6a235ef9..4f56098bb36 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c | |||
@@ -195,9 +195,9 @@ static void dcon_set_dconload_xo_1_5(int val) | |||
195 | } | 195 | } |
196 | } | 196 | } |
197 | 197 | ||
198 | static int dcon_read_status_xo_1_5(void) | 198 | static u8 dcon_read_status_xo_1_5(void) |
199 | { | 199 | { |
200 | int status; | 200 | u8 status; |
201 | 201 | ||
202 | if (!dcon_was_irq()) | 202 | if (!dcon_was_irq()) |
203 | return -1; | 203 | return -1; |
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index ac2bf11e111..701e8d52a9f 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c | |||
@@ -269,7 +269,7 @@ static int update_status(struct backlight_device *bd) | |||
269 | return 0; | 269 | return 0; |
270 | } | 270 | } |
271 | 271 | ||
272 | static struct backlight_ops backlight_ops = { | 272 | static const struct backlight_ops backlight_ops = { |
273 | .get_brightness = get_brightness, | 273 | .get_brightness = get_brightness, |
274 | .update_status = update_status, | 274 | .update_status = update_status, |
275 | }; | 275 | }; |
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 0d236f4bb8c..b00101972f2 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
@@ -284,12 +284,11 @@ static int samplerate = 100; | |||
284 | 284 | ||
285 | module_param(ixjdebug, int, 0); | 285 | module_param(ixjdebug, int, 0); |
286 | 286 | ||
287 | static struct pci_device_id ixj_pci_tbl[] __devinitdata = { | 287 | static DEFINE_PCI_DEVICE_TABLE(ixj_pci_tbl) = { |
288 | { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ, | 288 | { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ, |
289 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 289 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
290 | { } | 290 | { } |
291 | }; | 291 | }; |
292 | |||
293 | MODULE_DEVICE_TABLE(pci, ixj_pci_tbl); | 292 | MODULE_DEVICE_TABLE(pci, ixj_pci_tbl); |
294 | 293 | ||
295 | /************************************************************************ | 294 | /************************************************************************ |
@@ -6581,7 +6580,8 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar | |||
6581 | case IXJCTL_SET_FILTER: | 6580 | case IXJCTL_SET_FILTER: |
6582 | if (copy_from_user(&jf, argp, sizeof(jf))) | 6581 | if (copy_from_user(&jf, argp, sizeof(jf))) |
6583 | retval = -EFAULT; | 6582 | retval = -EFAULT; |
6584 | retval = ixj_init_filter(j, &jf); | 6583 | else |
6584 | retval = ixj_init_filter(j, &jf); | ||
6585 | break; | 6585 | break; |
6586 | case IXJCTL_SET_FILTER_RAW: | 6586 | case IXJCTL_SET_FILTER_RAW: |
6587 | if (copy_from_user(&jfr, argp, sizeof(jfr))) | 6587 | if (copy_from_user(&jfr, argp, sizeof(jfr))) |
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 1210534822d..5408186afc3 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
@@ -1320,7 +1320,7 @@ static struct imx_udc_struct controller = { | |||
1320 | }; | 1320 | }; |
1321 | 1321 | ||
1322 | /******************************************************************************* | 1322 | /******************************************************************************* |
1323 | * USB gadged driver functions | 1323 | * USB gadget driver functions |
1324 | ******************************************************************************* | 1324 | ******************************************************************************* |
1325 | */ | 1325 | */ |
1326 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | 1326 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, |
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 777972454e3..1eca8b47ce3 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -3086,7 +3086,7 @@ static void langwell_udc_remove(struct pci_dev *pdev) | |||
3086 | 3086 | ||
3087 | kfree(dev->ep); | 3087 | kfree(dev->ep); |
3088 | 3088 | ||
3089 | /* diable IRQ handler */ | 3089 | /* disable IRQ handler */ |
3090 | if (dev->got_irq) | 3090 | if (dev->got_irq) |
3091 | free_irq(pdev->irq, dev); | 3091 | free_irq(pdev->irq, dev); |
3092 | 3092 | ||
@@ -3406,7 +3406,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3406 | /* disable interrupt and set controller to stop state */ | 3406 | /* disable interrupt and set controller to stop state */ |
3407 | langwell_udc_stop(dev); | 3407 | langwell_udc_stop(dev); |
3408 | 3408 | ||
3409 | /* diable IRQ handler */ | 3409 | /* disable IRQ handler */ |
3410 | if (dev->got_irq) | 3410 | if (dev->got_irq) |
3411 | free_irq(pdev->irq, dev); | 3411 | free_irq(pdev->irq, dev); |
3412 | dev->got_irq = 0; | 3412 | dev->got_irq = 0; |
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 20092a27a1e..12fd184226f 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c | |||
@@ -98,13 +98,13 @@ void fhci_usb_enable_interrupt(struct fhci_usb *usb) | |||
98 | usb->intr_nesting_cnt--; | 98 | usb->intr_nesting_cnt--; |
99 | } | 99 | } |
100 | 100 | ||
101 | /* diable the usb interrupt */ | 101 | /* disable the usb interrupt */ |
102 | void fhci_usb_disable_interrupt(struct fhci_usb *usb) | 102 | void fhci_usb_disable_interrupt(struct fhci_usb *usb) |
103 | { | 103 | { |
104 | struct fhci_hcd *fhci = usb->fhci; | 104 | struct fhci_hcd *fhci = usb->fhci; |
105 | 105 | ||
106 | if (usb->intr_nesting_cnt == 0) { | 106 | if (usb->intr_nesting_cnt == 0) { |
107 | /* diable the timer interrupt */ | 107 | /* disable the timer interrupt */ |
108 | disable_irq_nosync(fhci->timer->irq); | 108 | disable_irq_nosync(fhci->timer->irq); |
109 | 109 | ||
110 | /* disable the usb interrupt */ | 110 | /* disable the usb interrupt */ |
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index 7be548ca218..38fe058fbe6 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c | |||
@@ -271,8 +271,8 @@ void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep, | |||
271 | 271 | ||
272 | /* | 272 | /* |
273 | * Collect the submitted frames and inform the application about them | 273 | * Collect the submitted frames and inform the application about them |
274 | * It is also prepearing the TDs for new frames. If the Tx interrupts | 274 | * It is also preparing the TDs for new frames. If the Tx interrupts |
275 | * are diabled, the application should call that routine to get | 275 | * are disabled, the application should call that routine to get |
276 | * confirmation about the submitted frames. Otherwise, the routine is | 276 | * confirmation about the submitted frames. Otherwise, the routine is |
277 | * called frome the interrupt service routine during the Tx interrupt. | 277 | * called frome the interrupt service routine during the Tx interrupt. |
278 | * In that case the application is informed by calling the application | 278 | * In that case the application is informed by calling the application |
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index e49b75a7800..f90d003f230 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c | |||
@@ -1658,7 +1658,7 @@ static int imx21_hc_reset(struct usb_hcd *hcd) | |||
1658 | 1658 | ||
1659 | spin_lock_irqsave(&imx21->lock, flags); | 1659 | spin_lock_irqsave(&imx21->lock, flags); |
1660 | 1660 | ||
1661 | /* Reset the Host controler modules */ | 1661 | /* Reset the Host controller modules */ |
1662 | writel(USBOTG_RST_RSTCTRL | USBOTG_RST_RSTRH | | 1662 | writel(USBOTG_RST_RSTCTRL | USBOTG_RST_RSTRH | |
1663 | USBOTG_RST_RSTHSIE | USBOTG_RST_RSTHC, | 1663 | USBOTG_RST_RSTHSIE | USBOTG_RST_RSTHC, |
1664 | imx21->regs + USBOTG_RST_CTRL); | 1664 | imx21->regs + USBOTG_RST_CTRL); |
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 32149be4ad8..e0cb12b573f 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c | |||
@@ -3094,7 +3094,7 @@ static int oxu_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
3094 | 3094 | ||
3095 | /* Some boards (mostly VIA?) report bogus overcurrent indications, | 3095 | /* Some boards (mostly VIA?) report bogus overcurrent indications, |
3096 | * causing massive log spam unless we completely ignore them. It | 3096 | * causing massive log spam unless we completely ignore them. It |
3097 | * may be relevant that VIA VT8235 controlers, where PORT_POWER is | 3097 | * may be relevant that VIA VT8235 controllers, where PORT_POWER is |
3098 | * always set, seem to clear PORT_OCC and PORT_CSC when writing to | 3098 | * always set, seem to clear PORT_OCC and PORT_CSC when writing to |
3099 | * PORT_POWER; that's surprising, but maybe within-spec. | 3099 | * PORT_POWER; that's surprising, but maybe within-spec. |
3100 | */ | 3100 | */ |
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 44f8b922505..a6afd15f6a4 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -717,7 +717,7 @@ static int adu_probe(struct usb_interface *interface, | |||
717 | goto exit; | 717 | goto exit; |
718 | } | 718 | } |
719 | 719 | ||
720 | /* allocate memory for our device state and intialize it */ | 720 | /* allocate memory for our device state and initialize it */ |
721 | dev = kzalloc(sizeof(struct adu_device), GFP_KERNEL); | 721 | dev = kzalloc(sizeof(struct adu_device), GFP_KERNEL); |
722 | if (dev == NULL) { | 722 | if (dev == NULL) { |
723 | dev_err(&interface->dev, "Out of memory\n"); | 723 | dev_err(&interface->dev, "Out of memory\n"); |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index c9078e4e1f4..e573e470401 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -769,7 +769,7 @@ static int iowarrior_probe(struct usb_interface *interface, | |||
769 | int i; | 769 | int i; |
770 | int retval = -ENOMEM; | 770 | int retval = -ENOMEM; |
771 | 771 | ||
772 | /* allocate memory for our device state and intialize it */ | 772 | /* allocate memory for our device state and initialize it */ |
773 | dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); | 773 | dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); |
774 | if (dev == NULL) { | 774 | if (dev == NULL) { |
775 | dev_err(&interface->dev, "Out of memory\n"); | 775 | dev_err(&interface->dev, "Out of memory\n"); |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index edffef64233..eefb8275bb7 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -642,7 +642,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * | |||
642 | int i; | 642 | int i; |
643 | int retval = -ENOMEM; | 643 | int retval = -ENOMEM; |
644 | 644 | ||
645 | /* allocate memory for our device state and intialize it */ | 645 | /* allocate memory for our device state and initialize it */ |
646 | 646 | ||
647 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 647 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
648 | if (dev == NULL) { | 648 | if (dev == NULL) { |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 9b162dfaa4f..ed58c6c8f15 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1684,7 +1684,7 @@ static inline void __init musb_g_init_endpoints(struct musb *musb) | |||
1684 | struct musb_hw_ep *hw_ep; | 1684 | struct musb_hw_ep *hw_ep; |
1685 | unsigned count = 0; | 1685 | unsigned count = 0; |
1686 | 1686 | ||
1687 | /* intialize endpoint list just once */ | 1687 | /* initialize endpoint list just once */ |
1688 | INIT_LIST_HEAD(&(musb->g.ep_list)); | 1688 | INIT_LIST_HEAD(&(musb->g.ep_list)); |
1689 | 1689 | ||
1690 | for (epnum = 0, hw_ep = musb->endpoints; | 1690 | for (epnum = 0, hw_ep = musb->endpoints; |
@@ -1765,7 +1765,7 @@ void musb_gadget_cleanup(struct musb *musb) | |||
1765 | * | 1765 | * |
1766 | * -EINVAL something went wrong (not driver) | 1766 | * -EINVAL something went wrong (not driver) |
1767 | * -EBUSY another gadget is already using the controller | 1767 | * -EBUSY another gadget is already using the controller |
1768 | * -ENOMEM no memeory to perform the operation | 1768 | * -ENOMEM no memory to perform the operation |
1769 | * | 1769 | * |
1770 | * @param driver the gadget driver | 1770 | * @param driver the gadget driver |
1771 | * @param bind the driver's bind function | 1771 | * @param bind the driver's bind function |
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index c7b1d8108de..8cb9d80207f 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c | |||
@@ -49,7 +49,7 @@ | |||
49 | * | 49 | * |
50 | * USB Stack port number 4 (1 based) | 50 | * USB Stack port number 4 (1 based) |
51 | * WUSB code port index 3 (0 based) | 51 | * WUSB code port index 3 (0 based) |
52 | * USB Addresss 5 (2 based -- 0 is for default, 1 for root hub) | 52 | * USB Address 5 (2 based -- 0 is for default, 1 for root hub) |
53 | * | 53 | * |
54 | * Now, because we don't use the concept as default address exactly | 54 | * Now, because we don't use the concept as default address exactly |
55 | * like the (wired) USB code does, we need to kind of skip it. So we | 55 | * like the (wired) USB code does, we need to kind of skip it. So we |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 8dce2512633..bac16345021 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -111,7 +111,7 @@ static int atmel_bl_get_brightness(struct backlight_device *bl) | |||
111 | return lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); | 111 | return lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); |
112 | } | 112 | } |
113 | 113 | ||
114 | static struct backlight_ops atmel_lcdc_bl_ops = { | 114 | static const struct backlight_ops atmel_lcdc_bl_ops = { |
115 | .update_status = atmel_bl_update_status, | 115 | .update_status = atmel_bl_update_status, |
116 | .get_brightness = atmel_bl_get_brightness, | 116 | .get_brightness = atmel_bl_get_brightness, |
117 | }; | 117 | }; |
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 34a0851bcbf..dd9de2e8058 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -1786,7 +1786,7 @@ static int aty128_bl_get_brightness(struct backlight_device *bd) | |||
1786 | return bd->props.brightness; | 1786 | return bd->props.brightness; |
1787 | } | 1787 | } |
1788 | 1788 | ||
1789 | static struct backlight_ops aty128_bl_data = { | 1789 | static const struct backlight_ops aty128_bl_data = { |
1790 | .get_brightness = aty128_bl_get_brightness, | 1790 | .get_brightness = aty128_bl_get_brightness, |
1791 | .update_status = aty128_bl_update_status, | 1791 | .update_status = aty128_bl_update_status, |
1792 | }; | 1792 | }; |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 5a3ce3ad1ec..767ab4fb1a0 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -2221,7 +2221,7 @@ static int aty_bl_get_brightness(struct backlight_device *bd) | |||
2221 | return bd->props.brightness; | 2221 | return bd->props.brightness; |
2222 | } | 2222 | } |
2223 | 2223 | ||
2224 | static struct backlight_ops aty_bl_data = { | 2224 | static const struct backlight_ops aty_bl_data = { |
2225 | .get_brightness = aty_bl_get_brightness, | 2225 | .get_brightness = aty_bl_get_brightness, |
2226 | .update_status = aty_bl_update_status, | 2226 | .update_status = aty_bl_update_status, |
2227 | }; | 2227 | }; |
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 256966e9667..9b811ddbce8 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c | |||
@@ -128,7 +128,7 @@ static int radeon_bl_get_brightness(struct backlight_device *bd) | |||
128 | return bd->props.brightness; | 128 | return bd->props.brightness; |
129 | } | 129 | } |
130 | 130 | ||
131 | static struct backlight_ops radeon_bl_data = { | 131 | static const struct backlight_ops radeon_bl_data = { |
132 | .get_brightness = radeon_bl_get_brightness, | 132 | .get_brightness = radeon_bl_get_brightness, |
133 | .update_status = radeon_bl_update_status, | 133 | .update_status = radeon_bl_update_status, |
134 | }; | 134 | }; |
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index 38ffc3fbcbe..c789c46e38a 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c | |||
@@ -155,7 +155,7 @@ out: | |||
155 | return -EINVAL; | 155 | return -EINVAL; |
156 | } | 156 | } |
157 | 157 | ||
158 | static struct backlight_ops pm860x_backlight_ops = { | 158 | static const struct backlight_ops pm860x_backlight_ops = { |
159 | .options = BL_CORE_SUSPENDRESUME, | 159 | .options = BL_CORE_SUSPENDRESUME, |
160 | .update_status = pm860x_backlight_update_status, | 160 | .update_status = pm860x_backlight_update_status, |
161 | .get_brightness = pm860x_backlight_get_brightness, | 161 | .get_brightness = pm860x_backlight_get_brightness, |
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index c67801e57aa..98ad3e5f7c8 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c | |||
@@ -25,7 +25,7 @@ | |||
25 | struct l4f00242t03_priv { | 25 | struct l4f00242t03_priv { |
26 | struct spi_device *spi; | 26 | struct spi_device *spi; |
27 | struct lcd_device *ld; | 27 | struct lcd_device *ld; |
28 | int lcd_on:1; | 28 | int lcd_state; |
29 | struct regulator *io_reg; | 29 | struct regulator *io_reg; |
30 | struct regulator *core_reg; | 30 | struct regulator *core_reg; |
31 | }; | 31 | }; |
@@ -62,11 +62,36 @@ static void l4f00242t03_lcd_init(struct spi_device *spi) | |||
62 | regulator_enable(priv->core_reg); | 62 | regulator_enable(priv->core_reg); |
63 | } | 63 | } |
64 | 64 | ||
65 | l4f00242t03_reset(pdata->reset_gpio); | ||
66 | |||
65 | gpio_set_value(pdata->data_enable_gpio, 1); | 67 | gpio_set_value(pdata->data_enable_gpio, 1); |
66 | msleep(60); | 68 | msleep(60); |
67 | spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16)); | 69 | spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16)); |
68 | } | 70 | } |
69 | 71 | ||
72 | static void l4f00242t03_lcd_powerdown(struct spi_device *spi) | ||
73 | { | ||
74 | struct l4f00242t03_pdata *pdata = spi->dev.platform_data; | ||
75 | struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); | ||
76 | |||
77 | dev_dbg(&spi->dev, "Powering down LCD\n"); | ||
78 | |||
79 | gpio_set_value(pdata->data_enable_gpio, 0); | ||
80 | |||
81 | if (priv->io_reg) | ||
82 | regulator_disable(priv->io_reg); | ||
83 | |||
84 | if (priv->core_reg) | ||
85 | regulator_disable(priv->core_reg); | ||
86 | } | ||
87 | |||
88 | static int l4f00242t03_lcd_power_get(struct lcd_device *ld) | ||
89 | { | ||
90 | struct l4f00242t03_priv *priv = lcd_get_data(ld); | ||
91 | |||
92 | return priv->lcd_state; | ||
93 | } | ||
94 | |||
70 | static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) | 95 | static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) |
71 | { | 96 | { |
72 | struct l4f00242t03_priv *priv = lcd_get_data(ld); | 97 | struct l4f00242t03_priv *priv = lcd_get_data(ld); |
@@ -79,35 +104,54 @@ static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) | |||
79 | const u16 disoff = 0x28; | 104 | const u16 disoff = 0x28; |
80 | 105 | ||
81 | if (power <= FB_BLANK_NORMAL) { | 106 | if (power <= FB_BLANK_NORMAL) { |
82 | if (priv->lcd_on) | 107 | if (priv->lcd_state <= FB_BLANK_NORMAL) { |
83 | return 0; | 108 | /* Do nothing, the LCD is running */ |
84 | 109 | } else if (priv->lcd_state < FB_BLANK_POWERDOWN) { | |
85 | dev_dbg(&spi->dev, "turning on LCD\n"); | 110 | dev_dbg(&spi->dev, "Resuming LCD\n"); |
86 | 111 | ||
87 | spi_write(spi, (const u8 *)&slpout, sizeof(u16)); | 112 | spi_write(spi, (const u8 *)&slpout, sizeof(u16)); |
88 | msleep(60); | 113 | msleep(60); |
89 | spi_write(spi, (const u8 *)&dison, sizeof(u16)); | 114 | spi_write(spi, (const u8 *)&dison, sizeof(u16)); |
90 | 115 | } else { | |
91 | priv->lcd_on = 1; | 116 | /* priv->lcd_state == FB_BLANK_POWERDOWN */ |
117 | l4f00242t03_lcd_init(spi); | ||
118 | priv->lcd_state = FB_BLANK_VSYNC_SUSPEND; | ||
119 | l4f00242t03_lcd_power_set(priv->ld, power); | ||
120 | } | ||
121 | } else if (power < FB_BLANK_POWERDOWN) { | ||
122 | if (priv->lcd_state <= FB_BLANK_NORMAL) { | ||
123 | /* Send the display in standby */ | ||
124 | dev_dbg(&spi->dev, "Standby the LCD\n"); | ||
125 | |||
126 | spi_write(spi, (const u8 *)&disoff, sizeof(u16)); | ||
127 | msleep(60); | ||
128 | spi_write(spi, (const u8 *)&slpin, sizeof(u16)); | ||
129 | } else if (priv->lcd_state < FB_BLANK_POWERDOWN) { | ||
130 | /* Do nothing, the LCD is already in standby */ | ||
131 | } else { | ||
132 | /* priv->lcd_state == FB_BLANK_POWERDOWN */ | ||
133 | l4f00242t03_lcd_init(spi); | ||
134 | priv->lcd_state = FB_BLANK_UNBLANK; | ||
135 | l4f00242t03_lcd_power_set(ld, power); | ||
136 | } | ||
92 | } else { | 137 | } else { |
93 | if (!priv->lcd_on) | 138 | /* power == FB_BLANK_POWERDOWN */ |
94 | return 0; | 139 | if (priv->lcd_state != FB_BLANK_POWERDOWN) { |
95 | 140 | /* Clear the screen before shutting down */ | |
96 | dev_dbg(&spi->dev, "turning off LCD\n"); | 141 | spi_write(spi, (const u8 *)&disoff, sizeof(u16)); |
97 | 142 | msleep(60); | |
98 | spi_write(spi, (const u8 *)&disoff, sizeof(u16)); | 143 | l4f00242t03_lcd_powerdown(spi); |
99 | msleep(60); | 144 | } |
100 | spi_write(spi, (const u8 *)&slpin, sizeof(u16)); | ||
101 | |||
102 | priv->lcd_on = 0; | ||
103 | } | 145 | } |
104 | 146 | ||
147 | priv->lcd_state = power; | ||
148 | |||
105 | return 0; | 149 | return 0; |
106 | } | 150 | } |
107 | 151 | ||
108 | static struct lcd_ops l4f_ops = { | 152 | static struct lcd_ops l4f_ops = { |
109 | .set_power = l4f00242t03_lcd_power_set, | 153 | .set_power = l4f00242t03_lcd_power_set, |
110 | .get_power = NULL, | 154 | .get_power = l4f00242t03_lcd_power_get, |
111 | }; | 155 | }; |
112 | 156 | ||
113 | static int __devinit l4f00242t03_probe(struct spi_device *spi) | 157 | static int __devinit l4f00242t03_probe(struct spi_device *spi) |
@@ -185,9 +229,9 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) | |||
185 | } | 229 | } |
186 | 230 | ||
187 | /* Init the LCD */ | 231 | /* Init the LCD */ |
188 | l4f00242t03_reset(pdata->reset_gpio); | ||
189 | l4f00242t03_lcd_init(spi); | 232 | l4f00242t03_lcd_init(spi); |
190 | l4f00242t03_lcd_power_set(priv->ld, 1); | 233 | priv->lcd_state = FB_BLANK_VSYNC_SUSPEND; |
234 | l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_UNBLANK); | ||
191 | 235 | ||
192 | dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n"); | 236 | dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n"); |
193 | 237 | ||
@@ -214,9 +258,11 @@ static int __devexit l4f00242t03_remove(struct spi_device *spi) | |||
214 | struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); | 258 | struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); |
215 | struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data; | 259 | struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data; |
216 | 260 | ||
217 | l4f00242t03_lcd_power_set(priv->ld, 0); | 261 | l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); |
218 | lcd_device_unregister(priv->ld); | 262 | lcd_device_unregister(priv->ld); |
219 | 263 | ||
264 | dev_set_drvdata(&spi->dev, NULL); | ||
265 | |||
220 | gpio_free(pdata->data_enable_gpio); | 266 | gpio_free(pdata->data_enable_gpio); |
221 | gpio_free(pdata->reset_gpio); | 267 | gpio_free(pdata->reset_gpio); |
222 | 268 | ||
@@ -230,6 +276,15 @@ static int __devexit l4f00242t03_remove(struct spi_device *spi) | |||
230 | return 0; | 276 | return 0; |
231 | } | 277 | } |
232 | 278 | ||
279 | static void l4f00242t03_shutdown(struct spi_device *spi) | ||
280 | { | ||
281 | struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); | ||
282 | |||
283 | if (priv) | ||
284 | l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); | ||
285 | |||
286 | } | ||
287 | |||
233 | static struct spi_driver l4f00242t03_driver = { | 288 | static struct spi_driver l4f00242t03_driver = { |
234 | .driver = { | 289 | .driver = { |
235 | .name = "l4f00242t03", | 290 | .name = "l4f00242t03", |
@@ -237,6 +292,7 @@ static struct spi_driver l4f00242t03_driver = { | |||
237 | }, | 292 | }, |
238 | .probe = l4f00242t03_probe, | 293 | .probe = l4f00242t03_probe, |
239 | .remove = __devexit_p(l4f00242t03_remove), | 294 | .remove = __devexit_p(l4f00242t03_remove), |
295 | .shutdown = l4f00242t03_shutdown, | ||
240 | }; | 296 | }; |
241 | 297 | ||
242 | static __init int l4f00242t03_init(void) | 298 | static __init int l4f00242t03_init(void) |
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index b2b2c7ba1f6..209acc105cb 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c | |||
@@ -92,7 +92,7 @@ static int max8925_backlight_get_brightness(struct backlight_device *bl) | |||
92 | return ret; | 92 | return ret; |
93 | } | 93 | } |
94 | 94 | ||
95 | static struct backlight_ops max8925_backlight_ops = { | 95 | static const struct backlight_ops max8925_backlight_ops = { |
96 | .options = BL_CORE_SUSPENDRESUME, | 96 | .options = BL_CORE_SUSPENDRESUME, |
97 | .update_status = max8925_backlight_update_status, | 97 | .update_status = max8925_backlight_update_status, |
98 | .get_brightness = max8925_backlight_get_brightness, | 98 | .get_brightness = max8925_backlight_get_brightness, |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 915448ec75b..c97491b8b39 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -375,7 +375,8 @@ static const char *vgacon_startup(void) | |||
375 | u16 saved1, saved2; | 375 | u16 saved1, saved2; |
376 | volatile u16 *p; | 376 | volatile u16 *p; |
377 | 377 | ||
378 | if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB) { | 378 | if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB || |
379 | screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) { | ||
379 | no_vga: | 380 | no_vga: |
380 | #ifdef CONFIG_DUMMY_CONSOLE | 381 | #ifdef CONFIG_DUMMY_CONSOLE |
381 | conswitchp = &dummy_con; | 382 | conswitchp = &dummy_con; |
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index 2fb552a6f32..6aac6d1b937 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c | |||
@@ -87,7 +87,7 @@ static int nvidia_bl_get_brightness(struct backlight_device *bd) | |||
87 | return bd->props.brightness; | 87 | return bd->props.brightness; |
88 | } | 88 | } |
89 | 89 | ||
90 | static struct backlight_ops nvidia_bl_ops = { | 90 | static const struct backlight_ops nvidia_bl_ops = { |
91 | .get_brightness = nvidia_bl_get_brightness, | 91 | .get_brightness = nvidia_bl_get_brightness, |
92 | .update_status = nvidia_bl_update_status, | 92 | .update_status = nvidia_bl_update_status, |
93 | }; | 93 | }; |
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index e1c765d1141..61026f96ad2 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c | |||
@@ -465,7 +465,7 @@ static int taal_bl_get_intensity(struct backlight_device *dev) | |||
465 | return 0; | 465 | return 0; |
466 | } | 466 | } |
467 | 467 | ||
468 | static struct backlight_ops taal_bl_ops = { | 468 | static const struct backlight_ops taal_bl_ops = { |
469 | .get_brightness = taal_bl_get_intensity, | 469 | .get_brightness = taal_bl_get_intensity, |
470 | .update_status = taal_bl_update_status, | 470 | .update_status = taal_bl_update_status, |
471 | }; | 471 | }; |
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 618f36bec10..da388186d61 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -331,7 +331,7 @@ static int riva_bl_get_brightness(struct backlight_device *bd) | |||
331 | return bd->props.brightness; | 331 | return bd->props.brightness; |
332 | } | 332 | } |
333 | 333 | ||
334 | static struct backlight_ops riva_bl_ops = { | 334 | static const struct backlight_ops riva_bl_ops = { |
335 | .get_brightness = riva_bl_get_brightness, | 335 | .get_brightness = riva_bl_get_brightness, |
336 | .update_status = riva_bl_update_status, | 336 | .update_status = riva_bl_update_status, |
337 | }; | 337 | }; |
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index dee64c3b1e6..2ab704118c4 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c | |||
@@ -536,7 +536,7 @@ static int sstfb_set_par(struct fb_info *info) | |||
536 | fbiinit2 = sst_read(FBIINIT2); | 536 | fbiinit2 = sst_read(FBIINIT2); |
537 | fbiinit3 = sst_read(FBIINIT3); | 537 | fbiinit3 = sst_read(FBIINIT3); |
538 | 538 | ||
539 | /* everything is reset. we enable fbiinit2/3 remap : dac acces ok */ | 539 | /* everything is reset. we enable fbiinit2/3 remap : dac access ok */ |
540 | pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, | 540 | pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, |
541 | PCI_EN_INIT_WR | PCI_REMAP_DAC ); | 541 | PCI_EN_INIT_WR | PCI_REMAP_DAC ); |
542 | 542 | ||
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index 1f51366417b..f0c909625bd 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig | |||
@@ -16,6 +16,17 @@ config W1_SLAVE_SMEM | |||
16 | Say Y here if you want to connect 1-wire | 16 | Say Y here if you want to connect 1-wire |
17 | simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire. | 17 | simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire. |
18 | 18 | ||
19 | config W1_SLAVE_DS2423 | ||
20 | tristate "Counter 1-wire device (DS2423)" | ||
21 | select CRC16 | ||
22 | help | ||
23 | If you enable this you can read the counter values available | ||
24 | in the DS2423 chipset from the w1_slave file under the | ||
25 | sys file system. | ||
26 | |||
27 | Say Y here if you want to use a 1-wire | ||
28 | counter family device (DS2423). | ||
29 | |||
19 | config W1_SLAVE_DS2431 | 30 | config W1_SLAVE_DS2431 |
20 | tristate "1kb EEPROM family support (DS2431)" | 31 | tristate "1kb EEPROM family support (DS2431)" |
21 | help | 32 | help |
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index f1f51f19b12..3c76350a24f 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o | 5 | obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o |
6 | obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o | 6 | obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o |
7 | obj-$(CONFIG_W1_SLAVE_DS2423) += w1_ds2423.o | ||
7 | obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o | 8 | obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o |
8 | obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o | 9 | obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o |
9 | obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o | 10 | obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o |
diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c new file mode 100644 index 00000000000..7a7dbe5026f --- /dev/null +++ b/drivers/w1/slaves/w1_ds2423.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /* | ||
2 | * w1_ds2423.c | ||
3 | * | ||
4 | * Copyright (c) 2010 Mika Laitio <lamikr@pilppa.org> | ||
5 | * | ||
6 | * This driver will read and write the value of 4 counters to w1_slave file in | ||
7 | * sys filesystem. | ||
8 | * Inspired by the w1_therm and w1_ds2431 drivers. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the therms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/moduleparam.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/crc16.h> | ||
32 | |||
33 | #include "../w1.h" | ||
34 | #include "../w1_int.h" | ||
35 | #include "../w1_family.h" | ||
36 | |||
37 | #define CRC16_VALID 0xb001 | ||
38 | #define CRC16_INIT 0 | ||
39 | |||
40 | #define COUNTER_COUNT 4 | ||
41 | #define READ_BYTE_COUNT 42 | ||
42 | |||
43 | static ssize_t w1_counter_read(struct device *device, | ||
44 | struct device_attribute *attr, char *buf); | ||
45 | |||
46 | static struct device_attribute w1_counter_attr = | ||
47 | __ATTR(w1_slave, S_IRUGO, w1_counter_read, NULL); | ||
48 | |||
49 | static ssize_t w1_counter_read(struct device *device, | ||
50 | struct device_attribute *attr, char *out_buf) | ||
51 | { | ||
52 | struct w1_slave *sl = dev_to_w1_slave(device); | ||
53 | struct w1_master *dev = sl->master; | ||
54 | u8 rbuf[COUNTER_COUNT * READ_BYTE_COUNT]; | ||
55 | u8 wrbuf[3]; | ||
56 | int rom_addr; | ||
57 | int read_byte_count; | ||
58 | int result; | ||
59 | ssize_t c; | ||
60 | int ii; | ||
61 | int p; | ||
62 | int crc; | ||
63 | |||
64 | c = PAGE_SIZE; | ||
65 | rom_addr = (12 << 5) + 31; | ||
66 | wrbuf[0] = 0xA5; | ||
67 | wrbuf[1] = rom_addr & 0xFF; | ||
68 | wrbuf[2] = rom_addr >> 8; | ||
69 | mutex_lock(&dev->mutex); | ||
70 | if (!w1_reset_select_slave(sl)) { | ||
71 | w1_write_block(dev, wrbuf, 3); | ||
72 | read_byte_count = 0; | ||
73 | for (p = 0; p < 4; p++) { | ||
74 | /* | ||
75 | * 1 byte for first bytes in ram page read | ||
76 | * 4 bytes for counter | ||
77 | * 4 bytes for zero bits | ||
78 | * 2 bytes for crc | ||
79 | * 31 remaining bytes from the ram page | ||
80 | */ | ||
81 | read_byte_count += w1_read_block(dev, | ||
82 | rbuf + (p * READ_BYTE_COUNT), READ_BYTE_COUNT); | ||
83 | for (ii = 0; ii < READ_BYTE_COUNT; ++ii) | ||
84 | c -= snprintf(out_buf + PAGE_SIZE - c, | ||
85 | c, "%02x ", | ||
86 | rbuf[(p * READ_BYTE_COUNT) + ii]); | ||
87 | if (read_byte_count != (p + 1) * READ_BYTE_COUNT) { | ||
88 | dev_warn(device, | ||
89 | "w1_counter_read() returned %u bytes " | ||
90 | "instead of %d bytes wanted.\n", | ||
91 | read_byte_count, | ||
92 | READ_BYTE_COUNT); | ||
93 | c -= snprintf(out_buf + PAGE_SIZE - c, | ||
94 | c, "crc=NO\n"); | ||
95 | } else { | ||
96 | if (p == 0) { | ||
97 | crc = crc16(CRC16_INIT, wrbuf, 3); | ||
98 | crc = crc16(crc, rbuf, 11); | ||
99 | } else { | ||
100 | /* | ||
101 | * DS2423 calculates crc from all bytes | ||
102 | * read after the previous crc bytes. | ||
103 | */ | ||
104 | crc = crc16(CRC16_INIT, | ||
105 | (rbuf + 11) + | ||
106 | ((p - 1) * READ_BYTE_COUNT), | ||
107 | READ_BYTE_COUNT); | ||
108 | } | ||
109 | if (crc == CRC16_VALID) { | ||
110 | result = 0; | ||
111 | for (ii = 4; ii > 0; ii--) { | ||
112 | result <<= 8; | ||
113 | result |= rbuf[(p * | ||
114 | READ_BYTE_COUNT) + ii]; | ||
115 | } | ||
116 | c -= snprintf(out_buf + PAGE_SIZE - c, | ||
117 | c, "crc=YES c=%d\n", result); | ||
118 | } else { | ||
119 | c -= snprintf(out_buf + PAGE_SIZE - c, | ||
120 | c, "crc=NO\n"); | ||
121 | } | ||
122 | } | ||
123 | } | ||
124 | } else { | ||
125 | c -= snprintf(out_buf + PAGE_SIZE - c, c, "Connection error"); | ||
126 | } | ||
127 | mutex_unlock(&dev->mutex); | ||
128 | return PAGE_SIZE - c; | ||
129 | } | ||
130 | |||
131 | static int w1_f1d_add_slave(struct w1_slave *sl) | ||
132 | { | ||
133 | return device_create_file(&sl->dev, &w1_counter_attr); | ||
134 | } | ||
135 | |||
136 | static void w1_f1d_remove_slave(struct w1_slave *sl) | ||
137 | { | ||
138 | device_remove_file(&sl->dev, &w1_counter_attr); | ||
139 | } | ||
140 | |||
141 | static struct w1_family_ops w1_f1d_fops = { | ||
142 | .add_slave = w1_f1d_add_slave, | ||
143 | .remove_slave = w1_f1d_remove_slave, | ||
144 | }; | ||
145 | |||
146 | static struct w1_family w1_family_1d = { | ||
147 | .fid = W1_COUNTER_DS2423, | ||
148 | .fops = &w1_f1d_fops, | ||
149 | }; | ||
150 | |||
151 | static int __init w1_f1d_init(void) | ||
152 | { | ||
153 | return w1_register_family(&w1_family_1d); | ||
154 | } | ||
155 | |||
156 | static void __exit w1_f1d_exit(void) | ||
157 | { | ||
158 | w1_unregister_family(&w1_family_1d); | ||
159 | } | ||
160 | |||
161 | module_init(w1_f1d_init); | ||
162 | module_exit(w1_f1d_exit); | ||
163 | |||
164 | MODULE_LICENSE("GPL"); | ||
165 | MODULE_AUTHOR("Mika Laitio <lamikr@pilppa.org>"); | ||
166 | MODULE_DESCRIPTION("w1 family 1d driver for DS2423, 4 counters and 4kb ram"); | ||
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index 3ca1b9298f2..f3b636d7caf 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define W1_FAMILY_SMEM_01 0x01 | 30 | #define W1_FAMILY_SMEM_01 0x01 |
31 | #define W1_FAMILY_SMEM_81 0x81 | 31 | #define W1_FAMILY_SMEM_81 0x81 |
32 | #define W1_THERM_DS18S20 0x10 | 32 | #define W1_THERM_DS18S20 0x10 |
33 | #define W1_COUNTER_DS2423 0x1D | ||
33 | #define W1_THERM_DS1822 0x22 | 34 | #define W1_THERM_DS1822 0x22 |
34 | #define W1_EEPROM_DS2433 0x23 | 35 | #define W1_EEPROM_DS2433 0x23 |
35 | #define W1_THERM_DS18B20 0x28 | 36 | #define W1_THERM_DS18B20 0x28 |
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 6e6180ccd72..5a48ce996de 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig | |||
@@ -29,6 +29,14 @@ config XEN_DEV_EVTCHN | |||
29 | firing. | 29 | firing. |
30 | If in doubt, say yes. | 30 | If in doubt, say yes. |
31 | 31 | ||
32 | config XEN_BACKEND | ||
33 | bool "Backend driver support" | ||
34 | depends on XEN_DOM0 | ||
35 | default y | ||
36 | help | ||
37 | Support for backend device drivers that provide I/O services | ||
38 | to other virtual machines. | ||
39 | |||
32 | config XENFS | 40 | config XENFS |
33 | tristate "Xen filesystem" | 41 | tristate "Xen filesystem" |
34 | default y | 42 | default y |
@@ -62,6 +70,9 @@ config XEN_SYS_HYPERVISOR | |||
62 | virtual environment, /sys/hypervisor will still be present, | 70 | virtual environment, /sys/hypervisor will still be present, |
63 | but will have no xen contents. | 71 | but will have no xen contents. |
64 | 72 | ||
73 | config XEN_XENBUS_FRONTEND | ||
74 | tristate | ||
75 | |||
65 | config XEN_PLATFORM_PCI | 76 | config XEN_PLATFORM_PCI |
66 | tristate "xen platform pci device driver" | 77 | tristate "xen platform pci device driver" |
67 | depends on XEN_PVHVM | 78 | depends on XEN_PVHVM |
diff --git a/drivers/xen/xenbus/Makefile b/drivers/xen/xenbus/Makefile index 5571f5b8422..8dca685358b 100644 --- a/drivers/xen/xenbus/Makefile +++ b/drivers/xen/xenbus/Makefile | |||
@@ -5,3 +5,8 @@ xenbus-objs += xenbus_client.o | |||
5 | xenbus-objs += xenbus_comms.o | 5 | xenbus-objs += xenbus_comms.o |
6 | xenbus-objs += xenbus_xs.o | 6 | xenbus-objs += xenbus_xs.o |
7 | xenbus-objs += xenbus_probe.o | 7 | xenbus-objs += xenbus_probe.o |
8 | |||
9 | xenbus-be-objs-$(CONFIG_XEN_BACKEND) += xenbus_probe_backend.o | ||
10 | xenbus-objs += $(xenbus-be-objs-y) | ||
11 | |||
12 | obj-$(CONFIG_XEN_XENBUS_FRONTEND) += xenbus_probe_frontend.o | ||
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index deb9c4ba3a9..baa65e7fbbc 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <xen/events.h> | 56 | #include <xen/events.h> |
57 | #include <xen/page.h> | 57 | #include <xen/page.h> |
58 | 58 | ||
59 | #include <xen/platform_pci.h> | ||
60 | #include <xen/hvm.h> | 59 | #include <xen/hvm.h> |
61 | 60 | ||
62 | #include "xenbus_comms.h" | 61 | #include "xenbus_comms.h" |
@@ -73,15 +72,6 @@ static unsigned long xen_store_mfn; | |||
73 | 72 | ||
74 | static BLOCKING_NOTIFIER_HEAD(xenstore_chain); | 73 | static BLOCKING_NOTIFIER_HEAD(xenstore_chain); |
75 | 74 | ||
76 | static void wait_for_devices(struct xenbus_driver *xendrv); | ||
77 | |||
78 | static int xenbus_probe_frontend(const char *type, const char *name); | ||
79 | |||
80 | static void xenbus_dev_shutdown(struct device *_dev); | ||
81 | |||
82 | static int xenbus_dev_suspend(struct device *dev, pm_message_t state); | ||
83 | static int xenbus_dev_resume(struct device *dev); | ||
84 | |||
85 | /* If something in array of ids matches this device, return it. */ | 75 | /* If something in array of ids matches this device, return it. */ |
86 | static const struct xenbus_device_id * | 76 | static const struct xenbus_device_id * |
87 | match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev) | 77 | match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev) |
@@ -102,34 +92,7 @@ int xenbus_match(struct device *_dev, struct device_driver *_drv) | |||
102 | 92 | ||
103 | return match_device(drv->ids, to_xenbus_device(_dev)) != NULL; | 93 | return match_device(drv->ids, to_xenbus_device(_dev)) != NULL; |
104 | } | 94 | } |
105 | 95 | EXPORT_SYMBOL_GPL(xenbus_match); | |
106 | static int xenbus_uevent(struct device *_dev, struct kobj_uevent_env *env) | ||
107 | { | ||
108 | struct xenbus_device *dev = to_xenbus_device(_dev); | ||
109 | |||
110 | if (add_uevent_var(env, "MODALIAS=xen:%s", dev->devicetype)) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | /* device/<type>/<id> => <type>-<id> */ | ||
117 | static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) | ||
118 | { | ||
119 | nodename = strchr(nodename, '/'); | ||
120 | if (!nodename || strlen(nodename + 1) >= XEN_BUS_ID_SIZE) { | ||
121 | printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename); | ||
122 | return -EINVAL; | ||
123 | } | ||
124 | |||
125 | strlcpy(bus_id, nodename + 1, XEN_BUS_ID_SIZE); | ||
126 | if (!strchr(bus_id, '/')) { | ||
127 | printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | *strchr(bus_id, '/') = '-'; | ||
131 | return 0; | ||
132 | } | ||
133 | 96 | ||
134 | 97 | ||
135 | static void free_otherend_details(struct xenbus_device *dev) | 98 | static void free_otherend_details(struct xenbus_device *dev) |
@@ -149,7 +112,30 @@ static void free_otherend_watch(struct xenbus_device *dev) | |||
149 | } | 112 | } |
150 | 113 | ||
151 | 114 | ||
152 | int read_otherend_details(struct xenbus_device *xendev, | 115 | static int talk_to_otherend(struct xenbus_device *dev) |
116 | { | ||
117 | struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver); | ||
118 | |||
119 | free_otherend_watch(dev); | ||
120 | free_otherend_details(dev); | ||
121 | |||
122 | return drv->read_otherend_details(dev); | ||
123 | } | ||
124 | |||
125 | |||
126 | |||
127 | static int watch_otherend(struct xenbus_device *dev) | ||
128 | { | ||
129 | struct xen_bus_type *bus = | ||
130 | container_of(dev->dev.bus, struct xen_bus_type, bus); | ||
131 | |||
132 | return xenbus_watch_pathfmt(dev, &dev->otherend_watch, | ||
133 | bus->otherend_changed, | ||
134 | "%s/%s", dev->otherend, "state"); | ||
135 | } | ||
136 | |||
137 | |||
138 | int xenbus_read_otherend_details(struct xenbus_device *xendev, | ||
153 | char *id_node, char *path_node) | 139 | char *id_node, char *path_node) |
154 | { | 140 | { |
155 | int err = xenbus_gather(XBT_NIL, xendev->nodename, | 141 | int err = xenbus_gather(XBT_NIL, xendev->nodename, |
@@ -174,39 +160,11 @@ int read_otherend_details(struct xenbus_device *xendev, | |||
174 | 160 | ||
175 | return 0; | 161 | return 0; |
176 | } | 162 | } |
163 | EXPORT_SYMBOL_GPL(xenbus_read_otherend_details); | ||
177 | 164 | ||
178 | 165 | void xenbus_otherend_changed(struct xenbus_watch *watch, | |
179 | static int read_backend_details(struct xenbus_device *xendev) | 166 | const char **vec, unsigned int len, |
180 | { | 167 | int ignore_on_shutdown) |
181 | return read_otherend_details(xendev, "backend-id", "backend"); | ||
182 | } | ||
183 | |||
184 | static struct device_attribute xenbus_dev_attrs[] = { | ||
185 | __ATTR_NULL | ||
186 | }; | ||
187 | |||
188 | /* Bus type for frontend drivers. */ | ||
189 | static struct xen_bus_type xenbus_frontend = { | ||
190 | .root = "device", | ||
191 | .levels = 2, /* device/type/<id> */ | ||
192 | .get_bus_id = frontend_bus_id, | ||
193 | .probe = xenbus_probe_frontend, | ||
194 | .bus = { | ||
195 | .name = "xen", | ||
196 | .match = xenbus_match, | ||
197 | .uevent = xenbus_uevent, | ||
198 | .probe = xenbus_dev_probe, | ||
199 | .remove = xenbus_dev_remove, | ||
200 | .shutdown = xenbus_dev_shutdown, | ||
201 | .dev_attrs = xenbus_dev_attrs, | ||
202 | |||
203 | .suspend = xenbus_dev_suspend, | ||
204 | .resume = xenbus_dev_resume, | ||
205 | }, | ||
206 | }; | ||
207 | |||
208 | static void otherend_changed(struct xenbus_watch *watch, | ||
209 | const char **vec, unsigned int len) | ||
210 | { | 168 | { |
211 | struct xenbus_device *dev = | 169 | struct xenbus_device *dev = |
212 | container_of(watch, struct xenbus_device, otherend_watch); | 170 | container_of(watch, struct xenbus_device, otherend_watch); |
@@ -234,11 +192,7 @@ static void otherend_changed(struct xenbus_watch *watch, | |||
234 | * work that can fail e.g., when the rootfs is gone. | 192 | * work that can fail e.g., when the rootfs is gone. |
235 | */ | 193 | */ |
236 | if (system_state > SYSTEM_RUNNING) { | 194 | if (system_state > SYSTEM_RUNNING) { |
237 | struct xen_bus_type *bus = bus; | 195 | if (ignore_on_shutdown && (state == XenbusStateClosing)) |
238 | bus = container_of(dev->dev.bus, struct xen_bus_type, bus); | ||
239 | /* If we're frontend, drive the state machine to Closed. */ | ||
240 | /* This should cause the backend to release our resources. */ | ||
241 | if ((bus == &xenbus_frontend) && (state == XenbusStateClosing)) | ||
242 | xenbus_frontend_closed(dev); | 196 | xenbus_frontend_closed(dev); |
243 | return; | 197 | return; |
244 | } | 198 | } |
@@ -246,25 +200,7 @@ static void otherend_changed(struct xenbus_watch *watch, | |||
246 | if (drv->otherend_changed) | 200 | if (drv->otherend_changed) |
247 | drv->otherend_changed(dev, state); | 201 | drv->otherend_changed(dev, state); |
248 | } | 202 | } |
249 | 203 | EXPORT_SYMBOL_GPL(xenbus_otherend_changed); | |
250 | |||
251 | static int talk_to_otherend(struct xenbus_device *dev) | ||
252 | { | ||
253 | struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver); | ||
254 | |||
255 | free_otherend_watch(dev); | ||
256 | free_otherend_details(dev); | ||
257 | |||
258 | return drv->read_otherend_details(dev); | ||
259 | } | ||
260 | |||
261 | |||
262 | static int watch_otherend(struct xenbus_device *dev) | ||
263 | { | ||
264 | return xenbus_watch_pathfmt(dev, &dev->otherend_watch, otherend_changed, | ||
265 | "%s/%s", dev->otherend, "state"); | ||
266 | } | ||
267 | |||
268 | 204 | ||
269 | int xenbus_dev_probe(struct device *_dev) | 205 | int xenbus_dev_probe(struct device *_dev) |
270 | { | 206 | { |
@@ -308,8 +244,9 @@ int xenbus_dev_probe(struct device *_dev) | |||
308 | fail: | 244 | fail: |
309 | xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename); | 245 | xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename); |
310 | xenbus_switch_state(dev, XenbusStateClosed); | 246 | xenbus_switch_state(dev, XenbusStateClosed); |
311 | return -ENODEV; | 247 | return err; |
312 | } | 248 | } |
249 | EXPORT_SYMBOL_GPL(xenbus_dev_probe); | ||
313 | 250 | ||
314 | int xenbus_dev_remove(struct device *_dev) | 251 | int xenbus_dev_remove(struct device *_dev) |
315 | { | 252 | { |
@@ -327,8 +264,9 @@ int xenbus_dev_remove(struct device *_dev) | |||
327 | xenbus_switch_state(dev, XenbusStateClosed); | 264 | xenbus_switch_state(dev, XenbusStateClosed); |
328 | return 0; | 265 | return 0; |
329 | } | 266 | } |
267 | EXPORT_SYMBOL_GPL(xenbus_dev_remove); | ||
330 | 268 | ||
331 | static void xenbus_dev_shutdown(struct device *_dev) | 269 | void xenbus_dev_shutdown(struct device *_dev) |
332 | { | 270 | { |
333 | struct xenbus_device *dev = to_xenbus_device(_dev); | 271 | struct xenbus_device *dev = to_xenbus_device(_dev); |
334 | unsigned long timeout = 5*HZ; | 272 | unsigned long timeout = 5*HZ; |
@@ -349,6 +287,7 @@ static void xenbus_dev_shutdown(struct device *_dev) | |||
349 | out: | 287 | out: |
350 | put_device(&dev->dev); | 288 | put_device(&dev->dev); |
351 | } | 289 | } |
290 | EXPORT_SYMBOL_GPL(xenbus_dev_shutdown); | ||
352 | 291 | ||
353 | int xenbus_register_driver_common(struct xenbus_driver *drv, | 292 | int xenbus_register_driver_common(struct xenbus_driver *drv, |
354 | struct xen_bus_type *bus, | 293 | struct xen_bus_type *bus, |
@@ -362,25 +301,7 @@ int xenbus_register_driver_common(struct xenbus_driver *drv, | |||
362 | 301 | ||
363 | return driver_register(&drv->driver); | 302 | return driver_register(&drv->driver); |
364 | } | 303 | } |
365 | 304 | EXPORT_SYMBOL_GPL(xenbus_register_driver_common); | |
366 | int __xenbus_register_frontend(struct xenbus_driver *drv, | ||
367 | struct module *owner, const char *mod_name) | ||
368 | { | ||
369 | int ret; | ||
370 | |||
371 | drv->read_otherend_details = read_backend_details; | ||
372 | |||
373 | ret = xenbus_register_driver_common(drv, &xenbus_frontend, | ||
374 | owner, mod_name); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | |||
378 | /* If this driver is loaded as a module wait for devices to attach. */ | ||
379 | wait_for_devices(drv); | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | EXPORT_SYMBOL_GPL(__xenbus_register_frontend); | ||
384 | 305 | ||
385 | void xenbus_unregister_driver(struct xenbus_driver *drv) | 306 | void xenbus_unregister_driver(struct xenbus_driver *drv) |
386 | { | 307 | { |
@@ -551,24 +472,7 @@ fail: | |||
551 | kfree(xendev); | 472 | kfree(xendev); |
552 | return err; | 473 | return err; |
553 | } | 474 | } |
554 | 475 | EXPORT_SYMBOL_GPL(xenbus_probe_node); | |
555 | /* device/<typename>/<name> */ | ||
556 | static int xenbus_probe_frontend(const char *type, const char *name) | ||
557 | { | ||
558 | char *nodename; | ||
559 | int err; | ||
560 | |||
561 | nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", | ||
562 | xenbus_frontend.root, type, name); | ||
563 | if (!nodename) | ||
564 | return -ENOMEM; | ||
565 | |||
566 | DPRINTK("%s", nodename); | ||
567 | |||
568 | err = xenbus_probe_node(&xenbus_frontend, type, nodename); | ||
569 | kfree(nodename); | ||
570 | return err; | ||
571 | } | ||
572 | 476 | ||
573 | static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type) | 477 | static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type) |
574 | { | 478 | { |
@@ -582,10 +486,11 @@ static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type) | |||
582 | return PTR_ERR(dir); | 486 | return PTR_ERR(dir); |
583 | 487 | ||
584 | for (i = 0; i < dir_n; i++) { | 488 | for (i = 0; i < dir_n; i++) { |
585 | err = bus->probe(type, dir[i]); | 489 | err = bus->probe(bus, type, dir[i]); |
586 | if (err) | 490 | if (err) |
587 | break; | 491 | break; |
588 | } | 492 | } |
493 | |||
589 | kfree(dir); | 494 | kfree(dir); |
590 | return err; | 495 | return err; |
591 | } | 496 | } |
@@ -605,9 +510,11 @@ int xenbus_probe_devices(struct xen_bus_type *bus) | |||
605 | if (err) | 510 | if (err) |
606 | break; | 511 | break; |
607 | } | 512 | } |
513 | |||
608 | kfree(dir); | 514 | kfree(dir); |
609 | return err; | 515 | return err; |
610 | } | 516 | } |
517 | EXPORT_SYMBOL_GPL(xenbus_probe_devices); | ||
611 | 518 | ||
612 | static unsigned int char_count(const char *str, char c) | 519 | static unsigned int char_count(const char *str, char c) |
613 | { | 520 | { |
@@ -670,32 +577,18 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus) | |||
670 | } | 577 | } |
671 | EXPORT_SYMBOL_GPL(xenbus_dev_changed); | 578 | EXPORT_SYMBOL_GPL(xenbus_dev_changed); |
672 | 579 | ||
673 | static void frontend_changed(struct xenbus_watch *watch, | 580 | int xenbus_dev_suspend(struct device *dev, pm_message_t state) |
674 | const char **vec, unsigned int len) | ||
675 | { | ||
676 | DPRINTK(""); | ||
677 | |||
678 | xenbus_dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend); | ||
679 | } | ||
680 | |||
681 | /* We watch for devices appearing and vanishing. */ | ||
682 | static struct xenbus_watch fe_watch = { | ||
683 | .node = "device", | ||
684 | .callback = frontend_changed, | ||
685 | }; | ||
686 | |||
687 | static int xenbus_dev_suspend(struct device *dev, pm_message_t state) | ||
688 | { | 581 | { |
689 | int err = 0; | 582 | int err = 0; |
690 | struct xenbus_driver *drv; | 583 | struct xenbus_driver *drv; |
691 | struct xenbus_device *xdev; | 584 | struct xenbus_device *xdev |
585 | = container_of(dev, struct xenbus_device, dev); | ||
692 | 586 | ||
693 | DPRINTK(""); | 587 | DPRINTK("%s", xdev->nodename); |
694 | 588 | ||
695 | if (dev->driver == NULL) | 589 | if (dev->driver == NULL) |
696 | return 0; | 590 | return 0; |
697 | drv = to_xenbus_driver(dev->driver); | 591 | drv = to_xenbus_driver(dev->driver); |
698 | xdev = container_of(dev, struct xenbus_device, dev); | ||
699 | if (drv->suspend) | 592 | if (drv->suspend) |
700 | err = drv->suspend(xdev, state); | 593 | err = drv->suspend(xdev, state); |
701 | if (err) | 594 | if (err) |
@@ -703,21 +596,20 @@ static int xenbus_dev_suspend(struct device *dev, pm_message_t state) | |||
703 | "xenbus: suspend %s failed: %i\n", dev_name(dev), err); | 596 | "xenbus: suspend %s failed: %i\n", dev_name(dev), err); |
704 | return 0; | 597 | return 0; |
705 | } | 598 | } |
599 | EXPORT_SYMBOL_GPL(xenbus_dev_suspend); | ||
706 | 600 | ||
707 | static int xenbus_dev_resume(struct device *dev) | 601 | int xenbus_dev_resume(struct device *dev) |
708 | { | 602 | { |
709 | int err; | 603 | int err; |
710 | struct xenbus_driver *drv; | 604 | struct xenbus_driver *drv; |
711 | struct xenbus_device *xdev; | 605 | struct xenbus_device *xdev |
606 | = container_of(dev, struct xenbus_device, dev); | ||
712 | 607 | ||
713 | DPRINTK(""); | 608 | DPRINTK("%s", xdev->nodename); |
714 | 609 | ||
715 | if (dev->driver == NULL) | 610 | if (dev->driver == NULL) |
716 | return 0; | 611 | return 0; |
717 | |||
718 | drv = to_xenbus_driver(dev->driver); | 612 | drv = to_xenbus_driver(dev->driver); |
719 | xdev = container_of(dev, struct xenbus_device, dev); | ||
720 | |||
721 | err = talk_to_otherend(xdev); | 613 | err = talk_to_otherend(xdev); |
722 | if (err) { | 614 | if (err) { |
723 | printk(KERN_WARNING | 615 | printk(KERN_WARNING |
@@ -748,6 +640,7 @@ static int xenbus_dev_resume(struct device *dev) | |||
748 | 640 | ||
749 | return 0; | 641 | return 0; |
750 | } | 642 | } |
643 | EXPORT_SYMBOL_GPL(xenbus_dev_resume); | ||
751 | 644 | ||
752 | /* A flag to determine if xenstored is 'ready' (i.e. has started) */ | 645 | /* A flag to determine if xenstored is 'ready' (i.e. has started) */ |
753 | int xenstored_ready = 0; | 646 | int xenstored_ready = 0; |
@@ -776,11 +669,6 @@ void xenbus_probe(struct work_struct *unused) | |||
776 | { | 669 | { |
777 | xenstored_ready = 1; | 670 | xenstored_ready = 1; |
778 | 671 | ||
779 | /* Enumerate devices in xenstore and watch for changes. */ | ||
780 | xenbus_probe_devices(&xenbus_frontend); | ||
781 | register_xenbus_watch(&fe_watch); | ||
782 | xenbus_backend_probe_and_watch(); | ||
783 | |||
784 | /* Notify others that xenstore is up */ | 672 | /* Notify others that xenstore is up */ |
785 | blocking_notifier_call_chain(&xenstore_chain, 0, NULL); | 673 | blocking_notifier_call_chain(&xenstore_chain, 0, NULL); |
786 | } | 674 | } |
@@ -809,16 +697,7 @@ static int __init xenbus_init(void) | |||
809 | 697 | ||
810 | err = -ENODEV; | 698 | err = -ENODEV; |
811 | if (!xen_domain()) | 699 | if (!xen_domain()) |
812 | goto out_error; | 700 | return err; |
813 | |||
814 | /* Register ourselves with the kernel bus subsystem */ | ||
815 | err = bus_register(&xenbus_frontend.bus); | ||
816 | if (err) | ||
817 | goto out_error; | ||
818 | |||
819 | err = xenbus_backend_bus_register(); | ||
820 | if (err) | ||
821 | goto out_unreg_front; | ||
822 | 701 | ||
823 | /* | 702 | /* |
824 | * Domain0 doesn't have a store_evtchn or store_mfn yet. | 703 | * Domain0 doesn't have a store_evtchn or store_mfn yet. |
@@ -874,7 +753,7 @@ static int __init xenbus_init(void) | |||
874 | if (err) { | 753 | if (err) { |
875 | printk(KERN_WARNING | 754 | printk(KERN_WARNING |
876 | "XENBUS: Error initializing xenstore comms: %i\n", err); | 755 | "XENBUS: Error initializing xenstore comms: %i\n", err); |
877 | goto out_unreg_back; | 756 | goto out_error; |
878 | } | 757 | } |
879 | 758 | ||
880 | #ifdef CONFIG_XEN_COMPAT_XENFS | 759 | #ifdef CONFIG_XEN_COMPAT_XENFS |
@@ -887,133 +766,13 @@ static int __init xenbus_init(void) | |||
887 | 766 | ||
888 | return 0; | 767 | return 0; |
889 | 768 | ||
890 | out_unreg_back: | ||
891 | xenbus_backend_bus_unregister(); | ||
892 | |||
893 | out_unreg_front: | ||
894 | bus_unregister(&xenbus_frontend.bus); | ||
895 | |||
896 | out_error: | 769 | out_error: |
897 | if (page != 0) | 770 | if (page != 0) |
898 | free_page(page); | 771 | free_page(page); |
772 | |||
899 | return err; | 773 | return err; |
900 | } | 774 | } |
901 | 775 | ||
902 | postcore_initcall(xenbus_init); | 776 | postcore_initcall(xenbus_init); |
903 | 777 | ||
904 | MODULE_LICENSE("GPL"); | 778 | MODULE_LICENSE("GPL"); |
905 | |||
906 | static int is_device_connecting(struct device *dev, void *data) | ||
907 | { | ||
908 | struct xenbus_device *xendev = to_xenbus_device(dev); | ||
909 | struct device_driver *drv = data; | ||
910 | struct xenbus_driver *xendrv; | ||
911 | |||
912 | /* | ||
913 | * A device with no driver will never connect. We care only about | ||
914 | * devices which should currently be in the process of connecting. | ||
915 | */ | ||
916 | if (!dev->driver) | ||
917 | return 0; | ||
918 | |||
919 | /* Is this search limited to a particular driver? */ | ||
920 | if (drv && (dev->driver != drv)) | ||
921 | return 0; | ||
922 | |||
923 | xendrv = to_xenbus_driver(dev->driver); | ||
924 | return (xendev->state < XenbusStateConnected || | ||
925 | (xendev->state == XenbusStateConnected && | ||
926 | xendrv->is_ready && !xendrv->is_ready(xendev))); | ||
927 | } | ||
928 | |||
929 | static int exists_connecting_device(struct device_driver *drv) | ||
930 | { | ||
931 | return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, | ||
932 | is_device_connecting); | ||
933 | } | ||
934 | |||
935 | static int print_device_status(struct device *dev, void *data) | ||
936 | { | ||
937 | struct xenbus_device *xendev = to_xenbus_device(dev); | ||
938 | struct device_driver *drv = data; | ||
939 | |||
940 | /* Is this operation limited to a particular driver? */ | ||
941 | if (drv && (dev->driver != drv)) | ||
942 | return 0; | ||
943 | |||
944 | if (!dev->driver) { | ||
945 | /* Information only: is this too noisy? */ | ||
946 | printk(KERN_INFO "XENBUS: Device with no driver: %s\n", | ||
947 | xendev->nodename); | ||
948 | } else if (xendev->state < XenbusStateConnected) { | ||
949 | enum xenbus_state rstate = XenbusStateUnknown; | ||
950 | if (xendev->otherend) | ||
951 | rstate = xenbus_read_driver_state(xendev->otherend); | ||
952 | printk(KERN_WARNING "XENBUS: Timeout connecting " | ||
953 | "to device: %s (local state %d, remote state %d)\n", | ||
954 | xendev->nodename, xendev->state, rstate); | ||
955 | } | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | /* We only wait for device setup after most initcalls have run. */ | ||
961 | static int ready_to_wait_for_devices; | ||
962 | |||
963 | /* | ||
964 | * On a 5-minute timeout, wait for all devices currently configured. We need | ||
965 | * to do this to guarantee that the filesystems and / or network devices | ||
966 | * needed for boot are available, before we can allow the boot to proceed. | ||
967 | * | ||
968 | * This needs to be on a late_initcall, to happen after the frontend device | ||
969 | * drivers have been initialised, but before the root fs is mounted. | ||
970 | * | ||
971 | * A possible improvement here would be to have the tools add a per-device | ||
972 | * flag to the store entry, indicating whether it is needed at boot time. | ||
973 | * This would allow people who knew what they were doing to accelerate their | ||
974 | * boot slightly, but of course needs tools or manual intervention to set up | ||
975 | * those flags correctly. | ||
976 | */ | ||
977 | static void wait_for_devices(struct xenbus_driver *xendrv) | ||
978 | { | ||
979 | unsigned long start = jiffies; | ||
980 | struct device_driver *drv = xendrv ? &xendrv->driver : NULL; | ||
981 | unsigned int seconds_waited = 0; | ||
982 | |||
983 | if (!ready_to_wait_for_devices || !xen_domain()) | ||
984 | return; | ||
985 | |||
986 | while (exists_connecting_device(drv)) { | ||
987 | if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { | ||
988 | if (!seconds_waited) | ||
989 | printk(KERN_WARNING "XENBUS: Waiting for " | ||
990 | "devices to initialise: "); | ||
991 | seconds_waited += 5; | ||
992 | printk("%us...", 300 - seconds_waited); | ||
993 | if (seconds_waited == 300) | ||
994 | break; | ||
995 | } | ||
996 | |||
997 | schedule_timeout_interruptible(HZ/10); | ||
998 | } | ||
999 | |||
1000 | if (seconds_waited) | ||
1001 | printk("\n"); | ||
1002 | |||
1003 | bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, | ||
1004 | print_device_status); | ||
1005 | } | ||
1006 | |||
1007 | #ifndef MODULE | ||
1008 | static int __init boot_wait_for_devices(void) | ||
1009 | { | ||
1010 | if (xen_hvm_domain() && !xen_platform_pci_unplug) | ||
1011 | return -ENODEV; | ||
1012 | |||
1013 | ready_to_wait_for_devices = 1; | ||
1014 | wait_for_devices(NULL); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | late_initcall(boot_wait_for_devices); | ||
1019 | #endif | ||
diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h index 6c5e3185a6a..24665812316 100644 --- a/drivers/xen/xenbus/xenbus_probe.h +++ b/drivers/xen/xenbus/xenbus_probe.h | |||
@@ -36,26 +36,15 @@ | |||
36 | 36 | ||
37 | #define XEN_BUS_ID_SIZE 20 | 37 | #define XEN_BUS_ID_SIZE 20 |
38 | 38 | ||
39 | #ifdef CONFIG_XEN_BACKEND | ||
40 | extern void xenbus_backend_suspend(int (*fn)(struct device *, void *)); | ||
41 | extern void xenbus_backend_resume(int (*fn)(struct device *, void *)); | ||
42 | extern void xenbus_backend_probe_and_watch(void); | ||
43 | extern int xenbus_backend_bus_register(void); | ||
44 | extern void xenbus_backend_bus_unregister(void); | ||
45 | #else | ||
46 | static inline void xenbus_backend_suspend(int (*fn)(struct device *, void *)) {} | ||
47 | static inline void xenbus_backend_resume(int (*fn)(struct device *, void *)) {} | ||
48 | static inline void xenbus_backend_probe_and_watch(void) {} | ||
49 | static inline int xenbus_backend_bus_register(void) { return 0; } | ||
50 | static inline void xenbus_backend_bus_unregister(void) {} | ||
51 | #endif | ||
52 | |||
53 | struct xen_bus_type | 39 | struct xen_bus_type |
54 | { | 40 | { |
55 | char *root; | 41 | char *root; |
56 | unsigned int levels; | 42 | unsigned int levels; |
57 | int (*get_bus_id)(char bus_id[XEN_BUS_ID_SIZE], const char *nodename); | 43 | int (*get_bus_id)(char bus_id[XEN_BUS_ID_SIZE], const char *nodename); |
58 | int (*probe)(const char *type, const char *dir); | 44 | int (*probe)(struct xen_bus_type *bus, const char *type, |
45 | const char *dir); | ||
46 | void (*otherend_changed)(struct xenbus_watch *watch, const char **vec, | ||
47 | unsigned int len); | ||
59 | struct bus_type bus; | 48 | struct bus_type bus; |
60 | }; | 49 | }; |
61 | 50 | ||
@@ -73,4 +62,16 @@ extern int xenbus_probe_devices(struct xen_bus_type *bus); | |||
73 | 62 | ||
74 | extern void xenbus_dev_changed(const char *node, struct xen_bus_type *bus); | 63 | extern void xenbus_dev_changed(const char *node, struct xen_bus_type *bus); |
75 | 64 | ||
65 | extern void xenbus_dev_shutdown(struct device *_dev); | ||
66 | |||
67 | extern int xenbus_dev_suspend(struct device *dev, pm_message_t state); | ||
68 | extern int xenbus_dev_resume(struct device *dev); | ||
69 | |||
70 | extern void xenbus_otherend_changed(struct xenbus_watch *watch, | ||
71 | const char **vec, unsigned int len, | ||
72 | int ignore_on_shutdown); | ||
73 | |||
74 | extern int xenbus_read_otherend_details(struct xenbus_device *xendev, | ||
75 | char *id_node, char *path_node); | ||
76 | |||
76 | #endif | 77 | #endif |
diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c new file mode 100644 index 00000000000..6cf467bf63e --- /dev/null +++ b/drivers/xen/xenbus/xenbus_probe_backend.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /****************************************************************************** | ||
2 | * Talks to Xen Store to figure out what devices we have (backend half). | ||
3 | * | ||
4 | * Copyright (C) 2005 Rusty Russell, IBM Corporation | ||
5 | * Copyright (C) 2005 Mike Wray, Hewlett-Packard | ||
6 | * Copyright (C) 2005, 2006 XenSource Ltd | ||
7 | * Copyright (C) 2007 Solarflare Communications, Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License version 2 | ||
11 | * as published by the Free Software Foundation; or, when distributed | ||
12 | * separately from the Linux kernel or incorporated into other | ||
13 | * software packages, subject to the following license: | ||
14 | * | ||
15 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
16 | * of this source file (the "Software"), to deal in the Software without | ||
17 | * restriction, including without limitation the rights to use, copy, modify, | ||
18 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
19 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
20 | * the following conditions: | ||
21 | * | ||
22 | * The above copyright notice and this permission notice shall be included in | ||
23 | * all copies or substantial portions of the Software. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
26 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
27 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
28 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
29 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
30 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
31 | * IN THE SOFTWARE. | ||
32 | */ | ||
33 | |||
34 | #define DPRINTK(fmt, args...) \ | ||
35 | pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \ | ||
36 | __func__, __LINE__, ##args) | ||
37 | |||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/err.h> | ||
40 | #include <linux/string.h> | ||
41 | #include <linux/ctype.h> | ||
42 | #include <linux/fcntl.h> | ||
43 | #include <linux/mm.h> | ||
44 | #include <linux/notifier.h> | ||
45 | |||
46 | #include <asm/page.h> | ||
47 | #include <asm/pgtable.h> | ||
48 | #include <asm/xen/hypervisor.h> | ||
49 | #include <asm/hypervisor.h> | ||
50 | #include <xen/xenbus.h> | ||
51 | #include <xen/features.h> | ||
52 | |||
53 | #include "xenbus_comms.h" | ||
54 | #include "xenbus_probe.h" | ||
55 | |||
56 | /* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */ | ||
57 | static int backend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) | ||
58 | { | ||
59 | int domid, err; | ||
60 | const char *devid, *type, *frontend; | ||
61 | unsigned int typelen; | ||
62 | |||
63 | type = strchr(nodename, '/'); | ||
64 | if (!type) | ||
65 | return -EINVAL; | ||
66 | type++; | ||
67 | typelen = strcspn(type, "/"); | ||
68 | if (!typelen || type[typelen] != '/') | ||
69 | return -EINVAL; | ||
70 | |||
71 | devid = strrchr(nodename, '/') + 1; | ||
72 | |||
73 | err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid, | ||
74 | "frontend", NULL, &frontend, | ||
75 | NULL); | ||
76 | if (err) | ||
77 | return err; | ||
78 | if (strlen(frontend) == 0) | ||
79 | err = -ERANGE; | ||
80 | if (!err && !xenbus_exists(XBT_NIL, frontend, "")) | ||
81 | err = -ENOENT; | ||
82 | kfree(frontend); | ||
83 | |||
84 | if (err) | ||
85 | return err; | ||
86 | |||
87 | if (snprintf(bus_id, XEN_BUS_ID_SIZE, "%.*s-%i-%s", | ||
88 | typelen, type, domid, devid) >= XEN_BUS_ID_SIZE) | ||
89 | return -ENOSPC; | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static int xenbus_uevent_backend(struct device *dev, | ||
94 | struct kobj_uevent_env *env) | ||
95 | { | ||
96 | struct xenbus_device *xdev; | ||
97 | struct xenbus_driver *drv; | ||
98 | struct xen_bus_type *bus; | ||
99 | |||
100 | DPRINTK(""); | ||
101 | |||
102 | if (dev == NULL) | ||
103 | return -ENODEV; | ||
104 | |||
105 | xdev = to_xenbus_device(dev); | ||
106 | bus = container_of(xdev->dev.bus, struct xen_bus_type, bus); | ||
107 | if (xdev == NULL) | ||
108 | return -ENODEV; | ||
109 | |||
110 | /* stuff we want to pass to /sbin/hotplug */ | ||
111 | if (add_uevent_var(env, "XENBUS_TYPE=%s", xdev->devicetype)) | ||
112 | return -ENOMEM; | ||
113 | |||
114 | if (add_uevent_var(env, "XENBUS_PATH=%s", xdev->nodename)) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | if (add_uevent_var(env, "XENBUS_BASE_PATH=%s", bus->root)) | ||
118 | return -ENOMEM; | ||
119 | |||
120 | if (dev->driver) { | ||
121 | drv = to_xenbus_driver(dev->driver); | ||
122 | if (drv && drv->uevent) | ||
123 | return drv->uevent(xdev, env); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | /* backend/<typename>/<frontend-uuid>/<name> */ | ||
130 | static int xenbus_probe_backend_unit(struct xen_bus_type *bus, | ||
131 | const char *dir, | ||
132 | const char *type, | ||
133 | const char *name) | ||
134 | { | ||
135 | char *nodename; | ||
136 | int err; | ||
137 | |||
138 | nodename = kasprintf(GFP_KERNEL, "%s/%s", dir, name); | ||
139 | if (!nodename) | ||
140 | return -ENOMEM; | ||
141 | |||
142 | DPRINTK("%s\n", nodename); | ||
143 | |||
144 | err = xenbus_probe_node(bus, type, nodename); | ||
145 | kfree(nodename); | ||
146 | return err; | ||
147 | } | ||
148 | |||
149 | /* backend/<typename>/<frontend-domid> */ | ||
150 | static int xenbus_probe_backend(struct xen_bus_type *bus, const char *type, | ||
151 | const char *domid) | ||
152 | { | ||
153 | char *nodename; | ||
154 | int err = 0; | ||
155 | char **dir; | ||
156 | unsigned int i, dir_n = 0; | ||
157 | |||
158 | DPRINTK(""); | ||
159 | |||
160 | nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", bus->root, type, domid); | ||
161 | if (!nodename) | ||
162 | return -ENOMEM; | ||
163 | |||
164 | dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n); | ||
165 | if (IS_ERR(dir)) { | ||
166 | kfree(nodename); | ||
167 | return PTR_ERR(dir); | ||
168 | } | ||
169 | |||
170 | for (i = 0; i < dir_n; i++) { | ||
171 | err = xenbus_probe_backend_unit(bus, nodename, type, dir[i]); | ||
172 | if (err) | ||
173 | break; | ||
174 | } | ||
175 | kfree(dir); | ||
176 | kfree(nodename); | ||
177 | return err; | ||
178 | } | ||
179 | |||
180 | static void frontend_changed(struct xenbus_watch *watch, | ||
181 | const char **vec, unsigned int len) | ||
182 | { | ||
183 | xenbus_otherend_changed(watch, vec, len, 0); | ||
184 | } | ||
185 | |||
186 | static struct device_attribute xenbus_backend_dev_attrs[] = { | ||
187 | __ATTR_NULL | ||
188 | }; | ||
189 | |||
190 | static struct xen_bus_type xenbus_backend = { | ||
191 | .root = "backend", | ||
192 | .levels = 3, /* backend/type/<frontend>/<id> */ | ||
193 | .get_bus_id = backend_bus_id, | ||
194 | .probe = xenbus_probe_backend, | ||
195 | .otherend_changed = frontend_changed, | ||
196 | .bus = { | ||
197 | .name = "xen-backend", | ||
198 | .match = xenbus_match, | ||
199 | .uevent = xenbus_uevent_backend, | ||
200 | .probe = xenbus_dev_probe, | ||
201 | .remove = xenbus_dev_remove, | ||
202 | .shutdown = xenbus_dev_shutdown, | ||
203 | .dev_attrs = xenbus_backend_dev_attrs, | ||
204 | }, | ||
205 | }; | ||
206 | |||
207 | static void backend_changed(struct xenbus_watch *watch, | ||
208 | const char **vec, unsigned int len) | ||
209 | { | ||
210 | DPRINTK(""); | ||
211 | |||
212 | xenbus_dev_changed(vec[XS_WATCH_PATH], &xenbus_backend); | ||
213 | } | ||
214 | |||
215 | static struct xenbus_watch be_watch = { | ||
216 | .node = "backend", | ||
217 | .callback = backend_changed, | ||
218 | }; | ||
219 | |||
220 | static int read_frontend_details(struct xenbus_device *xendev) | ||
221 | { | ||
222 | return xenbus_read_otherend_details(xendev, "frontend-id", "frontend"); | ||
223 | } | ||
224 | |||
225 | int xenbus_dev_is_online(struct xenbus_device *dev) | ||
226 | { | ||
227 | int rc, val; | ||
228 | |||
229 | rc = xenbus_scanf(XBT_NIL, dev->nodename, "online", "%d", &val); | ||
230 | if (rc != 1) | ||
231 | val = 0; /* no online node present */ | ||
232 | |||
233 | return val; | ||
234 | } | ||
235 | EXPORT_SYMBOL_GPL(xenbus_dev_is_online); | ||
236 | |||
237 | int __xenbus_register_backend(struct xenbus_driver *drv, | ||
238 | struct module *owner, const char *mod_name) | ||
239 | { | ||
240 | drv->read_otherend_details = read_frontend_details; | ||
241 | |||
242 | return xenbus_register_driver_common(drv, &xenbus_backend, | ||
243 | owner, mod_name); | ||
244 | } | ||
245 | EXPORT_SYMBOL_GPL(__xenbus_register_backend); | ||
246 | |||
247 | static int backend_probe_and_watch(struct notifier_block *notifier, | ||
248 | unsigned long event, | ||
249 | void *data) | ||
250 | { | ||
251 | /* Enumerate devices in xenstore and watch for changes. */ | ||
252 | xenbus_probe_devices(&xenbus_backend); | ||
253 | register_xenbus_watch(&be_watch); | ||
254 | |||
255 | return NOTIFY_DONE; | ||
256 | } | ||
257 | |||
258 | static int __init xenbus_probe_backend_init(void) | ||
259 | { | ||
260 | static struct notifier_block xenstore_notifier = { | ||
261 | .notifier_call = backend_probe_and_watch | ||
262 | }; | ||
263 | int err; | ||
264 | |||
265 | DPRINTK(""); | ||
266 | |||
267 | /* Register ourselves with the kernel bus subsystem */ | ||
268 | err = bus_register(&xenbus_backend.bus); | ||
269 | if (err) | ||
270 | return err; | ||
271 | |||
272 | register_xenstore_notifier(&xenstore_notifier); | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | subsys_initcall(xenbus_probe_backend_init); | ||
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c new file mode 100644 index 00000000000..5bcc2d6cf12 --- /dev/null +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c | |||
@@ -0,0 +1,294 @@ | |||
1 | #define DPRINTK(fmt, args...) \ | ||
2 | pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \ | ||
3 | __func__, __LINE__, ##args) | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/err.h> | ||
7 | #include <linux/string.h> | ||
8 | #include <linux/ctype.h> | ||
9 | #include <linux/fcntl.h> | ||
10 | #include <linux/mm.h> | ||
11 | #include <linux/proc_fs.h> | ||
12 | #include <linux/notifier.h> | ||
13 | #include <linux/kthread.h> | ||
14 | #include <linux/mutex.h> | ||
15 | #include <linux/io.h> | ||
16 | |||
17 | #include <asm/page.h> | ||
18 | #include <asm/pgtable.h> | ||
19 | #include <asm/xen/hypervisor.h> | ||
20 | #include <xen/xenbus.h> | ||
21 | #include <xen/events.h> | ||
22 | #include <xen/page.h> | ||
23 | |||
24 | #include <xen/platform_pci.h> | ||
25 | |||
26 | #include "xenbus_comms.h" | ||
27 | #include "xenbus_probe.h" | ||
28 | |||
29 | |||
30 | /* device/<type>/<id> => <type>-<id> */ | ||
31 | static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) | ||
32 | { | ||
33 | nodename = strchr(nodename, '/'); | ||
34 | if (!nodename || strlen(nodename + 1) >= XEN_BUS_ID_SIZE) { | ||
35 | printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename); | ||
36 | return -EINVAL; | ||
37 | } | ||
38 | |||
39 | strlcpy(bus_id, nodename + 1, XEN_BUS_ID_SIZE); | ||
40 | if (!strchr(bus_id, '/')) { | ||
41 | printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id); | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | *strchr(bus_id, '/') = '-'; | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | /* device/<typename>/<name> */ | ||
49 | static int xenbus_probe_frontend(struct xen_bus_type *bus, const char *type, | ||
50 | const char *name) | ||
51 | { | ||
52 | char *nodename; | ||
53 | int err; | ||
54 | |||
55 | nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", bus->root, type, name); | ||
56 | if (!nodename) | ||
57 | return -ENOMEM; | ||
58 | |||
59 | DPRINTK("%s", nodename); | ||
60 | |||
61 | err = xenbus_probe_node(bus, type, nodename); | ||
62 | kfree(nodename); | ||
63 | return err; | ||
64 | } | ||
65 | |||
66 | static int xenbus_uevent_frontend(struct device *_dev, | ||
67 | struct kobj_uevent_env *env) | ||
68 | { | ||
69 | struct xenbus_device *dev = to_xenbus_device(_dev); | ||
70 | |||
71 | if (add_uevent_var(env, "MODALIAS=xen:%s", dev->devicetype)) | ||
72 | return -ENOMEM; | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | |||
78 | static void backend_changed(struct xenbus_watch *watch, | ||
79 | const char **vec, unsigned int len) | ||
80 | { | ||
81 | xenbus_otherend_changed(watch, vec, len, 1); | ||
82 | } | ||
83 | |||
84 | static struct device_attribute xenbus_frontend_dev_attrs[] = { | ||
85 | __ATTR_NULL | ||
86 | }; | ||
87 | |||
88 | static struct xen_bus_type xenbus_frontend = { | ||
89 | .root = "device", | ||
90 | .levels = 2, /* device/type/<id> */ | ||
91 | .get_bus_id = frontend_bus_id, | ||
92 | .probe = xenbus_probe_frontend, | ||
93 | .otherend_changed = backend_changed, | ||
94 | .bus = { | ||
95 | .name = "xen", | ||
96 | .match = xenbus_match, | ||
97 | .uevent = xenbus_uevent_frontend, | ||
98 | .probe = xenbus_dev_probe, | ||
99 | .remove = xenbus_dev_remove, | ||
100 | .shutdown = xenbus_dev_shutdown, | ||
101 | .dev_attrs = xenbus_frontend_dev_attrs, | ||
102 | |||
103 | .suspend = xenbus_dev_suspend, | ||
104 | .resume = xenbus_dev_resume, | ||
105 | }, | ||
106 | }; | ||
107 | |||
108 | static void frontend_changed(struct xenbus_watch *watch, | ||
109 | const char **vec, unsigned int len) | ||
110 | { | ||
111 | DPRINTK(""); | ||
112 | |||
113 | xenbus_dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend); | ||
114 | } | ||
115 | |||
116 | |||
117 | /* We watch for devices appearing and vanishing. */ | ||
118 | static struct xenbus_watch fe_watch = { | ||
119 | .node = "device", | ||
120 | .callback = frontend_changed, | ||
121 | }; | ||
122 | |||
123 | static int read_backend_details(struct xenbus_device *xendev) | ||
124 | { | ||
125 | return xenbus_read_otherend_details(xendev, "backend-id", "backend"); | ||
126 | } | ||
127 | |||
128 | static int is_device_connecting(struct device *dev, void *data) | ||
129 | { | ||
130 | struct xenbus_device *xendev = to_xenbus_device(dev); | ||
131 | struct device_driver *drv = data; | ||
132 | struct xenbus_driver *xendrv; | ||
133 | |||
134 | /* | ||
135 | * A device with no driver will never connect. We care only about | ||
136 | * devices which should currently be in the process of connecting. | ||
137 | */ | ||
138 | if (!dev->driver) | ||
139 | return 0; | ||
140 | |||
141 | /* Is this search limited to a particular driver? */ | ||
142 | if (drv && (dev->driver != drv)) | ||
143 | return 0; | ||
144 | |||
145 | xendrv = to_xenbus_driver(dev->driver); | ||
146 | return (xendev->state < XenbusStateConnected || | ||
147 | (xendev->state == XenbusStateConnected && | ||
148 | xendrv->is_ready && !xendrv->is_ready(xendev))); | ||
149 | } | ||
150 | |||
151 | static int exists_connecting_device(struct device_driver *drv) | ||
152 | { | ||
153 | return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, | ||
154 | is_device_connecting); | ||
155 | } | ||
156 | |||
157 | static int print_device_status(struct device *dev, void *data) | ||
158 | { | ||
159 | struct xenbus_device *xendev = to_xenbus_device(dev); | ||
160 | struct device_driver *drv = data; | ||
161 | |||
162 | /* Is this operation limited to a particular driver? */ | ||
163 | if (drv && (dev->driver != drv)) | ||
164 | return 0; | ||
165 | |||
166 | if (!dev->driver) { | ||
167 | /* Information only: is this too noisy? */ | ||
168 | printk(KERN_INFO "XENBUS: Device with no driver: %s\n", | ||
169 | xendev->nodename); | ||
170 | } else if (xendev->state < XenbusStateConnected) { | ||
171 | enum xenbus_state rstate = XenbusStateUnknown; | ||
172 | if (xendev->otherend) | ||
173 | rstate = xenbus_read_driver_state(xendev->otherend); | ||
174 | printk(KERN_WARNING "XENBUS: Timeout connecting " | ||
175 | "to device: %s (local state %d, remote state %d)\n", | ||
176 | xendev->nodename, xendev->state, rstate); | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | /* We only wait for device setup after most initcalls have run. */ | ||
183 | static int ready_to_wait_for_devices; | ||
184 | |||
185 | /* | ||
186 | * On a 5-minute timeout, wait for all devices currently configured. We need | ||
187 | * to do this to guarantee that the filesystems and / or network devices | ||
188 | * needed for boot are available, before we can allow the boot to proceed. | ||
189 | * | ||
190 | * This needs to be on a late_initcall, to happen after the frontend device | ||
191 | * drivers have been initialised, but before the root fs is mounted. | ||
192 | * | ||
193 | * A possible improvement here would be to have the tools add a per-device | ||
194 | * flag to the store entry, indicating whether it is needed at boot time. | ||
195 | * This would allow people who knew what they were doing to accelerate their | ||
196 | * boot slightly, but of course needs tools or manual intervention to set up | ||
197 | * those flags correctly. | ||
198 | */ | ||
199 | static void wait_for_devices(struct xenbus_driver *xendrv) | ||
200 | { | ||
201 | unsigned long start = jiffies; | ||
202 | struct device_driver *drv = xendrv ? &xendrv->driver : NULL; | ||
203 | unsigned int seconds_waited = 0; | ||
204 | |||
205 | if (!ready_to_wait_for_devices || !xen_domain()) | ||
206 | return; | ||
207 | |||
208 | while (exists_connecting_device(drv)) { | ||
209 | if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { | ||
210 | if (!seconds_waited) | ||
211 | printk(KERN_WARNING "XENBUS: Waiting for " | ||
212 | "devices to initialise: "); | ||
213 | seconds_waited += 5; | ||
214 | printk("%us...", 300 - seconds_waited); | ||
215 | if (seconds_waited == 300) | ||
216 | break; | ||
217 | } | ||
218 | |||
219 | schedule_timeout_interruptible(HZ/10); | ||
220 | } | ||
221 | |||
222 | if (seconds_waited) | ||
223 | printk("\n"); | ||
224 | |||
225 | bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, | ||
226 | print_device_status); | ||
227 | } | ||
228 | |||
229 | int __xenbus_register_frontend(struct xenbus_driver *drv, | ||
230 | struct module *owner, const char *mod_name) | ||
231 | { | ||
232 | int ret; | ||
233 | |||
234 | drv->read_otherend_details = read_backend_details; | ||
235 | |||
236 | ret = xenbus_register_driver_common(drv, &xenbus_frontend, | ||
237 | owner, mod_name); | ||
238 | if (ret) | ||
239 | return ret; | ||
240 | |||
241 | /* If this driver is loaded as a module wait for devices to attach. */ | ||
242 | wait_for_devices(drv); | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | EXPORT_SYMBOL_GPL(__xenbus_register_frontend); | ||
247 | |||
248 | static int frontend_probe_and_watch(struct notifier_block *notifier, | ||
249 | unsigned long event, | ||
250 | void *data) | ||
251 | { | ||
252 | /* Enumerate devices in xenstore and watch for changes. */ | ||
253 | xenbus_probe_devices(&xenbus_frontend); | ||
254 | register_xenbus_watch(&fe_watch); | ||
255 | |||
256 | return NOTIFY_DONE; | ||
257 | } | ||
258 | |||
259 | |||
260 | static int __init xenbus_probe_frontend_init(void) | ||
261 | { | ||
262 | static struct notifier_block xenstore_notifier = { | ||
263 | .notifier_call = frontend_probe_and_watch | ||
264 | }; | ||
265 | int err; | ||
266 | |||
267 | DPRINTK(""); | ||
268 | |||
269 | /* Register ourselves with the kernel bus subsystem */ | ||
270 | err = bus_register(&xenbus_frontend.bus); | ||
271 | if (err) | ||
272 | return err; | ||
273 | |||
274 | register_xenstore_notifier(&xenstore_notifier); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | subsys_initcall(xenbus_probe_frontend_init); | ||
279 | |||
280 | #ifndef MODULE | ||
281 | static int __init boot_wait_for_devices(void) | ||
282 | { | ||
283 | if (xen_hvm_domain() && !xen_platform_pci_unplug) | ||
284 | return -ENODEV; | ||
285 | |||
286 | ready_to_wait_for_devices = 1; | ||
287 | wait_for_devices(NULL); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | late_initcall(boot_wait_for_devices); | ||
292 | #endif | ||
293 | |||
294 | MODULE_LICENSE("GPL"); | ||